/* ═══════════════════════════════════════════════════════════════
   MPE INSIGHT — "SIGNAL CHAIN" art direction layer
   ───────────────────────────────────────────────────────────────
   Loaded last, so it owns the final word on look and motion.
   site.css still holds the palette and the brand rules; nothing
   here invents a colour.

   The idea: the page is one signal path. A rail runs down the left
   edge and fills as you scroll, each section is a station on it,
   and every block is built out of the same three materials —

     RAIL     hairlines that carry the eye (never full-width boxes)
     CHAMBER  a dark volume with light entering from one edge
     WINDOW   a module tile lifted off the page, lit from the top

   Rules that keep it coherent:
     · green  = a note event. Only CTAs, strikes, note-on dots.
     · cyan   = interaction. Hover, focus, the live edge.
     · blue   = depth and distance. Glows, horizons, fog.
     · motion is transform/opacity/filter only, and always eased out.
     · nothing pops in; everything arrives.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* motion — one easing family, used everywhere */
  --e-soft:  cubic-bezier(0.16, 1, 0.3, 1);      /* expo out: arrivals   */
  --e-swift: cubic-bezier(0.22, 1, 0.36, 1);     /* quart out: hovers    */
  --e-io:    cubic-bezier(0.65, 0.05, 0.36, 1);  /* in-out: transitions  */

  /* depth — three altitudes, nothing in between */
  --lift-1: 0 1px 0 rgba(255, 255, 255, 0.045) inset,
            0 10px 30px -18px rgba(0, 0, 0, 0.9);
  --lift-2: 0 1px 0 rgba(255, 255, 255, 0.05) inset,
            0 30px 70px -34px rgba(0, 0, 0, 0.95),
            0 2px 10px -6px rgba(0, 0, 0, 0.7);
  --lift-3: 0 1px 0 rgba(255, 255, 255, 0.06) inset,
            0 60px 140px -50px rgba(0, 0, 0, 1),
            0 0 0 1px rgba(140, 160, 220, 0.07);

  --edge-lit: rgba(160, 180, 240, 0.22);   /* top edge catching light */
  --glow-c:   rgba(var(--cyan-rgb), 0.28);
  --glow-b:   rgba(var(--blue-rgb), 0.30);

  /* vertical rhythm — sections breathe in three sizes */
  --gap-s: clamp(28px, 3.4vw, 56px);
  --gap-m: clamp(52px, 6vw, 104px);
  --gap-l: clamp(96px, 13vw, 210px);

  --vw: 100vw;                 /* real viewport width, set by craft.js */
  --sp: 0;                     /* scroll progress 0..1 */

  /* ── THE MEASURE ──────────────────────────────────────────────
     One shell, one gutter, for the whole document. The numbers are
     the nav's own (1560 / clamp(16,3vw,48)), so every section starts
     on exactly the same vertical as the wordmark above it. Three
     competing left edges — a 1240 text column, a near-full-bleed
     product shot, a full-bleed video — read as carelessness however
     good each one is on its own. Only two things are allowed out of
     the shell, and both are deliberate: the trailer and the device
     marquee, which are full bleed by design. */
  --shell:  1560px;
  --gutter: clamp(16px, 3vw, 48px);   /* the nav's exact clamp — below
                                         533px the floor is what differs,
                                         and it must not */
  --read:   68ch;              /* comfortable line length for prose */
}

.wrap, .wrap-wide {
  max-width: var(--shell);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* ─────────────────────────────────────────────────────────────
   1 · TYPE
   Fraunces is a variable optical-size face. Large sizes want a
   low opsz (fine, high-contrast); small sizes want a high one.
   Setting it by hand is the difference between "a serif" and
   "typography".
   ───────────────────────────────────────────────────────────── */
h1, h2 {
  font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0;
  letter-spacing: -0.028em;
  text-wrap: balance;
}
h3 {
  font-variation-settings: 'opsz' 36;
  letter-spacing: -0.012em;
}
p { text-wrap: pretty; }

h1.hero-title { font-weight: 500; letter-spacing: -0.035em; }
.sec-head h2  { font-weight: 500; }
.sec-head p   { line-height: 1.65; }

/* the em inside a headline is the one word that carries the idea —
   it shifts to the interactive accent and leans, never both loud */
.manifesto-text em { font-style: italic; font-variation-settings: 'opsz' 144, 'WONK' 1; }

/* ─────────────────────────────────────────────────────────────
   2 · PAGE FURNITURE
   ───────────────────────────────────────────────────────────── */
.bleed {
  width: var(--vw);
  margin-left: calc(50% - var(--vw) / 2);
}

/* a hairline that fades out at both ends — the page never has a
   hard full-width border, it has a horizon */
.hair {
  height: 1px;
  background: linear-gradient(90deg,
    transparent, rgba(140, 160, 220, 0.16) 22%,
    rgba(140, 160, 220, 0.16) 78%, transparent);
}

/* sections drop their borders; separation comes from light, not lines */
section { border-top: 0 !important; }

/* CHAMBER — a section lit from its top edge. Used on alternating
   sections so the page reads as volumes, not as a scroll of blocks. */
.chamber { position: relative; isolation: isolate; }
.chamber::before {
  content: '';
  position: absolute;
  inset: 0 calc(50% - var(--vw) / 2);
  z-index: -1;
  background:
    radial-gradient(ellipse 90% 62% at 50% 0%, rgba(var(--blue-rgb), 0.075), transparent 62%),
    linear-gradient(180deg, rgba(10, 13, 23, 0.85), rgba(3, 4, 9, 0) 72%);
  pointer-events: none;
}
.chamber::after {
  content: '';
  position: absolute;
  top: 0; left: calc(50% - var(--vw) / 2);
  width: var(--vw); height: 1px;
  z-index: -1;
  background: linear-gradient(90deg,
    transparent, rgba(var(--blue-rgb), 0.35) 30%,
    rgba(var(--cyan-rgb), 0.30) 50%, rgba(var(--blue-rgb), 0.35) 70%, transparent);
  transform: scaleX(0.2);
  opacity: 0;
  transition: transform 1.4s var(--e-soft), opacity 0.9s ease;
}
.chamber.is-near::after { transform: scaleX(1); opacity: 1; }

/* ─────────────────────────────────────────────────────────────
   3 · THE SIGNAL RAIL
   A fixed hairline on the left edge that fills with the brand
   gradient as the page scrolls. Each section is a node on it;
   nodes light green once passed and jump you back to their station.
   Decorative on small screens, so it hides entirely.
   ───────────────────────────────────────────────────────────── */
.rail {
  position: fixed;
  left: clamp(16px, 2vw, 30px);
  top: 0; bottom: 0;
  width: 12px;
  z-index: 860;
  pointer-events: none;
}
.rail-track, .rail-fill {
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 1px;
  margin-left: -0.5px;
}
.rail-track {
  background: linear-gradient(180deg,
    transparent 0%, rgba(140, 160, 220, 0.13) 9%,
    rgba(140, 160, 220, 0.13) 91%, transparent 100%);
}
.rail-fill {
  background: linear-gradient(180deg, var(--green) 0%, var(--cyan) 42%, var(--blue) 100%);
  box-shadow: 0 0 12px rgba(var(--cyan-rgb), 0.45);
  transform-origin: top;
  transform: scaleY(var(--sp));
  opacity: 0.85;
}
.rail-node {
  position: absolute;
  left: 0;
  width: 12px; height: 12px;
  margin-top: -6px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}
.rail-node::before {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 4px; height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--text-faint);
  transition: background 0.4s ease, box-shadow 0.4s ease, transform 0.4s var(--e-swift);
}
.rail-node.is-past::before {
  background: var(--green);
  box-shadow: 0 0 9px rgba(var(--green-rgb), 0.75);
}
.rail-node.is-here::before {
  transform: scale(2);
  background: var(--cyan);
  box-shadow: 0 0 14px rgba(var(--cyan-rgb), 0.9);
}
.rail-node span {
  position: absolute;
  left: 20px; top: 50%;
  transform: translateY(-50%) translateX(-6px);
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.4s var(--e-swift);
}
/* the label is a hover affordance only — parked open on the current
   station it just reads as stray text floating in the left margin */
