/* Ermetis — site stylesheet.
   The public site's own copy of the design system, built for the flagship
   multi-page site (masterpiece transformation, 2026-08-27). Self-contained on
   purpose: the token values are copied in from ../../tokens/ so this folder
   deploys on its own. Only the live direction-M subset is carried; the
   deprecated blue, caution, and glass-panel tokens stay behind in the system
   files and must not be reintroduced here.

   Ground rules this file enforces (see readme.md and SHELL-CONTRACT.md):
   white paper ground; ink plate as the one gradient; hairline rules; no
   radius, no shadows; Schibsted Grotesk only; sentence case; links are ink
   with a slate underline; signal yellow on one argued element per view;
   focus is the registration-mark ring; motion is one orchestrated moment
   per view plus quiet scroll reveals, all reduced-motion guarded. */

/* Schibsted Grotesk, self-hosted (fix wave, 2026-08-28). The two woff2 files
   in assets/fonts/ are the variable font (wght 400-900) fetched from Google
   Fonts (OFL licensed; self-hosting permitted). No runtime request leaves
   this folder for type. The site carries no handwriting face: the hand is
   the drawn yellow stroke (.uw below), not a typeface. */
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* ---- Neutrals: white to graphite (cool) ---- */
  --paper:        #FFFFFF;
  --paper-alt:    #F7F8F8;
  --paper-sunk:   #F1F3F4;
  --mist:         #E7EAEC;
  --line:         #EAECED;
  --line-strong:  #DDE1E4;
  --slate-200:    #DCE0E3;
  --slate-300:    #BAC1C7;
  --slate-400:    #8D959C;
  --slate-500:    #5A6670;
  --slate-600:    #47525B;
  --slate-700:    #333D45;
  --ink:          #1E262E;
  --ink-soft:     #2B353D;
  --ink-deep:     #141A20;

  /* ---- Signal: the one accent ---- */
  --signal-700:   #A87F00;
  --signal-600:   #E8B800;
  --signal-500:   #FFDA1E;
  --signal-450:   #FFCB05;
  --signal-300:   #FFE97E;

  /* ---- Feedback: two hues, locked 2026-08-18 ---- */
  --positive:     #2F7D57;
  --critical:     #C13B29;
  --annotate:     #C13B29;

  /* ---- Surfaces ---- */
  --surface-ink: radial-gradient(120% 90% at 74% 18%, var(--ink-soft) 0%, #1B232A 46%, var(--ink-deep) 100%);

  /* ---- Text roles ---- */
  --text-primary:   var(--ink);
  --text-secondary: var(--slate-500);
  --text-muted:     var(--slate-400);
  --text-on-ink:    #AEB8BF;

  /* ---- Links: ink with a slate underline; no interactive hue ---- */
  --link:                 var(--ink);
  --link-underline:       var(--slate-300);
  --link-underline-hover: var(--ink);

  /* ---- Drawing layer (stroke colours for generated drawings) ---- */
  --draw-line:    #3A444C;
  --draw-mid:     #6B747B;
  --draw-fine:    #9BA3AA;
  --draw-faint:   #C7CDD2;
  --draw-ink:     #2B353D;
  --draw-on-ink:  #C7CDD2;
  --draw-fine-on-ink: #5C666E;

  /* ---- Watercolour (registered to one element, paper technique) ---- */
  --wash-warm:      #FFDA1E;
  --wash-warm-deep: #FFCB05;
  --wash-warm-rim:  #E8B800;
  --core-face-a:    #FFF0AD;
  --core-face-b:    #FFE68A;
  --core-face-top:  #FFF7D0;
  --core-lit-a:     #B8941C;
  --core-lit-b:     #D4AC23;
  --core-lit-top:   #F2C82E;

  /* ---- Type ---- */
  --font-sans: 'Schibsted Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --text-h3:       1.375rem;
  --text-h4:       1.125rem;
  --text-body-lg:  1.0625rem;
  --text-body:     0.9375rem;
  --text-small:    0.8125rem;

  /* The site's display scale. The flagship pushes past the old 64px ceiling
     where the composition earns it: the hero, and nowhere else by default. */
  --display-hero:    clamp(2.7rem, 5.2vw, 5rem);
  --display-section: clamp(1.8rem, 2.9vw, 2.6rem);
  --display-plate:   clamp(1.9rem, 3vw, 2.75rem);
  --display-close:   clamp(1.6rem, 2.4vw, 2.1rem);

  /* Laptop fit (2026-09-02, John's laptop review: the page read as zoomed
     in). On viewports up to 900px tall the hero has to land its actions
     above the fold, so the display scale steps down and the hero's own
     vertical spacing tightens with it. Phones are unaffected: the hero
     stacks below 1100 and the scale is already at its floor there. */
  --lh-tight:   1.06;
  --lh-snug:    1.24;
  --lh-relaxed: 1.62;

  --tracking-display: -0.03em;
  --tracking-tight:   -0.02em;

  /* ---- Spacing (4px base) ---- */
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --space-9:  96px;
  --gutter:   32px;

  /* ---- Motion: short, mechanical, no bounce ---- */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 120ms;
  --dur-med:  220ms;

  /* ---- Focus: a paper gap then a graphite ring ---- */
  --focus-ring:     0 0 0 2px var(--paper), 0 0 0 4px var(--ink);
  --focus-ring-ink: 0 0 0 2px var(--ink-deep), 0 0 0 4px #FFFFFF;
}

