/* ==========================================================================
   CALIGO DYNAMICS — site.css
   Direction: Precision/Swiss x Terminal, dark-committed.
   The accent ramp is the product's own thermal LUT. Not a stock blue.
   ========================================================================== */

/* Self-hosted: no third-party request, no FOIT dependency on a CDN,
   and a strict CSP that does not need a font-src exception. */
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/inter-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('/assets/fonts/inter-latin-600-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/inter-latin-700-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;
  src:url('/assets/fonts/space-grotesk-latin-500-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:600;font-display:swap;
  src:url('/assets/fonts/space-grotesk-latin-600-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/space-grotesk-latin-700-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-latin-700-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0100-024F,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
  U+0300-036F,U+1E00-1EFF,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

/* ---------- tokens ---------- */
:root{
  --bg:#08090B;
  --bg-deep:#050608;
  --surface:#0E1013;
  --surface-2:#14171C;
  --surface-3:#1A1E24;
  --border:#1F242B;
  --border-lit:#2E353F;

  --text:#EDEFF2;
  --text-dim:#9AA3B0;
  --text-faint:#79818A;   /* AA 4.5:1 on every surface incl. #14171C */

  --accent:#FF5A1F;
  --accent-hi:#FF7A45;
  --accent-warm:#FFB020;
  --ok:#3FB984;

  /* thermal ironbow — the brand ramp, taken from the sensor palette */
  --t0:#0B0620; --t1:#2B1160; --t2:#6A1B9A; --t3:#C2185B;
  --t4:#F4511E; --t5:#FFA000; --t6:#FFE082; --t7:#FFFDF5;

  --font-display:'Space Grotesk',ui-sans-serif,system-ui,sans-serif;
  --font-body:'Inter',ui-sans-serif,system-ui,-apple-system,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* one scale. 1.25 ratio above 16; three deliberate steps below it. */
  --fs-micro:11px;   /* mono labels, eyebrows, pills, tags */
  --fs-data:12.5px;  /* mono data lines, captions, sources */
  --fs-sm:14px;      /* supporting body */
  --fs-base:16px;    /* body */

  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s6:24px; --s8:32px;
  --s12:48px; --s16:64px; --s24:96px; --s32:128px;

  --radius:4px; --radius-lg:8px;
  --shadow-1:0 1px 2px rgba(0,0,0,.4);
  --shadow-2:0 24px 64px -16px rgba(0,0,0,.8);

  --maxw:1280px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --dur:220ms;
}

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;scroll-behavior:smooth;
  /* Tells the browser this document is dark, so the native scrollbar, form
     controls and the overscroll gutter render dark instead of flashing white
     at the edges of a black page. */
  color-scheme:dark;
}
/* A 300ms delay before every tap is the single most common reason a site
   "feels slow" on a phone, and the grey flash box on top of it is the second.
   Both are opt-out, and both are worth opting out of. */
html,body{
  touch-action:manipulation;
  -webkit-tap-highlight-color:rgba(255,90,31,.18);
  overscroll-behavior-y:none;
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--bg);color:var(--text);
  /* Notch and home-indicator safety for the full-bleed layouts below. */
  padding-left:env(safe-area-inset-left);
  padding-right:env(safe-area-inset-right);
  font-family:var(--font-body);font-size:16px;line-height:1.65;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,svg,video{display:block;max-width:100%}
img{height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
h1,h2,h3,h4{font-family:var(--font-display);font-weight:600;line-height:1.08;
  letter-spacing:-.02em;margin:0;
  /* Stops a heading dropping a single orphaned word onto its own line, which
     is the fastest way for otherwise good typography to look careless. */
  text-wrap:balance}
p,li{text-wrap:pretty}
p{margin:0}
::selection{background:var(--accent);color:#0A0A0A}

:focus-visible{outline:2px solid var(--accent-hi);outline-offset:3px;border-radius:2px}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--accent);
  color:#0A0A0A;padding:var(--s3) var(--s6);font-weight:600}
.skip:focus{left:var(--s4);top:var(--s4)}

/* ---------- layout ---------- */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--s6)}
@media(min-width:900px){.wrap{padding-inline:var(--s12)}}
section{position:relative}
/* the nav is fixed, so an anchor jump must stop short of it or the heading
   it was pointing at ends up underneath the bar. */
section[id],[id]{scroll-margin-top:88px}
.band{padding-block:var(--s24)}
@media(min-width:900px){.band{padding-block:var(--s32)}}
.rule{height:1px;background:var(--border);border:0;margin:0}

/* ---------- type utilities ---------- */
.eyebrow{
  font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;color:var(--text-faint);
  display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
}
.eyebrow .tick{width:14px;height:1px;background:var(--accent);flex:none}
.display{font-size:clamp(2.1rem,6.2vw,4.6rem);letter-spacing:-.035em;line-height:1.02}
.h2{font-size:clamp(1.7rem,3.6vw,2.9rem);letter-spacing:-.028em}
.h3{font-size:clamp(1.15rem,1.8vw,1.45rem);letter-spacing:-.015em}
.lede{font-size:clamp(1.02rem,1.5vw,1.22rem);color:var(--text-dim);max-width:64ch;line-height:1.62}
.body{color:var(--text-dim);max-width:70ch}
.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.hot{color:var(--accent)}
.small{font-size:var(--fs-sm)}
.tiny{font-size:var(--fs-data)}

/* ---------- nav ---------- */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  border-bottom:1px solid transparent;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),
             backdrop-filter var(--dur) var(--ease);
}
.nav.stuck{
  background:rgba(8,9,11,.82);backdrop-filter:blur(14px) saturate(1.3);
  border-bottom-color:var(--border);
}
.nav-in{display:flex;align-items:center;gap:var(--s8);height:66px;
  padding-top:env(safe-area-inset-top)}
.brand{display:flex;align-items:center;gap:var(--s3);flex:none;min-height:44px}
.brand-mark{height:30px;width:auto;flex:none;display:block}
@media(min-width:900px){.brand-mark{height:34px}}
.brand-txt{font-family:var(--font-display);font-weight:700;font-size:var(--fs-base);
  letter-spacing:.09em;text-transform:uppercase}
