/* ═══════════════════════════════════════════════════════════════════════
   SAMBIT — Portfolio for CERN IPT-PLS-2026-184-LD
   Aperture concept: observation → aperture → clarity
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1 · TOKENS ──────────────────────────────────────────────────────── */
:root{
  /* palette — sampled from the source photograph */
  --void:       #060607;
  --void-lift:  #111114;
  --paper:      #F2F1ED;
  --paper-2:    #EAE9E4;
  --paper-pure: #FFFFFF;
  --ink:        #0B0D10;
  --ink-soft:   #5A6068;
  --rule:       #D8D6D0;
  --beam:       #1B4DFF;
  --beam-deep:  #0A2A9E;
  --flare:      #E8A055;

  /* type */
  --f-display: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-body:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
  --f-serif:   'Instrument Serif', Georgia, 'Times New Roman', serif;

  --t-hero:    clamp(3.5rem, 11vw, 12rem);
  --t-display: clamp(2.5rem, 8vw,  8rem);
  --t-h2:      clamp(2rem,   5vw,  4rem);
  --t-h3:      clamp(1.35rem, 2.4vw, 2rem);
  --t-lead:    clamp(1.05rem, 1.6vw, 1.35rem);
  --t-body:    clamp(1rem,   1.1vw, 1.125rem);
  --t-mono:    clamp(.6875rem, .8vw, .8125rem);

  /* layout */
  --gut:  clamp(1.25rem, 5vw, 6rem);
  --max:  1440px;
  --sec:  clamp(6rem, 14vh, 11rem);

  /* Iris centre — single source of truth for the aperture; script.js reads
     these back rather than keeping its own copy.
     Fitted from the limbus (iris/sclera boundary) on the source photograph:
     sub-pixel edges across 18 scanlines, chord midpoints give centre x, and
     the parabola w² = r² − (y−cy)² through those chords gives centre y.
     Iris ⌀ 69.7px, centre (1365.8, 291.3) at 1672×941. See BUILD-PLAN §23. */
  --iris-x: 81.69%;
  --iris-y: 30.96%;

  --e-out:  cubic-bezier(.16,1,.3,1);
  --e-soft: cubic-bezier(.33,1,.68,1);
}

/* ── 2 · RESET ───────────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0 }

/* No `scroll-behavior:smooth` here — it fights Lenis, which owns smoothing.
   The reduced-motion block re-asserts `auto` for the same reason. */
html{ -webkit-text-size-adjust:100% }

body{
  font-family:var(--f-body);
  font-size:var(--t-body);
  line-height:1.65;
  color:var(--ink);
  background:var(--void);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  /* `clip`, not `hidden`. overflow-x:hidden turns <body> into a scroll
     container, which breaks position:sticky and ScrollTrigger's scroller
     detection. `clip` trims the same overflow without doing that. */
  overflow-x:clip;
  font-feature-settings:'kern' 1,'liga' 1;
}

img,picture,video{ display:block; max-width:100% }
ul,ol{ list-style:none }
a{ color:inherit; text-decoration:none }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer }
h1,h2,h3{ font-family:var(--f-display); font-weight:700; letter-spacing:-.03em; line-height:1 }
strong,b{ font-weight:600 }

