/* Helios flagship site — V1.
   Carries the LOCKED H-v2 crystal language (see app/entry/loader.css): warm
   monochrome, brass/amber/ember ramp, sage the only cool note, no cyan, no neon.
   This is a SCROLL surface — a second consumer of the pinned grammar, not a
   redesign of the loader. */
/* ── faces, SELF-HOSTED ──────────────────────────────────────────────────── */
/* Both families are SIL Open Font License, so we serve them ourselves instead
   of calling fonts.googleapis.com. That is a privacy decision as much as a
   perf one: it is what lets /privacy say this site makes NO third-party
   requests at all. 71KB for all three files. `swap` keeps text visible while
   they load — but the faces are the product's own and must actually paint, so
   verify computed font-family after any change (a silent fallback to Georgia
   has fooled a vision critic here before). */
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:300 600;
  font-display:swap;src:url('./assets/fonts/hanken-grotesk-var.woff2') format('woff2')}
@font-face{font-family:'Libre Caslon Text';font-style:normal;font-weight:400;
  font-display:swap;src:url('./assets/fonts/libre-caslon-text-regular.woff2') format('woff2')}
@font-face{font-family:'Libre Caslon Text';font-style:italic;font-weight:400;
  font-display:swap;src:url('./assets/fonts/libre-caslon-text-italic.woff2') format('woff2')}

:root{
  --bg:#080604; --bg-2:#100c07; --bg-room:#1c120a;
  --ink:#f5edd6; --ink-soft:rgba(245,237,214,.62); --ink-faint:rgba(245,237,214,.42);
  --amber:#ffb347; --brass:#d4af37; --brass-dim:#b08d2a; --brass-bright:#f2ca50; --cream:#fff4d6;
  --rim:#ff6b2b; --ember:#e5621f; --sage:#7fa688;
  --serif:'Libre Caslon Text',Georgia,serif;
  --sans:'Hanken Grotesk',system-ui,sans-serif;
  /* The measured entrance grammar: decelerate in ~500ms (easeOutQuint family). */
  --ease:cubic-bezier(.22,1,.36,1);
  --enter:500ms;
  --line:rgba(212,175,55,.18);
  --measure:56ch;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} }
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-weight:300;font-size:17px;line-height:1.55;-webkit-font-smoothing:antialiased}

/* ── atmosphere ──────────────────────────────────────────────────────────── */
#backdrop{position:fixed;inset:0;z-index:0;pointer-events:none}
#halation{position:absolute;left:50%;top:50%;width:120vmin;height:120vmin;transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(255,150,80,.10),rgba(255,120,50,.04) 30%,transparent 60%);
  mix-blend-mode:screen}
#vignette{position:absolute;inset:0;
  background:radial-gradient(115% 85% at 50% 48%,transparent 30%,rgba(4,2,1,.58) 74%,rgba(1,0,0,.94) 100%)}
#grain{position:absolute;inset:0;opacity:.055;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ── the star stage ──────────────────────────────────────────────────────── */
/* The stage MUST fill the viewport exactly. It used to ride 13vh high so the
   old crystal owned the upper field — but the renderer only draws
   window.innerHeight, so that offset left the bottom 13vh with no canvas at
   all. Against the crystal's dark ground the edge was invisible; against the
   sun's halation it printed as a hard brown-to-black horizon across every
   viewport. The star's own height is composed in 3D (sunGroup y + the journey
   keyframes in hero.js) — never by shifting the canvas out of frame. */
#stagewrap{position:fixed;inset:0;z-index:1;pointer-events:none}
#poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 42%;
  display:block;filter:saturate(.96)}
#stage{position:absolute;inset:0;width:100%;height:100%;display:none;touch-action:pan-y}
/* JS + WebGL + GLB all healthy → canvas takes over, poster retires. */
body.crystal-ready #poster{display:none}
body.crystal-ready #stage{display:block;pointer-events:auto;cursor:grab}
body.crystal-ready #stage:active{cursor:grabbing}
/* Past the hero the crystal recedes; the page owns the pointer again. */
body.past-hero #stage{pointer-events:none;cursor:default}