.brand-txt span{color:var(--text-faint);font-weight:500}
@media(max-width:600px){
  .brand-txt span{display:none}                      /* keep "CALIGO", drop the rest */
  .brand-txt{font-size:var(--fs-sm);letter-spacing:.12em}
  .nav-in{gap:var(--s4);height:60px}
  .nav-cta{padding-inline:var(--s4)}
  .brand-mark{height:26px}
}
/* .btn sets display later in the sheet, so this needs to outrank it */
@media(max-width:344px){.nav-in .nav-cta{display:none}.nav-in .nav-menu{margin-left:auto}}
@media(max-width:420px){
  /* At this width the bar cannot hold the wordmark, the CTA and the menu at once.
     The owl carries the brand on its own; the CTA and the menu both survive. */
  .brand-txt{display:none}
  .brand-mark{height:30px}
  .nav-cta{font-size:var(--fs-micro);padding-inline:var(--s3)}
}
.nav-links{display:none;gap:var(--s8);margin-left:auto;align-items:center}
@media(min-width:1220px){.nav-links{display:flex}}
.nav-links a{
  font-family:var(--font-mono);font-size:var(--fs-data);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-dim);padding:var(--s3) 0;
  position:relative;transition:color var(--dur) var(--ease);
}
.nav-links a::after{
  content:'';position:absolute;left:0;right:100%;bottom:0;height:1px;
  background:var(--accent);transition:right var(--dur) var(--ease);
}
.nav-links a:hover{color:var(--text)}
.nav-links a:hover::after{right:0}
.nav-cta{margin-left:auto}
@media(min-width:1220px){.nav-cta{margin-left:0}}

/* ---------- nav disclosure (< 960px) ----------
   A <details> rather than a scripted menu: it opens with JavaScript off, the
   browser owns the expanded state and the keyboard behaviour, and it costs the
   CSP nothing. site.js only adds the niceties (close on choose, close on Esc). */
.nav-menu{position:relative;flex:none;margin-left:var(--s3)}
@media(min-width:1220px){.nav-menu{display:none}}
.nav-menu>summary{
  list-style:none;display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:var(--radius);cursor:pointer;
  border:1px solid var(--border-lit);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.nav-menu>summary::-webkit-details-marker{display:none}
.nav-menu>summary::marker{content:''}
.nav-menu>summary:hover{border-color:var(--accent)}
.nav-bars{display:grid;gap:4px;width:18px}
.nav-bars i{display:block;height:1.5px;background:var(--text);border-radius:1px;
  transition:transform var(--dur) var(--ease),opacity var(--dur) var(--ease)}
.nav-menu[open]>summary{border-color:var(--accent);background:var(--surface-2)}
.nav-menu[open] .nav-bars i:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.nav-menu[open] .nav-bars i:nth-child(2){opacity:0}
.nav-menu[open] .nav-bars i:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}
.nav-panel{
  position:absolute;right:0;top:calc(100% + 10px);z-index:120;
  width:max(212px,58vw);max-width:min(320px,calc(100vw - 2 * var(--s6)));
  background:rgba(14,16,19,.97);backdrop-filter:blur(18px) saturate(1.25);
  border:1px solid var(--border-lit);border-radius:var(--radius-lg);
  padding:var(--s3);box-shadow:0 24px 60px -18px rgba(0,0,0,.85);
  overscroll-behavior:contain;
}
.nav-panel nav{display:grid}
.nav-panel a{
  font-family:var(--font-mono);font-size:var(--fs-data);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-dim);
  padding:var(--s3) var(--s4);border-radius:var(--radius);min-height:44px;
  display:flex;align-items:center;
  transition:color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.nav-panel a:hover{color:var(--text);background:var(--surface-2)}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:44px;padding:var(--s3) var(--s6);border-radius:var(--radius);
  font-family:var(--font-mono);font-size:var(--fs-data);font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),transform var(--dur) var(--ease);
}
.btn:active{transform:translateY(1px)}
/* nowrap is right for a button in a row; inside a narrow card a long label
   pushes the card past the viewport, so below the phone breakpoint it wraps. */
/* A button in a row should not wrap. A button inside a card must be allowed to,
   or a long label sets the card's minimum width and pushes the grid off-screen. */
.card .btn,.notice .btn{white-space:normal;text-align:center;line-height:1.35;padding-block:var(--s3)}
.btn-primary{background:var(--accent);color:#0A0A0A;font-weight:700}
.btn-primary:hover{background:var(--accent-hi)}
.btn-ghost{border:1px solid var(--border-lit);color:var(--text)}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
.btn-quiet{color:var(--text-dim);padding-inline:0}
.btn-quiet:hover{color:var(--accent)}
.btn .arw{transition:transform var(--dur) var(--ease)}
.btn:hover .arw{transform:translateX(3px)}

/* ---------- hero ---------- */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;
  justify-content:flex-end;overflow:hidden;padding-top:96px}
.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg img{width:100%;height:100%;object-fit:cover;object-position:center 42%}
.hero-bg::after{
  content:'';position:absolute;inset:0;
  background:
    linear-gradient(180deg,rgba(8,9,11,.78) 0%,rgba(8,9,11,.28) 20%,rgba(8,9,11,.68) 52%,
                          rgba(8,9,11,.90) 80%,var(--bg) 98%),
    linear-gradient(95deg,rgba(8,9,11,.90) 0%,rgba(8,9,11,.56) 44%,rgba(8,9,11,.06) 80%);
}
/* On a narrow screen the copy runs the full width, straight over the subject,
   so it needs its own ground rather than relying on the wide-screen side
   gradient. Readability first; atmosphere second. */
