/* ------------------------------------------------------------------
   hub.css — Paper & Volt at brand level, for the director page.

   This is the one surface where the doors visibly belong to one house
   (site/spec-hub.md), so it uses the shared P&V grammar rather than either
   door's skin: 2px ink borders, hard offset shadows, zero radius, Archivo
   display + system body, one chartreuse volt highlight.

   Tokens are duplicated from app/first-chart/css/paper-volt.css rather than
   imported — deliberately, matching how /cooked carries its own copy. A door
   restyle must never silently restyle the hub.

   TWO DELIBERATE DIVERGENCES from paper-volt.css, both accessibility fixes:

   1. Status text colours. paper-volt.css:285 sets .save-status.ok to
      --edge-green and .error to --edge-red, which as TEXT on --paper measure
      2.99:1 and 3.43:1 in light theme — both fail WCAG AA. The hub defines
      --status-ok / --status-err instead (4.69:1 and 5.53:1 on light paper,
      7.8:1 and 6.7:1 on dark). Do not "align" these back to --edge-*.
   2. A skip link. Neither door has one; the hub is the site entrance, so it
      does.

   VOLT LAW: volt is a highlight FILL, never a text colour. There must be zero
   `color: var(--volt)` in this file. Sanctioned uses here: the wordmark mark,
   section-title underlines, the primary CTA, ::selection. One volt-filled
   element per viewport is the design target.
------------------------------------------------------------------ */

:root {
  --paper: #F3F0E6;
  --paper-soft: #E9E5D8;
  --surface: #FFFFFF;
  --ink: #141310;
  --ink-soft: #5A574E;
  --volt: #D4F84C;
  --on-volt: #141310;
  --on-dark: #F3F0E6;
  --shadow: #141310;

  /* Accessible status pair — see divergence note 1 above. */
  --status-ok: #147A4A;   /* 4.69:1 on --paper */
  --status-err: #B3301C;  /* 5.53:1 on --paper */

  --bw: 2px;
  --sh-card: 6px 6px 0 var(--shadow);
  --sh-card-hover: 4px 4px 0 var(--shadow);
  --sh-btn: 5px 5px 0 var(--shadow);
  --sh-btn-hover: 3px 3px 0 var(--shadow);
  --sh-btn-active: 0 0 0 var(--shadow);

  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #141412; --paper-soft: #26251E; --surface: #1C1C19;
    --ink: #F3F0E6; --ink-soft: #B4AEA0; --on-dark: #141310; --shadow: #000000;
    --status-ok: #3FBE73; --status-err: #FF6B70;
  }
}

/* Explicit choice wins over the media query in both directions — the theme
   toggle stamps data-theme on :root, same mechanism and same localStorage key
   ("cmp-theme") as the First Chart door, so a visitor's choice survives the
   hop from hub into a door. */
:root[data-theme="dark"] {
  --paper: #141412; --paper-soft: #26251E; --surface: #1C1C19;
  --ink: #F3F0E6; --ink-soft: #B4AEA0; --on-dark: #141310; --shadow: #000000;
  --status-ok: #3FBE73; --status-err: #FF6B70;
}
:root[data-theme="light"] {
  --paper: #F3F0E6; --paper-soft: #E9E5D8; --surface: #FFFFFF;
  --ink: #141310; --ink-soft: #5A574E; --on-dark: #F3F0E6; --shadow: #141310;
  --status-ok: #147A4A; --status-err: #B3301C;
}

/* ---------- base ---------- */

* { box-sizing: border-box; border-radius: 0; }

/* Author display rules must never defeat the hidden attribute — the /cooked
   door shipped a broken toggle exactly this way (.free-row's display:flex
   outranked [hidden] in the cascade). */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  transition: background-color .15s ease, color .15s ease;
}

h1, h2, h3 { font-family: var(--font-display); margin: 0; }
p { margin: 0; }
img { max-width: 100%; }