/* ── mark ─────────────────────────────────────────────────────────────────── */
.mark{position:fixed;top:1.4rem;left:1.6rem;z-index:5;display:flex;align-items:center;gap:.55rem;
  font-family:var(--serif);letter-spacing:.14em;font-size:14px;text-transform:uppercase;color:var(--cream)}
.mark__glyph{color:var(--amber);font-size:11px}
@media (prefers-reduced-motion:no-preference){
  .mark__glyph{animation:glyph-breathe 4s var(--ease) infinite}
  @keyframes glyph-breathe{0%,100%{opacity:.75}50%{opacity:1;text-shadow:0 0 8px rgba(255,179,71,.7)}}
}

/* ── beats ────────────────────────────────────────────────────────────────── */
main{position:relative;z-index:2}
.hero{min-height:100vh;min-height:100svh;display:flex;flex-direction:column;align-items:center;
  justify-content:flex-end;text-align:center;padding:0 1.5rem 5.5vh;position:relative}
.hero__inner{max-width:44rem}
.hero__word{font-family:var(--serif);font-weight:400;margin:0;
  font-size:clamp(56px,10.5vw,124px);letter-spacing:.045em;line-height:1;color:var(--cream);
  text-shadow:0 2px 38px rgba(255,140,60,.42)}
.hero__line{margin:1rem 0 0;font-size:clamp(17px,2.4vw,22px);font-weight:300;color:var(--ink)}
.hero__sub{margin:.55rem 0 0;font-size:12.5px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink)}
.hero__hint{position:absolute;bottom:2.2vh;left:50%;transform:translateX(-50%);
  font-size:11px;letter-spacing:.4em;text-transform:uppercase;color:var(--ink-faint);margin:0}
@media (prefers-reduced-motion:no-preference){
  .hero__hint{animation:hint 2.6s var(--ease) infinite}
  @keyframes hint{0%,100%{transform:translate(-50%,0);opacity:.55}50%{transform:translate(-50%,6px);opacity:.9}}
}

.beat{position:relative;max-width:46rem;margin:0 auto;padding:22vh 1.5rem;
  background:linear-gradient(180deg,transparent,rgba(8,6,4,.0))}
/* Content beats sit on a soft ground so type never fights the star.
   The gradient must reach FULL transparency well inside its own box, or the
   box edge prints as a hard horizontal seam across the traveling sun. */
.beat::before{content:"";position:absolute;inset:-14vh -30vw;z-index:-1;
  background:radial-gradient(56% 44% at 50% 50%,rgba(8,6,4,.9),rgba(8,6,4,.48) 52%,rgba(8,6,4,0) 78%)}
.beat--last{padding-bottom:16vh}
.beat__eyebrow{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12.5px;
  font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--brass);
  margin:0 0 1.4rem}
/* eyebrows TRACK IN — letters settle from wide as the beat arrives */
body.js .beat__eyebrow[data-reveal]{letter-spacing:.46em;
  transition:opacity var(--enter) var(--ease),transform var(--enter) var(--ease),
    letter-spacing 700ms var(--ease)}
body.js .beat__eyebrow[data-reveal].is-in{letter-spacing:.24em}
@media (prefers-reduced-motion:reduce){
  body.js .beat__eyebrow[data-reveal]{letter-spacing:.24em;transition:none}
}
.beat__head{font-family:var(--serif);font-weight:400;font-size:clamp(36px,6.4vw,68px);
  line-height:1.05;margin:0 0 1.7rem;color:var(--cream);letter-spacing:0}
.beat__head em{font-style:italic;color:var(--amber)}
.beat__body{max-width:var(--measure);color:var(--ink-soft);line-height:1.6}
.beat__body p{margin:0 0 1.1em}
.beat__body p:last-child{margin-bottom:0}
.beat__body strong{font-weight:500;color:var(--ink)}

/* ── BEAT 01 — the glance, running ───────────────────────────────────────── */
/* A full-bleed band: the argument on the left, the product's own readout on the
   right, alive. The star sits UP-RIGHT at this beat (see hero.js KEYS.glance),
   so every edge light in here rakes from the top-right. Nothing is a picture of
   a UI in a frame — the instrument IS the UI, running. */