.rail-node:hover span,
.rail-node:focus-visible span { opacity: 1; transform: translateY(-50%) translateX(0); }
.rail-node:focus-visible { outline: none; }
.rail-node:focus-visible::before { box-shadow: 0 0 0 3px rgba(var(--cyan-rgb), 0.4); }

@media (max-width: 1240px) { .rail { display: none; } }

/* ─────────────────────────────────────────────────────────────
   4 · REVEAL SYSTEM
   One attribute, a handful of variants, a stagger token. Every
   arrival on the page goes through here so the whole document
   shares one tempo.
   ───────────────────────────────────────────────────────────── */
/* Arrivals ride the independent `translate` / `scale` properties, never
   `transform`. That is what lets a card drift with the page and lean
   toward the cursor while it is still arriving — the three effects
   compose instead of overwriting each other. */
@media (prefers-reduced-motion: no-preference) {
  [data-rv] {
    opacity: 0;
    transition:
      opacity 0.85s var(--e-soft) var(--rvd, 0s),
      translate 1.05s var(--e-soft) var(--rvd, 0s),
      scale 1.05s var(--e-soft) var(--rvd, 0s),
      clip-path 1.15s var(--e-soft) var(--rvd, 0s),
      filter 0.9s var(--e-soft) var(--rvd, 0s);
  }
  [data-rv="up"]    { translate: 0 30px; }
  [data-rv="rise"]  { translate: 0 68px; }
  [data-rv="left"]  { translate: -26px 0; }
  [data-rv="right"] { translate: 26px 0; }
  [data-rv="scale"] { translate: 0 30px; scale: 0.955; }
  [data-rv="mask"]  { clip-path: inset(0 0 101% 0); translate: 0 12px; }
  [data-rv="soft"]  { filter: blur(16px); scale: 1.03; }
  [data-rv="line"]  { scale: 0 1; transform-origin: left; opacity: 1; }

  [data-rv].rv-in {
    opacity: 1;
    translate: none;
    scale: none;
    clip-path: inset(0 0 0 0);
    filter: none;
  }
}

/* ─────────────────────────────────────────────────────────────
   5 · SECTION KICKER
   The MIDI-stream-log row stays (it is the site's signature), but
   it is now a real instrument readout: hairline box, live dot,
   and a rule that runs out to the edge of the column.
   ───────────────────────────────────────────────────────────── */
.sec-index {
  gap: 12px;
  margin-bottom: 26px;
  font-size: 10.5px;
  letter-spacing: 0.18em;
}
.sec-index .si-t {
  padding: 4px 9px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: rgba(10, 13, 23, 0.6);
  opacity: 1;
  color: var(--text-dim);
}
.sec-index .si-ev { position: relative; padding-left: 15px; }
.sec-index .si-ev::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 6px; height: 6px;
  margin-top: -3px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 9px currentColor;
  animation: kick-pulse 2.6s ease-in-out infinite;
}
@keyframes kick-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.sec-index::after { flex: 1 1 auto; max-width: 240px; }

.sec-head { margin-bottom: var(--gap-m); }
.sec-head h2 { line-height: 1.0; }

@media (prefers-reduced-motion: reduce) { .sec-index .si-ev::before { animation: none; } }

/* ─────────────────────────────────────────────────────────────
   6 · CONTROLS
   Buttons keep the bottom-fill (a pressure meter, per the brand
   note) and gain weight: a lit top edge, a real press, and an
   arrow that leans forward on hover.
   ───────────────────────────────────────────────────────────── */
.btn {
  border-radius: 9px;
  letter-spacing: 0.005em;
  box-shadow: var(--lift-1);
  transition:
    border-color 0.35s var(--e-swift),
    background-color 0.35s var(--e-swift),
    background-size 0.45s var(--e-soft),
    color 0.3s var(--e-swift),
    box-shadow 0.35s var(--e-swift),
    transform 0.16s var(--e-swift);
}
.btn:active { transform: scale(0.975); transition-duration: 0.08s; }
.btn-primary {
  box-shadow: var(--lift-1), 0 12px 34px -16px rgba(var(--green-rgb), 0.55);
}
.btn-primary:hover {
  box-shadow: var(--lift-1), 0 16px 44px -14px rgba(var(--green-rgb), 0.75);
}
.btn-ghost:hover { box-shadow: var(--lift-1), 0 0 34px -14px var(--glow-c); }
.btn svg { transition: transform 0.4s var(--e-soft); }
.btn:hover svg { transform: translateX(2px); }

/* ─────────────────────────────────────────────────────────────
   7 · CURSOR REACTION
   A single shared treatment: elements marked [data-tilt] get the
   pointer position as --mx/--my and answer with a sheen and a
   couple of degrees of parallax. Never more than a couple —
   the moment a card looks like a toy the page stops being premium.
   ───────────────────────────────────────────────────────────── */
/* parallax offset — one declaration, so an element that both drifts
   and tilts still writes a single transform */
[data-par] { transform: translate3d(0, var(--py, 0px), 0); will-change: transform; }

[data-tilt] {
  position: relative;
  transform-style: preserve-3d;
  transform: translate3d(0, var(--py, 0px), 0);
  transition: transform 0.65s var(--e-soft), box-shadow 0.5s var(--e-swift),
              border-color 0.5s var(--e-swift);
}
[data-tilt]::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--e-swift);
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%),
    rgba(var(--cyan-rgb), 0.10), transparent 62%);
  z-index: 3;
}
[data-tilt].is-hot::after { opacity: 1; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  [data-tilt].is-hot {
    transform: translate3d(0, var(--py, 0px), 0)
               perspective(1100px)
               rotateX(calc(var(--ty, 0) * -2.2deg))
               rotateY(calc(var(--tx, 0) * 2.2deg))
               translate3d(0, -3px, 0);
    transition-duration: 0.25s;
  }
}

/* ─────────────────────────────────────────────────────────────
   8 · HERO
   The field stays — it is the best thing on the site. What it
   gains is an exit: as you leave, the content sinks and the
   canvas pushes back into depth instead of just scrolling away.
   ───────────────────────────────────────────────────────────── */
.hero { padding-bottom: clamp(84px, 10vw, 128px); }
#heroCanvas {
  transform: scale(calc(1 + var(--hp, 0) * 0.10)) translate3d(0, calc(var(--hp, 0) * -3vh), 0);
  opacity: calc(1 - var(--hp, 0) * 0.85);
  will-change: transform, opacity;
}
.hero-content {
  transform: translate3d(0, calc(var(--hp, 0) * 8vh), 0);
  opacity: calc(1 - var(--hp, 0) * 1.15);
}
.hero-telemetry {
  transform: translate3d(0, calc(var(--hp, 0) * 13vh), 0);
  opacity: calc(1 - var(--hp, 0) * 1.4);
}