@media(max-width:899px){
  .hero-bg::after{
    background:linear-gradient(180deg,
      rgba(8,9,11,.80) 0%, rgba(8,9,11,.34) 18%,
      rgba(8,9,11,.72) 42%, rgba(8,9,11,.90) 68%, var(--bg) 98%);
  }
}
.hero-in{position:relative;z-index:2;padding-bottom:var(--s12);padding-top:var(--s8)}
.hero-in::before{
  content:'';position:absolute;z-index:-1;
  top:calc(var(--s8) * -1);bottom:0;left:calc(var(--s6) * -1);right:0;
  background:linear-gradient(100deg,
    rgba(8,9,11,.92) 0%, rgba(8,9,11,.86) 34%, rgba(8,9,11,.62) 64%, rgba(8,9,11,0) 94%);
  pointer-events:none;
}
@media(min-width:900px){.hero-in::before{top:calc(var(--s16) * -1);left:calc(var(--s12) * -1)}}
.hero .eyebrow{color:var(--text-dim)}
@media(min-width:900px){.hero-in{padding-top:var(--s16)}}
@media(max-height:820px) and (min-width:900px){
  .hero{padding-top:80px}
  .hero-in{padding-top:var(--s8);padding-bottom:var(--s8)}
  .hero h1{margin-block:var(--s4)}
  .hero .lede-claim{margin-top:var(--s5)}
  .hero-alt{margin-top:var(--s4)}
}
.hero h1{margin:var(--s6) 0 var(--s6);max-width:22ch}
@media(min-width:1100px){.hero h1{max-width:27ch}}
@media(min-height:760px) and (min-width:900px){.hero .display{font-size:clamp(2.1rem,5.4vw,4.1rem)}}
.hero h1 .num{
  font-family:var(--font-mono);font-weight:700;letter-spacing:-.04em;
  color:var(--accent-warm);   /* fallback: never an invisible headline */
}
/* The mono face is for figures. A whole clause set in it reads as a terminal
   dump rather than a sentence, so the emphasised line keeps the display face
   and takes only the colour. */
.hero h1 .hot-line{
  font-family:inherit;font-weight:600;letter-spacing:inherit;
  color:var(--accent-warm);
  background:linear-gradient(94deg,#FFC24A 0%,var(--accent-warm) 34%,var(--accent) 100%);
  -webkit-background-clip:text;background-clip:text;
}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .hero h1 .num,.hero h1 .hot-line{color:transparent}
}
/* The honesty claim is the differentiator, so it is not allowed to be the
   smallest, faintest thing in the hero. It gets body weight and an accent rule. */
.hero .lede-claim{
  margin-top:var(--s8);padding-left:var(--s5);border-left:2px solid var(--accent);
  font-size:var(--fs-base);line-height:1.6;color:var(--text-dim);max-width:64ch;
}
.hero-actions{display:flex;flex-wrap:wrap;gap:var(--s4);margin-top:var(--s6)}
/* The other audience. A fire chief had no path at all for 26 screens. */
.hero-alt{margin-top:var(--s6);font-size:var(--fs-sm);color:var(--text-dim);max-width:50ch;line-height:1.55}
.hero-alt a{color:var(--text);border-bottom:1px solid var(--border-lit);
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.hero-alt a:hover{color:var(--accent);border-color:var(--accent)}

/* stat strip */
.stats{
  position:relative;z-index:2;border-top:1px solid var(--border);
  display:grid;grid-template-columns:repeat(2,1fr);
}
@media(min-width:820px){.stats{grid-template-columns:repeat(4,1fr)}}
.stat{padding:var(--s6) var(--s4) var(--s6) 0;border-right:1px solid var(--border)}
.stat:last-child{border-right:0}
@media(max-width:819px){.stat:nth-child(2n){border-right:0}}
@media(min-width:820px){.stat{padding-right:var(--s6)}}
.stat-v{font-family:var(--font-mono);font-size:clamp(1.5rem,2.6vw,2rem);
  font-weight:700;letter-spacing:-.03em;color:var(--text);font-variant-numeric:tabular-nums}
.stat-l{font-size:var(--fs-data);color:var(--text-dim);margin-top:var(--s1);line-height:1.42}
.stat-s{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.06em;
  color:var(--text-faint);margin-top:var(--s2);text-transform:uppercase}
.stat-s a{display:inline-block;padding-block:5px;border-bottom:1px solid var(--border-lit);transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.stat-s a:hover{color:var(--accent);border-color:var(--accent)}

/* ---------- section head ---------- */
.head{max-width:74ch;margin-bottom:var(--s16)}
@media(max-width:759px){.head{margin-bottom:var(--s12)}}
.head .eyebrow{margin-bottom:var(--s6)}
.head h2{margin-bottom:var(--s6)}

/* ---------- thermal reveal ---------- */
.reveal{
  position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:var(--radius-lg);
  border:1px solid var(--border);background:var(--surface);
  cursor:ew-resize;touch-action:pan-y;user-select:none;-webkit-user-select:none;
}
.reveal img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.reveal-top{clip-path:inset(0 0 0 var(--split,50%))}
.reveal::after{content:'';position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 50%,transparent 52%,rgba(5,6,8,.42) 100%)}
.reveal-bar{
  position:absolute;top:0;bottom:0;left:var(--split,50%);width:2px;
  background:var(--accent);z-index:4;pointer-events:none;
  box-shadow:0 0 24px rgba(255,90,31,.55);
}
.reveal-grab{
  position:absolute;top:50%;left:var(--split,50%);z-index:5;
  transform:translate(-50%,-50%);
  width:44px;height:44px;border-radius:50%;
  background:var(--accent);color:#0A0A0A;
  display:grid;place-items:center;pointer-events:none;
  box-shadow:0 0 0 6px rgba(255,90,31,.16),var(--shadow-1);
}
.reveal-tag{
  position:absolute;z-index:6;top:var(--s4);
  font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.14em;
  text-transform:uppercase;padding:var(--s1) var(--s2);border-radius:var(--radius);
  background:rgba(5,6,8,.78);border:1px solid var(--border-lit);
  backdrop-filter:blur(6px);color:var(--text-dim);
}
.reveal-tag.l{left:var(--s4)}
.reveal-tag.r{right:var(--s4);color:var(--accent-warm);border-color:rgba(255,176,32,.4)}
.reveal-hint{
  position:absolute;z-index:6;bottom:var(--s4);left:50%;transform:translateX(-50%);
  font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-faint);background:rgba(5,6,8,.7);padding:var(--s1) var(--s2);border-radius:var(--radius);
  white-space:nowrap;transition:opacity var(--dur) var(--ease);
}
.reveal.touched .reveal-hint{opacity:0}
/* 342x192 is too small to read ironbow detail — and this is the most
   persuasive image on the page. */