a { color: inherit; }

::selection { background: var(--volt); color: var(--on-volt); }

:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* The hub is the site entrance — the one surface that earns a skip link. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--on-dark);
  padding: 12px 18px; font-family: var(--font-display); font-weight: 800;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.wrap { width: min(1080px, 100% - 40px); margin-inline: auto; }

/* ---------- nav ----------
   No Fig here, ever — the character is banned from the nav at every screen
   (design/brand/fig-placement-guide.md §3). The mark is an ink square + volt
   slash; it is not the character. */

.nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--paper);
  border-bottom: var(--bw) solid var(--ink);
}
.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 5px 0;
}
.wordmark {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-display); font-weight: 800; font-size: 17px;
  text-decoration: none;
  /* Slimmed 2026-07-26 (Taufiq): 38px keeps a real touch target while the
     bar itself reads compact. */
  min-height: 38px;
}
.wordmark-logo { width: 22px; height: 22px; display: block; }
/* Two approved lockups, switched as a pair, never filtered (Taufiq 2026-07-27):
   the all-black lockup on light paper, the lime lockup on dark. Mark and
   wordmark change together so the pair always matches one of the two approved
   artworks. Both <img>s ship in the markup; exactly one is ever displayed. */
.wordmark .mark-volt, .foot-lockup .mark-volt { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wordmark .mark-ink,
  :root:not([data-theme="light"]) .foot-lockup .mark-ink { display: none; }
  :root:not([data-theme="light"]) .wordmark .mark-volt,
  :root:not([data-theme="light"]) .foot-lockup .mark-volt { display: block; }
  :root:not([data-theme="light"]) .wordmark,
  :root:not([data-theme="light"]) .foot-lockup { color: var(--volt); }
}
:root[data-theme="dark"] .wordmark .mark-ink,
:root[data-theme="dark"] .foot-lockup .mark-ink { display: none; }
:root[data-theme="dark"] .wordmark .mark-volt,
:root[data-theme="dark"] .foot-lockup .mark-volt { display: block; }
:root[data-theme="dark"] .wordmark,
:root[data-theme="dark"] .foot-lockup { color: var(--volt); }
:root[data-theme="light"] .wordmark .mark-ink,
:root[data-theme="light"] .foot-lockup .mark-ink { display: block; }
:root[data-theme="light"] .wordmark .mark-volt,
:root[data-theme="light"] .foot-lockup .mark-volt { display: none; }
:root[data-theme="light"] .wordmark,
:root[data-theme="light"] .foot-lockup { color: var(--ink); }
/* The all-black lockup (Taufiq 2026-07-26). Dark theme inverts the fixed-ink
   SVG so the mark stays legible on dark paper. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .wordmark-logo { filter: invert(1); } }
:root[data-theme="dark"] .wordmark-logo { filter: invert(1); }

.theme-toggle { display: inline-flex; border: var(--bw) solid var(--ink); }
.theme-toggle button {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; padding: 5px 10px;
  /* 38px tall keeps the slim bar; 44px min-width preserves the touch width. */
  min-height: 38px; min-width: 44px;
  background: var(--surface); color: var(--ink);
  border: 0; border-right: var(--bw) solid var(--ink); cursor: pointer;
}
.theme-toggle button:last-child { border-right: 0; }
.theme-toggle button:hover:not([aria-pressed="true"]) { background: var(--paper-soft); }
.theme-toggle button[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); }

/* N9a (design/hub-audit-2-2026-07-26.md): the mobile cycling control that
   stands in for .theme-toggle below 420px. Both elements are always in the
   DOM (js/common.js wireTheme() drives both from one apply()); this media
   query is the only thing that decides which one paints, so crossing the
   boundary is a plain CSS swap, never a JS-timed reflow. 419.98px, not 420,
   keeps the three-button group untouched AT 420px and above as specified —
   max-width:420px would also catch exactly 420px itself. */