h1.hero-title { font-size: clamp(46px, 8.6vw, 124px); line-height: 0.98; margin-bottom: 34px; }
.hero-eyebrow { letter-spacing: 0.22em; }
.hero-sub { font-size: clamp(15.5px, 1.55vw, 19px); line-height: 1.65; max-width: 520px; }
.hero-ctas { gap: 16px; margin-top: 6px; }
.hero-note { max-width: 460px; line-height: 1.7; opacity: 0.85; }

/* the hero sits on the same shell as every other section */
.hero-content {
  max-width: var(--shell);
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* the telemetry strip reads as one instrument, not five boxes. It is a
   bordered object, so it carries the gutter as margin rather than
   padding — its edge is what has to line up, not its contents. */
.hero-telemetry {
  gap: 0;
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  overflow: hidden;
  background: rgba(7, 9, 16, 0.5);
  backdrop-filter: blur(10px);
  box-shadow: var(--lift-2);
  /* a bordered object: its EDGE is what has to sit on the axis, so the
     gutter is margin here — auto alone collapses to 0 below the shell.
     max-width: none kills site.css's old 1240 cap, which otherwise
     re-centres the strip on its own private axis. */
  width: min(100% - var(--gutter) * 2, var(--shell) - var(--gutter) * 2);
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  padding: 0;
}
.tele-cell {
  background: none;
  backdrop-filter: none;
  border: 0;
  border-left: 1px solid var(--line-soft);
  border-radius: 0 !important;
  padding: 15px 18px 17px;
}
.tele-cell:first-child { border-left: 0; }
.tele-value { font-size: 17px; letter-spacing: -0.01em; }
.tele-label { letter-spacing: 0.16em; }

/* the scroll cue is a playhead that drains and refills, not a bouncing arrow */
.hero-hint { gap: 14px; bottom: 30px; letter-spacing: 0.2em; font-size: 10px; }
.hero-hint-line {
  width: 46px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.hero-hint-line::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--cyan));
  transform: translateX(-100%);
  animation: playhead 2.8s var(--e-io) infinite;
}
@keyframes playhead {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(0); }
  100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) { .hero-hint-line::after { animation: none; opacity: 0.4; } }

/* ─────────────────────────────────────────────────────────────
   9 · CINEMA — the trailer
   Not a video card. The frame opens: a letterbox slit widens into
   a full-bleed screen as you scroll into it, the way a projector
   iris does. The title sits over it and lifts out of the way.
   ───────────────────────────────────────────────────────────── */
#trailer { padding-top: clamp(40px, 6vw, 90px); }
#trailer .sec-head { margin-bottom: clamp(30px, 4vw, 56px); }
#trailer .sec-head h2 { font-size: clamp(38px, 6.4vw, 86px); }

.cinema {
  position: relative;
  --iris: 0;                         /* 0 = closed slit, 1 = open */
}
.cinema-frame {
  position: relative;
  overflow: hidden;
  clip-path: inset(calc((1 - var(--iris)) * 34%) 0 calc((1 - var(--iris)) * 34%) 0
                   round calc(var(--iris) * 14px));
  will-change: clip-path;
}
.cinema .yt-stage {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  transform: scale(calc(1.14 - var(--iris) * 0.14));
  will-change: transform;
}
.cinema .yt-stage img { filter: brightness(0.6) saturate(1.1) contrast(1.05); }
.cinema .yt-stage:hover img { filter: brightness(0.78) saturate(1.12) contrast(1.05); transform: scale(1.02); }
.cinema-frame::after {                      /* vignette + floor shadow */
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 78% 70% at 50% 45%, transparent 40%, rgba(3, 4, 9, 0.65) 100%),
    linear-gradient(180deg, rgba(3, 4, 9, 0.5), transparent 26%, transparent 70%, rgba(3, 4, 9, 0.9));
}
/* the projector's light pool under the screen */
.cinema-glow {
  position: absolute;
  left: 50%; bottom: -14%;
  width: 62%; height: 40%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(var(--blue-rgb), 0.22), transparent 68%);
  filter: blur(40px);
  opacity: calc(var(--iris) * 0.9);
  pointer-events: none;
  z-index: -1;
}
.cinema .yt-play {
  width: clamp(64px, 6vw, 92px);
  height: clamp(64px, 6vw, 92px);
  background: rgba(3, 4, 9, 0.35);
  border: 1px solid rgba(var(--cyan-rgb), 0.5);
  color: var(--text);
  backdrop-filter: blur(10px);
  box-shadow: 0 0 0 0 rgba(var(--cyan-rgb), 0.35), 0 20px 50px -18px rgba(0, 0, 0, 0.9);
}
.cinema .yt-stage:hover .yt-play {
  transform: scale(1.08);
  background: rgba(var(--cyan-rgb), 0.12);
  border-color: var(--cyan);
  box-shadow: 0 0 0 12px rgba(var(--cyan-rgb), 0.06), 0 24px 60px -18px rgba(0, 0, 0, 0.9);
}
.cinema .yt-overlay .mono { letter-spacing: 0.24em; font-size: 10px; }
.cinema-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  max-width: var(--shell);
  margin: 20px auto 0;
  padding: 0 var(--gutter);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.cinema-meta a { transition: color 0.3s var(--e-swift); }
.cinema-meta a:hover { color: var(--cyan); }

/* ─────────────────────────────────────────────────────────────
   10 · DEVICE BUS — the controller marquee
   Reads like the app's connection list scrolling past on a bus,
   with a live scan sweeping across it.
   ───────────────────────────────────────────────────────────── */
.marquee {
  background: linear-gradient(180deg, rgba(10, 13, 23, 0.7), rgba(3, 4, 9, 0.7));
  padding: 26px 0;
  border-color: transparent;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}
.marquee::before, .marquee::after { display: none; }
.marquee-track span {
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--text-faint);
}
.marquee-track i {
  width: 4px; height: 4px;
  background: rgba(var(--green-rgb), 0.35);
  box-shadow: 0 0 0 rgba(var(--green-rgb), 0);
  animation: bus-tick 4.4s ease-in-out infinite;
}
.marquee-track i:nth-of-type(3n)   { animation-delay: 0.7s; }
.marquee-track i:nth-of-type(3n+1) { animation-delay: 1.9s; }
@keyframes bus-tick {
  0%, 88%, 100% { background: rgba(var(--green-rgb), 0.3); box-shadow: none; }
  92%           { background: var(--green); box-shadow: 0 0 10px rgba(var(--green-rgb), 0.9); }
}
.marquee-rule {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}
@media (prefers-reduced-motion: reduce) { .marquee-track i { animation: none; } }

/* ─────────────────────────────────────────────────────────────
   11 · MANIFESTO
   The statement is the whole section. It gets the full width and
   real air; the supporting prose sits under a sticky pull-quote
   so the credo stays on screen while the argument scrolls past.
   ───────────────────────────────────────────────────────────── */
.manifesto { padding-top: var(--gap-l); }
/* The statement IS this section's head, so it obeys the same centred
   axis as every other head on the page. It simply gets a far wider
   measure than a normal one. */
.manifesto-head { max-width: 1180px; }
.manifesto-text {
  font-size: clamp(30px, 4.8vw, 72px);
  line-height: 1.08;
  letter-spacing: -0.03em;
  max-width: none;
  margin-bottom: 0;
}
.manifesto-text .w { opacity: 0.13; transition: opacity 0.5s var(--e-soft); }
.manifesto-text .w.on { opacity: 1; }
.manifesto-text em { color: var(--cyan); }