.beat--glance{max-width:none;width:min(92rem,100%);
  padding-left:clamp(1.5rem,5vw,4.5rem);padding-right:clamp(1.5rem,5vw,4.5rem);
  display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
.glance__copy{max-width:34rem}
.glance__resolve{font-family:var(--serif);font-size:clamp(19px,2.1vw,26px);
  line-height:1.35;color:var(--ink-soft);margin:2rem 0 0;
  padding-left:1.1rem;border-left:2px solid rgba(212,175,55,.42)}
.glance__resolve em{font-style:italic;color:var(--amber)}

/* NB: no `transform-style:preserve-3d` here. The plate and the panel are DIRECT
   children, so `perspective` alone gives them their depth — and preserve-3d
   makes Chrome hand every hit-test back to this container, which kills :hover
   and click on the rows inside the instrument. Measured, not guessed. */
.glance__scene{position:relative;perspective:1500px;padding:2.5rem 0}

/* The instrument — a SLAB, not a sticker.
   Three things make it an object instead of a tilted div: the glass is
   translucent so the star blurs through it; the box-shadow stack extrudes a
   real edge down-left (the direction the -6.5deg turn exposes); and the
   star-facing edges carry a lit bevel while the away edges carry shadow. */
.panel{position:relative;z-index:1;border-radius:9px;overflow:hidden;
  background:linear-gradient(152deg,rgba(41,28,16,.72),rgba(10,7,5,.82));
  backdrop-filter:blur(18px) saturate(1.3);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);
  border:1px solid rgba(255,190,110,.20);
  transform:rotateY(-6.5deg) rotateX(2deg);
  box-shadow:
    /* the slab's exposed edge, stepped away from the light */
    -2px 2px 0 rgba(52,34,19,.96), -4px 4px 0 rgba(43,28,16,.96),
    -6px 6px 0 rgba(34,22,12,.96), -8px 8px 0 rgba(26,17,9,.96),
    -10px 10px 0 rgba(18,12,7,.96),
    /* the room */
    -14px 22px 46px -18px rgba(0,0,0,.85),
    0 70px 120px -55px rgba(0,0,0,1),
    /* the glass catching the star */
    0 0 70px -26px rgba(255,150,70,.55),
    /* bevels: lit on the star side (top/right), dark on the away side */
    inset 0 1px 0 rgba(255,214,150,.34), inset -1px 0 0 rgba(255,196,120,.24),
    inset 1px 0 0 rgba(0,0,0,.45), inset 0 -1px 0 rgba(0,0,0,.5)}
/* the star's rake, plus a specular streak where the glass turns to the light */
.panel::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(215deg,rgba(255,190,110,.20),rgba(255,120,50,.04) 38%,transparent 66%),
    linear-gradient(238deg,transparent 6%,rgba(255,230,190,.11) 11%,transparent 15%),
    radial-gradient(70% 55% at 100% 0%,rgba(255,150,70,.16),transparent 70%)}
.panel__bar{display:flex;align-items:center;justify-content:space-between;
  padding:.7rem 1.1rem;border-bottom:1px solid rgba(212,175,55,.16);
  font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:10.5px;
  letter-spacing:.26em;text-transform:uppercase;color:var(--ink-faint)}
.panel__id{display:flex;align-items:center;gap:.6rem;color:var(--brass)}
.panel__pip{width:6px;height:6px;border-radius:50%;background:var(--amber);flex:none;
  box-shadow:0 0 9px rgba(255,179,71,.85)}
@media (prefers-reduced-motion:no-preference){
  .panel__pip{animation:rail-pulse 2.4s var(--ease) infinite}
}
.panel__clock{font-variant-numeric:tabular-nums;letter-spacing:.14em}
.panel__lede{margin:0;padding:1.15rem 1.15rem .95rem;font-size:clamp(17px,1.6vw,21px);
  font-weight:300;color:var(--ink);display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}
/* The counts are the panel's largest marks, so they must obey its light too:
   the numeral carries the SAME 215deg rake as the glass — bright where the face
   turns to the star, falling off toward the shadow side — and sits on the
   surface with a contact shadow plus its own bloom. Flat type here reads as a
   leftover from the pre-material design. */