/* ============================== Base ==================================== */

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-body);
  line-height: var(--lh-relaxed);
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--signal-300); color: var(--ink); }

a { color: var(--link); text-decoration: none; }
main p a { border-bottom: 1px solid var(--link-underline); }
main p a:hover { border-bottom-color: var(--link-underline-hover); }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: none; box-shadow: var(--focus-ring);
}
/* Skip link (added 2026-08-31). Off-screen until focused, then the first thing
   a keyboard reader lands on. It sits on paper rather than ink so it reads as
   part of the page, and it targets main#top, which every page carries. */
.skip {
  position: absolute; left: 20px; top: -80px; z-index: 100;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--ink); padding: 11px 18px;
  font-size: var(--text-body);
  transition: top var(--dur-fast) var(--ease-standard);
}
.skip:focus { top: 12px; }
.ink a:focus-visible, .ink button:focus-visible,
.opportunity a:focus-visible, .opportunity button:focus-visible { box-shadow: var(--focus-ring-ink); }

h1, h2, h3, p { margin: 0; }
h1 { font-weight: 400; letter-spacing: var(--tracking-display); line-height: var(--lh-tight); }
h2 { font-weight: 600; letter-spacing: var(--tracking-tight); line-height: var(--lh-snug); }
h3 { font-weight: 600; letter-spacing: var(--tracking-tight); line-height: var(--lh-snug); }
h1, h2, h3 { text-wrap: balance; }

/* Tabular numerals on numeral-only elements. NEVER on prose: Schibsted's
   tnum feature gives commas and periods figure-width advances, so running
   text renders "1 ,250" and "loss ." (fix wave, 2026-08-28; it broke the
   evidence rows, the exhibit notes, and the footer contact line). Apply
   .tnum only to spans that are digits. */
.tnum, .ledger .row > span, .stations .n {
  font-variant-numeric: tabular-nums;
}

.wrap { max-width: 1360px; margin: 0 auto; padding: 0 48px; }
.lede { font-size: var(--text-body-lg); color: var(--text-secondary); max-width: 46ch; }
.kicker { font-size: var(--text-small); color: var(--slate-500); }

/* ============================ Shell: nav ================================ */
/* The hairline bar (board Z pick): full-bleed rule, contents on the page
   measure. Byte-identical markup on every page; site.js marks the current
   page with aria-current. */