::selection{ background:var(--beam); color:#fff }

.mono{
  font-family:var(--f-mono);
  font-size:var(--t-mono);
  font-weight:400;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.5;
}

.wrap{ width:100%; max-width:var(--max); margin-inline:auto; padding-inline:var(--gut) }

.visually-hidden{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

.skip{
  position:fixed; top:0; left:0; z-index:999;
  padding:.85rem 1.4rem; background:var(--beam); color:#fff;
  font-family:var(--f-mono); font-size:.75rem; letter-spacing:.12em; text-transform:uppercase;
  transform:translateY(-110%);
}
.skip:focus{ transform:translateY(0) }

:focus-visible{ outline:2px solid var(--beam); outline-offset:3px; border-radius:2px }
.arrival :focus-visible,.foot :focus-visible,.panel :focus-visible{ outline-color:var(--flare) }

/* ── 2b · GLASS UTILITY BAR ──────────────────────────────────────────── */
/* Translucent dark glass with white type reads on BOTH grounds — over the
   near-black hero and over the paper sections — so it needs no scroll-driven
   theme switching. The hairline border and inner highlight are what make it
   legible on dark; the tint and shadow are what make it legible on light. */
.glass{
  position:fixed; z-index:180;
  top:clamp(1rem,2.2vw,1.6rem); left:clamp(1rem,2.2vw,1.6rem);
  display:flex; align-items:center; gap:.15rem;
  padding:.3rem;
  border-radius:999px;
  background:rgba(18,22,28,.42);
  border:1px solid rgba(255,255,255,.20);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.28),
    inset 0 -1px 0 rgba(255,255,255,.06),
    0 6px 28px rgba(0,0,0,.34);
  -webkit-backdrop-filter:blur(22px) saturate(180%);
  backdrop-filter:blur(22px) saturate(180%);
}
/* no blur support → lean on opacity so it never becomes an unreadable slab */
@supports not (backdrop-filter:blur(2px)){
  .glass{ background:rgba(12,15,20,.82) }
}

.glass__item{
  display:inline-flex; align-items:center; gap:.5rem;
  padding:.52rem .9rem; border-radius:999px;
  font-family:var(--f-mono); font-size:.72rem;
  letter-spacing:.1em; text-transform:uppercase;
  color:rgba(255,255,255,.92); white-space:nowrap;
  transition:background .3s var(--e-soft), color .3s var(--e-soft);
}
.glass__item svg{
  width:15px; height:15px; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
.glass__sep{ width:1px; height:18px; background:rgba(255,255,255,.16) }

@media (hover:hover){
  .glass__item:hover{ background:rgba(255,255,255,.16); color:#fff }
}
.glass__item:focus-visible{ outline:2px solid #fff; outline-offset:2px }

@media (max-width:560px){
  .glass{ gap:0; padding:.25rem }
  .glass__item{ padding:.5rem .62rem }
  .glass__item span{ display:none }   /* icons only on small screens */
  .glass__sep{ display:none }
}

/* ── 2c · BACK TO TOP ────────────────────────────────────────────────── */
/* Same glass as the utility bar, opposite corner. Hidden until the reader is
   genuinely deep in the page, because 28 screens is a long scroll back. */
.totop{
  position:fixed; z-index:180;
  right:clamp(1rem,2.2vw,1.6rem); bottom:clamp(1rem,2.2vw,1.6rem);
  display:inline-flex; align-items:center; gap:.5rem;
  padding:.62rem 1rem; border-radius:999px;
  background:rgba(18,22,28,.42);
  border:1px solid rgba(255,255,255,.20);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.28),
    0 6px 28px rgba(0,0,0,.34);
  -webkit-backdrop-filter:blur(22px) saturate(180%);
  backdrop-filter:blur(22px) saturate(180%);
  color:rgba(255,255,255,.92);
  font-size:.72rem; letter-spacing:.1em; text-transform:uppercase;
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity .4s var(--e-soft), transform .4s var(--e-soft), visibility .4s;
}
.totop--on{ opacity:1; visibility:visible; transform:translateY(0) }
.totop svg{
  width:14px; height:14px; fill:none; stroke:currentColor;
  stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round;
}
@supports not (backdrop-filter:blur(2px)){ .totop{ background:rgba(12,15,20,.86) } }
@media (hover:hover){ .totop:hover{ background:rgba(255,255,255,.18); color:#fff } }
.totop:focus-visible{ outline:2px solid #fff; outline-offset:3px }
@media (max-width:560px){ .totop span{ display:none } .totop{ padding:.68rem } }

/* ── 3 · GRAIN + PROGRESS RAIL ───────────────────────────────────────── */
.grain{
  position:fixed; inset:-120%; z-index:200; pointer-events:none;
  opacity:.05; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1s steps(8) infinite;
}
@keyframes grain{
  0%{transform:translate(0,0)}        12.5%{transform:translate(-3%,-4%)}
  25%{transform:translate(-6%,2%)}    37.5%{transform:translate(3%,-5%)}
  50%{transform:translate(-2%,6%)}    62.5%{transform:translate(-6%,-2%)}
  75%{transform:translate(5%,3%)}     87.5%{transform:translate(-3%,5%)}
  100%{transform:translate(0,0)}
}

.rail{
  position:fixed; top:0; right:0; width:2px; height:100vh;
  z-index:150; background:rgba(90,96,104,.18);
}
.rail__fill{
  display:block; width:100%; height:100%; background:var(--beam);
  transform:scaleY(0); transform-origin:top;
}

/* ═══ 00 · APERTURE ═══════════════════════════════════════════════════ */
/* Base state is a single static frame — that is what a visitor gets if the
   motion layer never arrives. The tall scrub container is opt-in via .js. */
.aperture{ height:auto; position:relative; background:var(--void) }
.aperture__stage{
  position:relative; height:88svh; overflow:hidden;
  background:var(--void);
}
.js .aperture{ height:500vh }
.js .aperture__stage{ position:sticky; top:0; height:100svh }

.aperture__media,
.aperture__media img{ position:absolute; inset:0; width:100%; height:100% }

/* transform-origin sits on the pupil, so that point stays pinned while the
   image scales; a parallel translate then walks it to the centre of the
   frame, so the flood happens centre-screen instead of off in a corner.
   No `will-change` here on purpose — a permanent one keeps a full-viewport
   layer allocated for the whole session. GSAP promotes during the tween. */
.aperture__media img{
  object-fit:cover;
  object-position:var(--iris-x) var(--iris-y);
  transform-origin:var(--iris-x) var(--iris-y);
}

/* Tunnel vignette — tightens on push-in. Centred, like the pupil, because
   the image drifts to centre; by the time the falloff is strong enough to
   read, the eye is already there. */
.aperture__vignette{
  position:absolute; inset:0; pointer-events:none; opacity:.3;
  background:radial-gradient(circle at 50% 50%,
             transparent 18%, rgba(6,6,7,.5) 56%, rgba(6,6,7,.92) 95%);
}

/* THE COLLIDER — dilates out of the pupil before the flood.
   Sized in vmin with negative margins so the scroll tween is pure scale. */
.aperture__reactor{
  position:absolute; top:50%; left:50%;
  width:78vmin; height:78vmin; margin:-39vmin 0 0 -39vmin;
  opacity:0; transform:scale(.3);
}
.aperture__reactor svg{ width:100%; height:100%; overflow:visible }
.rx{ transform-origin:100px 100px; animation:rx 34s linear infinite }
.rx--ccw{ animation-direction:reverse }
.rx--cw{ animation-duration:52s }
@keyframes rx{ to{ transform:rotate(360deg) } }

/* the dilating pupil — a soft light disc, pure transform */
.aperture__pupil{
  position:absolute; top:50%; left:50%;
  width:100vmax; height:100vmax; margin:-50vmax 0 0 -50vmax;
  border-radius:50%;
  background:radial-gradient(circle,
             var(--paper-pure) 0 16%,
             rgba(255,255,255,.94) 32%,
             rgba(255,255,255,.62) 52%,
             rgba(255,255,255,.24) 72%,
             rgba(255,255,255,0) 88%);
  transform:scale(0);
}

/* final flood */
.aperture__bloom{
  position:absolute; inset:0; background:var(--paper-pure);
  opacity:0;
}

/* — hero type — */
.aperture__type{
  position:absolute; inset:0; z-index:5;
  padding:clamp(1.5rem,4vw,3.5rem) var(--gut);
  display:flex; flex-direction:column; justify-content:flex-end;
  color:var(--paper);
}

.aperture__name{
  font-size:var(--t-hero);
  line-height:.86;
  letter-spacing:-.045em;
  text-transform:uppercase;
}
.rvl{ display:block; overflow:hidden; padding-bottom:.04em }
.rvl > span{ display:block }
.js .rvl > span{ transform:translateY(105%) }
/* word-level mask boxes sit inline so the line still wraps naturally */
.rvl--w{ display:inline-block; vertical-align:top }
.rvl--w > span{ display:inline-block }

.aperture__role{
  margin-top:1.25rem;
  color:var(--flare);
}

.aperture__scroll{
  position:absolute; right:var(--gut); bottom:clamp(1.5rem,4vw,3.5rem);
  display:flex; align-items:center; gap:.75rem;
  color:rgba(242,241,237,.5);
}
.aperture__scroll i{
  display:block; width:1px; height:26px;
  background:linear-gradient(to bottom,transparent,rgba(242,241,237,.7));
  animation:drop 2s var(--e-soft) infinite;
}
@keyframes drop{
  0%{transform:scaleY(0); transform-origin:top}
  45%{transform:scaleY(1); transform-origin:top}
  55%{transform:scaleY(1); transform-origin:bottom}
  100%{transform:scaleY(0); transform-origin:bottom}
}

/* ═══ 01 · THESIS ═════════════════════════════════════════════════════ */
.thesis{
  position:relative; z-index:2;
  background:var(--paper);
  min-height:100svh;
  display:flex; align-items:center;
  padding-block:var(--sec);
}

.thesis__line{
  font-size:var(--t-display);
  letter-spacing:-.035em;
  line-height:.95;
  max-width:16ch;
}

.thesis__body{
  margin-top:clamp(2.5rem,6vw,5rem);
  max-width:58ch;
  margin-left:auto;
  font-size:var(--t-lead);
  color:var(--ink-soft);
}
.thesis__body p + p{ margin-top:1.4em }
.thesis__body em{ font-style:normal; font-weight:600; color:var(--beam) }

/* ═══ 02 · INSTRUMENT PANEL ═══════════════════════════════════════════ */
.panel{
  position:relative; z-index:2;
  background:var(--void); color:var(--paper);
  padding-block:clamp(4rem,9vh,7rem);
}

.panel__grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  border-top:1px solid rgba(242,241,237,.14);
}
.panel__cell{
  padding:clamp(1.75rem,3.5vw,2.75rem) clamp(1rem,2vw,2rem) clamp(1.75rem,3.5vw,2.75rem) 0;
  border-bottom:1px solid rgba(242,241,237,.14);
  border-right:1px solid rgba(242,241,237,.14);
}
.panel__cell:nth-child(3n){ border-right:0 }

.panel__fig{
  display:block;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(2.75rem,6vw,5rem);
  line-height:.9; letter-spacing:-.045em;
  font-variant-numeric:tabular-nums;
}
.panel__cell--flare .panel__fig{ color:var(--flare) }

.panel__lbl{
  display:block; margin-top:1rem;
  color:rgba(242,241,237,.5);
  max-width:26ch;
}

.panel__note{
  margin-top:2rem; color:rgba(242,241,237,.32);
}

/* ═══ 02b · THE UNBROKEN TAKE ════════════════════════════════════════
   Seven rooms sharing one sticky stage. Scroll drives a single progress
   value; each room owns a band of it and scrubs its own clip.
   ═══════════════════════════════════════════════════════════════════ */
/* Base state is a plain stack of full-height rooms, each showing its poster.
   That is what a visitor gets with motion reduced or the CDN blocked — the
   scrubbing rig is opt-in via .js, so the film degrades to a photo essay
   instead of 1040vh of blank page. */
.film{ position:relative; z-index:2; background:var(--paper); height:auto }
.film__stage{ position:relative; height:auto; background:var(--paper) }
.room{ position:relative; height:100svh; display:grid; place-items:center }

/* one band per room — keep this count in step with the markup */
.js .film{ height:calc(8 * 130vh) }
.js .film__stage{ position:sticky; top:0; height:100svh; overflow:hidden }
.js .room{ position:absolute; inset:0; height:auto; opacity:0; visibility:hidden }
.js .room--on{ visibility:visible }

/* The clips are framed with deliberate dead space for type, so they must be
   shown whole — cover would crop exactly the margins the words live in.
   Edges feather out so the letterboxing never reads as a boundary. */
.room__media{ position:absolute; inset:0; display:grid; place-items:center }
.room__media video{
  width:100%; aspect-ratio:16/9; max-height:100%; object-fit:cover;
  -webkit-mask-image:
    linear-gradient(to right,  transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 6%, #000 94%, transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(to right,  transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-composite:intersect;
}
/* rooms 06–07 are dark industrial — the page ground behind them must not
   glow white through the feathered edge */
.room--invert{ background:#10151b }
.room--invert .room__media video{
  -webkit-mask-image:none; mask-image:none;
}

.room__type{
  position:relative; z-index:2;
  width:100%; max-width:var(--max); height:100%;
  padding:clamp(2rem,5vw,4rem) var(--gut);
  display:flex; flex-direction:column; align-items:flex-start;
  gap:clamp(.75rem,1.6vw,1.5rem);
  pointer-events:none;
}
/* Each room frames its subject differently, so no single type position clears
   every one of them. A soft top scrim guarantees legibility over whatever is
   behind without reading as a panel — it just lifts the ground a little. */
.room__type::before{
  content:''; position:absolute; inset:0 0 auto 0; height:52%;
  z-index:-1; pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(242,241,237,.94) 0%, rgba(242,241,237,.72) 42%, rgba(242,241,237,0) 100%);
}
.room--dark .room__type::before,
.room--invert .room__type::before{
  background:linear-gradient(to bottom,
    rgba(8,11,15,.80) 0%, rgba(8,11,15,.48) 42%, rgba(8,11,15,0) 100%);
}

.room__no{ color:var(--beam); opacity:.75 }
.room__title{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(2.25rem,7vw,6.5rem); line-height:.92;
  letter-spacing:-.04em; text-transform:uppercase;
  color:var(--ink); max-width:14ch;
}
.room__line{
  max-width:44ch; font-size:clamp(.9rem,1.15vw,1.125rem);
  line-height:1.55; color:var(--ink-soft);
  text-wrap:pretty;
}

/* ── room 01: the opening statement ──────────────────────────────────
   Columns are set to the margins the shot actually leaves — measured at
   17.8% left and 17.6% right on the opening frame — so the data sits in
   the white either side of the players rather than on top of them. */
/* The clip's clear margin is 17.8% of the FULL frame width. The standard
   section padding would push these columns inward past that safe zone and
   onto the players, so this room uses a much tighter inline padding and
   columns sized to land inside the white. */
.room__type--open{
  display:grid;
  grid-template-columns:16% minmax(0,1fr) 16%;
  grid-template-rows:auto auto 1fr;
  column-gap:clamp(.75rem,1.5vw,2rem);
  align-items:start;
  padding-inline:clamp(.75rem,1.5vw,1.5rem);
}
.room__type--open .room__no{ grid-column:1/-1; grid-row:1; justify-self:center }
.room__title--mid{
  grid-column:1/-1; grid-row:2;
  text-align:center; justify-self:center; max-width:none;
  margin-bottom:clamp(1rem,3vh,2.5rem);
}

.fig{ grid-column:1; grid-row:3; display:flex; flex-direction:column; gap:clamp(.6rem,1.7vh,1.35rem) }
.fig li{ display:flex; flex-direction:column; gap:.15rem }
.fig__n{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.35rem,2.6vw,2.5rem); line-height:1;
  letter-spacing:-.035em; color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.fig li:first-child .fig__n{ color:var(--flare) }
.fig__n--word{ font-size:clamp(1.1rem,2vw,1.9rem); letter-spacing:-.02em }
.fig__l{
  font-style:normal; color:var(--ink-soft);
  font-size:clamp(.5rem,.62vw,.6875rem); line-height:1.35;
  letter-spacing:.09em; text-transform:uppercase;
}

/* The figures opposite get their presence from scale contrast — a large
   numeral over a tiny label. A flat stack of seven equal lines has none, so
   this column earns its own structure instead: an indexed editorial list
   where each rule draws in from the right and the word rises under it. */
/* ── room 02: headline centred, argument left, systems right ────────── */
/* Room 02's shot leaves ~39% clear on each side — far more than room 01 —
   so both columns get real width here. */
.room__type--sys{
  display:grid;
  grid-template-columns:32% minmax(0,1fr) 34%;
  grid-template-rows:auto auto 1fr;
  column-gap:clamp(.5rem,1vw,1.25rem);
  align-items:start;
  padding-inline:clamp(.75rem,1.5vw,1.5rem);
}
.room__type--sys .room__no{ grid-column:1/-1; grid-row:1; justify-self:center }
.room__type--sys .room__title--mid{ grid-column:1/-1; grid-row:2 }

/* ── left: the criteria, as a list rather than a sentence ───────────── */
.argue{ grid-column:1; grid-row:3; display:flex; flex-direction:column; gap:clamp(.7rem,1.8vh,1.2rem) }
.argue__lead{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1rem,1.85vw,1.8rem); line-height:1.06;
  letter-spacing:-.03em; color:var(--ink);
}
.argue__list{ display:flex; flex-direction:column }
.argue__list li{
  --rw:1;
  position:relative; display:flex; align-items:baseline; gap:.7rem;
  padding:clamp(.22rem,.8vh,.5rem) 0;
}
.argue__list li::before{
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background:var(--rule); transform:scaleX(var(--rw)); transform-origin:left;
}
.js .argue__list li{ --rw:0 }
.argue__list i{
  font-style:normal; color:var(--beam); opacity:.7; flex:none;
  font-size:clamp(.46rem,.56vw,.625rem); letter-spacing:.1em;
}
.argue__list span{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(.75rem,1.1vw,1.05rem); letter-spacing:-.015em;
  color:var(--ink); white-space:nowrap;
}
.argue__kick{
  margin-top:.35rem; padding-left:clamp(.6rem,1vw,1rem);
  border-left:2px solid var(--flare);
  font-size:clamp(.78rem,1.05vw,1rem); line-height:1.45;
  color:var(--ink); max-width:26ch;
}

/* ── shared split layout, rooms 04–07 ───────────────────────────────
   One pattern rather than four bespoke ones: statement left, indexed list
   right, headline centred across the top. Colour inverts automatically in
   the dark rooms via .room--invert. */
.room__type--split{
  display:grid;
  grid-template-columns:30% minmax(0,1fr) 30%;
  grid-template-rows:auto auto 1fr;
  column-gap:clamp(.5rem,1vw,1.25rem);
  align-items:start;
  padding-inline:clamp(.75rem,1.5vw,1.5rem);
}
.room__type--split .room__no{ grid-column:1/-1; grid-row:1; justify-self:center }
.room__type--split .room__title--mid{ grid-column:1/-1; grid-row:2 }

.rlead{
  grid-column:1; grid-row:3;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(.85rem,1.55vw,1.5rem); line-height:1.12;
  letter-spacing:-.028em; color:var(--ink);
}
.rlead em{ font-style:normal; color:var(--beam) }
/* room 04 carries a statement instead of a list, so it is set larger */
.rlead--big{ font-size:clamp(1.05rem,2.05vw,2rem); line-height:1.06 }
/* keeps the statement and its kicker as one block, high in the frame — room
   04's foreground shoulder owns everything below about a third of the height */
.rblock{ grid-column:1; grid-row:3; display:flex; flex-direction:column }
.rlead__sub{
  margin-top:clamp(.5rem,1.4vh,.9rem);
  padding-left:clamp(.6rem,1vw,1rem);
  border-left:2px solid var(--flare);
  font-size:clamp(.75rem,1.02vw,.98rem); line-height:1.45;
  color:var(--ink); max-width:24ch;
}
.room--invert .rlead{ color:var(--paper-pure) }
.room--invert .rlead em{ color:var(--flare) }

.rlist{ grid-column:3; grid-row:3; display:flex; flex-direction:column }
.rlist li{
  --rw:1;
  position:relative; display:flex; align-items:baseline; gap:.55rem;
  padding:clamp(.18rem,.7vh,.45rem) 0;
}
.rlist li::before{
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background:var(--rule); transform:scaleX(var(--rw)); transform-origin:left;
}
.room--invert .rlist li::before{ background:rgba(242,241,237,.22) }
.js .rlist li{ --rw:0 }

.rlist i{
  font-style:normal; color:var(--beam); opacity:.75; flex:none;
  font-size:clamp(.44rem,.54vw,.6rem); letter-spacing:.1em;
}
.room--invert .rlist i{ color:var(--flare); opacity:.85 }
.rlist b{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(.68rem,1.02vw,1rem); line-height:1.15;
  letter-spacing:-.015em; color:var(--ink); white-space:nowrap;
}
.room--invert .rlist b{ color:var(--paper-pure) }

/* the finale carries ten points, so it runs two columns — filled
   column-first so 01–05 read down the left, 06–10 down the right */
.rlist--two{
  display:grid; grid-auto-flow:column;
  grid-template-rows:repeat(5,auto); grid-template-columns:1fr 1fr;
  column-gap:clamp(.75rem,1.6vw,1.75rem);
}
.room__type--final{ grid-template-columns:26% minmax(0,1fr) 40% }

/* Rooms 04 and 05 keep their subject centre-to-right with dark foreground on
   that side, so a right-hand list lands dark-on-dark. Both those shots hold
   their LEFT clear — window in 04, pale wall in 05 — so the content stacks
   there instead of splitting. Placement follows each frame, not a template. */
.room__type--stack{
  grid-template-columns:36% minmax(0,1fr);
  grid-template-rows:auto auto auto 1fr;   /* own row, not a margin guess */
}
.room__type--stack .room__no,
.room__type--stack .room__title--mid{ grid-column:1/-1 }
.room__type--stack .rlead{ grid-column:1; grid-row:3 }
.room__type--stack .rlist{
  grid-column:1; grid-row:4;
  margin-top:clamp(.9rem,2.4vh,1.8rem);
}

@media (max-width:900px){
  .room__type--split,
  .room__type--final{ grid-template-columns:1fr; grid-template-rows:auto auto auto auto }
  .rlead{ grid-column:1; grid-row:3 }
  .rlist{ grid-column:1; grid-row:4; margin-top:1rem }
  .rlist--two{ grid-template-rows:repeat(5,auto) }
  .rlist b{ font-size:.8rem }
}

/* ── room 03: the contract sits centre, dark desk either side ────────
   The clip's own tabs are the design here — the list markers are the same
   amber flags he is placing in the footage, and they slide in from the page
   edge exactly as a real tab does. */
.room__type--clause{
  display:grid;
  grid-template-columns:26% minmax(0,1fr) 27%;
  grid-template-rows:auto auto 1fr;
  column-gap:clamp(.5rem,1vw,1.25rem);
  align-items:start;
  padding-inline:clamp(.75rem,1.5vw,1.5rem);
}
.room__type--clause .room__no{ grid-column:1/-1; grid-row:1; justify-self:center }
.room__type--clause .room__title--mid{ grid-column:1/-1; grid-row:2 }

.clause__lead{
  grid-column:1; grid-row:3;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(.95rem,1.75vw,1.7rem); line-height:1.08;
  letter-spacing:-.03em; color:var(--paper-pure);
}
.clause__lead em{ font-style:normal; color:var(--flare) }

.clause__list{ grid-column:3; grid-row:3; display:flex; flex-direction:column }
.clause__list li{
  --rw:1;
  position:relative; display:flex; align-items:baseline; gap:.55rem;
  padding:clamp(.22rem,.85vh,.52rem) 0 clamp(.22rem,.85vh,.52rem) .1rem;
}
.clause__list li::after{
  content:''; position:absolute; bottom:0; left:0; right:0; height:1px;
  background:rgba(242,241,237,.22);
  transform:scaleX(var(--rw)); transform-origin:left;
}
.js .clause__list li{ --rw:0 }

/* the tab itself — a small amber flag protruding from the left edge */
.clause__tab{
  flex:none; width:clamp(9px,.95vw,14px); height:clamp(5px,.55vw,8px);
  background:var(--flare); border-radius:1px;
  transform:translateX(-14px); opacity:0;
  transition:transform .5s var(--e-out), opacity .4s var(--e-soft);
  align-self:center;
}
.clause__list li.is-on .clause__tab{ transform:translateX(0); opacity:1 }

.clause__list i{
  font-style:normal; color:rgba(242,241,237,.55); flex:none;
  font-size:clamp(.46rem,.56vw,.625rem); letter-spacing:.1em;
}
.clause__list b{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(.72rem,1.1vw,1.05rem); line-height:1.15;
  letter-spacing:-.015em; color:var(--paper-pure); white-space:nowrap;
}

@media (max-width:900px){
  .room__type--clause{ grid-template-columns:1fr; grid-template-rows:auto auto auto auto }
  .clause__lead{ grid-column:1; grid-row:3 }
  .clause__list{ grid-column:1; grid-row:4; margin-top:1rem }
  .clause__list b{ font-size:.82rem }
}

/* ── right: systems, each arriving somewhere new ────────────────────── */
.sys{ grid-column:3; grid-row:3; position:relative; align-self:stretch; min-height:clamp(180px,42vh,360px) }
.sys__count{
  position:absolute; top:0; right:0; z-index:2;
  color:var(--ink-soft); font-variant-numeric:tabular-nums;
}
.sys__count b{ color:var(--beam); font-weight:500 }
.sys__count span{ opacity:.55 }

.sys__list{ position:absolute; inset:clamp(1.6rem,4vh,2.6rem) 0 0 0 }
/* Each item owns a coordinate, so the toolset scatters across the space
   instead of flickering in one spot — the eye has to travel to find each
   one, which is what makes the sequence feel alive rather than a slideshow. */
.sys__item{
  position:absolute; left:var(--x); top:var(--y);
  display:flex; flex-direction:column; align-items:center; gap:.5rem;
  opacity:0;
  transform:translate(-50%,calc(-50% + var(--dy))) scale(.9);
  transition:opacity .5s var(--e-soft), transform .6s var(--e-out);
}
.sys__item--on{ opacity:1; transform:translate(-50%,-50%) scale(1) }

.sys__item:nth-child(1){ --x:26%; --y:16%; --dy: 22px }
.sys__item:nth-child(2){ --x:70%; --y:30%; --dy:-20px }
.sys__item:nth-child(3){ --x:32%; --y:52%; --dy: 24px }
.sys__item:nth-child(4){ --x:74%; --y:66%; --dy: 18px }
.sys__item:nth-child(5){ --x:24%; --y:82%; --dy:-22px }
.sys__item:nth-child(6){ --x:62%; --y:12%; --dy: 20px }
.sys__item:nth-child(7){ --x:30%; --y:34%; --dy:-18px }
.sys__item:nth-child(8){ --x:72%; --y:48%; --dy: 22px }
.sys__item:nth-child(9){ --x:38%; --y:70%; --dy:-24px }
.sys__item:nth-child(10){ --x:66%; --y:86%; --dy: 18px }

.sys__item svg{
  width:clamp(24px,2.9vw,36px); height:clamp(24px,2.9vw,36px);
  fill:none; stroke:var(--beam); stroke-width:1.3;
  stroke-linecap:round; stroke-linejoin:round;
}
.sys__item span{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(.72rem,1.15vw,1.15rem); line-height:1.1;
  letter-spacing:-.02em; text-transform:uppercase;
  color:var(--ink); text-align:center; white-space:nowrap;
}

@media (max-width:900px){
  .room__type--sys{ grid-template-columns:1fr; grid-template-rows:auto auto auto auto }
  .argue{ grid-column:1; grid-row:3 }
  .sys{ grid-column:1; grid-row:4; min-height:120px; margin-top:1rem }
  .sys__list{ inset:1.6rem 0 0 0 }
  /* no room to scatter on a phone — centre them and let them cross-fade */
  .sys__item{ --x:50% !important; --y:50% !important }
  .sys__item span{ font-size:.85rem }
}

.prac{ grid-column:3; grid-row:3; display:flex; flex-direction:column }
.prac li{
  --rw:1;                       /* rule width, animated 0 → 1 */
  position:relative;
  display:flex; align-items:baseline; justify-content:space-between;
  gap:.6rem; padding:clamp(.3rem,.95vh,.62rem) 0;
}
.prac li::before{
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background:var(--rule);
  transform:scaleX(var(--rw)); transform-origin:right;
}
.js .prac li{ --rw:0 }

.prac__n{
  font-style:normal; color:var(--beam); opacity:.7;
  font-size:clamp(.46rem,.56vw,.625rem); letter-spacing:.1em;
  flex:none;
}
.prac__w{ display:block; overflow:hidden; padding-bottom:.06em }
.prac__w b{
  display:block;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(.76rem,1.22vw,1.2rem); line-height:1.1;
  letter-spacing:-.02em; text-transform:uppercase;
  color:var(--ink); white-space:nowrap;
}
.js .prac__w b{ transform:translateY(110%) }

@media (max-width:900px){
  /* the shot's side margins are too narrow in px on a phone — stack instead */
  .room__type--open{ grid-template-columns:1fr; grid-template-rows:auto auto auto auto }
  .room__title--mid{ margin-bottom:1.25rem }
  .fig,.prac{ grid-column:1 }
  .fig{ grid-row:3; display:grid; grid-template-columns:repeat(2,1fr); gap:.75rem 1rem }
  .prac{ grid-row:4; margin-top:1rem }
  .prac li{ padding:.3rem 0 }
  .prac__w b{ font-size:.82rem }
}

/* room 03 opens top-down on the desk: no clear top band, but a big dark
   field — so its type reverses out instead */
.room--dark .room__title,
.room--invert .room__title{ color:var(--paper-pure) }
.room--dark .room__line,
.room--invert .room__line{ color:rgba(242,241,237,.82) }
.room--dark .room__no,
.room--invert .room__no{ color:var(--flare); opacity:.9 }

/* progress through the film, distinct from the page rail */
.film__rail{
  display:none;
  position:absolute; left:var(--gut); bottom:clamp(1.5rem,4vw,3rem);
  width:clamp(80px,12vw,160px); height:2px;
  background:rgba(90,96,104,.25); z-index:3;
}
.js .film__rail{ display:block }
.film__railFill{
  display:block; width:100%; height:100%; background:var(--beam);
  transform:scaleX(0); transform-origin:left;
}
.room--invert ~ .film__rail .film__railFill{ background:var(--flare) }

/* ═══ 02c · THE SUPPLY BASE ══════════════════════════════════════════ */
.marq{
  position:relative; z-index:2;
  background:var(--paper);
  padding-block:clamp(3.5rem,9vh,6.5rem);
  overflow:hidden;
}
.marq__h{
  font-size:clamp(1.5rem,3.6vw,2.75rem); letter-spacing:-.03em;
  line-height:1.04; max-width:18ch;
}
.marq__sub{
  margin-top:1rem; max-width:58ch;
  color:var(--ink-soft); font-size:var(--t-body);
  text-wrap:pretty;
}
.marq__sub strong{ color:var(--ink); font-weight:600 }

.marq__vp{
  margin-top:clamp(2rem,5vw,3.5rem);
  display:flex; flex-direction:column; gap:clamp(.5rem,1.4vw,1.1rem);
  /* names dissolve at both edges instead of being chopped by the viewport */
  -webkit-mask-image:linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
  mask-image:linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}
.marq__row{
  display:flex; width:max-content;
  will-change:transform;
}
/* The set is duplicated in JS, so the track is exactly 2× one set: shifting
   by 50% lands on an identical frame and the loop is seamless. */
.marq__row[data-dir="ltr"]{ animation:marqLtr 64s linear infinite }
.marq__row[data-dir="rtl"]{ animation:marqRtl 74s linear infinite }
@keyframes marqLtr{ from{ transform:translate3d(-50%,0,0) } to{ transform:translate3d(0,0,0) } }
@keyframes marqRtl{ from{ transform:translate3d(0,0,0) } to{ transform:translate3d(-50%,0,0) } }

.marq__set{ display:flex; align-items:center; flex:none }
.marq__set li{
  flex:none; padding-inline:clamp(.85rem,2vw,1.9rem);
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(.95rem,2.1vw,1.9rem); line-height:1.3;
  letter-spacing:-.025em; white-space:nowrap;
  color:var(--ink-soft); opacity:.72;
}
/* a hairline between names, so it reads as one continuous ledger */
.marq__set li + li{ border-left:1px solid var(--rule) }

@media (prefers-reduced-motion:reduce){
  .marq__row{ animation:none }
  .marq__vp{ -webkit-mask-image:none; mask-image:none }
  .marq__row{ flex-wrap:wrap; width:auto }
  .marq__set{ flex-wrap:wrap }
  .marq__set li + li{ border-left:0 }
}

/* ═══ shared section furniture ═══════════════════════════════════════ */
.eyebrow{ color:var(--beam); margin-bottom:1.25rem }
.secHead{ margin-bottom:clamp(3rem,7vw,6rem) }
.secHead__h{ font-size:var(--t-h2); letter-spacing:-.028em; line-height:1.02 }

/* ═══ 03 · THE MANDATE ════════════════════════════════════════════════ */
.mandate{
  position:relative; z-index:2;
  background:var(--paper);
  padding-block:var(--sec);
}

.mandate__wrap{
  display:grid;
  grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:clamp(3rem,7vw,7rem);
  align-items:start;
}

.mandate__aside{ position:sticky; top:0; height:100svh; display:flex; align-items:center }
.mandate__asideIn{ max-width:34ch }
.mandate__h{ font-size:var(--t-h2); letter-spacing:-.03em }
.mandate__intro{
  margin-top:1.75rem; color:var(--ink-soft); font-size:var(--t-lead); max-width:32ch;
}
.mandate__intro .mono{ font-size:.85em; color:var(--ink) }
.mandate__count{
  margin-top:2.5rem; color:var(--ink-soft); font-variant-numeric:tabular-nums;
}
.mandate__count b{ color:var(--beam); font-weight:500 }

.mandate__list{ padding-block:clamp(4rem,18vh,14rem) }

.mand{ padding-block:clamp(3rem,8vh,6rem); border-top:1px solid var(--rule) }
.mand:first-child{ border-top:0; padding-top:0 }

.mand__tag{
  display:flex; align-items:center; gap:.85rem;
  color:var(--beam); margin-bottom:1.1rem;
}
.mand__tag i{
  display:block; height:1px; width:clamp(28px,4vw,56px);
  background:currentColor; transform:scaleX(0); transform-origin:left;
}
.mand__tag--e{ color:var(--ink); margin-top:2rem }

.mand__quote{
  font-family:var(--f-serif); font-style:italic;
  font-size:clamp(1.3rem,2.4vw,1.9rem);
  line-height:1.32; letter-spacing:.002em;
  color:var(--ink-soft);
  max-width:32ch;
}

/* step-wise evidence: numbered, scannable, one claim per line */
.mand__pts{ max-width:56ch; counter-reset:pt }
.mand__pts li{
  counter-increment:pt;
  position:relative; padding:.42rem 0 .42rem 2.25rem;
  font-size:clamp(.9rem,1.05vw,1.0625rem); line-height:1.5;
  border-top:1px solid var(--rule);
  text-wrap:pretty;
}
.mand__pts li:first-child{ border-top:0; padding-top:0 }
.mand__pts li::before{
  content:counter(pt,decimal-leading-zero);
  position:absolute; left:0; top:.62rem;
  font-family:var(--f-mono); font-size:.625rem; letter-spacing:.1em;
  color:var(--beam); opacity:.8;
}
.mand__pts li:first-child::before{ top:.2rem }
.mand__pts b{ font-weight:600; color:var(--ink) }
.mand__pts strong{ color:var(--beam); font-weight:600 }

.mandate__close{
  margin-top:clamp(4rem,10vh,8rem);
  padding-inline:var(--gut);
  text-align:center;
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(1.5rem,3.5vw,2.75rem);
  line-height:1.22; letter-spacing:-.025em;
  max-width:24ch; margin-inline:auto;
}

/* ═══ 04 · PILLARS ════════════════════════════════════════════════════ */
.pillars{
  position:relative; z-index:2; overflow:hidden;
  background:var(--paper-2);
  padding-block:var(--sec);
}
.pillars::before{
  content:''; position:absolute; inset:0; pointer-events:none;
  background-image:repeating-linear-gradient(to right,
    var(--rule) 0 1px, transparent 1px calc(100% / 12));
  background-size:calc(100% - 2 * var(--gut)) 100%;
  background-position:var(--gut) 0; background-repeat:no-repeat;
  opacity:.32;
}
.pillars__media{
  position:absolute; inset:0; opacity:.32; pointer-events:none;
  mix-blend-mode:multiply;
}
.pillars__media video{ width:100%; height:100%; object-fit:cover }
.pillars > .wrap{ position:relative; z-index:1 }

.pillars__grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:clamp(1rem,2vw,2rem);
}

.pillar{
  padding:clamp(1.75rem,2.6vw,2.5rem);
  background:rgba(255,255,255,.55);
  border:1px solid var(--rule);
  backdrop-filter:blur(2px);
  transition:transform .4s var(--e-soft), border-color .4s var(--e-soft), background .4s var(--e-soft);
}
.pillar__n{
  font-size:clamp(2.5rem,4vw,3.5rem); font-weight:500;
  line-height:1; letter-spacing:-.02em;
  color:transparent;
  -webkit-text-stroke:1px var(--ink-soft);
  transition:color .4s var(--e-soft), -webkit-text-stroke-color .4s var(--e-soft);
  margin-bottom:clamp(2rem,4vw,3.5rem);
}
.pillar__h{ font-size:var(--t-h3); letter-spacing:-.022em; line-height:1.08 }
.pillar__claim{
  margin-top:.9rem; color:var(--beam); font-weight:500;
  font-size:.95rem; line-height:1.45;
}
.pillar__list{ margin-top:1.75rem; border-top:1px solid var(--rule) }
.pillar__list li{
  padding:.9rem 0; border-bottom:1px solid var(--rule);
  font-size:.9375rem; line-height:1.5; color:var(--ink-soft);
}

@media (hover:hover){
  .pillar:hover{ transform:translateY(-6px); border-color:var(--beam); background:rgba(255,255,255,.8) }
  .pillar:hover .pillar__n{ color:var(--beam); -webkit-text-stroke-color:var(--beam) }
}

/* ═══ 05 · STORY ══════════════════════════════════════════════════════ */
.story{
  position:relative; z-index:2;
  background:var(--paper);
  padding-block:var(--sec);
}

/* Centre the reading column. Left-aligned inside a 1440px wrap it stranded
   most of a widescreen empty on the right. */
.story .secHead{ max-width:62ch; margin-inline:auto }
.story__body{ max-width:62ch; margin-inline:auto; font-size:var(--t-lead) }
.story__body p + p{ margin-top:1.5em }
.story__body p{ color:var(--ink-soft); text-wrap:pretty }
.story__body strong{ color:var(--ink); font-weight:600 }

/* the hook — one line, no explanation, sized to stop the eye */
.story__open{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.5rem,3.4vw,2.75rem); line-height:1.04;
  letter-spacing:-.03em; color:var(--ink) !important;
  max-width:20ch;
}

/* the turns: short declaratives that carry the story between chapters */
.story__beat{
  margin-top:1.8em !important;
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(1.1rem,1.9vw,1.6rem); line-height:1.18;
  letter-spacing:-.025em; color:var(--ink) !important;
  max-width:28ch;
}

/* the joke, set apart so it reads as an aside and lands on its own */
.story__aside{
  margin-top:1.4em !important;
  padding-left:clamp(1rem,2vw,1.75rem);
  border-left:2px solid var(--rule);
  font-size:clamp(.95rem,1.35vw,1.15rem);
  font-style:italic; color:var(--ink-soft) !important;
  max-width:46ch;
}

.story__turn{
  margin-top:2em !important;
  padding-left:clamp(1rem,2vw,1.75rem);
  border-left:2px solid var(--flare);
  color:var(--ink) !important;
}

/* the payoff, which answers the hook */
.story__last{
  margin-top:1.6em !important;
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.25rem,2.6vw,2.1rem); line-height:1.12;
  letter-spacing:-.03em; color:var(--ink) !important;
}

/* — scroll-driven timeline —
   The camera travels along a single horizontal line, markers alternating above
   and below it, in the manner of a corporate timeline title sequence. Vertical
   scroll is converted into horizontal travel by script.js.

   Base (no JS) is a plain vertical list: every fact stays readable if GSAP
   never arrives. The `.js` rules below opt into the horizontal stage. */
.tline{ margin-block:clamp(4rem,10vh,8rem); position:relative;
        --tl-w:clamp(14rem,20vw,19rem) }
.tline__head{ margin-bottom:clamp(2rem,5vh,3.5rem) }
.tline__h{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.6rem,4vw,2.9rem); letter-spacing:-.03em;
  line-height:1.04; color:var(--ink); margin:0;
}
.tline__hint{ display:none }

/* Stacked, the stage is a normal page column; the horizontal run below opts
   back out to full-bleed so the track can travel edge to edge. */
.tline__stage{
  position:relative;
  width:100%; max-width:var(--max); margin-inline:auto;
  padding-inline:var(--gut);
}
.tline__track{ position:relative }
.tline__rail{ display:none }

.tline__list{ list-style:none; margin:0; padding:0 0 0 1.75rem; position:relative }
.tline__list::before{
  content:''; position:absolute; left:4px; top:.55rem; bottom:.6rem;
  width:1px; background:var(--rule);
}
.tline__item{ position:relative; padding:0 0 1.9rem }
.tline__item:last-child{ padding-bottom:0 }
.tline__dot{
  position:absolute; left:-1.75rem; top:.45rem;
  display:block; width:9px; height:9px; border-radius:50%;
  background:var(--beam);
}
.tline__yr{
  display:block; font-family:var(--f-mono); font-weight:700;
  font-size:clamp(1rem,1.5vw,1.25rem); letter-spacing:.02em;
  color:var(--beam); line-height:1;
}
.tline__t{
  margin:.42rem 0 0; font-family:var(--f-display); font-weight:700;
  font-size:clamp(1.05rem,2vw,1.55rem); letter-spacing:-.022em;
  line-height:1.1; color:var(--ink);
}
/* These carry a sentence, not a label, so they are set as prose. Mono caps
   were fine for "PUNE, INDIA" and unreadable the moment the copy got real. */
.tline__s{
  margin:.45rem 0 0; font-size:.8125rem; line-height:1.5;
  letter-spacing:0; text-transform:none; color:var(--ink-soft);
  text-wrap:pretty;
}
/* The CERN moments and the two SETI beats carry the amber. They are the
   thread that runs from the 2012 announcement to the 2027 door. */
.tline__item--cern .tline__dot{ background:var(--flare) }
.tline__item--cern .tline__yr{ color:var(--flare) }
.tline__item--open .tline__dot{
  background:transparent; border:1.5px solid var(--flare);
  width:11px; height:11px;
}
.tline__item--open .tline__t{ color:var(--flare) }

/* — horizontal stage (JS only) — */
.js .tline__stage{
  position:sticky; top:0; height:100svh;
  max-width:none; padding-inline:0;
  display:flex; align-items:center; overflow:hidden;
}
.js .tline__hint{
  display:block; margin-top:1.1rem; font-size:.5625rem;
  letter-spacing:.22em; text-transform:uppercase; color:var(--ink-soft);
}
.js .tline__hint span{ position:relative; padding-right:2.6rem }
.js .tline__hint span::after{
  content:''; position:absolute; right:0; top:50%; width:2rem; height:1px;
  background:currentColor; opacity:.5;
  animation:tlHint 1.9s ease-in-out infinite;
}
@keyframes tlHint{
  0%,100%{ transform:translateX(0);   opacity:.5 }
  50%    { transform:translateX(.4rem); opacity:1 }
}

.js .tline__track{
  display:flex; align-items:center;
  /* Each dot sits at its card's leading edge. Half a viewport of lead-in puts
     the first marker under the playhead at 0%; the trailing side is short by
     one card width so the last marker lands there too at 100%. */
  padding-left:50vw;
  padding-right:calc(50vw - var(--tl-w));
  will-change:transform;
}
.js .tline__rail{
  display:block; position:absolute; left:0; right:0; top:50%;
  height:1px; background:var(--rule);
}
.js .tline__fill{
  display:block; height:100%; background:var(--beam);
  transform:scaleX(0); transform-origin:left;
}
.js .tline__list{
  display:flex; align-items:center;
  padding:0; margin:0;
  gap:clamp(2.25rem,5.5vw,5.5rem);
}
.js .tline__list::before{ display:none }

.js .tline__item{
  position:relative; flex:none;
  width:var(--tl-w);
  padding:0; height:46svh;
  display:flex; align-items:center;
}
.js .tline__item--up{ align-items:flex-end;   padding-bottom:2.6rem }
.js .tline__item--dn{ align-items:flex-start; padding-top:2.6rem }

.js .tline__card{
  opacity:.28; transform:translateY(10px);
  transition:opacity .5s ease, transform .5s ease;
}
.js .tline__item.is-live .tline__card{ opacity:1; transform:none }

.js .tline__dot{
  position:absolute; left:0; top:50%; margin-top:-4.5px;
  transform:scale(.55); transition:transform .45s ease;
}
.js .tline__item.is-live .tline__dot{ transform:scale(1) }
.js .tline__item--open .tline__dot{ margin-top:-5.5px }
/* The stem ties each card back to the rail so the marker reads as one object. */
.js .tline__item::before{
  content:''; position:absolute; left:4px; width:1px;
  background:var(--rule); transform:scaleY(0); transition:transform .5s ease;
}
.js .tline__item--up::before{ bottom:50%; height:2.1rem; transform-origin:bottom }
.js .tline__item--dn::before{ top:50%;    height:2.1rem; transform-origin:top }
.js .tline__item.is-live::before{ transform:scaleY(1) }

/* — spec sheet — */
.spec{ border-top:1px solid var(--rule) }
.spec > div{
  display:grid; grid-template-columns:minmax(0,10rem) 1fr; gap:1.5rem;
  padding:1.1rem 0; border-bottom:1px solid var(--rule);
}
.spec dt{ color:var(--ink-soft) }
.spec dd{ font-size:.9375rem }

/* ═══ 06 · CASE FILES ═════════════════════════════════════════════════ */
.cases{
  position:relative; z-index:2;
  background:var(--paper);
  padding-block:var(--sec);
}
.cases__list{ border-top:1px solid var(--rule) }
.case{ border-bottom:1px solid var(--rule) }

.case__btn{
  width:100%; display:grid;
  grid-template-columns:minmax(0,7rem) minmax(0,1fr) auto 2rem;
  align-items:center; gap:clamp(1rem,3vw,2.5rem);
  padding:clamp(1.5rem,3vw,2.25rem) 0;
  text-align:left;
  transition:color .35s var(--e-soft);
}
.case__n{ color:var(--ink-soft) }
.case__t{
  font-family:var(--f-display); font-weight:600;
  font-size:clamp(1.35rem,3vw,2.25rem);
  letter-spacing:-.025em; line-height:1.1;
}
.case__m{ color:var(--beam); text-align:right }
.case__i{
  position:relative; width:14px; height:14px; justify-self:end;
  transition:transform .4s var(--e-soft);
}
.case__i::before,.case__i::after{
  content:''; position:absolute; background:var(--ink);
  transition:opacity .3s var(--e-soft);
}
.case__i::before{ top:6px; left:0; width:14px; height:1.5px }
.case__i::after{ left:6px; top:0; width:1.5px; height:14px }
.case__btn[aria-expanded="true"] .case__i{ transform:rotate(135deg) }
.case__btn[aria-expanded="true"] .case__i::after{ opacity:0 }
@media (hover:hover){ .case__btn:hover .case__t{ color:var(--beam) } }

.case__panel{ overflow:hidden }
.case__panel[hidden]{ display:block; height:0 }
.case__inner{
  padding:0 0 clamp(2rem,4vw,3rem);
  display:grid; grid-template-columns:minmax(0,7rem) minmax(0,1fr);
  gap:clamp(1rem,3vw,2.5rem);
}
.case__meta{ color:var(--ink-soft) }
.case__inner dl{ max-width:58ch; grid-column:2 }
.case__inner dt{ margin-top:1.5rem; color:var(--beam) }
.case__inner dt:first-child{ margin-top:0 }
.case__inner dd{ margin-top:.5rem; color:var(--ink-soft) }
.case__kicker{
  grid-column:2; margin-top:2rem; padding-left:1.25rem;
  border-left:2px solid var(--flare);
  font-family:var(--f-serif); font-style:italic;
  font-size:clamp(1.1rem,1.9vw,1.4rem); line-height:1.4;
  color:var(--ink); max-width:48ch;
}

/* ═══ 07 · THE FILE ═══════════════════════════════════════════════════ */
.file{
  position:relative; z-index:2;
  background:var(--paper);
  padding-block:clamp(3rem,7vh,5rem) var(--sec);
}
.file__grid{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:clamp(1.5rem,3vw,3rem);
  border-top:1px solid var(--ink); padding-top:2rem;
}
.file__lbl{ color:var(--ink-soft); margin-bottom:1.5rem }
.file__col li{ font-size:.875rem; line-height:1.45; padding-block:.45rem }
.file__col li b{ display:block; font-weight:600 }
.file__col li span{ display:block; color:var(--ink-soft); font-size:.8125rem; margin-top:.15rem }
/* education reads reverse-chronologically with dates on their own aligned line */
.file__ed li{ padding-block:.6rem; border-bottom:1px solid var(--rule) }
.file__ed li:last-child{ border-bottom:0 }
.file__ed em{
  display:block; margin-top:.3rem; font-style:normal;
  font-size:.625rem; letter-spacing:.09em; text-transform:uppercase;
  color:var(--beam); opacity:.8;
}
.file__flat li{ color:var(--ink-soft); border-bottom:1px solid var(--rule) }
.file__flat a{ color:var(--beam) }
@media (hover:hover){ .file__flat a:hover{ text-decoration:underline; text-underline-offset:.2em } }

/* ═══ 08 · ARRIVAL ════════════════════════════════════════════════════ */
.arrival{
  position:relative; z-index:2; overflow:hidden;
  background:var(--void); color:var(--paper);
  min-height:100svh; display:flex; align-items:center;
  padding-block:var(--sec);
}
.arrival__media{ position:absolute; inset:0; opacity:.5 }
.arrival__media video{ width:100%; height:100%; object-fit:cover }
.arrival::before{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:
    radial-gradient(ellipse 80% 50% at 70% 15%, rgba(27,77,255,.20), transparent 70%),
    radial-gradient(ellipse 60% 45% at 20% 85%, rgba(232,160,85,.10), transparent 70%);
}
.arrival__scrim{
  position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(to top, var(--void) 8%, rgba(6,6,7,.55) 55%, rgba(6,6,7,.2) 100%);
}
.arrival__wrap{ position:relative; z-index:1 }

.arrival__h{
  font-size:clamp(1.85rem,5.4vw,5rem);
  line-height:1.02; letter-spacing:-.035em;
  color:var(--paper-pure); max-width:20ch;
}
/* the vacancy reference must never break across lines */
.arrival__ref{ white-space:nowrap }
.arrival__sub{
  margin-top:clamp(1.75rem,3vw,2.5rem);
  color:rgba(242,241,237,.6); line-height:1.9;
}
.arrival__cta{
  margin-top:clamp(2.5rem,5vw,4rem);
  display:flex; flex-wrap:wrap; gap:1rem;
}

.btn{
  position:relative; overflow:hidden; isolation:isolate;
  display:inline-flex; align-items:center; gap:.75rem;
  padding:1.15rem 2rem;
  font-family:var(--f-mono); font-size:.8125rem;
  letter-spacing:.12em; text-transform:uppercase;
  transition:color .4s var(--e-soft);
}
.btn::before{
  content:''; position:absolute; inset:0; z-index:-1;
  transform:scaleX(0); transform-origin:left;
  transition:transform .45s var(--e-out);
}
.btn--solid{ background:var(--paper-pure); color:var(--void) }
.btn--solid::before{ background:var(--beam) }
.btn--ghost{ border:1px solid rgba(242,241,237,.4); color:var(--paper) }
.btn--ghost::before{ background:var(--paper-pure) }
.btn span{ opacity:.5 }
@media (hover:hover){
  .btn:hover::before{ transform:scaleX(1) }
  .btn--solid:hover{ color:#fff }
  .btn--ghost:hover{ color:var(--void) }
}

/* ═══ 09 · FOOTER ═════════════════════════════════════════════════════ */
.foot{
  position:relative; z-index:2;
  background:var(--void); color:var(--paper);
  padding-block:clamp(3rem,7vh,5rem);
  border-top:1px solid rgba(242,241,237,.12);
}
.foot__grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:2rem; padding-bottom:clamp(3rem,6vh,5rem);
}
.foot__name{ font-family:var(--f-display); font-weight:600; font-size:1.05rem; letter-spacing:-.02em }
.foot__grid p{ font-size:.875rem; color:rgba(242,241,237,.62) }
.foot__grid .mono{ font-size:var(--t-mono) }
@media (hover:hover){ .foot a:hover{ color:var(--flare) } }
.foot a{ transition:color .3s var(--e-soft) }

.foot__sig{
  display:flex; justify-content:space-between; gap:1rem;
  padding-top:1.5rem; border-top:1px solid rgba(242,241,237,.12);
  color:rgba(242,241,237,.34); font-size:.6875rem;
}

/* ── reveal defaults ─────────────────────────────────────────────────
   Hidden only while the .js lock is present. script.js drops the lock if
   GSAP is missing or motion is reduced, so a blocked CDN yields a fully
   readable static page rather than a blank one. */
.js [data-reveal]{ opacity:0; transform:translateY(28px) }
html.reduced [data-reveal]{ opacity:1; transform:none }

/* ═══════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width:1024px){
  .mandate__wrap{ grid-template-columns:1fr; gap:0 }
  .mandate__aside{
    position:sticky; top:0; height:auto;
    padding-block:1.25rem; margin-bottom:2.5rem;
    background:var(--paper); border-bottom:1px solid var(--rule);
    z-index:3;
  }
  .mandate__asideIn{ max-width:none }
  .mandate__intro{ display:none }
  .mandate__h{ font-size:clamp(1.75rem,5vw,2.5rem) }
  .mandate__count{ margin-top:.75rem }
  .mandate__list{ padding-block:0 }

  .pillars__grid{ grid-template-columns:1fr; gap:1rem }
  .pillar__n{ margin-bottom:1.5rem }

  .file__grid{ grid-template-columns:repeat(2,1fr); row-gap:2.5rem }

  /* A 13-stop horizontal track needs room to travel. Below this width the
     timeline drops back to the vertical list, which is also the no-JS base,
     so every stop stays readable without sideways scrolling on a phone. */
  .js .tline{ height:auto !important }
  /* Undo the full-bleed opt-out: stacked, the list belongs in the gutter. */
  .js .tline__stage{
    position:relative; height:auto; display:block; overflow:visible;
    max-width:var(--max); padding-inline:var(--gut);
  }
  .js .tline__hint{ display:none }
  .js .tline__track{ display:block; padding-inline:0; transform:none !important }
  .js .tline__rail{ display:none }
  .js .tline__list{
    display:block; padding:0 0 0 1.75rem;
    gap:0;
  }
  .js .tline__list::before{ display:block }
  .js .tline__item{
    display:block; width:auto; height:auto;
    padding:0 0 1.9rem !important;
  }
  .js .tline__item:last-child{ padding-bottom:0 !important }
  .js .tline__item::before{ display:none }
  .js .tline__card{ opacity:1; transform:none }
  .js .tline__dot{
    position:absolute; left:-1.75rem; top:.45rem; margin-top:0;
    transform:scale(1);
  }
}