.panel__num{font-family:var(--serif);font-weight:400;font-size:1.75em;line-height:.9;
  font-variant-numeric:tabular-nums;
  background:linear-gradient(215deg,#fffaf0 0%,#ffdca8 32%,#d59a58 82%);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 1px 0 rgba(0,0,0,.55)) drop-shadow(0 0 24px rgba(255,150,70,.55))}
.panel__num--need{font-size:1.5em;
  background:linear-gradient(215deg,#ffd9b2 0%,#ff8f4a 38%,#c9491a 86%);
  -webkit-background-clip:text;background-clip:text;
  filter:drop-shadow(0 1px 0 rgba(0,0,0,.5)) drop-shadow(0 0 20px rgba(229,98,31,.7))}
.panel__sep{color:var(--ink-faint)}
.panel__need{color:var(--rim)}
/* Height is reserved for FIVE rows though only four are real: the duplicate
   that arrives and folds must not shove the panel taller while it exists. */
.panel__rows{list-style:none;margin:0;padding:0 .55rem .35rem;min-height:12.4rem}
.panel__foot{margin:0;padding:.75rem 1.15rem .9rem;border-top:1px solid rgba(212,175,55,.12);
  font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:10px;letter-spacing:.26em;
  text-transform:uppercase;color:var(--ink-faint)}

/* one line per fact */
.row{display:flex;align-items:center;gap:.75rem;padding:.62rem .6rem;border-radius:3px;
  font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12.5px;
  border-left:2px solid transparent;
  transition:background 240ms var(--ease),border-color 240ms var(--ease)}
.row + .row{box-shadow:inset 0 1px 0 rgba(212,175,55,.07)}
.row__repo{color:var(--brass-bright);flex:none;letter-spacing:.02em}
.row__what{color:var(--ink-soft);flex:1 1 auto;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* the merge counter wears the same unboxed register as the labels */
.row__dup{flex:none;color:var(--brass);font-size:10px;letter-spacing:.14em;
  opacity:0;transform:scale(.7);text-shadow:0 0 10px rgba(212,175,55,.6);
  transition:opacity 300ms var(--ease),transform 300ms var(--ease)}
.row__dup.on{opacity:1;transform:none}
/* The grounding label is a TYPOGRAPHIC marker, not a pill. Boxed tags read as
   framework furniture; a lit square plus letterspaced caps, right-aligned into a
   fixed column, reads as an instrument legend and holds a vertical rhythm. */
.row__tag{flex:none;font-size:9px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-faint);display:flex;align-items:center;justify-content:flex-end;
  gap:.5rem;min-width:7.4rem;text-align:right}
.row__tag::before{content:"";width:5px;height:5px;flex:none;background:currentColor;
  box-shadow:0 0 9px currentColor}
.row--observed .row__tag{color:var(--sage)}
.row--unverified .row__tag{color:var(--brass-bright)}
.row--need{border-left-color:var(--ember);background:rgba(229,98,31,.07)}
.row--need .row__what{color:var(--ink)}
.row--need .row__tag{color:var(--rim)}
@media (prefers-reduced-motion:no-preference){
  .row--need .row__tag::before{animation:need-pulse 2.2s var(--ease) infinite}
  @keyframes need-pulse{0%,100%{box-shadow:0 0 6px rgba(229,98,31,.5)}
    50%{box-shadow:0 0 16px 1px rgba(229,98,31,1)}}
}
/* hover is a MATERIAL change: light enters the row from its lit edge */
.row:hover{cursor:default;border-left-color:rgba(255,179,71,.7);
  background:linear-gradient(90deg,rgba(255,179,71,.13),rgba(255,179,71,.015) 62%);
  box-shadow:inset 0 0 26px -9px rgba(255,179,71,.6)}
/* the blocked line is a control — it says so when the hand arrives */
.row--need{cursor:pointer}
.row__steer{flex:none;font-size:9px;letter-spacing:.2em;text-transform:uppercase;
  color:#180f06;border-radius:3px;padding:.26rem .6rem;
  background:linear-gradient(180deg,#f7d879,#d4af37 55%,#b08d2a);
  box-shadow:inset 0 1px 0 rgba(255,247,225,.7), inset 0 -1px 0 rgba(0,0,0,.32),
    0 5px 16px -7px rgba(255,179,71,.95);
  opacity:0;transform:translateX(12px) scale(.88);
  transition:opacity 220ms var(--ease),transform 260ms var(--ease)}
.row--need:hover .row__steer,.row--need:focus-visible .row__steer{opacity:1;transform:none}
.row--need:hover{border-left-color:var(--rim);
  background:linear-gradient(90deg,rgba(229,98,31,.24),rgba(229,98,31,.03) 66%);
  box-shadow:inset 0 0 30px -8px rgba(255,120,50,.75)}
/* rows arrive one at a time, on the measured 60ms stagger */
body.js .row{opacity:0;transform:translateY(9px)}
body.js .row.in{opacity:1;transform:none;
  transition:opacity var(--enter) var(--ease),transform var(--enter) var(--ease),
    background 240ms var(--ease),border-color 240ms var(--ease)}
/* the duplicate that tried to land, folding into the count above it */
body.js .row.fold{opacity:0;transform:translateY(-14px) scaleY(.55);
  transition:opacity 340ms var(--ease),transform 340ms var(--ease)}
@media (prefers-reduced-motion:reduce){
  body.js .row{opacity:1;transform:none}
  .row__dup{opacity:1;transform:none}
}

@media (max-width:900px){
  .beat--glance{grid-template-columns:1fr;gap:2.5rem}
  .glance__copy{max-width:none}
  .glance__scene{padding-top:1rem;perspective:1100px}
  .panel{transform:rotateY(-3deg)}
}
/* phone: the readout keeps every fact, on a tighter register */
@media (max-width:560px){
  .glance__scene{padding-top:.5rem}
  .panel__lede{font-size:16px;padding:.95rem .9rem .8rem}
  .panel__rows{padding:0 .35rem .3rem;min-height:11.2rem}
  .row{gap:.5rem;font-size:11px;padding:.55rem .45rem}
  .row__tag{min-width:0;font-size:8px;letter-spacing:.14em;gap:.35rem}
  .row__tag::before{width:4px;height:4px}
}
@media (prefers-reduced-motion:reduce){
  .panel{transform:none}
}

/* ── grounding chips (the app's real grammar, site-rendered) ─────────────── */
.chips{display:flex;flex-wrap:wrap;gap:.6rem;margin:0 0 1.6rem}
.chip{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11.5px;
  letter-spacing:.12em;text-transform:uppercase;padding:.48rem .9rem;border-radius:2px;
  border:1px solid var(--line);color:var(--ink-soft);background:rgba(16,12,7,.72);
  transition:transform 240ms var(--ease),border-color 240ms var(--ease),
    box-shadow 240ms var(--ease)}
.chip:hover{transform:translateY(-3px)}
.chip--fact{border-color:rgba(127,166,136,.5);color:var(--sage)}
.chip--fact:hover{box-shadow:0 6px 18px -10px rgba(127,166,136,.6)}
.chip--claim{border-color:rgba(212,175,55,.45);color:var(--brass-bright)}
.chip--claim:hover{box-shadow:0 6px 18px -10px rgba(212,175,55,.6)}
.chip--fail{border-color:rgba(229,98,31,.5);color:var(--rim)}
.chip--fail:hover{box-shadow:0 6px 18px -10px rgba(229,98,31,.6)}
/* chips STAMP in one after another once their container reveals */
body.js .chips .chip{opacity:0;transform:translateY(10px) scale(.94);
  transition:opacity var(--enter) var(--ease),transform var(--enter) var(--ease)}
body.js .chips.is-in .chip{opacity:1;transform:none}
.chips.is-in .chip:nth-child(2){transition-delay:120ms}
.chips.is-in .chip:nth-child(3){transition-delay:240ms}
@media (prefers-reduced-motion:reduce){
  body.js .chips .chip{opacity:1;transform:none;transition:none}
  .chip:hover{transform:none}
}

/* ── the approvals rail (illustration, labeled as such in the HTML) ──────── */
.rail{margin:0 0 1.6rem;border:1px solid var(--line);border-radius:3px;background:rgba(16,12,7,.72)}
.rail__row{display:flex;align-items:center;gap:.8rem;padding:.85rem 1rem;flex-wrap:wrap}
.rail__dot{width:7px;height:7px;border-radius:50%;background:var(--ember);flex:none;
  box-shadow:0 0 8px rgba(229,98,31,.55)}
@media (prefers-reduced-motion:no-preference){
  .rail__dot{animation:rail-pulse 2.2s var(--ease) infinite}
  @keyframes rail-pulse{
    0%,100%{box-shadow:0 0 6px rgba(229,98,31,.45)}
    50%{box-shadow:0 0 14px rgba(229,98,31,.9)}}
}
.rail__text{font-size:14.5px;color:var(--ink);flex:1 1 14rem;
  transition:opacity 380ms var(--ease)}
.rail__text.swap{opacity:0}
.rail__acts{display:flex;gap:.45rem}
.rail__act{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--brass-bright);
  border:1px solid rgba(212,175,55,.28);border-radius:2px;padding:.34rem .7rem;
  transition:background 200ms var(--ease),color 200ms var(--ease),transform 200ms var(--ease),
    box-shadow 200ms var(--ease)}
.rail__act:hover{box-shadow:0 0 14px -4px rgba(255,179,71,.7)}
.rail__act:hover{background:var(--brass);color:var(--bg);transform:translateY(-2px)}

/* ── the constellation — a wide dark sky, the one break-out element ──────── */
.beat--sky{max-width:none;padding-left:0;padding-right:0}
.beat--sky > .beat__eyebrow,.beat--sky > .beat__head,.beat--sky > .beat__body{
  max-width:46rem;margin-left:auto;margin-right:auto;padding:0 1.5rem}
.beat--sky > .beat__eyebrow{margin-bottom:1.3rem}
.beat--sky > .beat__head{margin-bottom:1.6rem}
.sky{width:min(76rem,100%);margin:2.4rem auto 0;padding:0 1rem}
#sky{display:block;width:100%;height:min(58vh,460px);touch-action:pan-y;
  border-top:1px solid rgba(212,175,55,.14);border-bottom:1px solid rgba(212,175,55,.14)}

/* ── BEAT 05 — the specifics: the page's one plain-spoken surface ────────── */
/* Deliberately the least decorated thing here. After five beats of argument a
   reader wants a spec sheet, and a spec sheet earns trust by looking like one.
   The label column wears the instrument's monospace register so it reads as
   machine-stated fact rather than marketing. */
.beat--spec{max-width:54rem}
/* a spec sheet has to be legible before it is beautiful — this beat gets a
   deeper ground than the argument beats do */
.beat--spec::before{background:radial-gradient(62% 48% at 50% 50%,rgba(6,4,3,.96),rgba(6,4,3,.72) 54%,rgba(6,4,3,0) 80%)}
.spec{margin:0 0 2rem;padding:0;border-top:1px solid var(--line)}
.spec__row{display:grid;grid-template-columns:9.5rem minmax(0,1fr);gap:1.6rem;
  padding:1.15rem 0;border-bottom:1px solid var(--line)}
.spec dt{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--brass);padding-top:.32em}
.spec dd{margin:0;color:var(--ink-soft);line-height:1.6}
.spec dd strong{font-weight:500;color:var(--ink)}
.spec dd code{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:.88em;
  color:var(--brass-bright);background:rgba(212,175,55,.09);border-radius:2px;padding:.1em .35em}
@media (max-width:640px){
  .spec__row{grid-template-columns:1fr;gap:.5rem}
  .spec dt{padding-top:0}
}

/* ── the claim ───────────────────────────────────────────────────────────── */
.cmdline{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:clamp(17px,2.8vw,23px);
  color:var(--cream);background:rgba(16,12,7,.8);border:1px solid rgba(212,175,55,.35);
  border-radius:3px;padding:1.05rem 1.4rem;display:inline-block;margin:0 0 1.6rem;
  letter-spacing:.02em;box-shadow:0 0 34px -10px rgba(255,140,60,.45),
    inset 0 1px 0 rgba(255,179,71,.16)}
.cmdline__prompt{color:var(--brass);margin-right:.6em}
/* the terminal caret blinks after the command — the machine is waiting */
.cmdline__caret{display:inline-block;width:.55em;height:1.05em;margin-left:.35em;
  background:var(--brass);vertical-align:text-bottom}
@media (prefers-reduced-motion:no-preference){
  .cmdline__caret{animation:caret 1.1s steps(1) infinite}
  @keyframes caret{0%,49%{opacity:1}50%,100%{opacity:0}}
}

/* ── footer ──────────────────────────────────────────────────────────────── */
.foot{position:relative;z-index:2;padding:3.4rem 1.5rem 3.6rem;
  border-top:1px solid var(--line);background:rgba(4,3,2,.72)}
.foot__inner{max-width:54rem;margin:0 auto;display:flex;flex-wrap:wrap;
  align-items:center;justify-content:space-between;gap:1.2rem}
.foot__id{display:flex;flex-direction:column;gap:.3rem}
.foot__domain{font-family:var(--serif);font-size:15px;letter-spacing:.06em;color:var(--cream)}
.foot__by{font-size:12.5px;color:var(--ink-faint)}
.foot__by a{color:var(--ink-soft)}
.foot__nav{display:flex;flex-wrap:wrap;align-items:center;gap:1.4rem}
/* the repo isn't public yet — the slot is honest rather than a dead link */
.foot__soon{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);
  display:inline-flex;align-items:center;gap:.45rem;cursor:default}