.theme-cycle {
  display: none;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase;
  min-width: 44px; min-height: 44px; padding: 0 12px;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--ink); cursor: pointer;
}
.theme-cycle:hover { background: var(--paper-soft); }
@media (max-width: 419.98px) {
  .theme-toggle { display: none; }
  .theme-cycle { display: inline-flex; align-items: center; justify-content: center; }
}

/* ---------- shared bits ---------- */

.kicker {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft); margin: 0 0 8px;
}
/* Hero eyebrow — the volt chip, same component as the doors (STYLE-GUIDE §9.8).
   margin-bottom tightened from 24px to match the hero-stack's 16px rhythm
   (badge/H1/lede) now that the stack shares the row with the figure column. */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; padding: 7px 12px;
  border: var(--bw) solid var(--ink); box-shadow: 3px 3px 0 var(--shadow);
  background: var(--volt); color: var(--on-volt); margin-bottom: 16px;
}
.section-title {
  font-size: 22px; font-weight: 800;
  padding-bottom: 8px; border-bottom: 4px solid var(--volt);
  margin: 0 0 24px; display: inline-block;
}

.btn {
  display: inline-block; font-family: var(--font-display); font-weight: 800;
  font-size: 15px; text-transform: uppercase; letter-spacing: .04em;
  text-decoration: none; text-align: center;
  border: var(--bw) solid var(--ink); padding: 15px 26px; min-height: 44px;
  background: var(--surface); color: var(--ink); cursor: pointer;
  box-shadow: var(--sh-btn);
  transition: transform .08s ease, box-shadow .08s ease;
}
.btn:hover, .btn:focus-visible { transform: translate(2px, 2px); box-shadow: var(--sh-btn-hover); }
.btn:active { transform: translate(5px, 5px); box-shadow: var(--sh-btn-active); }
.btn-primary { background: var(--volt); color: var(--on-volt); }
.btn-ink { background: var(--ink); color: var(--on-dark); }

/* ---------- band 1 — brand + the fork ---------- */

/* Band rhythm: every band carries 32px top+bottom, so all inter-band gaps
   land on the system's 64px section spacing (STYLE-GUIDE §7.2) instead of
   four different values derived from padding arithmetic. */
.hero { padding: 56px 0 32px; }
/* Hero B, final direction: a two-column split — copy stack on the left, the
   pointing Poh on the right, flipped to look back at the headline (no
   plinth/box under the character). Below 760px it collapses to one column
   (STYLE-GUIDE mockup design/mockups/hub-rev2-board.html §1). */
.hero-split { display: flex; justify-content: space-between; align-items: flex-end; gap: 40px; }
.hero-stack { flex: 1 1 auto; min-width: 0; }
.hero h1 {
  /* UPPERCASE + volt swipe + door-scale size: the hero grammar every sibling
     page follows (STYLE-GUIDE §2.3). The brand page must not render the
     weakest H1 on the site. Scaled down from the single-column era (was
     clamp(40px,8vw,76px)) now that the H1 shares the row with a 300px-wide
     figure column instead of owning the full wrap width. */
  font-size: clamp(36px, 4.5vw, 64px); font-weight: 900; letter-spacing: -.01em;
  line-height: 1.04; margin: 0 0 16px; max-width: 15ch;
  text-transform: uppercase;
}
/* .swipe — the volt title-highlight, reusable on any display-level heading
   (the hero H1's "career." and the Then-What band's "half the answer.").
   Light theme: thin bottom bar, glyphs sit above it (the shipped look).
   Dark theme: DARK SWIPE FIX — the highlight becomes a full-height block and
   the word itself flips to ink-on-volt (Volt law: black on volt, always),
   because cream-on-a-thin-volt-bar is fine but cream glyphs over a
   full-height volt fill fails contrast. Covered for both the explicit
   data-theme="dark" toggle and the system prefers-color-scheme:dark media
   query below; an explicit data-theme wins over the system query in both
   directions via specificity, same mechanism as the :root token overrides
   above.
   z-index:0 (alongside position:relative) is load-bearing: it gives .swipe
   its OWN stacking context so the ::after's z-index:-1 resolves relative to
   THAT context (behind the glyphs, in front of whatever is immediately
   behind .swipe) instead of escaping to the page root. Without it, .swipe
   inside an opaque card (e.g. the Then-What band's .nextstep) renders its
   volt block behind the card's own background — invisible — because the
   negative z-index has nowhere local to land. Reproduced and fixed during
   the 2026-07-26 hub revision; caught in dark-mode QA. */