/* head, prose, credo and the channel strip all share the statement's
   1180 measure, so the whole section is one column instead of a wide
   block sitting under a narrow one */
.manifesto-body {
  max-width: 1180px;
  margin: 0 auto var(--gap-m);
}
.philo-sub {
  font-family: var(--display);
  font-variation-settings: 'opsz' 72;
  font-size: clamp(19px, 1.9vw, 26px);
  line-height: 1.36;
  color: var(--text);
  letter-spacing: -0.015em;
  max-width: 34ch;
  margin: clamp(38px, 4.4vw, 62px) auto 0;
  padding-top: 26px;
  text-align: center;
  position: relative;
}
.philo-sub::before {                    /* a note-on tick, not a side rule:
                                           a left border under a centred
                                           block is exactly the kind of
                                           stray axis this pass removes */
  content: '';
  position: absolute;
  left: 50%; top: 0;
  width: 26px; height: 2px;
  margin-left: -13px;
  border-radius: 2px;
  background: var(--green);
  box-shadow: 0 0 10px rgba(var(--green-rgb), 0.6);
}
.philo-sub em { font-style: italic; color: var(--green); }

.manifesto-cols {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(26px, 4vw, 64px);
  max-width: none;
  margin-bottom: 0;
}
.manifesto-cols p { font-size: clamp(15.5px, 1.5vw, 17px); line-height: 1.8; color: var(--text-dim); }

/* CHANNEL STRIP — the stats. Four vertical meters, mixer style. */
.stats {
  grid-template-columns: repeat(4, 1fr);
  border-top: 0;
  gap: clamp(16px, 2.6vw, 40px);
  padding-top: var(--gap-s);
  align-items: stretch;
  position: relative;
  max-width: 1180px;
  margin-left: auto;
  margin-right: auto;
}
.stats::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--line), transparent 85%);
}
/* The gap to the meter scales with the numeral: at 59px a small gap
   reads as the figure leaning on the rule.
   GOTCHA: site.css zeroes padding-left on :first-child (and on
   :nth-child(odd) under 880px) from the old bordered-column layout.
   Those beat a plain .stat rule, which is why only the first figure
   sat flush against its meter. Every cell now carries the same gap. */
.stat,
.stat:first-child,
.stat:nth-child(odd) {
  border-left: 0;
  padding: 0 16px 0 clamp(24px, 2.2vw, 38px);
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
.stat::before {                         /* meter track */
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  border-radius: 2px;
  background: rgba(140, 160, 220, 0.11);
}
.stat-bar {                             /* meter fill, grows on arrival */
  position: absolute;
  left: 0; top: 0;
  width: 2px;
  height: 0;
  max-width: none;
  margin: 0;
  border-radius: 2px;
  background: none;
  overflow: hidden;
}
.stat.is-in .stat-bar { height: 100%; }
.stat-bar b {
  width: 2px;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--green), var(--cyan));
  box-shadow: 0 0 12px rgba(var(--cyan-rgb), 0.55);
}
@media (prefers-reduced-motion: no-preference) {
  .stat-bar { transition: height 1.1s var(--e-soft) 0.15s; }
  .stat-bar b { transition: none; }
}
/* opsz 72 rather than 144: at this size the 144 master's hairlines are
   thin enough that Windows subpixel rendering fringes them pink/blue.
   A slightly lower optical size keeps the stroke honest on screen. */
.stat-num {
  font-size: clamp(44px, 4.6vw, 68px);
  font-weight: 500;
  font-variation-settings: 'opsz' 72;
  letter-spacing: -0.035em;
  margin-bottom: 16px;
  line-height: 0.9;
}
.stat-label {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  line-height: 1.65;
  max-width: 24ch;
}

/* ─────────────────────────────────────────────────────────────
   12 · THE INSTRUMENT — interactive module map
   The screenshot is the product shot. It arrives tilted back in
   space and levels out as it enters, sitting on its own bloom.
   Every hotspot, chip and lightbox behaviour is untouched.
   ───────────────────────────────────────────────────────────── */
#modules { padding-top: var(--gap-l); padding-bottom: var(--gap-l); }
#modules .sec-head { margin-bottom: clamp(38px, 4.4vw, 64px); }

#modules .mh-deck {
  position: relative;
  perspective: 2200px;
  perspective-origin: 50% 0%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
#modules .mh-wide { margin: 0; }
#modules .mh-stage {
  border-radius: 14px;
  border-color: rgba(140, 160, 220, 0.16);
  box-shadow: var(--lift-3);
  transform: rotateX(calc(var(--deck, 0) * 9deg)) translate3d(0, 0, calc(var(--deck, 0) * -80px));
  transform-origin: 50% 0%;
  will-change: transform;
}
#modules .mh-stage::after {                 /* top edge catching light */
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  box-shadow: inset 0 1px 0 var(--edge-lit);
}
/* the screen's own light spilling onto the page behind it */
#modules .mh-bloom {
  position: absolute;
  inset: 6% 4% -6% 4%;
  z-index: -1;
  filter: blur(58px) saturate(1.5);
  opacity: 0.4;
  transform: scale(1.02);
  background-size: cover;
  background-position: center;
  pointer-events: none;
  transition: opacity 0.8s ease;
}

#modules .mh-swatches { gap: 10px; margin-top: 26px; }
#modules .mh-swatch {
  width: 22px; height: 22px;
  border-radius: 6px;
  border-color: rgba(233, 234, 250, 0.16);
  box-shadow: var(--lift-1);
  transition: transform 0.4s var(--e-soft), box-shadow 0.4s var(--e-swift), border-color 0.3s;
}
#modules .mh-swatch:hover { transform: translateY(-3px) scale(1.1); border-color: rgba(var(--cyan-rgb), 0.5); }
#modules .mh-swatch.is-active {
  box-shadow: 0 0 0 1px var(--void), 0 0 0 2px var(--cyan), 0 8px 20px -8px rgba(var(--cyan-rgb), 0.6);
}

#modules .mh-hint {
  margin-top: 22px;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}
#modules .mh-hint b { color: var(--cyan); font-weight: 500; }

#modules .mh-legend { gap: 7px; margin-top: 22px; }
#modules .mh-chip {
  background: transparent;
  border-color: var(--line);
  border-radius: 7px;
  padding: 7px 14px;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  transition: color 0.3s var(--e-swift), border-color 0.3s var(--e-swift),
              background 0.3s var(--e-swift), transform 0.35s var(--e-soft);
}
#modules .mh-chip:hover, #modules .mh-chip:focus-visible, #modules .mh-chip.is-active {
  color: var(--text);
  border-color: rgba(var(--cyan-rgb), 0.45);
  background: rgba(var(--cyan-rgb), 0.06);
  transform: translateY(-2px);
}
#modules .mh-chip--chrome:hover, #modules .mh-chip--chrome:focus-visible, #modules .mh-chip--chrome.is-active {
  border-color: rgba(var(--green-rgb), 0.45);
  background: rgba(var(--green-rgb), 0.07);
}
#modules .mh-controls { margin-top: 20px; padding-top: 20px; position: relative; }
#modules .mh-controls::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  width: min(420px, 70%); height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}
#modules .mh-controls-label { letter-spacing: 0.18em; }