.foot__soon i{font-style:normal;font-size:9px;letter-spacing:.16em;
  border:1px solid var(--line);border-radius:2px;padding:.12rem .34rem;color:var(--brass-dim)}
.foot a,.docbody a{color:var(--ink-soft);text-decoration:none;
  border-bottom:1px solid rgba(212,175,55,.35);
  transition:color 200ms var(--ease),border-color 200ms var(--ease)}
.foot a:hover,.docbody a:hover{color:var(--amber);border-color:var(--amber)}
.foot__nav a{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;
  letter-spacing:.2em;text-transform:uppercase;border-bottom-color:transparent}
.foot__note{max-width:54rem;margin:1.6rem auto 0;font-size:12px;line-height:1.6;
  color:var(--ink-faint)}

/* ── document pages (privacy, terms) ─────────────────────────────────────── */
/* Same tokens, quieter register: no WebGL, no reveals, no cursor. A legal page
   that performs is a legal page nobody trusts. */
.doc{position:relative;z-index:2;max-width:44rem;margin:0 auto;padding:9rem 1.5rem 4rem}
.doc__back{display:inline-block;font-family:ui-monospace,'SF Mono',Menlo,monospace;
  font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--brass);
  text-decoration:none;margin:0 0 2.4rem;border-bottom:1px solid transparent}