.swipe { position: relative; z-index: 0; white-space: nowrap; }
.swipe::after {
  content: ""; position: absolute; left: -2%; right: -2%; bottom: 0.06em;
  height: 0.38em; background: var(--volt); z-index: -1;
}
@media (prefers-color-scheme: dark) {
  .swipe { color: var(--on-volt); }
  .swipe::after { bottom: -0.04em; height: 1.12em; }
}
:root[data-theme="dark"] .swipe { color: var(--on-volt); }
:root[data-theme="dark"] .swipe::after { bottom: -0.04em; height: 1.12em; }
:root[data-theme="light"] .swipe { color: inherit; }
:root[data-theme="light"] .swipe::after { bottom: 0.06em; height: 0.38em; }
.hero .lede {
  font-size: 18px; color: var(--ink-soft); max-width: 52ch; margin: 0;
}
/* The hero figure column — fig-11-pointing, ~300px wide, vertically centered
   against the H1 (align-self overrides the row's flex-end), flipped with
   scaleX so it looks back toward the headline it's gesturing at. No
   box/plinth underneath — a bare flipped image only. */
.hero-fig { width: 300px; flex: none; align-self: center; }
.hero-fig img { width: 100%; height: auto; display: block; transform: scaleX(-1); }

.fork { margin-top: 28px; }
.fork-lead {
  font-family: var(--font-display); font-weight: 800; font-size: 17px;
  margin: 0 0 14px;
}
.fork-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

.fork-card {
  display: flex; flex-direction: column; gap: 6px;
  text-align: left; text-decoration: none;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--ink); box-shadow: var(--sh-card);
  padding: 18px 18px 20px; min-height: 44px; cursor: pointer;
  font: inherit;
  transition: transform .08s ease, box-shadow .08s ease;
}
.fork-card:hover, .fork-card:focus-visible { transform: translate(2px, 2px); box-shadow: var(--sh-card-hover); }
.fork-card:active { transform: translate(6px, 6px); box-shadow: 0 0 0 var(--shadow); }

/* N9b (design/hub-audit-2-2026-07-26.md) — dark-mode presence fix, no new
   tokens. In dark mode --surface (#1C1C19) sits too close to --paper
   (#141412) to read as a lifted plane, and --shadow is black-on-near-black
   too, so the card was reading as flat, separated only by the --ink border
   hairline. --paper-soft is already noticeably lighter than --paper in dark
   (see the :root[data-theme="dark"] token block above), so swapping the fill
   to it restores a real card-vs-page step while reusing the exact same
   --sh-card hard-shadow variable already set above (unchanged) and the same
   --ink border (unchanged) — no glow, no blur, no new color. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .fork-card { background: var(--paper-soft); }
}
:root[data-theme="dark"] .fork-card { background: var(--paper-soft); }

.fork-fig { width: 40px; height: 40px; margin-bottom: 2px; }
.fork-fig img { width: 100%; height: 100%; object-fit: contain; display: block; }
.fork-label { font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.fork-hook { font-size: 14.5px; color: var(--ink-soft); }

/* ---------- band 2 — the receipts ethos ---------- */

