/* Starstruck v4 · shell styles. Scene styles live in scenes/<key>.css (each scene owns its own file). */
:root {
  --page: #000000;            /* THE page colour; the prompt pill is made of it */
  --page-2: #171717;
  --ink: #f3f3f3;
  --ink-2: rgba(243, 243, 243, 0.62);
  --ink-3: rgba(243, 243, 243, 0.5);   /* 4.86:1 on #000 (was .38 = 3.16:1) */
  --gold: #f5e050;          /* lemon (core #fff6b0 · lemon #f5e050 · deep #c9a227) */
  --lemon-core: #fff6b0; --lemon-deep: #c9a227;
  --blue: #f8e770;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, sans-serif;
  --font-inter: var(--font);
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --font-rounded: ui-rounded, "SF Pro Rounded", -apple-system, "Inter", system-ui, sans-serif;
  --spring: cubic-bezier(.2, .9, .25, 1.15);
  --out: cubic-bezier(.16, 1, .3, 1);
  --in: cubic-bezier(.55, 0, .85, .3);
  /* ---- vibe system (shared tokens: scenes may adopt these) ---- */
  --amber: var(--gold);
  --amber-glow: rgb(245 224 80 / .28);
  --glass: rgb(0 0 0 / .38);               /* translucent page colour for pills / dials */
  --glass-edge: rgb(243 243 243 / .14);       /* the hairline */
  --hairline: 1px solid var(--glass-edge);
  --ease-out-expo: cubic-bezier(.16, 1, .3, 1);   /* things arriving: fast, then settle */
  --ease-in-expo: cubic-bezier(.7, 0, .84, 0);    /* things leaving: slow, then gone */
  --ease-inout: cubic-bezier(.65, 0, .35, 1);
  --dur-quick: .18s; --dur-base: .42s; --dur-slow: .9s;
  --fs-display: clamp(34px, 5vw, 72px);       /* hero / section titles */
  --fs-talk: clamp(28px, 4.2vw, 60px);        /* the one line per screen */
  --fs-lede: clamp(16px, 1.45vw, 20px);       /* sub-lines, paragraphs */
  --fs-label: clamp(10.5px, .8vw, 12px);      /* mono / caps micro labels */
  --track-display: -0.035em; --track-caps: .14em;
  --pad-x: max(16px, env(safe-area-inset-left, 0px));
  color-scheme: dark;
}
::selection { background: rgb(245 224 80 / .32); color: #fff; }
:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; border-radius: 6px; }
:focus:not(:focus-visible) { outline: none; }
body { text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; font-kerning: normal; }
h1, h2, h3, .talk { text-wrap: balance; }
p, .sub { text-wrap: pretty; }
/* film grain + vignette: ONE static composited layer above the stage, below the dial. Never repainted. */
body::before { content: ""; position: fixed; inset: 0; z-index: 6; pointer-events: none; contain: strict;
  background:
    radial-gradient(120% 95% at 50% 46%, transparent 58%, rgb(0 0 0 / .42) 100%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .55 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 100% 100%, 160px 160px; opacity: .5; mix-blend-mode: soft-light; transform: translateZ(0); }
@media (prefers-reduced-transparency: reduce) { body::before { display: none; } }
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--page); color: var(--ink); font-family: var(--font); -webkit-font-smoothing: antialiased; overflow-x: hidden; overscroll-behavior-y: none; }
#sky { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; contain: strict; background: var(--page); }
#stage { position: fixed; inset: 0; z-index: 1; overflow: hidden; }
.scene { position: absolute; inset: 0; visibility: hidden; contain: layout paint; }
.scene.on { visibility: visible; }
#over { position: fixed; inset: 0; z-index: 5; pointer-events: none; }
#over > * { pointer-events: auto; }
#track { position: relative; z-index: -1; width: 1px; }
/* the talk: one line at a time, centred; scenes build theirs with talk() from shell.js */
.talk { position: absolute; left: 50%; width: min(92vw, 980px); transform: translateX(-50%); text-align: center;
  font-weight: 600; font-size: var(--fs-talk); line-height: 1.05; letter-spacing: var(--track-display); margin: 0;
  /* header clearance: scenes set top in vh (7–12vh) inline; on notched phones (viewport-fit=cover) and short windows the
     fixed header pill (12px + safe-area + 32px) would sit on the first line → push down by the inset + any shortfall */
  margin-top: calc(env(safe-area-inset-top, 0px) + max(0px, 58px - 7vh));
  /* legibility: lines drift up through the lemon horizon on their way in; a soft night halo keeps ≥ 4.5:1 there
     (static: rasterised once with each word's layer, nothing animates it) */
  text-shadow: 0 1px 2px rgb(0 0 0 / .35), 0 2px 26px rgb(0 0 0 / .55); }