.bar {
  position: sticky; top: 0; z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--line-strong);
}
.bar .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-5); min-height: 68px;
}
.mark { display: inline-flex; align-items: center; gap: 9px; }
.mark svg { width: 22px; height: 22px; flex-shrink: 0; }
.mark span { font-weight: 600; font-size: 21px; letter-spacing: var(--tracking-tight); }
.bar nav { display: flex; align-items: center; gap: var(--space-6); }
.bar nav a {
  font-size: var(--text-body);
  white-space: nowrap;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-standard);
}
.bar nav a:hover { border-bottom-color: var(--ink); }
.bar nav a[aria-current="page"] { border-bottom-color: var(--slate-300); }
.bar nav a[aria-current="page"]:hover { border-bottom-color: var(--ink); }

/* ============================ Buttons =================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit; font-size: var(--text-body); font-weight: 400;
  padding: 11px 20px; border-radius: 0; cursor: pointer;
  white-space: nowrap; text-decoration: none;
  transition: background var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard);
}
.btn-ink { background: var(--ink); color: var(--paper); border: 1px solid var(--ink); }
.btn-ink:hover { background: var(--ink-soft); }
.btn-quiet { background: transparent; color: var(--ink); border: 1px solid var(--line-strong); }
.btn-quiet:hover { background: var(--paper-alt); border-color: var(--slate-300); }
.btn-sm { padding: 8px 14px; }
.ink .btn-quiet, .opportunity .btn-quiet { color: var(--paper); border-color: rgba(255,255,255,0.28); }
.ink .btn-quiet:hover, .opportunity .btn-quiet:hover { background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.5); }

/* ============================ Sections ================================== */

section { padding: 88px 0; }
.ruled { border-top: 1px solid var(--line); }
.index {
  display: flex; align-items: center; gap: 10px;
  font-size: var(--text-small); color: var(--slate-500); margin-bottom: 16px;
}
/* Kickers are the bare label: no leading tick, no numbering, no trailing
   hairline (rulings 2026-08-24/25). */

.head { display: grid; grid-template-columns: 1fr 400px; gap: var(--space-8); align-items: start; margin-bottom: 48px; }
/* The head aligns to the top (2026-09-02): aligned to the end, a long lede
   floated above its own headline and read as misplaced. The lede then drops
   to the headline's first line rather than the kicker's. */
.head .lede { padding-top: 34px; }
@media (max-width: 900px) { .head .lede { padding-top: 0; } }
/* Large display is 400, never bold (design law; enforced at the display
   scale 2026-08-28 after the round-one critique caught section heads
   shipping at 600 while the hero held 400). */
.head h2 { font-size: var(--display-section); font-weight: 400; }
.close h2 { font-weight: 400; }

/* Rule-led columns: no container; a rule over the column and the content on
   the paper. 2px signal marks the one being argued. */