/* the lightbox becomes a proper overlay: deeper backdrop, lifted panel */
#modules .mod-modal-backdrop { background: rgba(2, 3, 7, 0.92); backdrop-filter: blur(14px) saturate(0.8); }
#modules .mod-modal-box {
  background: linear-gradient(180deg, rgba(12, 15, 26, 0.96), rgba(7, 9, 16, 0.96));
  border-color: rgba(140, 160, 220, 0.14);
  border-radius: 14px;
  box-shadow: var(--lift-3);
}
#modules .mod-title { font-variation-settings: 'opsz' 72; letter-spacing: -0.02em; }
#modules .mod-tag { letter-spacing: 0.18em; color: var(--cyan); }
#modules .mod-modal.is-chrome .mod-tag { color: var(--green); }

/* ─────────────────────────────────────────────────────────────
   13 · THE CHAIN — how it works
   Two movements. First the router animation pins itself and the
   explanation writes itself out word by word beside it. Then the
   nine modules arrive as an editorial mosaic, not a card grid:
   different spans, offset baselines, columns drifting at
   different speeds.
   ───────────────────────────────────────────────────────────── */
#how { padding-top: var(--gap-l); }

.chain {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(280px, 0.75fr);
  gap: clamp(28px, 4vw, 72px);
  align-items: center;
  margin-bottom: clamp(64px, 8vw, 128px);
}
.chain-stage { position: relative; }
.chain-stage .mpe-anim {
  margin: 0;
  border-radius: 14px;
  border-color: rgba(140, 160, 220, 0.14);
  background: linear-gradient(180deg, rgba(10, 13, 23, 0.9), rgba(5, 6, 12, 0.9));
  box-shadow: var(--lift-2);
}
.chain-stage::after {
  content: '';
  position: absolute;
  inset: 12% 8% -10% 8%;
  z-index: -1;
  background: radial-gradient(ellipse at center, rgba(var(--blue-rgb), 0.16), transparent 70%);
  filter: blur(40px);
  pointer-events: none;
}
/* No padded-out travel here. The two columns are almost the same
   height, so the sticky has little to do anyway — the 340px of air it
   used to buy read as a hole in the page, not as pacing. The sentence
   writes itself over the section's own scroll range instead. */
.chain-read {
  padding-top: clamp(8px, 1.6vw, 28px);
  padding-bottom: 0;
}
.chain-read .how-cap {
  font-family: var(--display);
  font-variation-settings: 'opsz' 48;
  font-size: clamp(19px, 2vw, 26px);
  line-height: 1.5;
  letter-spacing: -0.012em;
  color: var(--text);
  max-width: 30ch;
  margin: 0;
  opacity: 1;
}
.chain-read .how-cap .w { opacity: 0.16; transition: opacity 0.45s var(--e-soft); }
.chain-read .how-cap .w.on { opacity: 1; }
.chain-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 22px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.chain-label::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line), transparent); }

/* — the mosaic — */
/* Rhythm comes from the SPANS (7+5 · 4+4+4 · 12 · 4+4+4), never from
   nudging individual cards up and down: with captions of different
   lengths, offset tops plus ragged bottoms read as broken rather than
   editorial. Cards stretch so every row shares one baseline. */
#how .how-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(18px, 2vw, 34px);
  margin-top: 0;
  align-items: stretch;
}
#how .how-card {
  grid-column: span 4;
  position: relative;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, rgba(12, 15, 26, 0.9), rgba(7, 9, 16, 0.92));
  border: 1px solid rgba(140, 160, 220, 0.11);
  border-top-color: var(--edge-lit);
  border-radius: 12px;
  box-shadow: var(--lift-2);
  overflow: hidden;
  transition: border-color 0.5s var(--e-swift), box-shadow 0.5s var(--e-swift),
              transform 0.65s var(--e-soft);
}
#how .how-card:nth-child(1) { grid-column: span 7; }
#how .how-card:nth-child(2) { grid-column: span 5; }
#how .how-card:nth-child(6) { grid-column: span 12; }
/* the caption takes the slack so a short text does not leave a card
   floating half-empty inside a stretched row */
#how .how-card figcaption { flex: 1; }

#how .how-card.is-hot {
  border-color: rgba(var(--cyan-rgb), 0.3);
  box-shadow: var(--lift-2), 0 0 60px -26px var(--glow-c);
}
#how .how-card .mod-bar {
  background: rgba(6, 8, 15, 0.8);
  border-bottom-color: rgba(140, 160, 220, 0.09);
  padding: 12px 16px;
  letter-spacing: 0.16em;
  font-size: 10px;
  position: relative;
  z-index: 2;
}
#how .how-card .mod-bar::before { transition: box-shadow 0.5s var(--e-swift); }
#how .how-card.is-hot .mod-bar::before { box-shadow: 0 0 14px rgba(var(--green-rgb), 1); }
#how .how-card figcaption { padding: 18px 20px 24px; }
#how .how-card figcaption p {
  font-size: 13.5px;
  line-height: 1.72;
  color: var(--text-dim);
  opacity: 1;
  transition: color 0.5s var(--e-swift);
}
#how .how-card.is-hot figcaption p { color: #a4acc6; }
#how .how-card .mpe-anim { background: rgba(255, 255, 255, 0.012); }

/* the sixth card is the showpiece — it runs the full width and
   puts the animation and the reading side by side */
#how .how-card:nth-child(6) {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(280px, 1fr);
  grid-template-rows: auto 1fr;
}
#how .how-card:nth-child(6) .mod-bar { grid-column: 1 / -1; }
#how .how-card:nth-child(6) .mpe-anim { grid-column: 1; grid-row: 2; height: 100%; aspect-ratio: auto; min-height: 260px; }
#how .how-card:nth-child(6) figcaption {
  grid-column: 2; grid-row: 2;
  align-self: center;
  padding: clamp(24px, 3vw, 46px);
  border-left: 1px solid rgba(140, 160, 220, 0.09);
}
#how .how-card:nth-child(6) figcaption p { font-size: 15px; line-height: 1.8; }

/* ─────────────────────────────────────────────────────────────
   14 · SPEC LEDGER — what used to be a six-box feature grid.
   Now it reads like the back of a piece of hardware: numbered
   rows, hairline rules, one line of light sweeping the row you
   are on.
   ───────────────────────────────────────────────────────────── */
#how .tech-grid {
  display: block;
  margin-top: var(--gap-l) !important;
  border: 0;
  border-radius: 0;
  background: none;
  border-top: 1px solid var(--line);
}
#how .tech-item {
  display: grid;
  grid-template-columns: 74px minmax(160px, 0.9fr) minmax(0, 1.6fr);
  align-items: baseline;
  gap: clamp(16px, 3vw, 44px);
  padding: clamp(22px, 2.4vw, 34px) 0;
  border-bottom: 1px solid var(--line-soft);
  background: none;
  position: relative;
  transition: background 0.5s var(--e-swift);
}
#how .tech-item::before {                 /* the sweep */
  content: '';
  position: absolute;
  left: 0; bottom: -1px;
  height: 1px; width: 100%;
  background: linear-gradient(90deg, var(--cyan), rgba(var(--cyan-rgb), 0));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--e-soft);
}
#how .tech-item:hover { background: linear-gradient(90deg, rgba(var(--cyan-rgb), 0.035), transparent 60%); }
#how .tech-item:hover::before { transform: scaleX(1); }
#how .tech-num {
  margin-bottom: 0;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-faint);
  transition: color 0.4s var(--e-swift);
}
#how .tech-item:hover .tech-num { color: var(--cyan); }
#how .tech-item h3 {
  font-size: clamp(17px, 1.8vw, 22px);
  margin-bottom: 0;
  letter-spacing: -0.015em;
  font-variation-settings: 'opsz' 48;
}
#how .tech-item p {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-faint);
  max-width: var(--read);          /* the shell is wide; prose is not */
  transition: color 0.4s var(--e-swift);
}
#how .tech-item:hover p { color: var(--text-dim); }

