Perch layout: crows stand on the branch

- Each crow stands on its own branch segment; segments join into one
  line per row, names sit under it in one style
- Fixed headroom row for "?" and sparkles, centered over each crow
- Trust star gets its own corner, clear of the beak
- Dazed crows fade in place instead of tipping out of line
- Five crows per row on a phone; tighter rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQnSw4RRWp8uqpj3nsnnXF
This commit is contained in:
SmokeyandClaude Opus 5.5 committed 2026-10-27 12:31:17 -06:00
1 parent feb3bb1735
commit d0ae4fd1c0
1 file changed
+25 -22
+25 -22
View File
@@ -81,16 +81,12 @@ main { max-width: 680px; margin: 0 auto; padding: 0 16px 64px; }
}
.composer textarea:focus { outline: none; }
/* ---------- the perch: an inked branch with stippled underside ---------- */
.perch {
position: relative; display: flex; flex-wrap: wrap; gap: 10px 6px; justify-content: center; align-items: flex-end;
min-height: 140px; padding: 16px 8px 12px; margin: 8px 0 22px; border-bottom: 2px solid var(--ink);
}
.perch::after {
content: ""; position: absolute; left: 4%; right: 4%; bottom: -12px; height: 10px; background: var(--stipple);
-webkit-mask-image: linear-gradient(#000, transparent); mask-image: linear-gradient(#000, transparent);
}
.crow { margin: 0; width: 84px; display: grid; justify-items: center; position: relative; }
/* ---------- the perch ----------
Every crow stands on its own segment of one branch line; segments touch,
so each row reads as one branch. Names sit under the branch, all alike.
Each crow has a fixed 22px headroom row for marks ("?", sparkles). */
.perch { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 0; margin: 4px 0 26px; }
.crow { margin: 0; width: 76px; padding-top: 22px; display: grid; justify-items: center; position: relative; }
.crow.role-sentry { order: -1; }
.crow.role-elder { order: 99; }
.crow-body { width: 72px; height: 66px; }
@@ -100,16 +96,23 @@ main { max-width: 680px; margin: 0 auto; padding: 0 16px 64px; }
.crow.role-elder .disc { fill: #d6dde6; }
.crow .bird { fill: #000; }
.crow .jaw { transform-origin: 211px 182px; transition: transform 150ms; }
.crow figcaption { margin-top: 2px; font: 400 15px/1.2 var(--display); }
.crow.role-sentry figcaption, .crow.role-elder figcaption { font-style: italic; text-decoration: underline; text-underline-offset: 3px; }
.crow .badge {
position: absolute; top: -4px; right: 4px; width: 22px; height: 22px;
fill: var(--card); stroke: var(--ink); stroke-width: 1.6; stroke-linejoin: round;
opacity: 0; transform: scale(0.4); transition: 150ms;
.crow figcaption {
justify-self: stretch; position: relative; margin-top: 0; padding-top: 6px;
border-top: 2px solid var(--ink); text-align: center; font: 400 15px/1.2 var(--display);
}
.crow[data-trust="1"] .badge { opacity: 1; transform: rotate(-12deg); }
.crow[data-trust="2"] .badge { opacity: 1; transform: rotate(-12deg); fill: var(--ink); animation: twinkle 2.4s infinite; }
.crow figcaption::before {
content: ""; position: absolute; left: 0; right: 0; top: 0; height: 7px; background: var(--stipple);
-webkit-mask-image: linear-gradient(rgb(0 0 0 / 0.6), transparent); mask-image: linear-gradient(rgb(0 0 0 / 0.6), transparent);
}
/* Trust star: its own corner, top right of the headroom, clear of the beak. */
.crow .badge {
position: absolute; top: 4px; right: 4px; width: 18px; height: 18px;
fill: var(--card); stroke: var(--ink); stroke-width: 1.8; stroke-linejoin: round;
opacity: 0; transition: opacity 150ms;
}
.crow[data-trust="1"] .badge { opacity: 1; }
.crow[data-trust="2"] .badge { opacity: 1; fill: var(--ink); }
/* Body layer: poses */
.pose-perched .crow-body { animation: breathe 3.2s ease-in-out infinite; }
@@ -117,10 +120,10 @@ main { max-width: 680px; margin: 0 auto; padding: 0 16px 64px; }
.pose-flying .jaw { transform: rotate(-10deg); }
.pose-waiting .crow-body { animation: tilt 1.4s ease-in-out infinite; }
.pose-waiting::after {
content: "?"; position: absolute; top: -12px; left: 4px; font: 400 26px/1 var(--display);
content: "?"; position: absolute; top: 0; left: 0; right: 0; text-align: center; font: 400 22px/1 var(--display);
animation: pop 1.4s ease-in-out infinite;
}
.pose-grounded .crow-body { transform: rotate(-18deg) translateY(6px); opacity: 0.5; }
.pose-grounded .crow-body { opacity: 0.4; }
/* Reaction layer: one-shots on top */
.r-cheer .crow-body { animation: hop 0.8s ease-out; }
@@ -129,7 +132,7 @@ main { max-width: 680px; margin: 0 auto; padding: 0 16px 64px; }
.r-levelUp .crow-body { animation: levelup 2s ease-out; }
.r-levelUp .jaw { transform: rotate(16deg); }
.r-levelUp::before {
content: ""; position: absolute; top: -26px; width: 56px; height: 30px; animation: rise 2s ease-out forwards;
content: ""; position: absolute; top: -6px; left: calc(50% - 28px); width: 56px; height: 30px; animation: rise 2s ease-out forwards;
background: var(--sparkle) 16px 0 / 26px 26px no-repeat, var(--glint) 0 14px / 12px 12px no-repeat, var(--glint) 44px 10px / 10px 10px no-repeat;
}
.r-levelDown .crow-body { animation: shrug 1s ease-out; }