.cols { display: grid; gap: var(--space-7); }
.cols-4 { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
.cols-3 { grid-template-columns: repeat(3, 1fr); }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
.col { border-top: 1px solid var(--line-strong); padding-top: 20px; }
.col.lead { border-top: 2px solid var(--signal-500); }
.col.mark-ink { border-top: 2px solid var(--ink); }
.col h3 { font-size: var(--text-h3); }
.cols-4 .col h3 { font-size: var(--text-h4); }
.col .meta { font-size: var(--text-small); color: var(--slate-500); margin-top: 6px; }
.col p.body { margin-top: 14px; color: var(--text-secondary); }
.col .src { font-size: var(--text-small); color: var(--slate-500); margin-top: 12px; }
.col .src a { border-bottom: 1px solid var(--link-underline); }
.col .src a:hover { border-bottom-color: var(--link-underline-hover); }
.col svg.scheme { display: block; width: 100%; height: auto; margin-bottom: 20px; }

/* Ledgers: rule-led rows on the paper. Numbered only where the sequence
   itself carries meaning; .plain drops the numeral column. */
.ledger { border-top: 1px solid var(--line-strong); }
.ledger .row {
  display: grid; grid-template-columns: 44px 300px 1fr; gap: var(--space-5);
  padding: 22px 0; border-bottom: 1px solid var(--line);
}
.ledger .row > span { color: var(--slate-500); font-size: var(--text-small); padding-top: 4px; }
.ledger h3 { font-size: var(--text-body); }
.ledger .meta { font-size: var(--text-small); color: var(--slate-500); margin-top: 4px; }
.ledger .d { color: var(--text-secondary); align-self: start; }
.ledger.plain .row { grid-template-columns: 300px 1fr; }

/* Exhibits: a generated drawing on the measure. Wide figures keep a minimum
   width below 900px and scroll inside their own container. */
.exhibit { text-align: center; }
.exhibit svg { width: 100%; height: auto; }
.exhibit .note { font-size: var(--text-small); color: var(--slate-500); margin-top: 18px; }
@media (max-width: 900px) {
  .exhibit.wide { overflow-x: auto; }
  .exhibit.wide svg { min-width: 1100px; }
}

/* ============================ Ink plate ================================= */

.ink { background: var(--surface-ink); color: var(--paper); }
.ink .kicker { color: var(--slate-400); }
.ink .lede { color: var(--text-on-ink); }
.ink .index { color: var(--slate-300); }
.ink .col { border-top-color: rgba(255,255,255,0.28); }
.ink .col.lead { border-top-color: var(--signal-500); }
.ink .col p.body { color: var(--text-on-ink); }

/* The mounted plate (board AT, sheet AN): the ink section is a plate on the
   paper, inset with paper margin and framed by hairline rules that cross and
   overshoot at the corners. */
.opportunity { background: var(--surface-ink); color: var(--paper); padding: 0;
  width: min(1464px, calc(100% - 80px)); margin: 104px auto; position: relative; }
.opportunity::before { content: ""; position: absolute; top: -16px; bottom: -16px;
  left: -26px; right: -26px; border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink); pointer-events: none; }
.opportunity::after { content: ""; position: absolute; top: -26px; bottom: -26px;
  left: -16px; right: -16px; border-left: 1px solid var(--ink);
  border-right: 1px solid var(--ink); pointer-events: none; }
@media (max-width: 900px) {
  .opportunity { width: calc(100% - 32px); margin: 56px auto; }
  .opportunity::before { top: -9px; bottom: -9px; left: -16px; right: -16px; }
  .opportunity::after { top: -16px; bottom: -16px; left: -9px; right: -9px; }
}
.opportunity .plate { position: relative; max-width: 1464px; margin: 0 auto; }
.opportunity .ascent { display: block; width: 100%; height: auto; }
.opportunity .overlay { position: absolute; }
.opportunity .head-block { left: max(40px, calc((100% - 1360px) / 2)); top: 9%; width: min(620px, 46%); }
.opportunity .head-block h2 {
  font-size: var(--display-plate); font-weight: 400;
  letter-spacing: -0.03em; line-height: 1.27; color: #FFFFFF; margin-top: 20px;
}
.opportunity .index { color: var(--slate-300); }