#how .how-more {
  margin-top: clamp(32px, 4vw, 56px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  opacity: 1;
}
#how .how-more a {
  color: var(--text-dim);
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
  transition: color 0.3s, border-color 0.3s;
}
#how .how-more a:hover { color: var(--cyan); border-color: var(--cyan); }

/* ─────────────────────────────────────────────────────────────
   15 · SCREENING ROOM — the walkthrough
   Deliberately the opposite composition to the trailer: reading
   on the left, and the screen running off the right edge of the
   page on a slight plane, as if it stands in the room with you.
   ───────────────────────────────────────────────────────────── */
/* The stage stays inside the column: nothing may run off the page
   edge here. Distinction from the trailer comes from containment and
   light, not from breaking the grid — the trailer is the one that
   goes full bleed. */
#walkthrough .sec-head { margin-bottom: clamp(38px, 4.4vw, 62px); }
.screening {
  position: relative;
  max-width: 1120px;
  margin: 0 auto;
}
.screening-stage { position: relative; }
.screening-stage .yt-stage {
  border-radius: 14px;
  box-shadow: var(--lift-3);
  /* --plane runs 1 → 0 as the stage arrives: a small settle, not a turn.
     The fallback is the settled value, so with JS off nothing sits shrunk. */
  transform: scale(calc(1 - var(--plane, 0) * 0.05));
  transition: transform 0.9s var(--e-soft);
  will-change: transform;
}
.screening-stage::before {                  /* the projected light behind it */
  content: '';
  position: absolute;
  inset: 8% -4% -14% -4%;
  background: radial-gradient(ellipse at 50% 60%, rgba(var(--blue-rgb), 0.20), transparent 68%);
  filter: blur(52px);
  z-index: -1;
  pointer-events: none;
}
.screening-stage::after {                   /* floor pool under the screen */
  content: '';
  position: absolute;
  left: 12%; right: 12%; bottom: -9%;
  height: 26%;
  background: radial-gradient(ellipse at center, rgba(var(--cyan-rgb), 0.13), transparent 72%);
  filter: blur(40px);
  z-index: -1;
  pointer-events: none;
}
.screening .yt-play {
  background: rgba(3, 4, 9, 0.35);
  border: 1px solid rgba(var(--cyan-rgb), 0.5);
  color: var(--text);
  backdrop-filter: blur(10px);
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.9);
}
.screening .yt-stage:hover .yt-play {
  background: rgba(var(--cyan-rgb), 0.12);
  border-color: var(--cyan);
  box-shadow: 0 0 0 12px rgba(var(--cyan-rgb), 0.06);
}
.screening .yt-ext { justify-content: center; margin-top: 22px; }
.screening .yt-ext a {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ─────────────────────────────────────────────────────────────
   16 · THE LICENSE — pricing
   Not a plan card. An object: the deal on the left face, the
   spec ledger on the right, registration marks in the corners
   and a light that sweeps the surface when you approach it.
   ───────────────────────────────────────────────────────────── */
.pricing::before { display: none; }
.pricing { overflow: visible; }

.lic {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  max-width: 1020px;
  margin: 0 auto;
  border: 1px solid rgba(140, 160, 220, 0.14);
  border-top-color: var(--edge-lit);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(13, 16, 28, 0.94), rgba(6, 8, 15, 0.96));
  box-shadow: var(--lift-3);
  overflow: hidden;
}
.lic::after {                                   /* surface sweep */
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  opacity: 0;
  transition: opacity 0.6s var(--e-swift);
  background: radial-gradient(600px circle at var(--mx, 50%) var(--my, 0%),
    rgba(var(--cyan-rgb), 0.07), transparent 60%);
}
.lic.is-hot::after { opacity: 1; }
.lic-face {
  padding: clamp(30px, 3.4vw, 48px);
  border-right: 1px solid rgba(140, 160, 220, 0.1);
  display: flex;
  flex-direction: column;
}
.lic-spec {
  padding: clamp(30px, 3.4vw, 48px);
  background: rgba(3, 4, 9, 0.4);
  display: flex;
  flex-direction: column;
}
.lic-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  grid-column: 1 / -1;
  padding: 12px clamp(20px, 2.4vw, 30px);
  background: rgba(6, 8, 15, 0.85);
  border-bottom: 1px solid rgba(140, 160, 220, 0.1);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.lic-bar span:first-child { display: flex; align-items: center; gap: 10px; }
.lic-bar span:first-child::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 9px rgba(var(--green-rgb), 0.8);
}
.lic-serial { color: var(--text-faint); font-variant-numeric: tabular-nums; }

.lic-name {
  font-family: var(--display);
  font-variation-settings: 'opsz' 72;
  font-weight: 500;
  font-size: clamp(28px, 3vw, 40px);
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin-bottom: 8px;
}
.lic-platform {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: clamp(24px, 3vw, 38px);
}
.lic-price {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 6px;
}
.lic-price-now {
  font-family: var(--display);
  font-variation-settings: 'opsz' 144;
  font-weight: 500;
  font-size: clamp(48px, 6.4vw, 78px);
  line-height: 0.86;
  letter-spacing: -0.04em;
  color: var(--text);
}
.lic-vat {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  margin-bottom: clamp(24px, 3vw, 34px);
}
.lic-actions { margin-top: auto; display: flex; flex-direction: column; }
.lic .pricing-buy { width: 100%; padding: 16px 24px; font-size: 15px; }
.lic .pricing-or { margin: 16px 0 14px; font-size: 9.5px; letter-spacing: 0.2em; }
.lic .btn-steam { width: 100%; padding: 15px 24px; }
.lic .pricing-steam-note { margin-top: 12px; font-size: 10.5px; letter-spacing: 0.04em; line-height: 1.6; }

.lic-spec-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.lic-spec-label::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line), transparent); }

.lic .pricing-points { max-width: none; margin: 0; gap: 0; }
.lic .pricing-points li {
  gap: 14px;
  padding: 13px 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-dim);
  border-bottom: 1px solid var(--line-soft);
  transition: color 0.4s var(--e-swift);
}
.lic .pricing-points li:last-child { border-bottom: 0; }
.lic .pricing-points li:hover { color: var(--text); }
.lic .pt-dot { margin-top: 0.5em; }

.lic .winnote { margin-top: auto; padding-top: 22px; border-top: 1px solid var(--line-soft); }
.lic .winnote summary { justify-content: flex-start; letter-spacing: 0.16em; }
.lic .winnote summary:hover { color: var(--cyan); }
.lic .winnote-body em { color: var(--cyan); }
.lic .winnote-steps .n { color: var(--green); }

/* ─────────────────────────────────────────────────────────────
   17 · RELEASE TAPE — the update feed
   The accordion keeps its markup and its script; what changes is
   that it now runs down a rail like a tape log, and opening a
   release unrolls instead of snapping.
   ───────────────────────────────────────────────────────────── */