.ethos {
  border-block: var(--bw) solid var(--ink);
  background: var(--paper-soft);
  padding: 32px 0;
}
.ethos p { font-family: var(--font-display); font-weight: 800; font-size: clamp(19px, 3.2vw, 26px); }
.ethos .ethos-sub { font-family: var(--font-body); font-weight: 400; font-size: 15.5px; color: var(--ink-soft); margin-top: 8px; max-width: 62ch; }
.ethos-link {
  display: inline-block; margin-left: 4px; color: var(--ink);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 2px;
}

/* ---------- band 3 — the doors ---------- */

.doors { padding: 32px 0; }
.door-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: stretch; }

.door-card {
  /* Equal heights (Taufiq 2026-07-26, supersedes the earlier natural-height
     call): cards stretch to the row, and the CTA pins to the bottom so the
     slack lands above it instead of reading as dead space. */
  display: flex; flex-direction: column; gap: 10px;
  background: var(--surface);
  border: var(--bw) solid var(--ink); box-shadow: var(--sh-card);
  padding: 22px;
}
/* A real artifact from the door — border + chip shadow so it reads as an
   object sitting on the card, not a decoration. */
.door-thumb {
  width: 100%; height: auto; margin-top: 4px;
  border: var(--bw) solid var(--ink); box-shadow: 3px 3px 0 var(--shadow);
}
.door-card .kicker { margin: 0; }
.door-card h3 { font-size: 21px; font-weight: 800; line-height: 1.15; }
.door-card .who { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.door-card .what { font-size: 15px; color: var(--ink-soft); }
.door-card .what-note { font-size: 15px; color: var(--ink-soft); }
.door-card .door-cta { padding-top: 14px; margin: auto 0 0; }
.door-card .btn { width: 100%; }

.door-fig { width: 52px; height: 52px; }
.door-fig img { width: 100%; height: 100%; object-fit: contain; display: block; }

.door-card.is-soon { background: var(--paper-soft); }

/* The archetype card's "nothing to show yet" placeholder — honest about
   having no real artifact to demonstrate (unlike the degree/job cards'
   door-thumb), so it shows mood + status instead of fabricating one
   (Rule 1 / Law 1). Dashed border reads as "not built yet," not a card. */
.teaser {
  border: var(--bw) dashed var(--ink-soft);
  height: 140px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
}
.teaser img { height: 64px; width: auto; opacity: .45; display: block; }
.teaser-caption {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft); margin: 0;
}

/* the notify form on the archetype teaser */
.notify { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; }
.input {
  font-family: var(--font-body); font-size: 16px; padding: 13px 14px;
  min-height: 44px; width: 100%;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--ink);
}
.input::placeholder { color: var(--ink-soft); }
.notify-status { font-size: 14px; margin: 0; }
.notify-status.ok { color: var(--status-ok); }
.notify-status.error { color: var(--status-err); }
.notify-status.info { color: var(--ink-soft); }
.fineprint { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em; color: var(--ink-soft); }

/* ---------- band 4 — BrainWrk (the "then what?" band), rebuilt ---------- */

.brainwrk { padding: 32px 0; }
/* An attention-grabbing bridge, not just another card: the volt LEFT border
   (instead of the doors' plain ink border) marks this as the one place the
   page hands off somewhere else, and the hard 6px shadow keeps it door-grade
   (design/mockups/hub-rev2-board.html §3). */
.nextstep {
  background: var(--surface);
  border: var(--bw) solid var(--ink);
  border-left: 8px solid var(--volt);
  box-shadow: var(--sh-card);
  display: flex; align-items: center; gap: 28px;
  padding: 26px 32px;
}
.nextstep-fig { width: 84px; flex: none; }
.nextstep-fig img { width: 100%; height: auto; display: block; }
.nextstep-copy { flex: 1; min-width: 0; }
.nextstep-copy h2 { font-size: 26px; font-weight: 800; margin: 0 0 8px; }
.nextstep-copy p { font-size: 15px; line-height: 1.55; color: var(--ink-soft); max-width: 56ch; }
.nextstep-cta { flex: none; }