/* The ridge draws itself once when it scrolls into view, then holds. */
.js .opportunity .draw-route { stroke-dasharray: 1; stroke-dashoffset: 1; }
.js .opportunity .ghost, .js .opportunity .latecomer, .js .opportunity .glow { opacity: 0; }
.js .opportunity .trace { opacity: 0; }
.opportunity.run .draw-route { animation: ascend 1600ms var(--ease-standard) 200ms both; }
.opportunity.run .trace { animation: settle-trace 600ms var(--ease-out) 1600ms both; }
.opportunity.run .latecomer { animation: settle 500ms var(--ease-out) 1700ms both; }
.opportunity.run .ghost { animation: settle 900ms var(--ease-out) 2100ms both; }
.opportunity.run .glow { animation: settle 2000ms var(--ease-out) 2300ms both; }
@keyframes ascend { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes settle { from { opacity: 0; } to { opacity: 1; } }
@keyframes settle-trace { from { opacity: 0; } to { opacity: 0.16; } }
@media (max-width: 1100px) {
  .opportunity { padding: 64px 0 0 0; }
  .opportunity .plate { display: flex; flex-direction: column; }
  .opportunity .ascent { order: 3; }
  .opportunity .overlay { position: static; width: auto; }
  .opportunity .head-block {
    width: auto; max-width: 660px; margin-left: var(--gutter); margin-right: var(--gutter);
  }
}
/* Below 900 the ridge scales proportionally with the plate instead of
   scrolling (fix wave, 2026-08-28). Below 720 its labels fall under 5px
   and the drawing is dark noise, so the plate is the headline and the
   evidence rows there (design review, 2026-09-02). */
@media (max-width: 900px) {
  .opportunity .ascent { width: 100%; }
}
@media (max-width: 720px) {
  .opportunity .ascent { display: none; }
  .opportunity .head-block { padding-bottom: 8px; }
}

/* The evidence ledger on the ink plate: findings relayed from named sources
   in the drafting reference-table register. */
.opportunity .evidence { padding: 8px max(40px, calc((100% - 1360px) / 2)) 52px; }
.opportunity .evidence .row {
  display: grid; grid-template-columns: 1fr 320px; gap: var(--space-6);
  align-items: baseline; padding: 15px 0;
  border-bottom: 1px solid rgba(255,255,255,0.16);
}
.opportunity .evidence .row:first-child { border-top: 1px solid rgba(255,255,255,0.30); }
.opportunity .evidence .f { color: rgba(255,255,255,0.88); }
.opportunity .evidence .s { font-size: var(--text-small); color: var(--slate-300); text-align: right; }
.opportunity .evidence .s a { color: inherit; border-bottom: 1px solid rgba(255,255,255,0.35); }
.opportunity .evidence .s a:hover { border-bottom-color: rgba(255,255,255,0.7); }
@media (max-width: 900px) {
  .opportunity .evidence { padding: 8px 20px 40px; }
  .opportunity .evidence .row { grid-template-columns: 1fr; gap: 6px; }
  .opportunity .evidence .s { text-align: left; }
}

/* ========================= Home hero: the field ========================= */
/* A full-bleed drawing field on the paper: the engine schematic bleeds off
   the right edge and draws itself once on load (site.js staggers the pencil
   strokes, then the faces and the wash settle in). With reduced motion or
   scripting off, the finished drawing simply stands. */

.hero {
  position: relative; overflow: hidden;
  border-bottom: 1px solid var(--line);
}
.hero .band {
  display: grid; grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  align-items: center; gap: var(--space-7);
  min-height: calc(100vh - 68px);
}
.hero .copy { padding: clamp(48px, 7vh, 96px) 0; }
.hero h1 { font-size: var(--display-hero); max-width: 15ch; }
/* The underlined words: the share-card treatment (landing/og-card.html).
   The words stay in Schibsted with the rest of the H1; the hand is the
   drawn yellow stroke beneath them. On the home hero the stroke draws
   itself once as part of the hero moment (guarded below); everywhere else,
   and with scripting off or reduced motion, the finished stroke stands. */
.uw { position: relative; white-space: nowrap; }
.uw svg {
  position: absolute; left: -2%; bottom: -0.16em;
  width: 104%; height: 0.24em; overflow: visible; pointer-events: none;
}
.uw svg path { stroke: var(--signal-500); stroke-width: 5; stroke-linecap: round; fill: none; }
.js .hero .uw path {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: uw-draw 700ms var(--ease-standard) 500ms forwards;
}
@keyframes uw-draw { to { stroke-dashoffset: 0; } }
.hero p.lede { margin-top: 28px; max-width: 52ch; }
.hero p.note { font-size: var(--text-small); color: var(--slate-500); margin-top: 12px; max-width: 52ch; }
.hero .actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 40px; }

.hero .draw-field { position: relative; align-self: stretch; min-height: 0; }
.hero .draw-field svg {
  position: absolute; top: 50%; left: 0;
  height: min(118%, 940px); width: auto;
  transform: translateY(-50%);
  transition: opacity 600ms var(--ease-standard);
}
/* The engine self-draw: site.js assigns .dp (a pencil stroke, drawn) and .fp
   (a face or wash, settled) with a per-path delay in --d. Nothing is hidden
   until the script assigns the classes, so no-JS shows the finished sheet. */