@media(max-width:760px){.reveal{aspect-ratio:4/3}}
.caption{font-family:var(--font-mono);font-size:var(--fs-data);letter-spacing:.04em;
  color:var(--text-faint);margin-top:var(--s4);line-height:1.6}

/* ---------- cards / grid ---------- */
.grid{display:grid;gap:var(--s6)}
.g2{grid-template-columns:1fr}
.g3{grid-template-columns:1fr}
@media(min-width:760px){.g2{grid-template-columns:1fr 1fr}}
@media(min-width:960px){.g3{grid-template-columns:repeat(3,1fr)}}
.card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:var(--s8);transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.card:hover{border-color:var(--border-lit);background:var(--surface-2)}
.card .idx{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.14em;
  color:var(--accent);margin-bottom:var(--s6);display:block}
.card h3{margin-bottom:var(--s4)}
.card p{color:var(--text-dim);font-size:var(--fs-sm)}
.card ul{margin:var(--s6) 0 0;padding:0;list-style:none;
  border-top:1px solid var(--border);padding-top:var(--s4)}
.card li{font-family:var(--font-mono);font-size:var(--fs-data);color:var(--text-faint);
  padding:var(--s1) 0 var(--s1) var(--s4);position:relative;line-height:1.5}
.card li::before{content:'';position:absolute;left:0;top:11px;width:var(--s1);height:1px;background:var(--accent)}

/* ---------- status table (the honesty table) ---------- */
.tbl-wrap{overflow-x:auto;overscroll-behavior-x:contain;border:1px solid var(--border);
  border-radius:var(--radius-lg);background:var(--surface);
  scrollbar-width:thin}
table.status{width:100%;border-collapse:collapse;min-width:660px}
table.status th,table.status td{
  text-align:left;padding:var(--s4) var(--s6);border-bottom:1px solid var(--border);
  vertical-align:top;font-size:var(--fs-sm);
}
table.status thead th{
  font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-faint);font-weight:500;background:var(--surface-2);white-space:nowrap;
}
table.status tbody tr:last-child td{border-bottom:0}
table.status tbody tr{transition:background var(--dur) var(--ease)}
table.status tbody tr:hover{background:var(--surface-2)}
table.status td.sub{color:var(--text-dim);font-size:var(--fs-sm)}
.pill{
  display:inline-flex;align-items:center;gap:var(--s2);white-space:nowrap;
  font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.1em;text-transform:uppercase;
  padding:var(--s1) var(--s2);border-radius:99px;border:1px solid;
}
.pill .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}
.pill.flying{color:var(--ok);border-color:rgba(63,185,132,.34);background:rgba(63,185,132,.07)}
.pill.bench{color:var(--accent-warm);border-color:rgba(255,176,32,.32);background:rgba(255,176,32,.07)}
.pill.sim{color:#7FA8D8;border-color:rgba(127,168,216,.3);background:rgba(127,168,216,.07)}
.pill.notyet{color:var(--text-faint);border-color:var(--border-lit);background:transparent}

/* Below 760px a 660px-wide table hides its last column behind a horizontal
   swipe — and that last column, "what it still needs", is the whole argument.
   So on narrow screens each capability becomes a card carrying all four fields. */
@media(max-width:759.98px){
  table.status[data-stack]{min-width:0;display:block}
  table.status[data-stack] thead{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
  table.status[data-stack] tbody,table.status[data-stack] tr,table.status[data-stack] th,table.status[data-stack] td{display:block;width:auto}
  table.status[data-stack] tbody tr{
    border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);
    padding:var(--s5);margin-bottom:var(--s4);
  }
  table.status[data-stack] tbody tr:last-child{margin-bottom:0}
  table.status[data-stack] tbody tr:hover{background:var(--surface)}
  table.status[data-stack] tbody th[scope="row"]{
    padding:0 0 var(--s3);border-bottom:0;
    font-family:var(--font-display);font-size:var(--fs-base);font-weight:700;
    letter-spacing:.01em;color:var(--text);
  }
  table.status[data-stack] tbody td{padding:0;border-bottom:0}
  table.status[data-stack] tbody td.status-cell{padding-bottom:var(--s5)}
  table.status[data-stack] tbody td[data-label]{padding-bottom:var(--s5)}
  table.status[data-stack] tbody td[data-label]:last-child{padding-bottom:0}
  table.status[data-stack] tbody td[data-label]::before{
    content:attr(data-label);display:block;margin-bottom:var(--s2);
    font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.14em;
    text-transform:uppercase;color:var(--text-faint);
  }
  table.status[data-stack] tbody td[data-label="What it still needs"]{
    border-top:1px solid var(--border);padding-top:var(--s4);
  }
}

/* ---------- orbit diagram ---------- */
.orbit-shell{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);padding:var(--s8);display:grid;gap:var(--s8);align-content:start}
.orbit-svg{width:100%;height:auto;max-width:520px;margin-inline:auto}
.legend{display:grid;gap:var(--s3);border-top:1px solid var(--border);padding-top:var(--s6)}
.legend div{display:flex;gap:var(--s3);align-items:flex-start;
  font-family:var(--font-mono);font-size:var(--fs-data);color:var(--text-faint);line-height:1.55}
.legend b{color:var(--text-dim);font-weight:500;flex:none;min-width:74px}