/* ---------- band 5 — trust footer ---------- */

/* Footer — Option A "utility bar" (Taufiq pick, 2026-07-26): brand left,
   trust line right, privacy sentence below. One glance, no character. */
.foot {
  border-top: var(--bw) solid var(--ink);
  background: var(--paper-soft);
  padding: 16px 0 18px;
}
.foot-row { display: flex; gap: 24px; justify-content: space-between; flex-wrap: wrap; align-items: center; }
.foot-lockup {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-weight: 800; font-size: 15px;
  color: var(--ink); text-decoration: none; min-height: 38px;
}
.foot-proj { margin-left: 4px; }
.foot .mono { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.foot-priv { font-size: 13px; color: var(--ink-soft); margin-top: 4px; max-width: 62ch; }

/* ---------- motion ---------- */

.reveal { opacity: 0; transform: translateY(10px); transition: opacity 260ms ease-out, transform 260ms ease-out; }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* Print / PDF must never inherit the scroll-reveal state.
   IntersectionObserver only fires on a real scroll in a real viewport, so
   anything still below the fold when the user hits Ctrl+P would otherwise
   print as blank space — two of the five bands, in practice. The same gap
   affects screenshot and visual-regression tooling, which resizes the capture
   canvas without dispatching scroll events. hub.js carries a matching
   failsafe timer for the case where the observer never fires at all. */
@media print {
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ---------- responsive — matching the door breakpoints (760/720/460/420) ---------- */

@media (max-width: 860px) {
  .door-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  /* Hero B collapses to one column below the mockup's split breakpoint; the
     pointing Poh shrinks and tucks against the headline instead of owning a
     300px column (design/mockups/hub-rev2-board.html §1, mobile block). */
  .hero-split { flex-direction: column; align-items: flex-start; gap: 8px; }
  .hero-fig { width: 168px; align-self: flex-end; margin: -14px 0 0; }
  .nextstep { flex-direction: column; align-items: flex-start; }
  .nextstep-cta { width: 100%; }
  .nextstep-cta .btn { width: 100%; }
}
@media (max-width: 720px) {
  /* N2 mobile-fold budget starts tightening here: nav + badge + H1 + lede +
     "Where are you right now?" + all three fork cards must fit inside the
     first 844px at 390×844 (the smallest supported phone). */
  .hero { padding: 24px 0 20px; }
  .fork { margin-top: 18px; }
  .fork-lead { margin: 0 0 10px; }
  .fork-grid { grid-template-columns: 1fr; gap: 10px; }
  .fork-card { padding: 14px 16px 15px; gap: 4px; }
  .door-grid { grid-template-columns: 1fr; }
}
@media (max-width: 460px) {
  .wrap { width: min(1080px, 100% - 28px); }
  .nav-inner { padding: 10px 0; }
  .wordmark { font-size: 15.5px; }
  .theme-toggle button { padding: 7px 8px; font-size: 10px; }
}
@media (max-width: 420px) {
  /* Fold wins over character size on the smallest phones (N2): the pointing
     Poh is hidden outright here rather than shrunk further, freeing the
     vertical budget the 390×844 fold needs (spec explicitly allows this). */
  .hero-fig { display: none; }
  .hero { padding: 18px 0 18px; }
  .badge { margin-bottom: 12px; }
  .hero h1 { margin-bottom: 10px; }
}

/* Landscape phone: without this, the fork — the page's whole point — sits
   ~183px below the fold. The character yields; the decision doesn't. */
@media (max-height: 480px) and (orientation: landscape) {
  .hero { padding: 20px 0 24px; }
  .hero-fig { display: none; }
  .badge { margin-bottom: 12px; }
  .hero h1 { font-size: clamp(28px, 5vh, 40px); }
}
