/* ============================================================
   POWER EXPECTATIONS — RESTORATION
   Energy-tech for the yard. Emerald high-voltage + warm gold.
   ============================================================ */

:root{
  --void:#090c22;
  --void-2:#0c1330;
  --charcoal:#111c42;
  --ink:#fff6e6;
  --ink-dim:#a9c6ba;
  --ink-faint:#9fc0b0;

  --volt:#f6a51e;          /* high-voltage emerald */
  --volt-bright:#ffd47a;
  --volt-deep:#8a5a10;
  --teal:#d99e2c;
  --amber:#ffb24d;         /* energized work-light gold */
  --amber-bright:#ffd27a;
  --surge:#fff6e2;

  --glass-bg:rgba(11,15,36,0.5);   /* navy glass — was rgba(14,32,26) (emerald-era green the navy recolor missed) */
  --glass-brd:rgba(242,178,58,0.22);
  --glass-hi:rgba(255,225,166,0.28);

  --display:"Space Grotesk","Inter",-apple-system,sans-serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --mono:"Space Grotesk",ui-monospace,"SF Mono",Menlo,monospace;

  --ease:cubic-bezier(0.22,1,0.36,1);
  --ease-io:cubic-bezier(0.65,0.05,0.36,1);
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-stopped{overflow:hidden}

html{ -webkit-text-size-adjust:100%; }
body{
  background:var(--void);
  color:var(--ink);
  font-family:var(--sans);
  overflow-x:hidden;
  overscroll-behavior-y:none;   /* no iOS rubber-band / pull-to-refresh mid-film */
  touch-action:pan-y;           /* lock vertical intent -> cleaner Lenis deltas */
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

::selection{background:var(--volt); color:var(--void)}
::-webkit-scrollbar{width:0; height:0}
html{scrollbar-width:none}

/* ---------- WebGL stage ---------- */
#stage{
  /* 100% + dvh (not vh): on iOS 100vh is the LARGE viewport, so the canvas
     overshot and every address-bar show/hide re-allocated the render targets */
  position:fixed; inset:0; width:100%; height:100%; height:100dvh;
  display:block; z-index:0; touch-action:pan-y; cursor:default;
}

/* ---------- Film grade overlays ---------- */
.grade{
  position:fixed; inset:0; z-index:1; pointer-events:none;
  mix-blend-mode:soft-light; opacity:.35;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(246,165,30,.10), transparent 60%),
    radial-gradient(120% 90% at 50% 110%, rgba(255,178,77,.08), transparent 55%);
  transition:opacity 1.2s var(--ease);
}
.vignette{
  position:fixed; inset:0; z-index:2; pointer-events:none;
  background:radial-gradient(135% 105% at 50% 42%, transparent 66%, rgba(0,0,0,.30) 100%);
}
.grade::after{
  content:""; position:absolute; inset:-50%;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.5'/></svg>");
  opacity:.012; mix-blend-mode:overlay;
}

/* ---------- Boot loader ---------- */
.boot{
  position:fixed; inset:0; z-index:60; display:flex;
  flex-direction:column; align-items:center; justify-content:center; gap:22px;
  background:radial-gradient(80% 80% at 50% 38%,var(--void-2),var(--void));
  transition:opacity .9s var(--ease), visibility .9s;
}
.boot.is-done{opacity:0; visibility:hidden; pointer-events:none}
.boot__mark{ display:flex; align-items:center; justify-content:center; }
.boot__logo{
  width:clamp(190px,34vw,260px); height:auto; aspect-ratio:900/520; display:block;
  filter:drop-shadow(0 0 24px rgba(246,165,30,.18));   /* whisper of the film's gold */
}
.boot__bar{width:220px; height:2px; background:rgba(242,178,58,.2); border-radius:2px; overflow:hidden}
.boot__bar i{display:block; height:100%; width:0%;
  background:linear-gradient(90deg,var(--volt-deep),var(--volt-bright)); box-shadow:0 0 12px var(--volt);
  transition:width .4s var(--ease)}
.boot__status{font:500 11px/1 var(--mono); letter-spacing:.26em; color:var(--ink-faint); text-transform:uppercase}