#system .modules-container {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}
#system .uf-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 26px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
#system .uf-head-label { color: var(--text-dim); display: flex; align-items: center; gap: 10px; }
#system .uf-head-label::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 9px rgba(var(--green-rgb), 0.8);
}
#system .uf-head a { color: var(--text-faint); transition: color 0.3s var(--e-swift); }
#system .uf-head a:hover { color: var(--cyan); }

/* the changelog is a reading column, like the price card and the signup
   form: a centred object under a centred head, not a full-width table */
#system .uf-head, #system .uf-feed {
  max-width: 1040px;
  margin-left: auto;
  margin-right: auto;
}
#system .uf-feed {
  position: relative;
  padding-left: clamp(0px, 3vw, 40px);
}
#system .uf-item {
  border-top: 0;
  border-bottom: 1px solid var(--line-soft) !important;
  position: relative;
}
#system .uf-item:first-child { border-top: 1px solid var(--line-soft); }
#system .uf-row {
  padding: 22px 0;
  gap: 18px;
  transition: transform 0.5s var(--e-soft), opacity 0.3s;
}
#system .uf-row:hover { opacity: 1; transform: translateX(6px); }
#system .uf-item::before {                    /* the rail node */
  content: '';
  position: absolute;
  left: clamp(-18px, -1.6vw, -10px);
  top: 42px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--text-faint);
  transition: background 0.4s, box-shadow 0.4s, transform 0.4s var(--e-swift);
}
#system .uf-item:first-child::before {
  background: var(--green);
  box-shadow: 0 0 10px rgba(var(--green-rgb), 0.8);
}
#system .uf-item.is-open::before {
  background: var(--cyan);
  box-shadow: 0 0 12px rgba(var(--cyan-rgb), 0.9);
  transform: scale(1.5);
}
#system .uf-thumb, #system .uf-item--text .uf-mark {
  width: 44px;
  border-radius: 7px;
  transition: transform 0.5s var(--e-soft);
}
#system .uf-row:hover .uf-thumb { transform: scale(1.06); }
#system .uf-date { letter-spacing: 0.14em; text-transform: uppercase; }
#system .uf-badge { border-radius: 4px; letter-spacing: 0.12em; }
#system .uf-badge-update { background: rgba(var(--blue-rgb), 0.1); color: var(--blue); border-color: rgba(var(--blue-rgb), 0.28); }
#system .uf-title {
  font-family: var(--display);
  font-variation-settings: 'opsz' 36;
  font-weight: 500;
  font-size: clamp(15px, 1.6vw, 20px);
  letter-spacing: -0.012em;
  white-space: normal;
  overflow: visible;
  line-height: 1.25;
}
#system .uf-chevron { transition: transform 0.45s var(--e-soft), color 0.3s; }
#system .uf-row:hover .uf-chevron { color: var(--cyan); }

/* unroll instead of display:none — the grid-row trick keeps the
   two-column body intact while giving it a height to animate */
#system .uf-body {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) 0;
  grid-template-rows: 0fr;
  gap: 0 28px;
  opacity: 0;
  padding: 0 0 0 62px;
  /* only the bottom gap animates — transitioning the whole shorthand
     would make a breakpoint change slide the indent across too */
  transition: grid-template-rows 0.6s var(--e-soft), opacity 0.4s ease, padding-bottom 0.6s var(--e-soft);
}
#system .uf-body > * { min-height: 0; overflow: hidden; }
#system .uf-item.is-open .uf-body {
  grid-template-rows: 1fr;
  opacity: 1;
  padding-bottom: 30px;
}
#system .uf-item.is-open .uf-body,
#system .uf-item.is-wide.is-open .uf-body { grid-template-columns: minmax(0, 1fr) 0; }
#system .uf-item .uf-video-col { width: 0; opacity: 0; transition: opacity 0.4s ease; }
#system .uf-item.is-open .uf-video-col { width: auto; opacity: 1; }
#system .uf-item.is-open .uf-body { grid-template-columns: minmax(0, 1fr) 100px; }
#system .uf-item.is-wide.is-open .uf-body { grid-template-columns: minmax(0, 1fr) 240px; }
#system .uf-item--text.is-open .uf-body { grid-template-columns: minmax(0, 1fr); }

#system .uf-body-title {
  font-family: var(--display);
  font-variation-settings: 'opsz' 36;
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.012em;
  margin-bottom: 10px;
}
#system .uf-body-desc { font-size: 14.5px; line-height: 1.75; max-width: var(--read); }
#system .uf-bullets { max-width: var(--read); }
#system .uf-bullets li { padding-left: 18px; line-height: 1.65; }
#system .uf-bullets li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgba(var(--cyan-rgb), 0.5);
}
#system .uf-bullets li strong { color: var(--text); font-weight: 600; }
#system .uf-yt-link {
  border-radius: 6px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 10px;
  padding: 7px 12px;
  transition: border-color 0.3s, color 0.3s, background 0.3s;
}
#system .uf-yt-link:hover { border-color: rgba(var(--cyan-rgb), 0.5); color: var(--cyan); background: rgba(var(--cyan-rgb), 0.06); }
#system .uf-video-frame { border-radius: 8px; }

@media (max-width: 620px) {
  #system .uf-item.is-open .uf-body,
  #system .uf-item.is-wide.is-open .uf-body { grid-template-columns: minmax(0, 1fr); }
  #system .uf-body { padding-left: 0; }
}

/* ─────────────────────────────────────────────────────────────
   18 · SUSTAIN — the newsletter
   The last chamber. One statement, one line to type on. The box
   is gone; the field is a rule that lights when you touch it.
   ───────────────────────────────────────────────────────────── */
.newsletter { padding: var(--gap-l) 0 clamp(56px, 6vw, 86px); }
.newsletter::before { display: none; }
.newsletter .newsletter-inner { max-width: 760px; }
.newsletter h2 {
  font-size: clamp(38px, 6vw, 82px);
  line-height: 1.0;
  letter-spacing: -0.035em;
  margin-bottom: 20px;
}
.newsletter > .wrap > p, .newsletter-inner > p {
  font-size: clamp(15px, 1.5vw, 17.5px);
  line-height: 1.7;
  max-width: 46ch;
  margin: 0 auto 44px;
}
.newsletter-form {
  gap: 0;
  align-items: center;
  padding-bottom: 0;
  margin-bottom: 26px;
  position: relative;
}
/* the rule belongs to the field, not to the row — running it under the
   button made the button look like it was sitting on a shelf. It fills
   from the left on focus, the same gesture the buttons use. */
.newsletter-form input {
  background-color: transparent !important;
  background-image: linear-gradient(90deg, var(--cyan), var(--green));
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 1px;
  border: 0 !important;
  border-radius: 0;
  box-shadow: inset 0 -1px 0 var(--line) !important;
  padding: 16px 4px;
  font-size: clamp(16px, 1.7vw, 20px);
  font-family: var(--display);
  font-variation-settings: 'opsz' 36;
  color: var(--text);
  text-align: left;
  transition: background-size 0.7s var(--e-soft), box-shadow 0.4s var(--e-swift);
}
.newsletter-form input:focus { background-size: 100% 1px; outline: none; }
.newsletter-form input::placeholder { color: var(--text-faint); }
.newsletter-form .btn { border-radius: 8px; align-self: center; margin-left: 12px; flex-shrink: 0; }
.newsletter-tags { justify-content: center; gap: 8px; margin-bottom: 0; }
.newsletter .tag-label {
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: border-color 0.35s var(--e-swift), color 0.35s, background 0.35s, transform 0.35s var(--e-soft);
}
.newsletter .tag-label:hover { transform: translateY(-2px); border-color: rgba(var(--cyan-rgb), 0.4); color: var(--text-dim); }
.newsletter-note { margin-top: 22px; letter-spacing: 0.14em; text-transform: uppercase; font-size: 10px; }
.newsletter-confirm, .newsletter-error { border-radius: 10px; letter-spacing: 0.04em; }