.hero .draw-field .dp {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: hero-draw 800ms var(--ease-standard) var(--d, 0ms) forwards;
}
.hero .draw-field .fp {
  opacity: 0;
  animation: hero-settle 700ms var(--ease-out) var(--d, 0ms) forwards;
}
@keyframes hero-draw { to { stroke-dashoffset: 0; } }
@keyframes hero-settle { to { opacity: 1; } }

@media (min-width: 1101px) and (max-height: 900px) {
  :root { --display-hero: clamp(2.5rem, 4.4vw, 4.25rem); }
  .hero p.lede { margin-top: 20px; }
  .hero .actions { margin-top: 28px; }
  .hero .draw-field svg { height: min(112%, 820px); }
}
@media (max-width: 1100px) {
  .hero .band { grid-template-columns: 1fr; gap: 0; min-height: 0; }
  .hero .copy { padding: 72px 0 8px; }
  .hero .draw-field { overflow: hidden; max-height: 480px; margin-top: 32px; }
  .hero .draw-field svg { position: static; width: 100%; height: auto; transform: none; }
}
@media (max-width: 720px) {
  .hero h1 { max-width: none; }
}

/* ==================== Home: stations on a rule (04) ===================== */
/* The four stages as stations on one rule: the process-chain convention for
   an ordered sequence. Numerals are earned here; the order is the method. */

.stations {
  position: relative;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-6);
  margin-top: 64px; padding-top: 24px;
}
/* One continuous rule with a tick at each station: the process-chain
   convention for an ordered sequence, drawn in CSS. */
.stations::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0;
  height: 1px; background: var(--line-strong);
}
.station { position: relative; }
.station::before {
  content: ""; position: absolute; top: -24px; left: 0;
  width: 1px; height: 13px; background: var(--slate-400);
}
/* The argued station: a 2px signal segment on the rule over its span. */
.station.lead::after {
  content: ""; position: absolute; top: -25px; left: 0; right: 0;
  height: 2px; background: var(--signal-500);
}
.station.lead::before { background: var(--signal-600); z-index: 1; }
.station .n { font-size: var(--text-small); color: var(--slate-500); display: block; margin-bottom: 10px; }
.station h3 { font-size: var(--text-h4); }
.station p { margin-top: 12px; color: var(--text-secondary); }
@media (max-width: 1080px) {
  .stations { grid-template-columns: repeat(2, 1fr); row-gap: var(--space-7); padding-top: 0; }
  .stations::before { content: none; }
  .station { border-top: 1px solid var(--line-strong); padding-top: 24px; }
  .station::before { top: -1px; }
  .station.lead { border-top: 2px solid var(--signal-500); }
  .station.lead::after { content: none; }
  .station.lead::before { top: -2px; }
}
@media (max-width: 640px) { .stations { grid-template-columns: 1fr; } }

/* ======================== Home: proof teaser (05) ======================= */

.proof-row { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: var(--space-8); align-items: start; }
.proof-row .frame svg { display: block; width: 100%; height: auto; }
.proof-row .frame .note { font-size: var(--text-small); color: var(--slate-500); margin-top: 16px; }
@media (max-width: 1080px) { .proof-row { grid-template-columns: 1fr; } .proof-row .frame { max-width: 720px; } }

/* ====================== Close band + footer (shell) ===================== */

.close { border-top: 1px solid var(--line); background: var(--paper-alt); }
.close .wrap { display: grid; grid-template-columns: 1fr 380px; gap: var(--space-8); align-items: end; }
.close h2 { font-size: var(--display-close); }