@media (max-width:768px){
  .thesis__body{ margin-left:0 }

  .panel__grid{ grid-template-columns:repeat(2,1fr) }
  .panel__cell:nth-child(3n){ border-right:1px solid rgba(242,241,237,.14) }
  .panel__cell:nth-child(2n){ border-right:0 }

  .case__btn{ grid-template-columns:1fr 2rem; gap:.5rem 1rem; row-gap:.6rem }
  .case__n{ grid-column:1 }
  .case__t{ grid-column:1/-1; order:2 }
  .case__m{ grid-column:1/-1; order:3; text-align:left }
  .case__i{ grid-column:2; grid-row:1 }
  .case__inner{ grid-template-columns:1fr }
  .case__inner dl,.case__kicker{ grid-column:1 }
  .case__meta{ margin-bottom:1.5rem }

  .spec > div{ grid-template-columns:1fr; gap:.4rem }

  .foot__grid{ grid-template-columns:1fr; gap:1.5rem }
  .foot__sig{ flex-direction:column; gap:.4rem }
}

@media (max-width:640px){
  .aperture{ height:380vh }
  .aperture__name{ font-size:clamp(2.75rem,15vw,5rem) }
  .aperture__scroll{ display:none }

  .thesis__line{ font-size:clamp(1.75rem,9vw,3rem); max-width:none }

  .file__grid{ grid-template-columns:1fr }

  .arrival__cta{ flex-direction:column; align-items:stretch }
  .btn{ justify-content:center; padding-block:1.25rem }
}

/* ═══════════════════════════════════════════════════════════════════════
   REDUCED MOTION — the argument must survive with all motion off
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .grain{ animation:none }
  .aperture{ height:auto }
  .aperture__stage{ position:relative; height:82svh }
  .aperture__vignette{ opacity:.55 }
  .aperture__pupil,.aperture__reactor{ display:none }
  .rvl > span{ transform:none }
  [data-reveal]{ opacity:1; transform:none }
  .rail{ display:none }
  .mandate__aside{ position:relative; height:auto; padding-block:0; margin-bottom:3rem }
  .mand__tag i{ transform:scaleX(1) }
  .tline__fill{ transform:scaleX(1) }
  .tline__card{ opacity:1 !important; transform:none !important }
  .tline__dot{ transform:scale(1) !important }
  .tline__item::before{ transform:scaleY(1) !important }
}