/* ─────────────────────────────────────────────────────────────
   19 · END CARD — the footer
   Signs off with the line the hero opened with, at size.
   ───────────────────────────────────────────────────────────── */
footer {
  border-top: 0;
  padding: 0 0 46px;
  position: relative;
}
/* block-only padding: this element is also a .wrap and must keep the
   column's horizontal gutter */
.footer-sign {
  padding-top: clamp(40px, 4.4vw, 66px);
  padding-bottom: clamp(34px, 4vw, 56px);
  border-top: 1px solid var(--line-soft);
  text-align: center;
}
/* the sign-off follows the centred newsletter, so it centres too: left-aligned
   it leaves the right half of the column empty and reads as a stray paragraph */
.footer-line {
  font-family: var(--display);
  font-variation-settings: 'opsz' 96;
  font-weight: 500;
  font-size: clamp(28px, 4.4vw, 62px);
  line-height: 1.06;
  letter-spacing: -0.03em;
  color: var(--text);
  max-width: 26ch;
  margin-inline: auto;
  text-wrap: balance;
}
.footer-line em { font-style: italic; color: var(--text-faint); }

/* NOTE: the element carries .wrap .footer-row .footer-grid at once, and
   the legacy .footer-row is a centred flex column. Both live in this
   file, so the grid has to out-specify it rather than merely follow it —
   ordering alone broke this once already. */
.footer-row.footer-grid {
  display: grid;
  grid-template-columns: minmax(200px, 0.9fr) minmax(0, 1.3fr) auto;
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
  padding-top: clamp(32px, 3.4vw, 50px);
  border-top: 1px solid var(--line-soft);
  text-align: left;
}
.footer-brand .wordmark { color: var(--text); letter-spacing: 0.14em; }
.footer-tag { color: var(--text-faint); letter-spacing: 0.14em; text-transform: uppercase; font-size: 9.5px; margin-top: 14px; }
.footer-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(120px, max-content));
  gap: 12px 40px;
  justify-content: start;
  font-size: 13px;
  color: var(--text-dim);
}
.footer-links a {
  position: relative;
  width: max-content;
  transition: color 0.3s var(--e-swift);
}
.footer-links a::after {
  content: '';
  position: absolute;
  left: 0; bottom: -3px;
  width: 100%; height: 1px;
  background: var(--cyan);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.45s var(--e-soft);
}
.footer-links a:hover { color: var(--text); }
.footer-links a:hover::after { transform: scaleX(1); transform-origin: left; }
.footer-social { justify-content: flex-end; gap: 10px; }
.footer-social a {
  width: 42px; height: 42px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.015);
}
.footer-social svg { width: 17px; height: 17px; }
.footer-base {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding-top: 28px;
  margin-top: clamp(32px, 4vw, 52px);
  border-top: 1px solid var(--line-soft);
}
.copyright { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; }

/* ─────────────────────────────────────────────────────────────
   20 · OVERLAYS
   ───────────────────────────────────────────────────────────── */
.video-modal-backdrop, .impressum-backdrop { backdrop-filter: blur(14px) saturate(0.8); background: rgba(2, 3, 7, 0.9); }
.video-modal-frame { border-radius: 14px; box-shadow: var(--lift-3); }
.impressum-panel { border-radius: 20px 20px 0 0; box-shadow: var(--lift-3); }
.impressum-panel h2 { font-variation-settings: 'opsz' 48; letter-spacing: -0.02em; }
.cookie-banner { border-radius: 14px; box-shadow: var(--lift-3); background: rgba(10, 13, 23, 0.92); backdrop-filter: blur(16px); }
.cookie-btn-accept { border-radius: 8px; }
.cookie-btn-decline { border-radius: 8px; }

/* grain is a property of the lens, not of the page: it stays above
   every layer including the overlays, just quieter than before */
.grain { opacity: 0.035; }

/* ─────────────────────────────────────────────────────────────
   21 · RESPONSIVE
   The composition simplifies in three steps: the offset mosaic
   squares up, the split sections stack, the plane flattens.
   ───────────────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  #how .how-card:nth-child(1),
  #how .how-card:nth-child(2) { grid-column: span 6; }
  #how .how-card { grid-column: span 6; }
  #how .how-card:nth-child(6) { grid-column: span 12; }
  .chain { grid-template-columns: 1fr; }
  .manifesto-cols { grid-template-columns: 1fr; }
  .lic { grid-template-columns: 1fr; }
  .lic-face { border-right: 0; border-bottom: 1px solid rgba(140, 160, 220, 0.1); }
  .footer-row.footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-social { grid-column: 1 / -1; justify-content: flex-start; }
}
@media (max-width: 880px) {
  .stats { grid-template-columns: repeat(2, 1fr); row-gap: clamp(24px, 5vw, 44px); }
  .stat, .stat:first-child, .stat:nth-child(odd) { padding-left: 22px; }
  #how .how-card:nth-child(6) { grid-template-columns: 1fr; }
  #how .how-card:nth-child(6) .mpe-anim { grid-column: 1; min-height: 0; aspect-ratio: 16 / 6; }
  #how .how-card:nth-child(6) figcaption { grid-column: 1; grid-row: 3; border-left: 0; border-top: 1px solid rgba(140, 160, 220, 0.09); }
  #how .tech-item { grid-template-columns: 56px 1fr; row-gap: 8px; }
  #how .tech-item p { grid-column: 2; }
  .cinema-frame { clip-path: inset(calc((1 - var(--iris)) * 24%) 0 calc((1 - var(--iris)) * 24%) 0 round calc(var(--iris) * 12px)); }
}
@media (max-width: 680px) {
  #how .how-card,
  #how .how-card:nth-child(1),
  #how .how-card:nth-child(2) { grid-column: span 12; }
  .newsletter-form { flex-direction: column; align-items: stretch; }
  .newsletter-form input { text-align: center; }
  .newsletter-form .btn { margin-left: 0; margin-top: 18px; }
  .footer-row.footer-grid { grid-template-columns: 1fr; }
  .footer-links { grid-template-columns: repeat(2, minmax(110px, 1fr)); }
  .lic-face, .lic-spec { padding: 26px 22px; }
}

/* ─────────────────────────────────────────────────────────────
   22 · REDUCED MOTION
   Everything still arrives, it just arrives already there.
   ───────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .rail-fill { transition: none; }
  .cinema-frame { clip-path: none; }
  .cinema .yt-stage { transform: none; }
  #modules .mh-stage { transform: none; }
  .screening-stage .yt-stage { transform: none; }
  .screening-stage::before, .screening-stage::after { filter: none; opacity: 0.5; }
  #heroCanvas, .hero-content, .hero-telemetry { transform: none; opacity: 1; }
  .chamber::after { transform: scaleX(1); opacity: 1; }
  [data-tilt].is-hot { transform: none; }
  .manifesto-text .w, .chain-read .how-cap .w { opacity: 1; }
}