.doc__back:hover{border-bottom-color:var(--brass)}
.doc h1{font-family:var(--serif);font-weight:400;font-size:clamp(34px,5.2vw,54px);
  line-height:1.08;margin:0 0 .6rem;color:var(--cream)}
.doc__meta{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);margin:0 0 2.6rem}
.doc h2{font-family:var(--serif);font-weight:400;font-size:clamp(21px,2.6vw,27px);
  line-height:1.25;margin:2.8rem 0 .9rem;color:var(--cream)}
.docbody{color:var(--ink-soft);line-height:1.68}
.docbody p{margin:0 0 1.05em}
.docbody strong{font-weight:500;color:var(--ink)}
.docbody code{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:.88em;
  color:var(--brass-bright);background:rgba(212,175,55,.09);border-radius:2px;padding:.1em .35em}
.docbody ul{margin:0 0 1.05em;padding-left:1.1rem}
.docbody li{margin:0 0 .5em}
/* the short version — the only thing most readers will read */
.tldr{border:1px solid rgba(212,175,55,.3);border-left:2px solid var(--brass);
  border-radius:4px;background:rgba(16,12,7,.66);padding:1.3rem 1.5rem;margin:0 0 2.4rem}
.tldr p:last-child{margin-bottom:0}
/* what leaves the machine, and when */
.flow{width:100%;border-collapse:collapse;margin:0 0 1.6rem;font-size:14px;
  table-layout:fixed}