.talk .w { display: inline-block; will-change: transform, opacity, filter; }
.talk .sub { display: block; margin-top: 14px; font-weight: 400; font-size: var(--fs-lede); line-height: 1.45; letter-spacing: -0.011em; color: var(--ink-2); max-width: 36em; margin-inline: auto; }
.proto-tag { font: 500 11px/1 var(--font); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
@media (prefers-reduced-motion: reduce) { .talk .w { will-change: auto; } }
/* idle: nobody has touched the page for a while → every ambient CSS animation holds still (no GPU work at rest) */
html.idle *, html.idle *::before, html.idle *::after { animation-play-state: paused !important; }
.scene:not(.on) *, .scene:not(.on) *::before, .scene:not(.on) *::after { animation-play-state: paused !important; }
@view-transition { navigation: auto; }
/* the page moves beat by beat (shell.js): the native scrollbar would be a second, unpaced way through the story */
html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
/* the first-visit cue (shell.js): appears only until the reader moves the page once */
.cue { position: fixed; left: 50%; bottom: calc(30px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; align-items: center; gap: 6px;
  transform: translate3d(-50%, 8px, 0); opacity: 0; pointer-events: none !important; color: var(--ink-2);
  font: 500 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase;
  transition: opacity var(--dur-slow) var(--ease-out-expo), transform var(--dur-slow) var(--ease-out-expo); }
.cue.on { opacity: 1; transform: translate3d(-50%, 0, 0); }
.cue svg { animation: cue-bob 1.6s var(--out) infinite; }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); opacity: .55; } 50% { transform: translateY(4px); opacity: 1; } }
@media (max-width: 899px), (pointer: coarse) { .cue { bottom: calc(26px + env(safe-area-inset-bottom, 0px)); } .cue span { display: none; } }
@media (prefers-reduced-motion: reduce) { .cue svg { animation: none; } }

/* ---- THE backdrop (backdrop.js): one deep night base + ONE lemon horizon glow, shared by every scene -----------------
   Hosts: #sky (fixed, behind #stage) and a lockstep clone inside the prompt's .pr-back. All gradients are painted once;
   backdrop.js only writes the .bd-hz transform (glow position / scale per chapter) and the three .bd-g opacities
   (lemon / amber / pale core crossfaded = the hue drift). Scenes paint NO full-viewport fills of their own. */
.bd, .bd-base, .bd-g { position: absolute; inset: 0; pointer-events: none; }
.bd { overflow: hidden; }
.bd-base { background:
  radial-gradient(90% 55% at 50% -12%, rgb(56 56 56 / .22), transparent 70%),
  linear-gradient(180deg, #000000 0%, #000000 34%, var(--page) 56%, #000000 78%, #110f0a 100%); }
/* the horizon group: 160vw × 100vh, its ellipse centre sits on the viewport's bottom edge (top 40vh + 60%) */
.bd-hz { position: absolute; left: -30vw; top: 40vh; width: 160vw; height: 100vh; transform-origin: 50% 60%;
  will-change: transform; backface-visibility: hidden; }
.bd-g { will-change: opacity; opacity: 0; }
.bd-g1 { background: radial-gradient(50% 50% at 50% 60%, rgb(255 246 176 / .46) 0%, rgb(245 224 80 / .3) 14%, rgb(201 162 39 / .15) 34%, rgb(201 162 39 / .055) 56%, transparent 78%); }
.bd-g2 { background: radial-gradient(56% 54% at 50% 62%, rgb(232 176 64 / .4) 0%, rgb(201 140 39 / .2) 26%, rgb(120 80 24 / .08) 52%, transparent 76%); }
.bd-g3 { background: radial-gradient(44% 10% at 50% 60%, rgb(255 250 214 / .62) 0%, rgb(255 246 176 / .22) 42%, transparent 100%),
  radial-gradient(30% 26% at 50% 60%, rgb(255 246 176 / .24), transparent 80%); }
@media (prefers-reduced-motion: reduce) { .bd-hz { will-change: auto; } }