/* intro title sequence — plays after the loader, then lifts to the film */
.titlecard{
  position:fixed; inset:0; z-index:55; pointer-events:none; text-align:center;
  display:flex; align-items:center; justify-content:center;
  background:
    radial-gradient(58% 48% at 50% 45%, rgba(168,120,24,.12) 0%, rgba(4,12,9,0) 62%),
    linear-gradient(180deg,#060a26 0%,#08102e 56%,#060820 100%);
  transition:opacity 1.1s var(--ease), visibility 1.1s;
}
.titlecard.is-done{opacity:0; visibility:hidden}
.titlecard__inner{max-width:1000px; padding:0 8vw}
.titlecard__mark{
  position:relative; display:inline-flex; justify-content:center;
  margin-bottom:clamp(20px,4.6vh,44px);
}
.titlecard__emblem{ position:relative; z-index:1; display:block; overflow:hidden; line-height:0; border-radius:6px; }
.titlecard__logo{ display:block; width:clamp(240px,40vw,460px); height:auto; aspect-ratio:900/520; }
.titlecard__glow{
  position:absolute; left:50%; top:50%; z-index:0; transform:translate(-50%,-50%);
  width:78%; height:150%; border-radius:50%; pointer-events:none; opacity:0;
  background:radial-gradient(closest-side, rgba(246,165,30,.34), rgba(246,165,30,.10) 55%, transparent 72%);
  filter:blur(16px); mix-blend-mode:screen; will-change:opacity,transform;
}
.titlecard__glint{
  position:absolute; top:0; left:0; width:58%; height:100%; opacity:0; pointer-events:none; mix-blend-mode:screen;
  background:linear-gradient(105deg, rgba(255,236,200,0) 34%, rgba(255,236,200,.5) 50%, rgba(255,214,140,0) 66%);
}
.titlecard__kicker{font:600 11px/1 var(--mono); letter-spacing:.34em; text-transform:uppercase; color:#ffcf6a; margin-bottom:16px}
.titlecard__title{font:650 clamp(34px,6.6vw,86px)/1.03 var(--display); letter-spacing:-.02em; color:#fff6e6; margin:0}
.titlecard__title .tc-line{display:block; will-change:clip-path,opacity}
.titlecard__sub{font:400 clamp(13px,1.7vw,19px)/1.5 var(--sans); color:#efe0c2; margin-top:22px}

/* ============================================================
   HUD — grid-ops command center (glassmorphism)
   ============================================================ */
.glass{
  background:var(--glass-bg);
  border:1px solid rgba(255,212,122,.16);
  border-radius:14px;
  backdrop-filter:blur(22px) saturate(140%);
  -webkit-backdrop-filter:blur(22px) saturate(140%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.15),
    0 0 0 1px rgba(0,0,0,.28),
    0 22px 55px -22px rgba(0,0,0,.7);
}
/* phones/tablets: a 22px backdrop blur over a canvas that repaints EVERY frame
   forces the compositor to re-blur every frame on 5+ glass elements — real
   ms/frame on mid-tier phones. A deeper solid glass reads nearly identically. */
@media (pointer:coarse){
  .glass{
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    background:rgba(11,15,36,.9);
  }
}
.hud{
  position:fixed; inset:0; z-index:20; pointer-events:none;
  padding:clamp(14px,2.4vw,30px);
  opacity:0; transition:opacity 1s var(--ease);
}
.hud.is-live{opacity:1}
.hud > *{position:absolute; pointer-events:auto}

.hud__brand{
  top:clamp(14px,2.4vw,30px); left:clamp(14px,2.4vw,30px);
  display:flex; align-items:center; gap:12px; padding:12px 16px;
}
.hud__mark{ width:28px; height:28px; flex:none; object-fit:contain;
  filter:drop-shadow(0 0 6px rgba(246,165,30,.4)); }   /* matches the old bolt's glow */
.hud__brandtext{display:flex; flex-direction:column; line-height:1.2}
.hud__brandtext strong{font:700 12px/1 var(--display); letter-spacing:.16em}
.hud__brandtext span{font:500 9.5px/1.4 var(--sans); letter-spacing:.14em; color:var(--ink-faint); margin-top:4px; text-transform:uppercase}

.hud__phase{
  top:clamp(14px,2.4vw,30px); left:50%; transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; gap:3px; padding:9px 22px;
  text-align:center;
}
.hud__phaselabel{font:600 9.5px/1 var(--mono); letter-spacing:.26em; color:var(--volt-bright)}
.hud__phasename{font:600 15px/1 var(--display); letter-spacing:.22em; color:var(--ink)}

.hud__panel{
  top:clamp(14px,2.4vw,30px); right:clamp(14px,2.4vw,30px);
  width:min(300px,76vw); padding:16px 18px; display:flex; flex-direction:column; gap:15px;
}
.stat{display:flex; flex-direction:column; gap:6px}
.stat--row{flex-direction:row; gap:26px}
.stat--row > div{display:flex; flex-direction:column; gap:6px}
.stat__k{font:600 9px/1 var(--sans); letter-spacing:.18em; color:var(--ink-faint); text-transform:uppercase}
.stat__v{font:600 30px/0.9 var(--display); color:var(--ink); display:flex; align-items:baseline; gap:5px;
  font-variant-numeric:tabular-nums; letter-spacing:-.01em}
.stat__v b{font-weight:600}
.stat__v em{font:600 11px/1 var(--mono); font-style:normal; letter-spacing:.08em; color:var(--ink-dim)}
.stat__bar{height:3px; border-radius:3px; background:rgba(242,178,58,.16); overflow:hidden}
.stat__bar i{display:block; height:100%; width:0%;
  background:linear-gradient(90deg,var(--volt-deep),var(--volt-bright)); box-shadow:0 0 10px var(--volt); transition:width .15s linear}
.stat__bar--amber i{background:linear-gradient(90deg,#c97a14,var(--amber-bright)); box-shadow:0 0 10px var(--amber)}
.stat__sub{font:500 9px/1 var(--mono); letter-spacing:.02em; color:var(--ink-faint); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

.hud__ticker{
  left:clamp(14px,2.4vw,30px); bottom:clamp(14px,2.4vw,30px);
  display:flex; align-items:center; gap:10px; padding:10px 16px;
  font:500 10px/1 var(--mono); letter-spacing:.1em; color:var(--ink-dim); text-transform:uppercase;
  max-width:min(490px,86vw); white-space:nowrap;
}
.hud__ticker span{overflow:hidden; text-overflow:ellipsis; min-width:0}   /* climax strings must not spill the pill */
.hud__dot{width:7px;height:7px;border-radius:50%;background:var(--volt-bright);
  box-shadow:0 0 10px var(--volt); animation:pulse 1.8s var(--ease) infinite; flex:none}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}

/* projected 3D annotation labels (plants / line voltages / cities) */
.anno-layer{position:fixed; inset:0; width:100%; height:100%; pointer-events:none; z-index:8; overflow:visible}
.anno{transition:opacity .3s var(--ease)}
.anno-dot{fill:var(--volt-bright)}
.anno-tick{stroke:var(--volt-bright); stroke-width:1; opacity:.45}
.anno-label{font:600 9px var(--mono); letter-spacing:.13em; text-transform:uppercase; fill:#f6ecd6;
  paint-order:stroke; stroke:rgba(2,12,9,.72); stroke-width:2.6px}
.anno--plant .anno-dot{fill:var(--amber-bright)}
.anno--plant .anno-tick{stroke:var(--amber-bright)}
.anno--plant .anno-label{fill:#ffe1b0; letter-spacing:.16em}
.anno--trunk .anno-dot{fill:#ffcf5a}
.anno--trunk .anno-label{fill:#ffe6b4; font-size:8px}
.anno--city .anno-label{font-size:8.5px}
@media (max-width:640px){ .anno--trunk{display:none} .anno-label{font-size:8px} }

/* finale data-viz widgets (PR mini-map locator + restoration load-curve) */
.minimap, .loadcurve{position:fixed; z-index:9; opacity:0; pointer-events:none;
  transition:opacity .6s var(--ease); padding:8px}
body.dv-on .minimap, body.dv-on .loadcurve{opacity:1}
.minimap{left:clamp(14px,2.4vw,30px); bottom:120px; width:190px; height:104px}
.loadcurve{right:clamp(14px,2.4vw,30px); bottom:120px; width:300px; height:124px}
.dv-grid{stroke:rgba(255,212,122,.10); stroke-width:.5}
.dv-axis{stroke:rgba(255,212,122,.22); stroke-width:.6}
.dv-axislabel{font:600 6.5px var(--mono); letter-spacing:.08em; fill:var(--ink-faint); text-transform:uppercase}
.dv-mw-area{fill:rgba(246,165,30,.14)}
.dv-mw-line{stroke:var(--volt-bright); stroke-width:1.4; fill:none}
.dv-feed-line{stroke:var(--amber-bright); stroke-width:1.2; fill:none}
.dv-tick{stroke:rgba(255,230,180,.4); stroke-width:.6}
.dv-sweep{stroke:#f6ecd6; stroke-width:.7; opacity:.5}
.dv-readout{font:600 8px var(--mono); letter-spacing:.06em; fill:#f6ecd6}
.mm-coast{stroke:#ffc23a; stroke-width:1; fill:rgba(32,48,94,.32)}
.mm-plant{fill:var(--amber-bright)}
.mm-plantlabel{font:600 6px var(--mono); letter-spacing:.06em; fill:#ffe1b0; text-transform:uppercase}
.mm-city{fill:#d99e2c; opacity:.22}
.mm-city.is-live{opacity:1}
.mm-key230{stroke:#ffcf5a; stroke-width:1.4}
.mm-key115{stroke:#d99e2c; stroke-width:1.4}
.mm-keytext{font:600 6px var(--mono); letter-spacing:.06em; fill:var(--ink-faint); text-transform:uppercase}
@media (max-width:1100px){ .minimap{display:none} .loadcurve{width:236px; bottom:100px} }

/* chapter rail — left-edge act navigation */
.chapters{position:fixed; left:clamp(10px,1.6vw,20px); top:50%; transform:translateY(-50%);
  z-index:22; display:flex; flex-direction:column; gap:14px; opacity:0;
  transition:opacity 1s var(--ease); pointer-events:none}
.hud.is-live ~ .chapters{opacity:1}
.chapters__item{pointer-events:auto; display:flex; align-items:center; gap:9px;
  background:none; border:0; cursor:pointer; padding:3px 2px; color:var(--ink-faint)}
.chapters__dot{width:8px; height:8px; border-radius:50%; flex:none; background:transparent;
  border:1.4px solid rgba(255,212,122,.4); transition:background .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease)}
.chapters__txt{font:600 8.5px var(--mono); letter-spacing:.16em; text-transform:uppercase;
  opacity:0; transform:translateX(-4px); white-space:nowrap;
  transition:opacity .25s var(--ease), transform .25s var(--ease)}
@media (hover:hover) and (pointer:fine){
  .chapters__item:hover .chapters__txt{opacity:1; transform:none}
  .chapters__item:hover .chapters__dot{border-color:var(--volt-bright)}
}
.chapters__item:focus-visible .chapters__txt{opacity:1; transform:none}
.chapters__item:focus-visible{outline:none}
.chapters__item:focus-visible .chapters__dot{box-shadow:0 0 0 3px rgba(255,212,122,.35)}
.chapters__item.is-active .chapters__dot{background:var(--volt-bright); border-color:var(--volt-bright); box-shadow:0 0 10px var(--volt)}
.chapters__item.is-active .chapters__txt{opacity:1; transform:none; color:var(--ink)}
/* phones: the rail becomes a bottom-center dot strip (44px targets) instead of
   vanishing — a ~7-viewport film needs an act-jump affordance on touch too */
@media (max-width:720px){
  .chapters{
    top:auto; bottom:max(56px, calc(env(safe-area-inset-bottom) + 48px));
    left:50%; transform:translateX(-50%);
    flex-direction:row; gap:0;
  }
  .chapters__item{padding:0; width:40px; height:44px; justify-content:center}
  .chapters__txt{display:none}
  .chapters__dot{width:9px; height:9px}
}

/* language toggle — EN/ES glass chip in the freed bottom-right corner (the old
   sound-toggle spot). Fixed + safe-area-aware like the other HUD corners; sits
   OUTSIDE the aria-hidden #hud so it stays keyboard/AT-operable. Reveals with
   the HUD (sibling selector) and shows the language you'd switch TO. */
.hud__lang{
  position:fixed; z-index:23;
  right:max(clamp(14px,2.4vw,30px), env(safe-area-inset-right));
  bottom:max(clamp(14px,2.4vw,30px), env(safe-area-inset-bottom));
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:36px; padding:10px 14px;
  font:600 10.5px/1 var(--mono); letter-spacing:.24em; text-indent:.24em; /* re-center the 2 letters */
  color:var(--ink-dim); text-transform:uppercase; cursor:pointer;
  opacity:0; pointer-events:none;
  transition:opacity 1s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.hud.is-live ~ .hud__lang{opacity:1; pointer-events:auto}
@media (hover:hover) and (pointer:fine){
  .hud__lang:hover{color:var(--ink); border-color:var(--glass-hi)}
}
.hud__lang:focus-visible{outline:2px solid var(--volt-bright); outline-offset:3px}
.hud__lang:active{transform:scale(.96)}
@media (pointer:coarse){ .hud__lang{min-width:44px; min-height:44px} }   /* touch floor */
@media (max-width:560px){
  .hud__lang{right:max(12px, env(safe-area-inset-right)); bottom:max(12px, env(safe-area-inset-bottom)); padding:8px 11px}
}

/* HUD frequency strip-chart (dead-bus sag + recovery) */
.freqchart{display:block; width:72px; height:20px; margin-top:6px; opacity:0;
  transition:opacity .4s var(--ease); overflow:visible}
.fc-grid{stroke:rgba(255,212,122,.20); stroke-width:.5; vector-effect:non-scaling-stroke}
.fc-line{fill:none; stroke:var(--volt-bright); stroke-width:1.2; stroke-linejoin:round;
  vector-effect:non-scaling-stroke; filter:drop-shadow(0 0 2px var(--volt))}

/* ============================================================
   SCROLL NARRATIVE
   ============================================================ */
.scroll{position:relative; z-index:10}
.act{
  position:relative; min-height:118vh;
  display:flex; align-items:center;
  padding:14vh clamp(26px,7vw,150px);
}
.act--hero{min-height:128vh}
/* finale: a tall scroll track with a sticky inner pinned to the viewport, so the
   content stays vertically centred and never clips at the page bottom */
.act--finale{display:block; min-height:0; padding:0}
.finale-scroll{height:172vh; position:relative}
.act--finale .act__inner.center{
  position:sticky; top:0; height:100vh; height:100svh;
  display:flex; flex-direction:column; justify-content:center; align-items:center;
  margin:0 auto; padding:6vh clamp(26px,7vw,150px);
}
/* soft scrim so the copy reads against the bright relit island behind it */
.act--finale .act__inner.center::before{
  content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse 64% 54% at 50% 46%, rgba(9,12,34,.58) 0%, rgba(9,12,34,.34) 42%, rgba(9,12,34,0) 76%);
}
/* keep "back to light." on ONE line (2 lines total, not 3) so the finale fits
   100vh and the headline clears the top HUD bar instead of rendering behind it */
/* the persistent HUD already shows "PHASE 05 · RESTORE", so the finale's own
   "05 RESTORE" marker is redundant + crowds the pill — drop it here */
.act--finale .marker{display:none}
.act--finale .mega{font-size:clamp(38px,5.2vw,76px); line-height:.96}
.act--finale .lede{margin-top:clamp(14px,2.2vh,24px)}
.act--finale .finalstat{margin-top:clamp(12px,2.2vh,26px)}
.act--finale .finalstat b{font-size:clamp(46px,6.4vw,90px)}
.act--finale .signoff{margin-top:clamp(10px,1.8vh,22px)}
.act--finale .cta{margin-top:clamp(14px,2.4vh,28px)}
@media (max-height:760px){
  /* shorter viewports: shrink the big type a touch more so nothing clips */
  .act--finale .mega{font-size:clamp(34px,4.4vw,58px)}
  .act--finale .finalstat b{font-size:clamp(40px,5.2vw,66px)}
  .act--finale .lede{font-size:clamp(15px,1.5vw,18px)}
}
@media (max-height:560px){
  /* overscroll-behavior:contain: the nested scroll must hand the swipe back to
     the page instead of trapping it (landscape phones) */
  .act--finale .act__inner.center{justify-content:flex-start; padding-top:6vh; overflow:auto; overscroll-behavior:contain}
}
:focus-visible{outline:2px solid var(--volt-bright); outline-offset:3px}
.act__inner{max-width:min(66rem,92vw); width:100%; position:relative}
/* copy scrim — a DP's flag/net: a feathered dark ellipse anchored to the text
   column keeps type readable over the bright warm-sky beats. Invisible as a
   shape; reads only as the subject being lit. Left/right acts only — CENTERED
   blocks are excluded: the hero sits over a dark scene (the offset ellipse read
   as a weird shadow), and the finale defines its own centered scrim. */
.act__inner:not(.center)::before{
  content:''; position:absolute; inset:-10% -14%; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse 58% 62% at 26% 50%, rgba(9,12,34,.46) 0%, rgba(9,12,34,.24) 46%, rgba(9,12,34,0) 74%);
}
.act__inner.right{margin-left:auto; text-align:right}
.act__inner.right::before{
  background:radial-gradient(ellipse 58% 62% at 74% 50%, rgba(9,12,34,.46) 0%, rgba(9,12,34,.24) 46%, rgba(9,12,34,0) 74%);
}
.act__inner.center{margin:0 auto; text-align:center; max-width:min(48rem,92vw)}

.kicker{font:600 12px/1 var(--mono); letter-spacing:.24em; color:var(--volt-bright); text-transform:uppercase; margin-bottom:24px}
.dateline{font:600 10px/1.5 var(--mono); letter-spacing:.2em; color:var(--ink-faint); text-transform:uppercase; margin:-14px 0 24px}
.cta__cred{font:400 11px/1.55 var(--sans); color:var(--ink-faint); max-width:54ch; margin:10px auto 0; opacity:.9}
.marker{font:600 12px/1 var(--mono); letter-spacing:.2em; color:var(--ink-dim); text-transform:uppercase; margin-bottom:22px; display:flex; align-items:baseline; gap:14px}
.act__inner.right .marker{justify-content:flex-end}
.marker i{font-style:normal; font:600 13px/1 var(--display); color:var(--volt-bright);
  padding:5px 10px; border:1px solid var(--glass-brd); border-radius:7px; background:rgba(246,165,30,.06)}

.mega{font-family:var(--display); font-weight:600; letter-spacing:-.022em; line-height:.97;
  font-size:clamp(44px,7.4vw,104px)}
.big{font-family:var(--display); font-weight:600; letter-spacing:-.018em; line-height:1.0;
  font-size:clamp(32px,5.4vw,76px)}
.mega span,.big span{display:block}

.lede{font:400 clamp(17px,1.9vw,23px)/1.5 var(--sans); color:var(--ink); margin-top:28px; letter-spacing:-.005em;
  text-shadow:0 2px 18px rgba(0,10,6,.55)}
.act__inner.center .lede{margin-left:auto; margin-right:auto; max-width:38ch; color:var(--ink-dim)}
.body{font:400 clamp(15px,1.5vw,18px)/1.62 var(--sans); color:var(--ink-dim); margin-top:24px; max-width:44ch;
  text-shadow:0 2px 18px rgba(0,10,6,.55)}
/* deploy/energize play over the brightest sky — lift the body copy a step */
.act[data-act="3"] .body, .act[data-act="4"] .body{color:#c9e2d6}
.act__inner.right .body{margin-left:auto}

.scrollcue{margin-top:48px; font:500 10px/1 var(--mono); letter-spacing:.26em; text-transform:uppercase; color:var(--ink-faint);
  display:inline-flex; flex-direction:column; align-items:center; gap:12px}
/* the animated 1px line is its own classed span — the cue word sits in a
   .scrollcue__txt sibling so data-i18n can swap it without wiping the line */
.scrollcue__line{width:1px; height:46px; background:linear-gradient(var(--volt),transparent);
  animation:cue 2.2s var(--ease) infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}
  55%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

.finalstat{margin-top:34px; display:flex; align-items:baseline; gap:13px;
  font-family:var(--display); justify-content:center; line-height:1.0}
.finalstat b{font-size:clamp(52px,9vw,112px); font-weight:600; line-height:1.0; letter-spacing:-.02em;
  color:var(--volt-bright); text-shadow:0 0 42px rgba(246,165,30,.5); font-variant-numeric:tabular-nums}
.finalstat em{font:600 15px/1 var(--mono); font-style:normal; letter-spacing:.22em; color:var(--amber)}
.signoff{margin-top:34px; font:500 11px/1.6 var(--mono); letter-spacing:.2em; color:var(--ink-dim); text-transform:uppercase}

/* closing CTA */
.cta{margin-top:40px; display:flex; flex-direction:column; align-items:center; gap:clamp(11px,1.7vh,16px)}
.cta__vp{font:300 clamp(15px,1.6vw,18px)/1.5 var(--sans); color:var(--ink-dim); max-width:34ch; margin:0 auto}
.cta__btn{
  font:600 12px/1 var(--mono); letter-spacing:.18em; text-transform:uppercase; color:var(--void);
  background:linear-gradient(180deg,var(--volt-bright),var(--volt)); border:0; cursor:pointer;
  padding:14px 26px; border-radius:10px; box-shadow:0 0 28px rgba(246,165,30,.45);
  min-height:44px; display:inline-flex; align-items:center; justify-content:center;  /* touch floor */
  transition:transform .22s var(--ease), box-shadow .22s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .cta__btn:hover{transform:translateY(-2px); box-shadow:0 0 40px rgba(246,165,30,.7)}
}
.cta__btn:active{transform:translateY(0) scale(.98)}
.cta__btn:focus-visible{outline:2px solid var(--volt-bright); outline-offset:4px}

/* staggered line reveal — fixed (small) offset so tall headlines never
   overlap the lines below them mid-animation */
.reveal-line{
  opacity:0; transform:translateY(46px);
  will-change:transform,opacity;
}

/* ============================================================
   POSTER (degraded / no-webgl)
   ============================================================ */
.poster{
  position:fixed; inset:0; z-index:40; display:flex; align-items:center; justify-content:center;
  text-align:center; padding:8vw;
  background:
    radial-gradient(80% 60% at 50% 18%, rgba(246,165,30,.18), transparent 60%),
    radial-gradient(90% 70% at 50% 100%, rgba(255,178,77,.14), transparent 60%),
    linear-gradient(180deg,var(--void-2),var(--void));
}
.poster[hidden]{display:none}
.poster .kicker{margin-bottom:22px}
.poster .lede{max-width:40ch; margin:28px auto 0}
.poster .signoff{margin-top:40px}
.poster__logo{ width:clamp(220px,42vw,300px); height:auto; aspect-ratio:900/520; margin:40px auto 0; display:block;
  filter:drop-shadow(0 0 24px rgba(246,165,30,.18)); }

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .reveal-line{opacity:1; transform:none}
  .hud__dot,.scrollcue__line{animation:none}
}

@media (max-width:720px){
  .hud__panel{width:min(220px,62vw); padding:13px 14px; gap:11px}
  .stat__v{font-size:23px}
  .hud__brandtext span{display:none}
  .stat--row{gap:16px}
  .act{padding:12vh 24px}
}
@media (max-width:560px){
  .hud{padding:12px}
  .hud__brand{top:12px; left:12px; padding:8px 10px; gap:7px}
  .hud__mark{width:22px; height:22px}
  .hud__brandtext strong{font-size:9px; letter-spacing:.1em}
  .hud__phase{top:12px; padding:6px 11px}
  .hud__phaselabel{font-size:7.5px; letter-spacing:.22em}
  .hud__phasename{font-size:11px; letter-spacing:.14em}
  .hud__panel{top:12px; right:12px; width:150px; padding:10px 11px; gap:9px}
  .stat__v{font-size:18px}
  .stat__k{font-size:7.5px; letter-spacing:.1em}
  .stat__v em{font-size:9px}
  .stat--row{gap:9px}
  .stat__sub,.hud__brandtext span{display:none}
  .hud__ticker{font-size:8.5px; padding:8px 11px; max-width:76vw; letter-spacing:.08em}
}

/* ================= mobile / narrow-viewport pack ================= */

/* notched devices: HUD corners respect the safe areas (env()=0 elsewhere) */
.hud__brand{top:max(clamp(14px,2.4vw,30px), env(safe-area-inset-top)); left:max(clamp(14px,2.4vw,30px), env(safe-area-inset-left))}
.hud__phase{top:max(clamp(14px,2.4vw,30px), env(safe-area-inset-top))}
.hud__panel{top:max(clamp(14px,2.4vw,30px), env(safe-area-inset-top)); right:max(clamp(14px,2.4vw,30px), env(safe-area-inset-right))}
.hud__ticker{left:max(clamp(14px,2.4vw,30px), env(safe-area-inset-left)); bottom:max(clamp(14px,2.4vw,30px), env(safe-area-inset-bottom))}

/* desktop-width collision guards (same defect class as the fixed finale bug):
   - Acts 2/4 are right-anchored, so the only reliable lever vs the top-right
     stats panel is VERTICAL clearance (max-width cannot move a right edge)
   - Acts 1/3 start behind the chapter rail's active label on narrow desktops */
@media (min-width:721px){
  .act{padding-left:clamp(96px,7vw,150px)}
  .act--finale{padding-left:0}   /* the gutter is for the rail-side acts — keep the finale dead-centred */
  /* height-aware: flex-centering halves margins, and the ~357px-tall panel is a
     fixed-px band — so the clearance must GROW as the viewport shrinks.
     calc(1040px - 100vh) lands the marker just under the panel for h<=1040
     and disappears on tall viewports where centering already clears it. */
  .act[data-act="2"] .act__inner.right, .act[data-act="4"] .act__inner.right{margin-top:clamp(0px, calc(1040px - 100vh), 340px)}
}

/* the SAME panel collision, phone side — never guarded, because the desktop fix
   above relies on a left column whose right edge never reaches the panel's x-band.
   At 390px every act is full-width (the .right ones included): copy runs to x=366
   and the panel occupies x=218..378, y=12..237. Acts 1/2 happened to clear it;
   acts 3/4 have TALLER copy blocks, so flex-centering starts them higher and their
   headlines landed 51px / 15px behind the panel — measured at the chapter-dot
   landing, which is where a tap on the rail leaves you.
   The lever is vertical: the dot targets come from REPP (the film's representative
   moment per act) and must not move, so the copy sits lower inside its act instead.
   Height-aware for the same reason the desktop guard is — the panel is a fixed
   ~225px band, so a SHORTER viewport centres the block higher and needs MORE
   clearance, not less (a flat 140px cleared 390x844 but put act 3 back 35px under
   on a 375x667 SE). Fitted to act 3, the worst case: measured headTop = base(vh) +
   margin/2 with base ≈ 132px + 0.305*(vh-667), so 655px - 61vh holds a constant
   19px gap from 667 through 932, and self-cancels above ~1074px tall where
   centring already clears. Capped at 260px. */
@media (max-width:720px){
  .act:not(.act--finale):not(.act--hero) .act__inner{margin-top:clamp(0px, calc(655px - 61vh), 260px)}
  /* the copy still SWEEPS past the panel while scrolling (it isn't pinned) — at
     50% alpha it smeared through as a ghost. Near-opaque on phones only, so the
     pass-behind reads as clean occlusion; desktop keeps the glass, where nothing
     ever crosses it. */
  .hud__panel{background:rgba(11,15,36,.88)}
}

/* phones <=560px: the offset ellipse is a DESKTOP-COLUMN device — it flags the
   left/right text column while the 3D subject sits on the opposite side. On a
   phone the copy spans the full width AND the subject (convoy/yard) is centred
   behind it, so a scrim anchored at 26%/74% leaves ~45% of every line bare and
   the bright beats wash the body copy out. Re-anchor to the copy block itself:
   full coverage. Both selectors are listed because .act__inner.right::before
   ties on specificity and would otherwise win on source order. */
@media (max-width:560px){
  .act__inner:not(.center)::before,
  .act__inner.right::before{
    background:radial-gradient(ellipse 86% 60% at 50% 50%, rgba(9,12,34,.60) 0%, rgba(9,12,34,.36) 48%, rgba(9,12,34,0) 78%);
  }
  /* the scrim alone loses to the convoy/arc bloom, which on a phone sits DIRECTLY
     behind the paragraph rather than beside it. Cranking its alpha far enough to
     win would read as a dark blob over the frame — so hold the type instead: a
     tight 2px edge for local contrast against the hot core, plus two softer falls
     for the mid glow. Dims the letters' surround, not the shot. EVERY copy line
     gets it, not just body/lede: the iOS-sim pass showed the hero HEADLINE ("Power
     Puerto" over the convoy headlights) and the finale vision line ("Building the
     power…" over the relit grid) washing out too — the centre acts (hero/finale)
     have no offset scrim, so the type edge is their only protection. Invisible over
     the dark beats; only earns its keep over the bright ones. */
  .act .mega, .act .big, .act .lede, .act .body,
  .act .finalstat, .act .signoff, .act .cta__vp, .act .cta__cred{
    text-shadow:0 1px 2px rgba(6,8,22,.92), 0 2px 12px rgba(6,8,22,.8), 0 0 32px rgba(6,8,22,.65);
  }
}

/* phones <=430px: the display type tightens so the whole payoff fits the fold.
   The stack used to be pushed down 440px to start below the stats panel, but the
   payoff simply does not fit what the panel leaves behind: measured 489px of copy
   (EN, the worst case — ES is 17px SHORTER, so the old "sized for the LONGEST (ES)
   lede" note had it backwards) against a 406px gap between the panel and the fold
   on a 375x667 phone. It overflowed by 111px there and 36px at 390x844, dropping
   the CTA off the bottom and under the load curve. Phones hide both at the payoff
   instead (below), so there is nothing left to clear and the stack just centres. */
@media (max-width:430px){
  .act--finale .mega{font-size:clamp(30px,8.6vw,38px)}
  .act--finale .finalstat b{font-size:clamp(34px,10vw,46px)}
}

/* phones: at the payoff the stats panel and load curve are REDUNDANT — the finale
   states the same MW-online figure in display type — and on a phone they
   are also the two things the payoff collides with. Fading them out is what buys
   the stack its room. Desktop keeps both: it has the width for them.
   body.fin-on is set by the film at its own act-5 threshold (app.js), i.e. before
   the pinned finale settles, so the panel is already gone by the time the copy
   lands — no mid-scroll jump. Fades, so it reads as the HUD standing down. */
@media (max-width:720px){
  body.fin-on .hud__panel, body.fin-on .loadcurve, body.fin-on .anno-layer{opacity:0}
  .hud__panel, .anno-layer{transition:opacity .6s var(--ease)}
  /* the projected city labels (Arecibo/Aguirre/…) are a mid-scroll restore-cascade
     flourish; at the settled payoff they cluttered UNDER the closing copy on a phone
     (narrow column, labels span the island behind it). Stand them down with the rest
     of the HUD so "An island, back to light." owns the frame. Desktop keeps them —
     wider column, the labels sit clear of the centred copy. */
}

/* phones <=430px: reflow the top HUD trio (brand row 1, phase pill row 2 left,
   panel compressed right) — at 390px the centered pill overlapped the panel */
@media (max-width:430px){
  .hud__brand{top:max(12px, env(safe-area-inset-top)); left:max(12px, env(safe-area-inset-left))}
  .hud__mark{width:20px; height:20px}
  .titlecard__logo{width:min(76vw,320px)}
  .titlecard__mark{margin-bottom:24px}
  .hud__phase{top:calc(max(12px, env(safe-area-inset-top)) + 44px); left:12px; transform:none}
  .hud__panel{top:max(12px, env(safe-area-inset-top)); right:max(12px, env(safe-area-inset-right)); width:min(160px,50vw)}
  .minimap{display:none}
  .loadcurve{width:min(280px,80vw); height:100px; bottom:96px; left:50%; right:auto; transform:translateX(-50%)}
  .hud__ticker{max-width:58vw; font-size:8px; letter-spacing:.06em; padding:8px 10px}
}

/* short landscape phones: compress the stats panel so it can't crowd the copy */
@media (max-height:420px){
  .hud__panel{padding:9px 10px; gap:7px; width:150px}
  .stat__v{font-size:16px}
  .stat__k{font-size:6.5px; letter-spacing:.06em}
  .stat--row{gap:8px}
  .hud__ticker{max-width:44vw; font-size:7.5px}
}

/* ---------- VO narration pill (DOM built by narration.js attach()) ----------
   No position here on purpose — place .vo like .hud__lang (fixed + safe-area)
   or inside an existing HUD corner. The element carries .glass already. */
.vo{display:inline-flex; align-items:center; padding:2px 4px 2px 2px}
.vo__btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:44px; padding:0;
  background:none; border:0; cursor:pointer; color:var(--ink-dim);
  transition:color .25s var(--ease);
}
.vo__btn svg{width:13px; height:13px; display:block}
.vo__ic-pause{display:none}
.vo.is-on .vo__ic-play{display:none}
.vo.is-on .vo__ic-pause{display:block}
.vo.is-on .vo__btn{color:var(--volt-bright)}
.vo__btn:focus-visible,.vo__voice:focus-visible{outline:2px solid var(--volt-bright); outline-offset:3px; border-radius:8px}
.vo__btn:active,.vo__voice:active{transform:scale(.94)}

/* speaking equalizer — three 1.5px bars; only animates while audio is audible */
.vo__eq{
  display:inline-flex; align-items:flex-end; gap:2.5px;
  width:0; height:11px; opacity:0; overflow:hidden;
  transition:width .3s var(--ease), opacity .3s var(--ease), margin .3s var(--ease);
}
.vo.is-speaking .vo__eq{width:12px; opacity:1; margin-right:3px}
.vo__eq i{
  flex:none; width:1.5px; height:100%; border-radius:1px;
  background:var(--volt-bright); box-shadow:0 0 5px var(--volt);
  transform:scaleY(.22); transform-origin:bottom;
}
.vo.is-speaking .vo__eq i{animation:vo-eq .84s ease-in-out infinite}
.vo.is-speaking .vo__eq i:nth-child(2){animation-duration:.66s; animation-delay:.12s}
.vo.is-speaking .vo__eq i:nth-child(3){animation-duration:1.02s; animation-delay:.26s}
@keyframes vo-eq{0%,100%{transform:scaleY(.22)} 50%{transform:scaleY(1)}}
@media (prefers-reduced-motion:reduce){
  .vo.is-speaking .vo__eq i{animation:none; transform:scaleY(.6)}
}

/* voice cycle chip — shows the CURRENT narrator; tap cycles onyx→michael→george */
.vo__voice{
  min-height:44px; padding:0 12px 0 8px;
  background:none; border:0; cursor:pointer;
  font:600 10.5px/1 var(--mono); letter-spacing:.22em; text-indent:.22em;
  color:var(--ink-dim); text-transform:uppercase;
  transition:color .25s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .vo__btn:hover{color:var(--ink)}
  .vo.is-on .vo__btn:hover{color:var(--volt-bright)}
  .vo__voice:hover{color:var(--ink)}
}
/* VO pill placement: bottom-right, stacked above the language chip */
.vo-root{
  position:fixed; z-index:25;
  right:max(clamp(14px,2.4vw,30px), env(safe-area-inset-right));
  bottom:calc(max(clamp(14px,2.4vw,30px), env(safe-area-inset-bottom)) + 56px);
  opacity:0; transition:opacity 1s var(--ease);
}
.hud.is-live ~ .vo-root{opacity:1}