.flow th,.flow td{text-align:left;vertical-align:top;padding:.8rem .7rem .8rem 0;
  border-bottom:1px solid var(--line)}
.flow th{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:10px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--brass);font-weight:500}
.flow td{color:var(--ink-soft);line-height:1.5}
.flow td:first-child{color:var(--ink)}
/* fixed widths — otherwise the first cell eats half the table and the rest
   wrap to one word per line */
.flow col.c1{width:26%} .flow col.c2{width:26%} .flow col.c3{width:26%} .flow col.c4{width:22%}
.flow__wrap{overflow-x:auto}
/* phone: a four-column table is unreadable — each destination becomes a block */
@media (max-width:660px){
  .flow,.flow tbody,.flow tr,.flow td{display:block;width:auto}
  .flow thead{display:none}
  .flow tr{border-bottom:1px solid var(--line);padding:.9rem 0}
  .flow td{border:0;padding:.18rem 0}
  .flow td:first-child{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12px;
    letter-spacing:.06em;color:var(--brass-bright);margin-bottom:.3rem}
  .flow td[data-l]::before{content:attr(data-l) " ";font-family:ui-monospace,'SF Mono',Menlo,monospace;
    font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}
}

/* ── entrances — progressive enhancement, decelerating, 500ms ────────────── */
/* Hidden ONLY when JS has landed (body.js) and the element hasn't entered yet,
   so no-JS readers get the full page. Reduced motion: simply present. */