/* ---------- figure ---------- */
figure{margin:0}
.fig{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.fig img{width:100%;aspect-ratio:16/9;object-fit:cover}
.fig.tall img{aspect-ratio:3/2}
figcaption{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.04em;
  color:var(--text-faint);padding:var(--s4) var(--s6);border-top:1px solid var(--border);line-height:1.55}

/* native 3:2 — the plate is a deliberate composition, so it is shown whole:
   no crop, and no letterbox bars against a backdrop that is not flat black. */
.fig.plate img{aspect-ratio:3/2}

/* Full-bleed panorama. It sits outside .wrap as a direct child of the section,
   so there is no 100vw arithmetic and therefore no scrollbar-width overflow.
   The source is far brighter than anything else on a near-black page, so it is
   graded down to sit in the palette rather than read as stock photography. */
.fig.bleed{border-inline:0;border-radius:0}
.fig.bleed img{aspect-ratio:2.36/1;max-height:min(70vh,720px);
  filter:brightness(.72) contrast(1.1) saturate(.84)}
.fig.bleed figcaption{padding-inline:0}
.fig.bleed figcaption .wrap{display:block}
@media(max-width:760px){.fig.bleed img{aspect-ratio:16/10}}

/* ---------- notice block ---------- */
.notice{
  border:1px solid var(--border-lit);border-left:2px solid var(--accent);
  border-radius:var(--radius-lg);background:var(--surface);
  padding:var(--s8);display:grid;gap:var(--s5);max-width:78ch;
}
.notice-k{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.16em;
  text-transform:uppercase;color:var(--accent)}
.notice .body{color:var(--text-dim)}

/* Kept for the day the footage lands — see HANDOVER.md. */
video.evidence{width:100%;aspect-ratio:16/9;object-fit:cover;background:#000;
  border-radius:var(--radius-lg);border:1px solid var(--border)}

/* ---------- timeline ---------- */
.tl{display:grid;gap:0;border-top:1px solid var(--border)}
.tl-row{
  display:grid;grid-template-columns:1fr;gap:var(--s3);
  padding:var(--s8) 0;border-bottom:1px solid var(--border);
  transition:background var(--dur) var(--ease);
}
@media(min-width:860px){
  .tl-row{grid-template-columns:150px 1fr 240px;gap:var(--s8);align-items:start}
}
.tl-when{font-family:var(--font-mono);font-size:var(--fs-data);letter-spacing:.08em;line-height:1.5;
  text-transform:uppercase;color:var(--accent);padding-top:var(--s1)}
.tl-row.done .tl-when{color:var(--ok)}
.tl-what h3{margin-bottom:var(--s3);font-size:1.15rem}
.tl-what p{color:var(--text-dim);font-size:var(--fs-sm);max-width:60ch}
.tl-proof{font-family:var(--font-mono);font-size:var(--fs-data);color:var(--text-faint);line-height:1.6}
.tl-proof b{display:block;color:var(--text-dim);font-weight:500;margin-bottom:4px;
  letter-spacing:.1em;text-transform:uppercase;font-size:var(--fs-micro)}

/* ---------- objection blocks ---------- */
.obj{border-left:2px solid var(--accent);padding-left:var(--s6);margin-bottom:var(--s12)}
.obj:last-child{margin-bottom:0}
.obj q{display:block;font-family:var(--font-display);font-size:1.22rem;font-weight:500;
  color:var(--text);margin-bottom:var(--s4);quotes:'"' '"';letter-spacing:-.015em}
.obj p{color:var(--text-dim);font-size:var(--fs-sm);max-width:68ch}
.obj p + p{margin-top:var(--s4)}

/* ---------- team ---------- */
.person{display:flex;gap:var(--s6);align-items:flex-start}
.person .av{width:56px;height:56px;border-radius:50%;flex:none;
  border:1px solid var(--border-lit);background:var(--surface-2);
  display:grid;place-items:center;font-family:var(--font-mono);font-size:var(--fs-sm);
  font-weight:700;color:var(--accent);letter-spacing:.04em}
.person h3{font-size:1.1rem;margin-bottom:2px}
.person .role{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-faint);margin-bottom:var(--s3)}
.person p{font-size:var(--fs-sm);color:var(--text-dim)}

/* ---------- CTA ---------- */
.cta{position:relative;overflow:hidden;border-top:1px solid var(--border)}
.cta-bg{position:absolute;inset:0;z-index:0}
.cta-bg img{width:100%;height:100%;object-fit:cover;opacity:.34}
.cta-bg::after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,var(--bg) 0%,rgba(8,9,11,.6) 40%,var(--bg) 100%)}
.cta .wrap{position:relative;z-index:2}
.cta-actions{display:flex;flex-wrap:wrap;gap:var(--s4);margin-top:var(--s8)}
.contact-lines{display:grid;gap:var(--s3);margin-top:var(--s12);
  border-top:1px solid var(--border);padding-top:var(--s8)}
.contact-lines div{display:flex;gap:var(--s4);font-family:var(--font-mono);font-size:var(--fs-data);
  flex-wrap:wrap}
.contact-lines b{color:var(--text-faint);font-weight:400;min-width:104px;
  letter-spacing:.1em;text-transform:uppercase;font-size:var(--fs-micro);padding-top:2px}
.contact-lines a{color:var(--text);border-bottom:1px solid var(--border-lit)}
.contact-lines a:hover{color:var(--accent);border-color:var(--accent)}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--border);background:var(--bg-deep);
  padding-block:var(--s12) calc(var(--s12) + env(safe-area-inset-bottom))}
.foot{display:grid;gap:var(--s8)}
@media(min-width:860px){.foot{grid-template-columns:1.4fr 1fr 1fr;gap:var(--s12)}}
.foot h4{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-faint);font-weight:500;margin:0 0 var(--s4)}
.foot ul{list-style:none;margin:0;padding:0;display:grid;gap:var(--s3)}
.foot a{font-size:var(--fs-sm);color:var(--text-dim)}
.foot a:hover{color:var(--accent)}
.foot-note{font-size:var(--fs-data);color:var(--text-faint);max-width:46ch;line-height:1.65}
.foot-bottom{margin-top:var(--s12);padding-top:var(--s6);border-top:1px solid var(--border);
  display:flex;flex-wrap:wrap;gap:var(--s4) var(--s8);justify-content:space-between;
  font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-faint);letter-spacing:.05em}

/* ---------- sources ---------- */
.src{border-top:1px solid var(--border);padding-top:var(--s8)}
.src ol{margin:0;padding-left:var(--s6);display:grid;gap:var(--s3)}
.src li{font-size:var(--fs-data);color:var(--text-faint);line-height:1.6}
.src a{color:var(--text-dim);border-bottom:1px solid var(--border-lit);word-break:break-word}
.src a:hover{color:var(--accent);border-color:var(--accent)}
sup.ref{font-family:var(--font-mono);font-size:9.5px;vertical-align:super;
  color:var(--accent);margin-left:2px}