footer { border-top: 1px solid var(--line-strong); }
footer .wrap {
  display: flex; justify-content: space-between; align-items: flex-start;
  flex-wrap: wrap; gap: var(--space-6); padding-top: 44px; padding-bottom: 44px;
}
footer .kicker { margin-top: 10px; }
footer .pages { display: flex; flex-direction: column; gap: 6px; }
footer .pages a { font-size: var(--text-small); color: var(--slate-500); align-self: flex-start; border-bottom: 1px solid transparent; }
footer .pages a:hover { color: var(--ink); border-bottom-color: var(--link-underline); }
footer .contact { font-size: var(--text-small); color: var(--slate-500); text-align: right; line-height: 2; }
footer .contact a { border-bottom: 1px solid var(--link-underline); }
footer .contact a:hover { border-bottom-color: var(--link-underline-hover); }
@media (max-width: 720px) { footer .contact { text-align: left; } }

/* ====================== Scroll reveals (site-wide) ====================== */
/* Figure reveals only (narrowed 2026-09-02). Text is never hidden: the
   old page-wide reveal left every section blank for 0.7 to 2.9 seconds on a
   laptop, which read as empty white space. data-reveal now sits only on
   drawings and stages, site.js pre-triggers 200px before they enter, and
   the rise is short. Hidden only when the js class is present, so no-JS
   renders everything. */

.js [data-reveal] { opacity: 0; transform: translateY(6px); }
.js [data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity 300ms var(--ease-out) var(--rd, 0ms),
              transform 300ms var(--ease-out) var(--rd, 0ms);
}

/* ============================== Narrow ================================== */

@media (max-width: 1080px) {
  .cols-4 { grid-template-columns: repeat(2, 1fr); row-gap: var(--space-7); }
}
@media (max-width: 900px) {
  .cols-3, .cols-2, .cols-4, .head, .close .wrap { grid-template-columns: 1fr; }
  .ledger .row { grid-template-columns: 44px 1fr; }
  .ledger .d { grid-column: 2; }
  .ledger.plain .row { grid-template-columns: 1fr; gap: var(--space-2); }
  .ledger.plain .d { grid-column: auto; }
  .head, .close .wrap { gap: var(--space-5); align-items: start; }
  section { padding: 64px 0; }
}
@media (max-width: 720px) {
  .wrap { padding: 0 20px; }
  .bar nav a { padding: 10px 0; }
  /* The five labels share one ruled row that scrolls if it must: no hamburger. */
  /* The bar stops sticking below 720 (fix wave, 2026-08-31). The wrapped nav
     row makes this header 144px tall at 390 and 174px at 320, and sticking it
     charged that against every screen of every page for the whole visit. It
     scrolls away now, and the in-page and footer calls to action carry the
     next step. */
  .bar { position: static; }
  .bar .wrap { flex-wrap: wrap; min-height: 0; padding-top: 10px; }
  .bar nav {
    order: 3; width: 100%; gap: var(--space-4);
    border-top: 1px solid var(--line); margin-top: 10px; padding: 10px 0;
    overflow-x: auto; scrollbar-width: none;
  }
  .bar nav::-webkit-scrollbar { display: none; }
}
@media (max-width: 420px) {
  /* The labels wrap onto a second ruled line instead of clipping mid-word
     at the viewport edge (fix wave, 2026-08-28: at 320 the scroll row cut
     "Who we are" with no affordance). Still no hamburger. */
  .bar nav { gap: var(--space-3); flex-wrap: wrap; row-gap: 6px; overflow-x: visible; }
  .bar nav a { font-size: var(--text-small); }
}

/* =========================== Reduced motion ============================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .opportunity .draw-route { stroke-dashoffset: 0; }
  .js .opportunity .ghost, .js .opportunity .latecomer, .js .opportunity .glow { opacity: 1; }
  .js .opportunity .trace { opacity: 0.16; }
  .opportunity.run .draw-route, .opportunity.run .ghost, .opportunity.run .trace,
  .opportunity.run .latecomer, .opportunity.run .glow { animation: none; }
  .hero .draw-field .dp { animation: none; stroke-dashoffset: 0; }
  .hero .draw-field .fp { animation: none; opacity: 1; }
  .js .hero .uw path { animation: none; stroke-dashoffset: 0; }
  .js [data-reveal] { opacity: 1; transform: none; }
  .js [data-reveal].is-in { transition: none; }
  * { transition-duration: 1ms !important; }
}