body.js [data-reveal]{opacity:0;transform:translateY(18px);
  transition:opacity var(--enter) var(--ease),transform var(--enter) var(--ease)}
body.js [data-reveal].is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  body.js [data-reveal]{opacity:1;transform:none;transition:none}
}

/* ── split-word assembly — headlines build word by word (60ms stagger) ────── */
.split .w{display:inline-block;opacity:0;transform:translateY(0.45em) rotate(0.5deg);
  transition:opacity var(--enter) var(--ease),transform 620ms var(--ease)}
.split.is-in .w,[data-reveal].is-in .w{opacity:1;transform:none}
.hero__word.split .w{transform:translateY(0.35em) scale(0.96)}
.hero__word.split.is-in .w{transform:none}

/* ── scroll progress hairline ─────────────────────────────────────────────── */
#progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:30;
  background:linear-gradient(90deg,var(--brass),var(--amber));
  transform:scaleX(0);transform-origin:0 50%;pointer-events:none}

/* ── ember cursor ─────────────────────────────────────────────────────────── */
body.has-cursor{cursor:none}
body.has-cursor a,body.has-cursor .cmdline{cursor:none}
#cursor{position:fixed;left:-4px;top:-4px;width:8px;height:8px;border-radius:50%;
  background:var(--amber);z-index:60;pointer-events:none;mix-blend-mode:screen;
  box-shadow:0 0 10px rgba(255,179,71,.8)}
#cursor-ring{position:fixed;left:-17px;top:-17px;width:34px;height:34px;border-radius:50%;
  border:1px solid rgba(212,175,55,.55);z-index:59;pointer-events:none;
  transition:width 240ms var(--ease),height 240ms var(--ease),left 240ms var(--ease),
    top 240ms var(--ease),border-color 240ms var(--ease)}
/* over the star: the ring opens — the sun is a live control */
body.sun-hover #cursor-ring{width:52px;height:52px;left:-26px;top:-26px;
  border-color:rgba(255,179,71,.9)}
body.sun-grab #cursor-ring{width:40px;height:40px;left:-20px;top:-20px}

/* ── the claim: copy feedback ─────────────────────────────────────────────── */
.cmdline{position:relative;user-select:none;-webkit-user-select:none;cursor:pointer}
.cmdline::after{content:"click to copy";position:absolute;left:0;bottom:-1.7rem;
  font-family:var(--sans);font-size:11px;letter-spacing:.3em;text-transform:uppercase;
  color:var(--ink-faint);opacity:0;transition:opacity var(--enter) var(--ease)}
.cmdline:hover::after,.cmdline:focus-visible::after{opacity:1}
.cmdline.copied::after{content:"copied ✓";color:var(--sage);opacity:1}
:focus-visible{outline:2px solid var(--brass);outline-offset:4px}

/* ── reduced motion: the static sun dims once the story begins ───────────── */
@media (prefers-reduced-motion:reduce){
  #stage{transition:opacity 400ms linear}
  body.past-hero #stage{opacity:.22}
}