sup.ref a{color:inherit}

/* ---------- motion ---------- */
[data-rise]{opacity:0;transform:translateY(18px);
  transition:opacity 620ms var(--ease),transform 620ms var(--ease)}
[data-rise].in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  [data-rise]{opacity:1;transform:none;transition:none}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
}

/* ---------- scroll progress ---------- */
.prog{position:fixed;top:0;left:0;height:2px;width:0;z-index:120;
  background:linear-gradient(90deg,var(--t3),var(--accent),var(--t5));
  transition:width 90ms linear}

/* ==========================================================================
   MOTION — every animation below explains a causality or a state change.
   Easing tokens per motion-principles; loops use linear because a loop with
   an eased curve reads as a stutter.
   ========================================================================== */
:root{
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-in:cubic-bezier(.7,0,.84,0);
  --ease-io:cubic-bezier(.65,0,.35,1);
}

/* micro: things the pointer touches. In fast, out slower. */
.btn{transition:background 130ms var(--ease-out),color 130ms var(--ease-out),
     border-color 130ms var(--ease-out),transform 110ms var(--ease-out)}
.btn:hover{transition-duration:130ms}
.btn .arw{transition:transform 140ms var(--ease-out)}
.nav-links a{transition:color 130ms var(--ease-out)}
.nav-links a::after{transition:right 180ms var(--ease-out)}
.card{transition:border-color 140ms var(--ease-out),background 140ms var(--ease-out),
      transform 140ms var(--ease-out)}
.card:hover{transform:translateY(-2px)}
.stat-s a,.src a,.contact-lines a{transition:color 120ms var(--ease-out),border-color 120ms var(--ease-out)}

/* structural: a section arriving as you reach it. 480ms, ease-out, once. */
[data-rise]{transition:opacity 480ms var(--ease-out),transform 480ms var(--ease-out)}

/* ---- visually hidden (kept in the a11y tree) ---- */
.visually-hidden{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ==========================================================================
   ORBIT DIAGRAM
   One 14s cycle explains the whole thesis: an aircraft empties and leaves,
   a standby takes the slot, and the ring is never short. Continuous → linear.
   ========================================================================== */
.orb-ring-rot{transform-origin:160px 160px;animation:orb-spin 26s linear infinite}
@keyframes orb-spin{to{transform:rotate(360deg)}}

.orb-ring{transform-origin:160px 160px;animation:orb-spin-slow 60s linear infinite;opacity:.8}
@keyframes orb-spin-slow{to{transform:rotate(-360deg)}}

.orb-core{transform-origin:160px 160px;animation:orb-breathe 4.2s var(--ease-io) infinite}
@keyframes orb-breathe{0%,100%{transform:scale(1);opacity:.95}50%{transform:scale(1.07);opacity:1}}

/* u1 is the one that runs dry. Its spray thins, it dims, it departs, it returns
   full — which is exactly what the real aircraft does. */
.orb-unit.u1{animation:orb-deplete 14s linear infinite}
@keyframes orb-deplete{
  0%,52%   {opacity:1}
  62%      {opacity:.42}
  70%      {opacity:.18}
  78%,88%  {opacity:0}
  96%,100% {opacity:1}
}
.orb-unit.u1 line{animation:orb-dry 14s linear infinite}
@keyframes orb-dry{
  0%,46%{opacity:.55}
  60%{opacity:.12}
  66%,92%{opacity:0}
  100%{opacity:.55}
}

/* the standby rises into the ring as u1 leaves it */
.orb-standby{transform-origin:160px 300px;animation:orb-insert 14s var(--ease-io) infinite}
@keyframes orb-insert{
  0%,60%   {transform:translateY(0) scale(1);opacity:.5}
  74%      {transform:translateY(-104px) scale(1.05);opacity:1}
  86%      {transform:translateY(-142px) scale(1);opacity:.9}
  92%,100% {transform:translateY(0) scale(1);opacity:.5}
}

@media (prefers-reduced-motion:reduce){
  .orb-ring-rot,.orb-ring,.orb-core,.orb-unit.u1,.orb-unit.u1 line,.orb-standby{
    animation:none!important}
  .orb-unit.u1,.orb-unit.u1 line{opacity:1}
  .card:hover{transform:none}
}

/* ==========================================================================
   UTILITY LAYER
   A deliberately small, hand-named set. It exists so the HTML carries no
   style="" attributes — which lets the Content-Security-Policy stay at
   style-src 'self' with no 'unsafe-inline' exception. Add to it sparingly.
   ========================================================================== */
.mb-4{margin-bottom:var(--s4)}   .mb-6{margin-bottom:var(--s6)}
.mb-8{margin-bottom:var(--s8)}   .mb-12{margin-bottom:var(--s12)}
.mb-16{margin-bottom:var(--s16)} .mb-24{margin-bottom:var(--s24)}
.mt-4{margin-top:var(--s4)}      .mt-6{margin-top:var(--s6)}
.mt-16{margin-top:var(--s16)}    .mt-24{margin-top:var(--s24)}
.mt-0{margin-top:0}
.pt-12{padding-top:var(--s12)}   .pt-0{padding-top:0}
.pb-16{padding-block:var(--s16)}
.pt-page{padding-top:calc(66px + var(--s24))}
.bt-1{border-top:1px solid var(--border)}
.bt-0{border-top:0}
.c-text{color:var(--text)}       .c-dim{color:var(--text-dim)}
.c-faint{color:var(--text-faint)}.c-accent{color:var(--accent)}
.fs-sm{font-size:var(--fs-sm)}
.mw-78{max-width:78ch}
.mi-auto{margin-inline:auto}
.jc-center{justify-content:center}
.ai-center{align-items:center}   .ai-start{align-items:flex-start}
.gap-12{gap:var(--s12)}
.bg-surface-2{background:var(--surface-2)}
.display-page{font-size:clamp(2rem,4.6vw,3.4rem)}
.display-404{font-size:clamp(2rem,5vw,3.2rem)}
.screen-center{min-height:100svh;display:grid;place-content:center;
  text-align:center;padding:var(--s8)}

/* ==========================================================================
   NO-JAVASCRIPT SAFETY
   The scroll reveals used to default to opacity:0 and were switched on by
   script. With JavaScript blocked — a corporate proxy, a privacy extension,
   one syntax error — that left 42 sections permanently invisible. The page
   is now visible by default and only opts into the hidden state where
   scripting is actually available, so every failure mode degrades to
   "everything is readable" rather than "everything is blank".
   ========================================================================== */
[data-rise]{opacity:1;transform:none}
@media (scripting: enabled){
  [data-rise]{opacity:0;transform:translateY(18px)}
  [data-rise].in{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  [data-rise]{opacity:1!important;transform:none!important;transition:none}
}

/* ==========================================================================
   WEBGL LAYERS
   Every canvas is decorative by construction: it sits behind or over artwork
   that already carries the meaning, and it only becomes visible once the
   context has actually initialised (.gl-on). A device that cannot run it, or
   a visitor who has asked for less motion, sees the static version and loses
   nothing but the atmosphere.
   ========================================================================== */
.gl-layer{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:0;transition:opacity 900ms var(--ease-out);pointer-events:none;z-index:2;
}
.gl-layer.gl-on{opacity:1}

/* ---------- orbit stage ---------- */
.orbit-stage{position:relative;width:100%;max-width:520px;margin-inline:auto;aspect-ratio:1/1}
.orbit-stage .orbit-svg{position:absolute;inset:0;width:100%;height:100%;
  transition:opacity 700ms var(--ease-out)}
.orbit-stage .gl-layer.gl-on ~ .orbit-svg{opacity:0}
.orbit-readout{
  text-align:center;font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);margin-top:var(--s4);min-height:1.4em;
}

/* ---------- radial geometry, echoed ---------- */
/* The airframe's four-arm symmetry is the layout's grammar: convergence marks
   at the corners of every card, and arcs instead of plain rules. */
.card{position:relative}
.card::before,.card::after{
  content:'';position:absolute;width:7px;height:7px;pointer-events:none;
  border-color:var(--border-lit);border-style:solid;opacity:0;
  transition:opacity 180ms var(--ease-out);
}
.card::before{top:-1px;left:-1px;border-width:1px 0 0 1px}
.card::after{bottom:-1px;right:-1px;border-width:0 1px 1px 0}
.card:hover::before,.card:hover::after{opacity:1;border-color:var(--accent)}

hr.rule{position:relative;overflow:visible}
hr.rule::after{
  content:'';position:absolute;left:50%;top:-3px;width:6px;height:6px;
  transform:translateX(-50%) rotate(45deg);
  background:var(--bg);border:1px solid var(--border-lit);
}

/* ---------- precision cursor ---------- */
/* A reticle rather than an arrow. The logo's eyes are targeting rings; the
   cursor is the same idea. Pointer devices only — never on touch. */
@media (hover:hover) and (pointer:fine){
  html.reticle, html.reticle *{cursor:none}
/* …except where the native cursor is carrying information the reticle cannot:
   a resize affordance, a text caret, a disabled state. */
html.reticle .reveal,html.reticle .reveal *{cursor:ew-resize}
html.reticle a,html.reticle button,html.reticle summary,
html.reticle [role="slider"],html.reticle label{cursor:pointer}
html.reticle input,html.reticle textarea,html.reticle p,
html.reticle li,html.reticle td,html.reticle th{cursor:auto}
  .reticle-el{
    position:fixed;left:0;top:0;z-index:300;pointer-events:none;
    width:26px;height:26px;margin:-13px 0 0 -13px;
    transition:width 140ms var(--ease-out),height 140ms var(--ease-out),
               margin 140ms var(--ease-out),opacity 200ms var(--ease-out);
    will-change:transform;
  }
  .reticle-el::before,.reticle-el::after{
    content:'';position:absolute;background:var(--accent);
  }
  .reticle-el::before{left:50%;top:0;bottom:0;width:1px;margin-left:-.5px}
  .reticle-el::after{top:50%;left:0;right:0;height:1px;margin-top:-.5px}
  .reticle-ring{
    position:absolute;inset:0;border:1px solid var(--accent);border-radius:50%;
    opacity:.55;transition:transform 180ms var(--ease-out),opacity 180ms var(--ease-out);
  }
  .reticle-el.hot{width:44px;height:44px;margin:-22px 0 0 -22px}
  .reticle-el.hot .reticle-ring{opacity:1;transform:scale(1)}
  .reticle-el.down .reticle-ring{transform:scale(.72)}
}
@media (prefers-reduced-motion:reduce){
  html.reticle,html.reticle *{cursor:auto!important}
  .reticle-el{display:none}
}

/* ==========================================================================
   THE MISSION
   A sticky stage with the copy scrolling past it. The section is tall on
   purpose: its height minus one viewport is the scrub distance, so the
   visitor's scroll is literally the playhead of the sequence.
   ========================================================================== */
.mission{position:relative;background:var(--bg)}
@media(min-width:900px){.mission{height:460vh}}
@media(max-width:899px){.mission{height:400vh}}

.mission-stage{
  position:sticky;top:0;height:100svh;overflow:hidden;isolation:isolate;
  background:
    radial-gradient(120% 78% at 62% 78%, #16110F 0%, #0B0C10 42%, var(--bg) 76%),
    var(--bg);
}
.mission-gl{
  position:absolute;inset:0;width:100%;height:100%;z-index:2;
  opacity:0;transition:opacity 1100ms var(--ease-out);pointer-events:none;
}
.mission-gl.gl-on{opacity:1}
.mission-fallback{position:absolute;inset:0;z-index:1;transition:opacity 800ms var(--ease-out)}
.mission-fallback img{width:100%;height:100%;object-fit:cover;opacity:.38}
.mission-gl.gl-on ~ .mission-fallback{opacity:0}
.mission-vig{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:
    radial-gradient(90% 70% at 50% 52%, transparent 38%, rgba(6,7,10,.52) 82%, var(--bg) 100%),
    linear-gradient(180deg, var(--bg) 0%, transparent 14%, transparent 66%, rgba(8,9,11,.92) 100%);
}
/* zero-height sticky layer. .mission-stage sets isolation:isolate, so nothing
   inside it can paint above .mission-beats whatever its z-index — which is why
   the phase read-out kept disappearing behind the beat copy. */
.mission-chrome{position:sticky;top:0;height:0;z-index:8;pointer-events:none}

.mission-hud{
  position:absolute;left:var(--s6);top:calc(66px + var(--s6));
  font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);display:flex;align-items:center;gap:var(--s3);
  padding:var(--s2) var(--s4);border-radius:99px;
  background:rgba(6,7,10,.82);border:1px solid rgba(255,90,31,.28);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
.mission-hud::before{
  content:'';width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 0 rgba(255,90,31,.6);animation:ping 2.4s var(--ease-out) infinite;
}
@keyframes ping{
  0%{box-shadow:0 0 0 0 rgba(255,90,31,.55)}
  70%,100%{box-shadow:0 0 0 11px rgba(255,90,31,0)}
}
@media(max-width:759.98px){.mission-hud{display:none}}
@media(min-width:900px){.mission-hud{left:auto;right:var(--s12)}}
.mission-scrollhint{
  position:absolute;left:50%;top:calc(100svh - 58px);transform:translateX(-50%);
  font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;color:var(--text-faint);
  animation:hint 3.4s var(--ease-io) infinite;white-space:nowrap;
  padding:var(--s1) var(--s4);border-radius:99px;background:rgba(6,7,10,.7);
  transition:opacity 500ms var(--ease-out);
}
.mission-scrollhint.gone{opacity:0;animation:none;pointer-events:none}
@keyframes hint{0%,100%{opacity:.3;transform:translate(-50%,0)}50%{opacity:.85;transform:translate(-50%,4px)}}

/* the mark settles over the aircraft once it is down — glass, not a sticker */
.mission-mark{
  position:absolute;left:50%;bottom:16%;z-index:6;
  transform:translate(-50%,14px) scale(.96);
  display:flex;align-items:center;gap:var(--s4);
  padding:var(--s4) var(--s8) var(--s4) var(--s4);
  border-radius:14px;border:1px solid rgba(255,255,255,.14);
  background:linear-gradient(135deg, rgba(255,255,255,.09), rgba(255,255,255,.03));
  backdrop-filter:blur(16px) saturate(1.25);
  -webkit-backdrop-filter:blur(16px) saturate(1.25);
  box-shadow:0 24px 60px -20px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.16);
  opacity:0;pointer-events:none;
  transition:opacity 700ms var(--ease-out),transform 700ms var(--ease-out);
}
.mission-mark.in{opacity:1;transform:translate(-50%,0) scale(1)}
.mission-mark img{height:38px;width:auto}
.mission-mark b{display:block;font-family:var(--font-display);font-weight:600;
  font-size:var(--fs-base);letter-spacing:.02em;color:var(--text)}
.mission-mark span{display:block;font-family:var(--font-mono);font-size:var(--fs-micro);
  letter-spacing:.12em;text-transform:uppercase;color:var(--text-dim);margin-top:3px}

/* the copy that scrolls past the stage */
.mission-beats{position:relative;z-index:4;margin-top:-100svh;pointer-events:none}
.beat{
  min-height:100svh;display:flex;flex-direction:column;justify-content:center;
  max-width:min(46ch,90%);pointer-events:auto;
}
@media(min-width:900px){.beat{max-width:min(42ch,46%)}}
.beat:nth-child(even){margin-left:auto;text-align:right}
.beat:nth-child(even) .eyebrow{justify-content:flex-end}
.beat .h2{margin:var(--s6) 0 var(--s6)}
.beat .eyebrow{color:var(--text-dim)}
/* The stage behind is a moving render, so the copy carries its own ground —
   all of it. When only the lede had a panel, the eyebrow and part of the
   headline sat bare on the flame and were unreadable at most scrub positions. */
.beat-copy{
  background:linear-gradient(90deg, rgba(8,9,11,.93) 0%, rgba(8,9,11,.90) 74%, rgba(8,9,11,0) 100%);
  margin-left:calc(var(--s6) * -1);
  padding:var(--s6) var(--s16) var(--s6) var(--s6);
  border-radius:var(--radius-lg);
}
.beat:nth-child(even) .beat-copy{
  background:linear-gradient(270deg, rgba(8,9,11,.93) 0%, rgba(8,9,11,.90) 74%, rgba(8,9,11,0) 100%);
  margin-left:0;margin-right:calc(var(--s6) * -1);
  padding:var(--s6) var(--s6) var(--s6) var(--s16);
}
.beat-status{
  margin-top:var(--s5);padding-top:var(--s4);border-top:1px solid var(--border-lit);
  font-family:var(--font-mono);font-size:var(--fs-data);line-height:1.6;color:var(--text-faint);
}
@media(max-width:899px){
  .beat,.beat:nth-child(even){max-width:100%;text-align:left;margin-left:0}
  .beat:nth-child(even) .eyebrow{justify-content:flex-start}
  .beat .beat-copy,.beat:nth-child(even) .beat-copy{
    /* full-width copy on a phone sits directly over the brightest part of the
       render at the discharge beat; 88% was not enough for 11px type there */
    background:rgba(8,9,11,.94);margin:0;padding:var(--s6);border-radius:var(--radius-lg);
  }
}

.mission.mission-static{height:auto}
.mission.mission-static .mission-stage{position:relative;height:60svh}
.mission.mission-static .mission-beats{margin-top:0}
.mission.mission-static .beat{min-height:auto;padding-block:var(--s16)}
.mission.mission-static .beat-copy{opacity:1 !important}
.mission.mission-static .mission-mark{opacity:1;transform:translate(-50%,0)}
.mission.mission-static .mission-chrome{display:none}

@media (prefers-reduced-motion:reduce){
  .mission{height:auto}
  .mission-stage{position:relative;height:60svh}
  .mission-beats{margin-top:0}
  .beat{min-height:auto;padding-block:var(--s16)}
  .beat-copy{opacity:1 !important}
  .mission-mark{opacity:1;transform:translate(-50%,0)}
  /* with the stage static there is no playhead and no live phase, so the
     chrome that narrates them would simply be untrue */
  .mission-chrome{display:none}
}
