/* ═══════════════════════════════════════════════════════════════════════════
   APERTURE X — V9 homepage system
   Founder correction gate (V8.1). Rebuilt: typography, pacing, media handling,
   conversion and finale.

   THREE VOICES (all Google Fonts OFL, all variable, all verified live):
     STUDIO  Fraunces    opsz 9-144 · wght 100-900 · SOFT 0-100   — the cinema
     WORK    Archivo     wdth 62-125 · wght 100-900               — the working voice
     MACHINE Geist Mono  wght 100-900                             — the instruments
   The page is typographically flat no longer: eight roles, each with its own
   family, axis position, scale, case and tracking.

   ARCHITECTURE unchanged in kind: the EDITORIAL edition is the document's
   default; the cinematic scene engine is enhancement.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* == V1 COLOUR SYSTEM . a light neutral environment =======================
     One warm-neutral ramp carries the site, charcoal carries the type, and
     the canonical brand red is an accent and nothing else.

       LIGHT / NEUTRAL   dominant
       DARK              supporting - one anchor per page, never the ground
       RED               accent - marks, rules, numerals, states, one CTA sweep

     The legacy token names are KEPT (every selector in this file and every
     page already speaks them) and re-pointed at the system below, so this is
     a change of value, not a change of architecture.
     ---------------------------------------------------------------------- */

  /* grounds and surfaces */
  --color-bg-primary:#faf9f7;       /* soft warm white - the site's ground   */
  --color-bg-secondary:#f1efea;     /* one differentiated step down          */
  --color-surface:#ffffff;          /* clean white - elevated panels, menu   */
  --color-surface-muted:#e9e6e0;    /* the deepest light step - footer       */
  --color-ground-cool:#eef0f3;      /* the technology room, cool by a hair   */
  --color-ground-warm:#f6f1e8;      /* the studio room, warm by a hair       */
  --color-media-backing:#e6e3dd;    /* what shows behind a picture, briefly  */

  /* type - charcoal, never pure black */
  --color-text-primary:#1c1b1a;     /* 16.3:1 on the ground                  */
  --color-text-secondary:#5c5a55;   /*  6.5:1                                */
  --color-text-muted:#67655f;       /*  5.3:1                                */

  /* lines - low visual weight by design */
  --color-border:#dcd8d1;
  --color-hairline:rgba(28,27,26,.10);
  --color-hairline-strong:rgba(28,27,26,.17);

  /* brand */
  --color-brand:#da1f26;            /* canonical Lion Creatives red          */
  --color-brand-hover:#b81a20;
  --color-brand-text:#a3161d;       /* small red text on light - 7.4:1       */

  /* ── STRUCTURAL BLACK (V2, 60/30/10) ──
     V1 treated dark as an occasional anchor. The founder's correction: black
     is a real design element and should carry roughly 30% of the visual
     weight — section grounds, editorial bands, media framing, the footer —
     while white stays the dominant environment at ~60% and red stays an
     accent at ~10%. These are the blacks that do that work. */
  --color-black:#0f0f11;            /* the structural ground                 */
  --color-black-2:#191a1d;          /* a panel sitting ON the black          */
  --color-on-black:#f7f6f3;
  --color-on-black-muted:#a9a7a2;   /* 8.0:1 on the black                    */
  --color-on-black-dim:#84827e;     /* 4.9:1 - metadata only                 */
  --color-hairline-on-black:rgba(255,255,255,.15);
  --color-border-on-black:#33333a;

  /* the dark: a supporting anchor, and what type sits in over film */
  --color-dark:#17171a;
  --color-dark-2:#202024;
  --color-on-dark:#f7f6f3;
  --color-on-dark-muted:#b8b7b3;
  --color-on-dark-dim:#8f8d89;
  --color-hairline-on-dark:rgba(255,255,255,.14);

  /* -- legacy names, re-pointed -- */
  --void:var(--color-bg-primary); --plane:var(--color-surface);
  --edge:var(--color-border); --hair:var(--color-hairline);
  --hair-ink:var(--color-hairline);
  --signal:var(--color-brand); --fg:var(--color-text-primary);
  --muted:var(--color-text-secondary); --dim:var(--color-text-muted);
  --field:var(--color-bg-secondary); --ink:var(--color-text-primary);
  --ease:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,0,.35,1);

  --f-studio:'Fraunces',Georgia,'Times New Roman',serif;
  --f-work:'Archivo','Helvetica Neue',Arial,system-ui,sans-serif;
  --f-machine:'Geist Mono','JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* HEADER SAFE ZONE (founder §15). --nav-h is measured at runtime by the engine;
     this is the fallback. NOTHING may render above --safe-top inside a stage. */
  --nav-h:82px;
  --safe-top:calc(var(--nav-h) + clamp(14px,2.4vh,30px));
  --gut:clamp(1.2rem,4vw,4rem);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--void);color:var(--fg);
  font-family:var(--f-work);font-stretch:100%;font-weight:400;
  font-size:1.02rem;line-height:1.6;-webkit-font-smoothing:antialiased;
  font-synthesis:none;overflow-x:clip}
img,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
::selection{background:var(--signal);color:#fff}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;white-space:nowrap}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
[id]{scroll-margin-top:var(--safe-top)}

/* ══ THE EIGHT TYPE ROLES ════════════════════════════════════════════════ */
/* 1 · DISPLAY / CINEMATIC — Fraunces at full optical size, light, tight */
.t-display{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 144,'wght' 300,'SOFT' 0,'WONK' 0;font-weight:300;
  font-size:clamp(2.7rem,7.6vw,6.6rem);line-height:.92;letter-spacing:-.028em;
  margin:0;text-wrap:balance}
/* 2 · SCENE HEAD — same family, different optical size = different texture */
.t-scene{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 400,'SOFT' 0,'WONK' 0;font-weight:400;
  font-size:clamp(1.9rem,4vw,3.3rem);line-height:1.02;letter-spacing:-.018em;margin:0}
/* 3 · EDITORIAL — warmer terminals (SOFT 40), reading size */
.t-editorial{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 30,'wght' 400,'SOFT' 40,'WONK' 0;font-weight:400;
  font-size:clamp(1.25rem,2.1vw,1.85rem);line-height:1.28;letter-spacing:-.008em;margin:0}
/* 4 · TECHNICAL — Archivo condensed, the engineering register */
.t-tech{font-family:var(--f-work);font-stretch:88%;font-weight:700;
  font-size:clamp(1.5rem,3.1vw,2.6rem);line-height:1.04;letter-spacing:-.005em;
  text-transform:uppercase;margin:0}
/* 5 · PROJECT IDENTITY — Archivo expanded: names get room */
.proj-name{font-family:var(--f-work);font-stretch:118%;font-weight:600;
  font-size:clamp(1.02rem,1.5vw,1.32rem);line-height:1.15;letter-spacing:.002em;margin:0}
/* 6 · BODY */
.lede{font-family:var(--f-work);font-stretch:100%;font-weight:400;
  font-size:clamp(1rem,1.35vw,1.16rem);line-height:1.55;color:var(--muted);max-width:52ch;margin:0}
.factline{font-family:var(--f-work);font-stretch:100%;font-weight:400;
  font-size:.96rem;line-height:1.6;color:var(--muted);max-width:50ch;margin:0}
/* 7 · METADATA — Geist Mono, the instruments */
.label{font-family:var(--f-machine);font-weight:400;font-size:.7rem;
  letter-spacing:.15em;text-transform:uppercase;color:var(--dim);margin:0;
  font-variant-numeric:tabular-nums slashed-zero}
.label-sig{border-left:2px solid var(--signal);padding-left:.62em}
.spec{font-family:var(--f-machine);font-weight:400;font-size:.72rem;
  letter-spacing:.09em;color:var(--dim);font-variant-numeric:tabular-nums slashed-zero;margin:0}
/* 8 · NAV + CTA */
.nav-links a{font-family:var(--f-work);font-stretch:92%;font-weight:500;
  font-size:.9rem;letter-spacing:.012em}
.btn{font-family:var(--f-machine);font-weight:600;font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase}

h1,h2,h3{margin:0;font-weight:inherit}
.sig{color:var(--signal)}
i.sig,em.sig{font-style:italic}
.t-display i,.t-scene i{font-style:italic;font-variation-settings:'opsz' 144,'wght' 300,'SOFT' 0,'WONK' 0}

/* ══ CHROME ══════════════════════════════════════════════════════════════ */
/* ── RED, PLACED (V2) ──
   Red is the accent, so it earns its 10% by being present on every screen
   rather than by covering area: the editorial rule that marks each change of
   architecture, the numeral in front of every index, the arrow in every action
   square, the indicator on the page you are on, and the states. Nothing here
   is a fill. */
.nav-links a[aria-current="page"]{position:relative}
.nav-links a[aria-current="page"]::after{content:"";position:absolute;
  left:0;right:0;bottom:-.42em;height:2px;background:var(--signal)}
/* the action square carries the accent at rest on BOTH button variants */
.btn .tick{color:var(--signal-text)}
.btn:hover .tick,.btn:focus-visible .tick{color:inherit}
html[data-ground="dark"] .nav .btn .tick{color:var(--signal-text-media)}
/* arrows on text links */
.ix-go i,.ph2-foot a i,.wk-ix a .ix-go i{color:var(--signal-text)}
/* ── THE CHROME READS ITS GROUND (V2) ──
   Black is a real structural colour now, so the fixed chrome crosses black
   regions on every route: the photography essay, the cinema edit, every
   anchor band, every footer, and the hero once the film owns the frame. A
   charcoal wordmark on black is invisible, so the nav, the menu button and
   the motion control all invert when a dark region is behind them. The engine
   sets data-ground on <html>; nothing here guesses. */
.nav-mark,.nav-mark svg,.nav-links a,.menu-btn,.motion-toggle,.nav.scrolled{
  transition:color 320ms var(--ease),fill 320ms var(--ease),
             background-color 320ms var(--ease),border-color 320ms var(--ease)}
html[data-ground="dark"] .nav-mark{color:var(--color-on-black)}
html[data-ground="dark"] .nav-mark svg{fill:var(--color-on-black)}
html[data-ground="dark"] .nav-links a{color:var(--color-on-black)}
html[data-ground="dark"] .nav.scrolled{background:rgba(15,15,17,.72);
  border-bottom-color:var(--color-hairline-on-black)}
html[data-ground="dark"] .nav .btn,
html[data-ground="dark"] .menu-btn{color:var(--color-on-black);border-color:var(--color-on-black)}
html[data-ground="dark"] .nav .btn::before,
html[data-ground="dark"] .menu-btn::before{background:var(--color-on-black)}
html[data-ground="dark"] .nav .btn:hover,html[data-ground="dark"] .nav .btn:focus-visible,
html[data-ground="dark"] .menu-btn:hover,html[data-ground="dark"] .menu-btn:focus-visible{
  color:var(--color-black);border-color:var(--color-on-black)}
html[data-ground="dark"] .nav .btn .tick{color:var(--signal-text-media)}
html[data-ground-bottom="dark"] .motion-toggle{background:rgba(15,15,17,.86);
  color:var(--color-on-black);border-color:var(--color-border-on-black)}

html[data-ground="dark"] .wk-rail{background:rgba(15,15,17,.80);
  border-bottom-color:var(--color-hairline-on-black);color:var(--color-on-black-dim)}
html[data-ground="dark"] .wk-rail a{color:var(--color-on-black-dim)}
html[data-ground="dark"] .wk-rail a:hover,html[data-ground="dark"] .wk-rail a:focus-visible,
html[data-ground="dark"] .wk-rail a[aria-current="true"]{color:var(--color-on-black)}
html[data-ground="dark"] .wk-rail a .n{color:var(--signal-text-media)}
html[data-ground="dark"] .wk-rail .bar{background:var(--color-hairline-on-black)}
@media(prefers-reduced-motion:reduce){
  .nav-mark,.nav-mark svg,.nav-links a,.menu-btn,.motion-toggle,.nav.scrolled{transition:none}
}
.nav{position:fixed;inset:0 0 auto 0;z-index:110;display:flex;align-items:center;
  gap:1.4rem;padding:1rem var(--gut);pointer-events:none;
  transition:background 400ms var(--ease)}
.nav>*{pointer-events:auto}
.nav.scrolled{background:rgba(250,249,247,.74);
  backdrop-filter:blur(14px) saturate(1.05);
  border-bottom:1px solid var(--hair)}
.nav-mark{display:flex;align-items:center;gap:.7rem;font-family:var(--f-work);
  font-stretch:118%;font-weight:600;font-size:1rem;letter-spacing:.004em}
.nav-mark svg{width:30px;height:30px;fill:var(--fg)}
.nav-mark svg polygon:nth-child(3){fill:var(--signal)}
.nav-links{display:none;gap:1.7rem;margin-left:auto}
.nav-links a{opacity:.82;transition:opacity 180ms var(--ease)}
.nav-links a:hover,.nav-links a[aria-current="page"]{opacity:1}
@media(min-width:900px){.nav-links{display:flex}}

/* CTA — a plate with a divided action square, not a pill (founder §35) */
.btn{display:inline-flex;align-items:stretch;gap:0;border:1px solid currentColor;
  cursor:pointer;color:var(--fg);background:transparent;padding:0;
  min-height:44px;position:relative;overflow:hidden;
  transition:color 180ms var(--ease),border-color 180ms var(--ease)}
.btn>span{display:flex;align-items:center;padding:.78rem 1.15rem;position:relative;z-index:2}
.btn::before{content:"";position:absolute;inset:0;background:var(--fg);
  transform:scaleX(0);transform-origin:left;z-index:1;
  transition:transform 420ms var(--ease)}
.btn:hover::before,.btn:focus-visible::before{transform:scaleX(1)}
.btn:hover,.btn:focus-visible{border-color:var(--fg);color:var(--color-on-dark)}
.btn .tick{border-left:1px solid currentColor;padding:.78rem .8rem;z-index:2;
  display:flex;align-items:center}
/* PRIMARY (S5): a sophisticated charcoal plate. Red is not the resting
   background of every call to action - it arrives as the hover sweep, which
   is the one moment a control is allowed to speak in the brand colour. */
.btn-solid{background:var(--fg);border-color:var(--fg);color:var(--color-on-dark)}
.btn-solid::before{background:#31302c}
.btn-solid:hover,.btn-solid:focus-visible{color:#fff;border-color:#31302c}
/* the accent lives in the action square, at rest: a tiny red arrow and the
   hairline that divides it from the label */
.btn-solid .tick{color:var(--signal-text-media)}
.nav-cta{margin-left:auto;min-height:40px}
.nav-cta>span{padding:.55rem .9rem}
@media(min-width:900px){.nav-cta{margin-left:0}}
@media(max-width:899px){.nav-cta{display:none}}
.menu-btn{margin-left:auto;display:inline-flex}
@media(min-width:900px){.menu-btn{display:none}}

.menu{position:fixed;inset:0;z-index:120;background:var(--plane);visibility:hidden;
  clip-path:polygon(0 0,100% 0,100% 0,0 0);
  transition:clip-path 620ms var(--ease-io),visibility 0s linear 620ms;
  display:flex;flex-direction:column;justify-content:center;padding:var(--gut)}
.menu[data-open="true"]{clip-path:polygon(0 0,100% 0,100% 100%,0 100%);
  visibility:visible;transition-delay:0s,0s}
.menu nav a{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 72,'wght' 400,'SOFT' 0,'WONK' 0;
  font-size:2.3rem;padding:.42rem 0;display:block}
.menu .label{margin-bottom:1.3rem}
.menu-close{position:absolute;top:1rem;right:var(--gut)}

.motion-toggle{position:fixed;right:1rem;bottom:1rem;z-index:130;
  font-family:var(--f-machine);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  padding:.55rem .75rem;border:1px solid var(--edge);background:rgba(250,249,247,.88);
  color:var(--fg);cursor:pointer;backdrop-filter:blur(6px)}
.motion-toggle:hover,.motion-toggle:focus-visible{border-color:var(--signal)}

/* ══ FILM AUDIO — the sound key on the Vidflow-fed films ═════════════════
   One key per film, injected by filmAudio() only in the cinematic edition.
   It lives INSIDE the film plane, so the hero's aperture clip and the cinema
   blade wipes carry it naturally — it belongs to the picture, not the chrome.
   Films always START muted; the key hands the visitor the original audio. */
.film-audio{position:absolute;z-index:7;width:44px;height:44px;margin:0;
  display:grid;place-items:center;padding:0;cursor:pointer;
  color:var(--color-on-dark);background:rgba(10,10,11,.62);
  border:1px solid var(--color-hairline-on-dark);
  border-radius:50%;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .2s,background-color .2s}
.film-audio svg{width:17px;height:17px;display:block;fill:none;
  stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.film-audio:hover,.film-audio:focus-visible{border-color:var(--signal)}
.film-audio[aria-pressed="true"]{background:rgba(10,10,11,.85)}
/* THE FILM CONTROL ROW. Anchored to the film's own lower-left edge and moved
   there by the engine (--ctl-l / --ctl-b, in vw / svh), so it stays welded to
   the picture through the entire opening instead of drifting across the stage.
   Sound is the first control in the row. */
.hero-controls{position:absolute;z-index:7;display:flex;align-items:center;gap:.5rem;
  /* the fallbacks are the REST position the engine computes for the opening
     composition (film lower-left + a margin), not an arbitrary corner: before
     the first animation frame the row would otherwise sit in the bottom-left
     of the stage, momentarily under other layers, and a fast click could miss */
  left:var(--ctl-l,47.6vw);bottom:var(--ctl-b,28.4svh);opacity:var(--ctl-o,1);
  will-change:left,bottom}
@media(max-width:900px){
  .hero-controls{left:var(--ctl-l,8.2vw);bottom:var(--ctl-b,58.2svh)}
}
.hero-controls .film-audio{position:static}
html[data-mode="editorial"] .hero-controls{display:none}
.cut .film-audio{right:calc(var(--gut) + .2rem);
  bottom:calc(var(--barh,0px) + 1.15rem)}
/* the reels carry their key inside their own frame, bottom-left, clear of the
   subject. Small, translucent, legible over a light or a dark frame (§10). */
.reel .film-audio{left:.6rem;bottom:.6rem;width:38px;height:38px}
.reel .film-audio svg{width:15px;height:15px}
html[data-mode="editorial"] .film-audio{display:none}

/* ══ LOADER — V1 integrity treatment, unchanged (founder-approved cat G) ══ */
.loader{position:fixed;inset:0;z-index:200;background:var(--void);
  display:grid;place-items:center;
  transition:clip-path 700ms var(--ease-io);clip-path:inset(0 0 0 0);
  animation:loader-bail 400ms ease 6s forwards}
@keyframes loader-bail{to{visibility:hidden;opacity:0;pointer-events:none}}
html[data-mode="editorial"] .loader{display:none;animation:none}
.loader[data-done="true"]{clip-path:inset(0 0 100% 0);pointer-events:none}
.loader svg{width:min(150px,26vw)}
.loader polygon{fill:var(--fg);opacity:0;transform-box:fill-box;transform-origin:center;
  transform:scale(.82);transition:opacity 460ms var(--ease),transform 620ms var(--ease)}
.loader polygon:nth-child(3){fill:var(--signal)}
.loader.lit polygon{opacity:1;transform:scale(1)}
.loader.lit polygon:nth-child(1){transition-delay:0ms}
.loader.lit polygon:nth-child(2){transition-delay:80ms}
.loader.lit polygon:nth-child(3){transition-delay:160ms}
.loader.lit polygon:nth-child(4){transition-delay:240ms}
.loader.lit polygon:nth-child(5){transition-delay:320ms}
.loader .prog{position:absolute;bottom:2.6rem;left:50%;transform:translateX(-50%);
  width:min(210px,42vw);height:1px;background:var(--hair)}
.loader .prog i{display:block;height:100%;width:0%;background:var(--signal);
  transition:width 260ms linear}

/* ══ SCENE ENGINE BASE ═══════════════════════════════════════════════════ */
.wrap{max-width:1500px;margin:0 auto;padding-inline:var(--gut);width:100%}
html[data-mode="cinematic"] .scene[data-len]{min-height:calc(var(--len,2) * 100svh);position:relative}
html[data-mode="cinematic"] .scene[data-len] .stage{position:sticky;top:0;height:100svh;
  display:grid;align-items:center;overflow:clip;padding-top:var(--safe-top)}
[data-beat]{opacity:0;transform:translateY(26px);visibility:hidden;
  transition:opacity 620ms var(--ease),transform 720ms var(--ease),visibility 0s linear 620ms}
[data-beat].on{opacity:1;transform:none;visibility:visible;transition-delay:0s,0s,0s}
html[data-mode="editorial"] [data-beat]{opacity:1;transform:none;visibility:visible;transition:none}

/* ══ S1 · HERO — "OPEN ON BLACK" (V3) ════════════════════════════════════
   ONE concept, carried the whole way: the page opens as a black field, the
   field becomes a film, and the film hands its black straight to the locked
   reel chapter. Nothing is cropped into a plane, nothing stands on anything,
   nothing is split. There is no second idea competing with the first.

   THE ENTRANCE is a sequence, not a fade-in:
     0.0s  black. The mark alone, centred, quiet.
     0.5s  the film rises out of the black at 1.08 and settles to 1.00 over
           two seconds — a slow push-in that ends exactly when the reading
           starts. The mark cross-fades away as the picture takes over.
     1.5s  the statement is uncovered line by line, 90ms apart, masked from
           below. Type is never faded in from nothing; it is revealed.
     2.2s  the chapter marker and the one quiet action arrive.

   THE EXIT is the transition into the locked section: the statement leaves
   upward, a scrim closes over the picture, and the frame is black again at
   exactly the moment the reels throw in. Two chapters, one continuous field.

   Compositor-only throughout: transform, opacity, clip-path. */

#hero .stage{background:var(--color-black);overflow:clip;color:var(--color-on-black)}

/* THE FILM — full bleed, and the only thing in the frame */
.hero-film{position:absolute;inset:0;z-index:1;overflow:hidden;
  background:var(--color-black);
  opacity:var(--film-in,0);
  transition:opacity 1100ms var(--e-std)}
.hero-film video,.hero-film .rm-poster{position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;will-change:transform}
.hero-film .rm-poster{display:none}
html[data-mode="editorial"] .hero-film video{display:none}
html[data-mode="editorial"] .hero-film .rm-poster{display:block}

/* the edge vignette: it holds the corners so the frame reads as a projected
   image rather than a browser window with a video in it */
.hero-vig{position:absolute;inset:0;z-index:2;pointer-events:none;
  opacity:var(--film-in,0);transition:opacity 1100ms var(--e-std);
  background:radial-gradient(118% 92% at 50% 42%,transparent 42%,rgba(6,6,8,.42) 100%)}

/* the reading scrim. Type never sits on unprotected picture. */
.hero-scrim{position:absolute;inset:auto 0 0 0;height:78%;z-index:3;
  pointer-events:none;opacity:var(--film-in,0);
  transition:opacity 1100ms var(--e-std);
  background:linear-gradient(180deg,rgba(6,6,8,0) 0%,rgba(6,6,8,.20) 32%,
    rgba(6,6,8,.58) 62%,rgba(6,6,8,.88) 100%)}

/* THE MARK — the entire brand presence for the first half-second */
.hero-mark{position:absolute;left:50%;top:50%;z-index:6;translate:-50% -50%;
  width:clamp(46px,5vw,68px);pointer-events:none;
  opacity:var(--mark,0);scale:var(--mark-s,.94);
  transition:opacity 620ms var(--e-std),scale 900ms var(--e-out)}
.hero-mark svg{width:100%;height:auto;fill:var(--color-on-black)}
.hero-mark svg polygon:nth-child(3){fill:var(--signal)}

/* THE STATEMENT — lower left, on the scrim, with the whole right side left
   empty. The negative space is the composition. */
.hero-say{position:absolute;left:0;right:0;bottom:0;z-index:7;
  padding:0 var(--gut) clamp(2.2rem,7svh,4.6rem);
  pointer-events:none;
  transform:translate3d(0,var(--say-y,0),0);opacity:var(--say-o,1)}
.hero-say>*{pointer-events:auto}
.hero-say .chapter{color:#d8d6d2;
  opacity:var(--meta,0);transition:opacity 620ms var(--e-std) 60ms}
.hero-say .chapter .n{color:var(--signal-text-media)}
.hero-say .chapter i{background:var(--color-on-black-muted)}

.hero-h1{margin:var(--s-5) 0 0;max-width:15ch;
  /* the size lives here as well as on the line, so `ch` resolves against the
     display size rather than the inherited body size — that mistake collapsed
     the measure to about 165px and wrapped the statement into four lines */
  font-size:var(--t-hero-size);line-height:var(--t-hero-lh);
  letter-spacing:var(--t-hero-ls);font-weight:var(--t-hero-w)}
.hero-h1 .ln{display:block;overflow:hidden;padding-bottom:.06em;margin-bottom:-.06em}
.hero-h1 .ln i{display:block;font-style:normal;
  font-size:var(--t-hero-size);line-height:var(--t-hero-lh);
  letter-spacing:var(--t-hero-ls);font-weight:var(--t-hero-w);
  color:var(--color-on-black);
  transform:translate3d(0,110%,0);
  transition:transform 900ms var(--e-out)}
#hero.is-said .hero-h1 .ln i{transform:translate3d(0,0,0)}
#hero.is-said .hero-h1 .ln:nth-child(2) i{transition-delay:90ms}
.hero-h1 .dot{color:var(--signal)}

.hero-sub{margin:var(--s-5) 0 0;max-width:46ch;
  font-size:var(--t-lede-size);line-height:var(--t-lede-lh);
  letter-spacing:var(--t-lede-ls);color:#d5d3cf;
  opacity:var(--meta,0);transform:translate3d(0,calc((1 - var(--meta,0)) * 10px),0);
  transition:opacity 700ms var(--e-std) 120ms,transform 700ms var(--e-out) 120ms}

/* the one action in the hero: a piece of type with a direction */
.hero-cue{display:inline-flex;align-items:center;gap:.5em;margin:var(--s-8) 0 0;
  padding:.4rem 0;background:none;border:0;cursor:pointer;
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;color:var(--color-on-black);position:relative;
  opacity:var(--meta,0);transition:opacity 700ms var(--e-std) 200ms}
.hero-cue span{position:relative}
.hero-cue span::after{content:"";position:absolute;left:0;right:0;bottom:-.3em;
  height:1.5px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.hero-cue:hover span::after,.hero-cue:focus-visible span::after{transform:scaleX(1)}
.hero-cue i{font-style:normal;color:var(--signal-text-media);
  transition:transform var(--d-move) var(--e-out)}
.hero-cue:hover i,.hero-cue:focus-visible i{transform:translateY(.24em)}
.hero-cue:active{opacity:.62}

/* the film's identification. It arrives with the statement, at the far right
   of the same baseline, so the frame reads as a titled shot. */
.hero-slate{position:absolute;right:var(--gut);z-index:7;
  bottom:clamp(2.2rem,7svh,4.6rem);text-align:right;max-width:24ch;
  opacity:var(--slate,0);transform:translate3d(0,calc((1 - var(--slate,0)) * 10px),0);
  pointer-events:none;background:none;padding:0;display:block}
.hero-slate>*{margin:0;pointer-events:auto}
.hero-slate .label{color:var(--color-on-black-dim)}
.hero-slate .proj-name{font-size:.9375rem;font-weight:500;letter-spacing:-.008em;
  color:var(--color-on-black);margin-top:.35rem}
.hero-slate-m{margin-top:.3rem;font-size:var(--t-label-size);letter-spacing:.1em;
  color:var(--color-on-black-dim)}
.hero-slate-m a{color:var(--color-on-black-muted);text-decoration:underline;
  text-underline-offset:4px;text-decoration-color:var(--signal)}
@media(max-width:1100px){.hero-slate{display:none}}

/* the sound key: quiet, discoverable, and never over the type.
   V4: the V2 rule above still carried left:var(--ctl-l,47.6vw) and
   bottom:var(--ctl-b,28.4svh) - positions the scene engine stopped writing
   when the hero was rebuilt. With right AND left both set the control
   stretched into a 676px box and the key came to rest in the middle of the
   frame, over the subject, with no anchor. Both axes are released here. */
.hero-controls{position:absolute;z-index:8;right:var(--gut);left:auto;bottom:auto;
  top:calc(var(--safe-top) + .4rem);display:flex;align-items:center;gap:.5rem;
  width:auto;opacity:var(--meta,0);transition:opacity 700ms var(--e-std) 260ms}
.hero-controls .film-audio{position:static}
.film-audio{background:rgba(255,255,255,.10);border:0;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  color:var(--color-on-black);
  transition:background var(--d-state) var(--e-std),transform var(--d-press) var(--e-out)}
.film-audio:hover,.film-audio:focus-visible{background:rgba(255,255,255,.2)}
.film-audio:active{transform:scale(.94)}
html[data-mode="editorial"] .hero-controls{display:none}

/* ── phones: the same sequence, re-authored ── */
@media(max-width:900px){
  .hero-say{padding-bottom:clamp(1.8rem,6svh,3rem)}
  .hero-h1{max-width:none}
  .hero-h1 .ln i{font-size:clamp(2.15rem,9.4vw,3.1rem);line-height:1.0}
  .hero-sub{font-size:.9375rem;max-width:34ch;margin-top:var(--s-4)}
  .hero-cue{margin-top:var(--s-6)}
  .hero-scrim{height:88%}
  .hero-controls{right:var(--gut);left:auto;top:auto;bottom:clamp(1.6rem,5svh,2.6rem)}
}
@media(max-width:900px) and (max-height:800px){
  .hero-h1 .ln i{font-size:clamp(1.95rem,8.4vw,2.6rem)}
  .hero-sub{font-size:.875rem;max-width:30ch}
}

/* ── EDITORIAL EDITION — no choreography, so the hero is a printed frame ── */
html[data-mode="editorial"] #hero .stage{overflow:visible;display:block;height:auto;
  padding-top:0}
html[data-mode="editorial"] .hero-mark,
html[data-mode="editorial"] .hero-vig{display:none}
html[data-mode="editorial"] .hero-film{position:relative;inset:auto;
  width:100%;height:auto;aspect-ratio:1600/720;opacity:1;clip-path:none!important}
html[data-mode="editorial"] .hero-film video,
html[data-mode="editorial"] .hero-film .rm-poster{position:absolute;inset:0;
  transform:none!important;scale:1.07}
html[data-mode="editorial"] .hero-scrim{position:absolute;opacity:1;height:70%}
html[data-mode="editorial"] .hero-say{position:absolute;opacity:1;transform:none}
html[data-mode="editorial"] .hero-h1 .ln i{transform:none}
html[data-mode="editorial"] .hero-say .chapter,
html[data-mode="editorial"] .hero-sub,
html[data-mode="editorial"] .hero-cue{opacity:1;transform:none}
html[data-mode="editorial"] .hero-slate{position:static;opacity:1;transform:none;
  text-align:left;max-width:none;padding:1.2rem var(--gut) 0;color:var(--fg)}
html[data-mode="editorial"] .hero-slate .proj-name{color:var(--fg)}
html[data-mode="editorial"] .hero-slate .label,
html[data-mode="editorial"] .hero-slate-m{color:var(--muted)}
html[data-mode="editorial"] .hero-slate-m a{color:var(--fg)}

@media(prefers-reduced-motion:reduce){
  .hero-h1 .ln i{transform:none!important;transition:none}
  .hero-film,.hero-vig,.hero-scrim,.hero-say .chapter,.hero-sub,.hero-cue,
  .hero-controls,.hero-mark{transition:opacity 240ms linear}
}
/* ══ THE ON-BLACK RAMP ═══════════════════════════════════════════════════
   Every structurally dark region re-points the SAME token names at their
   on-black values, so one rule makes every descendant correct. (Restored
   here: replacing the V2 hero block removed it along with the hero.) */
#commercial .stage,#cinema .stage,#film .stage,#photography .stage{
  --fg:var(--color-on-black);
  --muted:var(--color-on-black-muted);
  --dim:var(--color-on-black-dim);
  --hair:var(--color-hairline-on-black);
  --line:var(--color-hairline-on-black);
  --edge:var(--color-border-on-black);
  --void:var(--color-black);
  --plane:var(--color-black-2);
  --color-media-backing:var(--color-black-2);
  --signal-text:var(--signal-text-media);
  color:var(--color-on-black)}

/* ══ CHAPTER 03 · THE THESIS ══════════════════════════════════════════════
   The lights come up. Two dark chapters have just proved the studio can shoot;
   this is where the page says what it is, once, in white, with almost nothing
   on the screen. It is the hinge of the whole story: everything before it is
   film, everything after it is the range.

   The three disciplines are a numbered LIST, not three cards — they are an
   order, and order is what a list is for. The organisations that commissioned
   the work are one quiet line of type; a marquee was movement that said
   nothing, which is the definition of decoration. */
.claim{background:var(--color-bg-primary);color:var(--color-text-primary);
  padding-block:calc(var(--chapter) * 1.15);position:relative;overflow:clip}
.claim::before{display:none}
.claim-in{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);
  width:100%;display:block}

.claim-say{max-width:19ch}
.claim-h{margin:var(--s-6) 0 0;
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  color:var(--color-text-primary);text-wrap:balance}
.claim-sub{margin:var(--s-6) 0 0;max-width:44ch;
  font-size:var(--t-lede-size);line-height:var(--t-lede-lh);
  letter-spacing:var(--t-lede-ls);color:var(--color-text-secondary)}

/* the three disciplines, as an index */
.claim-list{list-style:none;margin:clamp(3rem,7vw,5.5rem) 0 0;padding:0;
  border-top:1px solid var(--color-hairline)}
.claim-list li{display:grid;grid-template-columns:2.6rem 1fr;
  gap:var(--s-2) var(--s-6);align-items:baseline;
  padding:clamp(1.1rem,2.4vw,1.7rem) 0;
  border-bottom:1px solid var(--color-hairline)}
@media(min-width:820px){
  .claim-list li{grid-template-columns:2.6rem minmax(0,12rem) minmax(0,1fr) auto}
}
.claim-list .n{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);color:var(--signal-text);
  font-variant-numeric:tabular-nums}
.claim-list b{font-weight:600;font-size:var(--t-head-size);
  letter-spacing:var(--t-head-ls);line-height:1.2}
.claim-list p{margin:0;color:var(--color-text-secondary);
  font-size:var(--t-small-size);line-height:var(--t-small-lh);max-width:42ch}
.claim-list .go{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;
  color:var(--color-text-muted);justify-self:end;white-space:nowrap;
  transition:color var(--d-state) var(--e-std)}
.claim-list .go i{font-style:normal;color:var(--signal-text);display:inline-block;
  transition:transform var(--d-move) var(--e-out)}
.claim-list a{display:contents}
.claim-list li:hover .go,.claim-list a:focus-visible .go{color:var(--color-text-primary)}
.claim-list li:hover .go i,.claim-list a:focus-visible .go i{transform:translateX(.32em)}
@media(max-width:819px){
  .claim-list .go{grid-column:2;justify-self:start;margin-top:var(--s-2)}
}

/* the commissioners: named, once, quietly. No ticker. */
.claim-by{margin:clamp(2.4rem,5vw,3.6rem) 0 0;display:flex;flex-wrap:wrap;
  align-items:baseline;gap:var(--s-3) var(--s-6)}
.claim-by dt{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;
  color:var(--color-text-muted);margin:0}
.claim-by dd{margin:0;display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-5);
  font-size:var(--t-small-size);letter-spacing:-.004em;
  color:var(--color-text-primary)}
.claim-by dd span{white-space:nowrap}

/* the reveal: the statement is uncovered, the list arrives a beat later */
html[data-mode="cinematic"] .claim .rv-line{display:block;overflow:hidden;
  padding-bottom:.08em;margin-bottom:-.08em}
html[data-mode="cinematic"] .claim .rv-line>i{display:block;font-style:normal;
  transform:translate3d(0,108%,0);transition:transform 900ms var(--e-out)}
html[data-mode="cinematic"] .claim.on .rv-line>i{transform:none}
html[data-mode="cinematic"] .claim.on .rv-line:nth-child(2)>i{transition-delay:80ms}
html[data-mode="cinematic"] .claim .claim-sub,
html[data-mode="cinematic"] .claim .claim-list,
html[data-mode="cinematic"] .claim .claim-by{
  opacity:0;transform:translate3d(0,14px,0);
  transition:opacity 700ms var(--e-std),transform 700ms var(--e-out)}
html[data-mode="cinematic"] .claim.on .claim-sub{opacity:1;transform:none;transition-delay:140ms}
html[data-mode="cinematic"] .claim.on .claim-list{opacity:1;transform:none;transition-delay:220ms}
html[data-mode="cinematic"] .claim.on .claim-by{opacity:1;transform:none;transition-delay:300ms}
@media(prefers-reduced-motion:reduce){
  .claim .rv-line>i{transform:none!important;transition:none}
  .claim .claim-sub,.claim .claim-list,.claim .claim-by{
    opacity:1!important;transform:none!important;transition:none}
}
/* ══ S2 · COMMERCIAL — the reel wall ═════════════════════════════════════
   Mechanics measured from the founder's reference (motion study in
   04-Design/REFERENCE-VISTA-REELS-MOTION-STUDY.md). Deliberately 2D: the
   reference has perspective:none everywhere, and the depth read comes from an
   opposing tilt, a long horizontal throw, mirrored outward shadow and a
   brightness/scale differential — not from rotateY. */
/* MEDIA FRAMING (V2). Two 9:16 films standing in a room: the room is black,
   which is what a room for looking at film is. */
#commercial .stage{background:var(--color-black)}
.reel-wall{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:clamp(1rem,2.4vw,3rem)}
.reel{--reel-h:min(67svh,625px);height:var(--reel-h);
  width:calc(var(--reel-h) * 9 / 16);flex:0 0 auto;position:relative;
  will-change:transform,filter}
/* ROUNDED REEL EDGE (founder correction). The reference uses 28px on a 334x594
   reel = 0.047 of the reel HEIGHT, so the radius is tied to --reel-h and stays
   proportional at every size instead of being a fixed pixel value.
   The radius is repeated on the media itself: an overflow:hidden parent alone
   lets transformed video bleed past a rounded corner in WebKit, which would
   show exactly the jagged edge the founder is trying to get rid of. */
.reel{--reel-r:clamp(10px, calc(var(--reel-h) * 0.047), 30px)}
.reel .frame{position:relative;width:100%;height:100%;overflow:hidden;background:var(--color-media-backing);
  border-radius:var(--reel-r);isolation:isolate;-webkit-backface-visibility:hidden}
.reel video,.reel .rm-poster{width:100%;height:100%;object-fit:cover;
  border-radius:inherit;-webkit-backface-visibility:hidden}
.reel .rm-poster{position:absolute;inset:0;display:none}
html[data-mode="editorial"] .reel video{display:none}
html[data-mode="editorial"] .reel .rm-poster{display:block;position:static}
/* mirrored outward shadow — the cue that reads as two lifted planes */
.reel-a .frame{box-shadow:-10px 22px 60px rgba(28,25,20,.17)} /* follows border-radius */
.reel-b .frame{box-shadow:10px 22px 60px rgba(28,25,20,.17)}

.reel-centre{text-align:center;display:flex;flex-direction:column;align-items:center;
  gap:.5rem;position:relative;padding-inline:.5rem}
.rc-name{font-family:var(--f-work);font-stretch:118%;font-weight:600;
  font-size:clamp(1.05rem,1.7vw,1.5rem);line-height:1.15;margin:0;
  transition:opacity 420ms var(--ease)}
.rc-name span{display:inline-block;padding-bottom:.22em;border-bottom:2px solid transparent;
  transition:border-color 420ms var(--ease)}
.rc-name.lit span{border-bottom-color:var(--signal)}
.rc-plus{font-family:var(--f-machine);font-size:.8rem;color:var(--dim);margin:.1rem 0}
.rc-thread{display:block;width:clamp(26px,2.6vw,40px);opacity:0;margin:.3rem 0}
.rc-thread svg{width:100%;height:auto;fill:var(--signal)}
.rc-facts{position:relative;width:100%;min-height:5.2em;margin-top:.4rem}
.rc-f{position:absolute;inset:0;margin:0 auto;max-width:30ch;font-size:.86rem;
  text-align:center;transition:opacity 420ms var(--ease)}
@media(max-width:1200px){.reel{--reel-h:min(54svh,470px)}
  .rc-name{font-size:clamp(.95rem,1.5vw,1.2rem)} .rc-f{font-size:.78rem}}

/* ══ S3 · TECHNOLOGY — the drawing becomes the site ══════════════════════ */
#tech .stage{background:var(--tech-ground,var(--color-ground-cool))}
#tech .stage::before{content:"";position:absolute;inset:0;pointer-events:none;
  opacity:var(--grid-o,0);transition:opacity 300ms linear;
  background:
    repeating-linear-gradient(to right,rgba(44,72,124,.11) 0 1px,transparent 1px 64px),
    repeating-linear-gradient(to bottom,rgba(44,72,124,.11) 0 1px,transparent 1px 64px)}
/* .wrap carries width:100% AND horizontal padding. On an absolutely positioned
   element width:100% WINS over the left/right pair, so the box resolved to
   left:58px + width:1440px = a right edge 58px past the viewport, and the
   right-hand readout was clipped away by the stage's overflow:clip. Any
   absolutely positioned .wrap needs width:auto to honour left/right. */
.tech-hud{position:absolute;left:var(--gut);right:var(--gut);top:var(--safe-top);
  width:auto;padding-left:0;padding-right:0;
  display:flex;align-items:baseline;gap:1.2rem;flex-wrap:wrap;
  padding-bottom:.55rem;border-bottom:1px solid rgba(44,72,124,.22);z-index:6}
.tech-hud .rd{margin-left:auto;display:flex;gap:1rem;align-items:baseline}
/* the route/product readout orphaned its last word at 1440 */
.tech-copy .spec{text-wrap:balance}
.tech-body{display:grid;grid-template-columns:1fr;gap:1.4rem;align-items:center;
  padding-top:3.2rem}
@media(min-width:1050px){
  .tech-body{grid-template-columns:minmax(0,30%) minmax(0,1fr);gap:clamp(1.6rem,3vw,3rem)}
}
.tech-copy{position:relative;z-index:4}
.tech-copy .t-tech{color:#1b2029}
.tech-copy .factline{color:#59636f;max-width:34ch}
.tech-rule{height:2px;background:var(--signal);transform-origin:left;
  transform:scaleX(var(--rule,0));margin:1rem 0 1.2rem;max-width:320px}
/* the composed surface: a drafting frame, not OS chrome */
.dun-surface{position:relative;border:1px solid rgba(44,72,124,.24);background:#ffffff;
  width:100%;margin-inline:auto;will-change:width}
.dun-chrome{display:flex;align-items:center;gap:.6rem;height:34px;padding:0 .7rem;
  border-bottom:1px solid rgba(44,72,124,.16);background:#f3f5f8}
.dun-chrome .sq{width:7px;height:7px;background:var(--signal);flex:0 0 auto}
.dun-chrome .u{font-family:var(--f-machine);font-size:.68rem;color:#5b6675;letter-spacing:.05em}
.dun-chrome .cap-chip{margin-left:auto;font-family:var(--f-machine);font-size:.6rem;
  letter-spacing:.13em;text-transform:uppercase;color:#5f6a78;
  border:1px solid rgba(44,72,124,.22);padding:.15rem .4rem}
.dun-view{position:relative;overflow:hidden;background:#fff;will-change:height}
/* height:auto is LOAD-BEARING. The <img> carries width/height attributes; with a
   CSS width but no CSS height the attribute acts as a presentational hint and the
   image renders at its natural PIXEL height — a 2.45x vertical stretch of the
   client's website. This is the aspect distortion the founder rejected. */
.dun-view img{position:absolute;top:0;left:0;display:block;height:auto;will-change:transform}
/* ── the Dunamis live hero mirror ──────────────────────────────────────────
   Faithful to the client's own public implementation: the "globe" is a flat
   equirectangular Earth texture panning inside a circular mask (their real
   mechanic - 70s per revolution), the headline types and deletes with their
   measured timing, the caret blinks with their hard 0.9s cut. Sizes scale
   with --s (band width / 1440) so the band stays in register with the
   capture pixels around it at any surface width. */
.dun-live{position:absolute;top:calc(var(--s,0.7)*112px);left:0;width:100%;
  aspect-ratio:2160/1132;overflow:hidden;opacity:0;pointer-events:none;
  background:linear-gradient(180deg,#0d1830 0%,#0a1526 46%,#091120 100%);
  will-change:transform,opacity;contain:layout paint}
/* the mobile mirror is driven by the engine exactly like the desktop one
   (opacity = paintIn, .run while it is the band on screen). It was left
   display:none by an earlier build, which silently reduced the phone
   presentation to a dead screenshot — the one thing this section must not be. */
.dg{position:absolute;left:50%;top:calc(var(--s,0.7)*-6px);
  width:calc(var(--s,0.7)*1100px);aspect-ratio:1;translate:-50% 0;
  border-radius:50%;overflow:hidden;background:#0a1628;display:block;
  box-shadow:inset -95px -55px 150px rgba(6,12,24,.85),
    inset 38px 24px 70px rgba(255,255,255,.07),
    0 0 120px rgba(47,90,180,.22),0 0 200px rgba(30,60,140,.14)}
.dg::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:radial-gradient(circle at 34% 22%,rgba(10,22,44,.30),rgba(6,12,26,.78) 74%)}
.dg-slide{position:absolute;top:0;bottom:0;left:0;width:240%;display:block;
  background:url(../media/dun-earth-bluemarble.jpg);background-repeat:repeat-x;
  background-size:50% 100%;
  filter:saturate(.82) contrast(1.05) brightness(.5) hue-rotate(-4deg);
  animation:dgSpin 70s linear infinite;animation-play-state:paused}
.dun-live.run .dg-slide{animation-play-state:running}
@keyframes dgSpin{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.dun-live::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:calc(var(--s,0.7)*130px);
  background:linear-gradient(180deg,transparent,#0a1220 88%)}
.dl-content{position:relative;z-index:2;text-align:center;
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  padding-top:calc(var(--s,0.7)*64px)}
.dl-eyebrow{margin:0;font-size:calc(var(--s,0.7)*11.5px);letter-spacing:.22em;
  color:#8fb0ff;font-weight:600}
.dl-eyebrow b{color:#f5a623;font-weight:400;letter-spacing:0}
.dl-h1{margin:calc(var(--s,0.7)*16px) 0 0;font-size:calc(var(--s,0.7)*50px);
  line-height:1.1;font-weight:700;color:#fff;letter-spacing:-.01em}
.dl-typed{color:#5b8cff}
.dl-caret{color:#5b8cff;font-weight:400;animation:dlBlink .9s infinite}
@keyframes dlBlink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
.dl-sub{margin:calc(var(--s,0.7)*14px) auto 0;max-width:calc(var(--s,0.7)*640px);
  font-size:calc(var(--s,0.7)*15px);line-height:1.55;color:#b7c2d8}
.dl-card{display:block;width:calc(var(--s,0.7)*620px);
  margin:calc(var(--s,0.7)*26px) auto 0;background:#fff;
  border-radius:calc(var(--s,0.7)*14px);padding:calc(var(--s,0.7)*14px);
  box-shadow:0 24px 60px rgba(4,10,24,.45);text-align:left}
.dl-row{display:flex;gap:calc(var(--s,0.7)*10px)}
.dl-input{flex:1;border:1px solid #e2e6ee;border-radius:calc(var(--s,0.7)*8px);
  padding:calc(var(--s,0.7)*12px) calc(var(--s,0.7)*14px);color:#9aa3b2;
  font-size:calc(var(--s,0.7)*14px);white-space:nowrap;overflow:hidden}
.dl-btn{background:#2f6bff;color:#fff;border-radius:calc(var(--s,0.7)*8px);
  padding:calc(var(--s,0.7)*12px) calc(var(--s,0.7)*22px);
  font-size:calc(var(--s,0.7)*14px);font-weight:600}
.dl-chips{display:flex;align-items:center;gap:calc(var(--s,0.7)*8px);
  margin-top:calc(var(--s,0.7)*10px);flex-wrap:wrap}
.dl-chips i{background:#eef1f6;border-radius:999px;font-style:normal;
  padding:calc(var(--s,0.7)*6px) calc(var(--s,0.7)*12px);
  font-size:calc(var(--s,0.7)*12px);color:#24304a;font-weight:600}
.dl-viewall{margin-left:auto;color:#2f6bff;font-size:calc(var(--s,0.7)*12px);
  font-weight:600}
.dl-transfer{margin:calc(var(--s,0.7)*20px) 0 0;color:#cdd6e6;
  font-size:calc(var(--s,0.7)*13px)}
.dl-transfer u{color:#fff;font-weight:600;text-underline-offset:3px}
.dl-pill{display:inline-flex;align-items:center;gap:calc(var(--s,0.7)*12px);
  margin-top:calc(var(--s,0.7)*22px);background:#fff;border-radius:999px;
  padding:calc(var(--s,0.7)*8px) calc(var(--s,0.7)*18px) calc(var(--s,0.7)*8px) calc(var(--s,0.7)*10px)}
.dl-avs{display:inline-flex;align-items:center}
.dl-avs img{width:calc(var(--s,0.7)*30px);height:calc(var(--s,0.7)*30px);
  border-radius:50%;object-fit:cover;border:2px solid #fff;
  margin-right:calc(var(--s,0.7)*-9px)}
.dl-avs i{width:calc(var(--s,0.7)*30px);height:calc(var(--s,0.7)*30px);
  border-radius:50%;background:#e8efff;color:#2f6bff;font-style:normal;
  font-size:calc(var(--s,0.7)*10px);font-weight:700;display:inline-flex;
  align-items:center;justify-content:center;border:2px solid #fff}
.dl-pill-t{font-size:calc(var(--s,0.7)*12px);color:#212b40;text-align:left;
  line-height:1.35}
.dl-pill-t b{color:#0d1730}
.dl-badges{display:flex;justify-content:center;gap:calc(var(--s,0.7)*10px);
  margin-top:calc(var(--s,0.7)*22px);flex-wrap:wrap}
.dl-badges i{border:1px solid rgba(255,255,255,.22);border-radius:999px;
  padding:calc(var(--s,0.7)*7px) calc(var(--s,0.7)*14px);font-style:normal;
  font-size:calc(var(--s,0.7)*11.5px);color:#d6deeb;
  background:rgba(10,20,40,.35)}
.dl-cue{display:flex;flex-direction:column;align-items:center;
  gap:calc(var(--s,0.7)*8px);margin-top:calc(var(--s,0.7)*26px)}
.dl-mouse{width:calc(var(--s,0.7)*18px);height:calc(var(--s,0.7)*30px);
  border:1.5px solid rgba(255,255,255,.5);border-radius:calc(var(--s,0.7)*10px);
  position:relative;display:block}
.dl-mouse::after{content:"";position:absolute;left:50%;top:calc(var(--s,0.7)*6px);
  width:calc(var(--s,0.7)*3px);height:calc(var(--s,0.7)*6px);translate:-50% 0;
  border-radius:2px;background:rgba(255,255,255,.7)}
.dun-live.run .dl-mouse::after{animation:dlBob 2.6s ease-in-out infinite}
@keyframes dlBob{0%,100%{transform:translateY(0)}50%{transform:translateY(6px)}}
.dl-cue span{font-size:calc(var(--s,0.7)*10px);letter-spacing:.22em;
  color:#93a0b8}
/* ── the mobile hero mirror: same content, the phone layout ── */
.dun-live-m{top:calc(var(--sm,0.85)*115px);aspect-ratio:1170/2955;
  background:linear-gradient(180deg,#0d1830 0%,#0a1526 40%,#091120 100%)}
.dun-live-m::after{height:calc(var(--sm,0.85)*140px)}
.dun-live-m .dg{top:calc(var(--sm,0.85)*140px);width:calc(var(--sm,0.85)*640px)}
.dun-live-m .dl-content{padding-top:calc(var(--sm,0.85)*66px)}
.dun-live-m .dl-eyebrow{font-size:calc(var(--sm,0.85)*12px);line-height:1.6;
  padding-inline:calc(var(--sm,0.85)*30px)}
.dun-live-m .dl-h1{font-size:calc(var(--sm,0.85)*33px);
  margin-top:calc(var(--sm,0.85)*14px)}
.dun-live-m .dl-sub{font-size:calc(var(--sm,0.85)*16px);
  max-width:calc(var(--sm,0.85)*330px);margin-top:calc(var(--sm,0.85)*16px)}
.dun-live-m .dl-card{width:calc(var(--sm,0.85)*330px);
  border-radius:calc(var(--sm,0.85)*16px);padding:calc(var(--sm,0.85)*16px);
  margin-top:calc(var(--sm,0.85)*30px)}
.dun-live-m .dl-row{flex-direction:column}
.dun-live-m .dl-input{font-size:calc(var(--sm,0.85)*15px);
  padding:calc(var(--sm,0.85)*13px) calc(var(--sm,0.85)*14px)}
.dun-live-m .dl-btn{text-align:center;font-size:calc(var(--sm,0.85)*15px);
  padding:calc(var(--sm,0.85)*13px)}
.dun-live-m .dl-chips i{font-size:calc(var(--sm,0.85)*13px)}
.dun-live-m .dl-viewall{font-size:calc(var(--sm,0.85)*13px)}
.dun-live-m .dl-transfer{font-size:calc(var(--sm,0.85)*14px);
  margin-top:calc(var(--sm,0.85)*24px)}
.dun-live-m .dl-pill{border-radius:calc(var(--sm,0.85)*16px);
  width:calc(var(--sm,0.85)*330px);justify-content:flex-start;
  padding:calc(var(--sm,0.85)*12px);margin-top:calc(var(--sm,0.85)*26px)}
.dun-live-m .dl-pill-t{font-size:calc(var(--sm,0.85)*13px)}
.dun-live-m .dl-avs img,.dun-live-m .dl-avs i{width:calc(var(--sm,0.85)*34px);
  height:calc(var(--sm,0.85)*34px)}
.dun-live-m .dl-badges{flex-direction:column;align-items:center;
  gap:calc(var(--sm,0.85)*10px);margin-top:calc(var(--sm,0.85)*28px)}
.dun-live-m .dl-badges i{font-size:calc(var(--sm,0.85)*13px);
  padding:calc(var(--sm,0.85)*9px) calc(var(--sm,0.85)*16px)}
.dun-live-m .dl-cue{margin-top:calc(var(--sm,0.85)*30px)}
html[data-mode="editorial"] .dun-live{display:none}
.dun-scroll-rail{position:absolute;top:6px;bottom:6px;right:4px;width:3px;
  background:rgba(0,0,0,.10);z-index:3}
.dun-scroll-rail i{position:absolute;left:0;width:100%;background:rgba(0,0,0,.34);
  height:var(--thumb-h,20%);top:var(--thumb-y,0%)}
.tech-facts{margin-top:1.1rem}
.tech-facts .factline{color:#59636f;max-width:64ch}
.route-ribbon{display:flex;align-items:center;gap:5px;margin-top:.8rem;flex-wrap:wrap}
.route-ribbon i{width:16px;height:2px;background:rgba(44,72,124,.24);display:block}
.route-ribbon i.on{background:var(--signal)}

/* ══ CHAPTER 04 · PHOTOGRAPHY — "THE GALLERY" (V3) ════════════════════════
   The previous two attempts were both essays on black. This one is a room.

   White, and a great deal of it. The photographs are hung at four different
   sizes with real distance between them, and the distance is the design: a
   print needs air around it before the eye will read it as a print rather
   than as content. One frame — the fourth — takes the entire viewport, and it
   only lands because the three before it were held back.

   Captions live in the margins, never on a picture, set in the instrument
   voice so they read as a museum label rather than as a headline competing
   with the image.

   The pace: hold, hold, pair, FULL, release. */
.ph2{background:var(--color-bg-primary);color:var(--color-text-primary);
  position:relative;overflow:clip;
  padding-block:calc(var(--chapter) * 1.1) var(--chapter)}
.ph2::before{display:none}

.ph2-in,.ph2-open{max-width:var(--max);margin-inline:auto;
  padding-inline:var(--gut);width:100%}
.ph2-open{margin-bottom:clamp(4rem,11vw,9rem)}
.ph2-marker{margin:0}
.ph2-h{margin:var(--s-6) 0 0;max-width:15ch;
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  color:var(--color-text-primary)}
.ph2-h i{font-style:normal;color:var(--color-text-muted)}
.ph2-sub{margin:var(--s-6) 0 0;max-width:44ch;
  font-size:var(--t-lede-size);line-height:var(--t-lede-lh);
  letter-spacing:var(--t-lede-ls);color:var(--color-text-secondary)}

/* ── the frames ── */
.ph2-fig{margin:0;position:relative}
.ph2-win{display:block;position:relative;overflow:hidden;
  background:var(--color-bg-secondary);border-radius:var(--r-media)}
.ph2-win img{position:absolute;inset:-6% 0;width:100%;height:112%;
  object-fit:cover;display:block;
  translate:0 var(--pxy,0px);scale:1;will-change:translate,scale}

/* the museum label */
.ph2-cap{display:flex;flex-direction:column;gap:.3rem;
  margin:var(--s-4) 0 0}
.ph2-cap .n{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);color:var(--signal-text);
  font-variant-numeric:tabular-nums}
.ph2-cap b{font-weight:500;font-size:var(--t-small-size);
  letter-spacing:-.004em;color:var(--color-text-primary)}
.ph2-cap span:last-child{font-family:var(--f-mono);
  font-size:var(--t-label-size);letter-spacing:.11em;text-transform:uppercase;
  color:var(--color-text-muted)}

/* 01 · held small and high, with the whole right side empty */
.ph2-01{max-width:var(--max);margin:0 auto;padding-inline:var(--gut);width:100%}
.ph2-01 .ph2-win{width:min(46%,600px);aspect-ratio:4/5}
.ph2-01 .ph2-cap{width:min(46%,600px)}

/* 02 + 03 · a pair at two scales, offset, with a long fall between them */
.ph2-pair{max-width:var(--max);margin:clamp(5rem,13vw,11rem) auto 0;
  padding-inline:var(--gut);width:100%;
  display:grid;grid-template-columns:repeat(12,1fr);
  gap:clamp(1.5rem,3vw,3rem);align-items:start}
.ph2-02{grid-column:7 / 13}
.ph2-02 .ph2-win{aspect-ratio:3/2}
.ph2-03{grid-column:2 / 6;margin-top:clamp(4rem,14vw,12rem)}
.ph2-03 .ph2-win{aspect-ratio:9/16}

/* 04 · THE FULL FRAME. Edge to edge, nearly the whole viewport. It is the
   only picture in the chapter allowed to take everything. */
.ph2-04{margin-top:clamp(5rem,14vw,12rem)}
.ph2-04 .ph2-win{width:100%;height:min(92svh,940px);border-radius:0}
.ph2-04 .ph2-cap{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut)}

/* 05 · the release: a wide frame back inside the margin */
.ph2-05{max-width:var(--max);margin:clamp(4.5rem,11vw,9rem) auto 0;
  padding-inline:var(--gut);width:100%}
.ph2-05 .ph2-win{width:min(72%,960px);margin-left:auto;aspect-ratio:16/9}
.ph2-05 .ph2-cap{width:min(72%,960px);margin-left:auto}

/* the close */
.ph2-foot{max-width:var(--max);margin:clamp(3.5rem,8vw,6rem) auto 0;
  padding:var(--s-5) var(--gut) 0;width:100%;
  border-top:1px solid var(--color-hairline);
  display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s-4) var(--s-8);flex-wrap:wrap}
.ph2-count{margin:0;font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;
  color:var(--color-text-muted);font-variant-numeric:tabular-nums}
.ph2-count .n{color:var(--signal-text)}
.ph2-foot a{display:inline-flex;align-items:center;gap:.45em;
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;color:var(--color-text-primary);position:relative;
  border:0;padding:0}
.ph2-foot a span{position:relative}
.ph2-foot a span::after{content:"";position:absolute;left:0;right:0;bottom:-.3em;
  height:1.5px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.ph2-foot a:hover span::after,.ph2-foot a:focus-visible span::after{transform:scaleX(1)}
.ph2-foot a i{font-style:normal;color:var(--signal-text);
  transition:transform var(--d-move) var(--e-out)}
.ph2-foot a:hover i,.ph2-foot a:focus-visible i{transform:translateX(.3em)}

/* ── MOTION — the print is uncovered, then settles. Nothing fades in. ── */
html[data-mode="cinematic"] .ph2-fig[data-ph] .ph2-win{
  clip-path:inset(0 0 0 0);transition:clip-path 1.05s var(--e-out)}
html[data-mode="cinematic"] .ph2-fig[data-ph]:not(.on) .ph2-win{clip-path:inset(0 0 100% 0)}
html[data-mode="cinematic"] .ph2-fig[data-ph] .ph2-win img{transition:scale 1.5s var(--e-out)}
html[data-mode="cinematic"] .ph2-fig[data-ph]:not(.on) .ph2-win img{scale:1.06}
html[data-mode="cinematic"] .ph2-fig[data-ph] .ph2-cap{
  transition:opacity .8s var(--e-std) .22s,translate .8s var(--e-out) .22s}
html[data-mode="cinematic"] .ph2-fig[data-ph]:not(.on) .ph2-cap{opacity:0;translate:0 10px}
html[data-mode="cinematic"] .ph2-03 .ph2-win,
html[data-mode="cinematic"] .ph2-03 .ph2-win img{transition-delay:.12s}
@media(prefers-reduced-motion:reduce){
  .ph2-fig[data-ph] .ph2-win{clip-path:none!important;transition:none!important}
  .ph2-fig[data-ph] .ph2-win img{scale:1!important;translate:none!important;transition:none!important}
  .ph2-fig[data-ph] .ph2-cap{opacity:1!important;translate:none!important;transition:none!important}
}

/* ── phones and tablets: the room is narrower, so the hang changes.
   The pair keeps its two scales by staying two different widths. ── */
@media(max-width:900px){
  .ph2-01 .ph2-win,.ph2-01 .ph2-cap{width:min(82%,520px)}
  .ph2-pair{display:block;margin-top:clamp(3.5rem,10vw,6rem)}
  .ph2-02{width:100%}
  .ph2-03{width:58%;margin:clamp(2.4rem,8vw,4rem) 0 0 auto}
  .ph2-04{margin-top:clamp(3.5rem,10vw,6rem)}
  .ph2-04 .ph2-win{height:min(76svh,660px)}
  .ph2-05{margin-top:clamp(3.5rem,10vw,6rem)}
  .ph2-05 .ph2-win,.ph2-05 .ph2-cap{width:100%}
  .ph2-h{max-width:none}
}
@media(max-width:520px){
  .ph2-01 .ph2-win,.ph2-01 .ph2-cap{width:100%}
  .ph2-03{width:72%}
  .ph2-04 .ph2-win{height:min(68svh,540px)}
}
/* ══ S5 · CINEMA — "The Edit" ════════════════════════════════════════════
   Six full-bleed cuts on void between letterbox bars: a second couple's ask
   opens the edit (portfolio breadth — the hero owns the water footage), then
   the hero couple's day runs in true order. Scroll advances the edit: each frame arrives through a
   diagonal blade wipe (hard-scrubbed; the easing lives in the scroll mapping),
   and every cut keeps a slow live settle so no still ever sits dead. The bars
   carry ALL type — nothing is ever written over the picture. */
/* THE ONE DARK ROOM (S3). The edit is the single place on this page where a
   dark ground genuinely improves the composition: six full-bleed cuts between
   letterbox bars that carry all the type. Warm charcoal, never #000. */
#cinema .stage{background:var(--color-black);color:var(--color-on-black);overflow:clip}
.cin-frame{position:absolute;inset:0;z-index:1}
.cut{position:absolute;inset:0;margin:0;visibility:hidden;will-change:clip-path}
.cut img,.cut video{position:absolute;left:50%;top:50%;width:100%;height:auto;
  transform:translate(-50%,-50%);will-change:transform}
/* the two Vidflow-fed cuts keep the stills' 1600:720 band; the 16:9 stream
   cover-crops into it exactly as the earlier local excerpts were reframed */
.cut video{aspect-ratio:1600/720;object-fit:cover}
/* captions are for the editorial edition and assistive tech; the bars carry
   the visible slate in cinematic mode */
.cut-cap{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}
.cin-top,.cin-bot{position:absolute;left:var(--gut);right:var(--gut);z-index:6;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  pointer-events:none;opacity:var(--cinui,0)}
/* the fixed nav owns the upper ~70px of the top bar, so the title hangs from
   the bar's BOTTOM edge instead of its centre */
.cin-top{top:calc(var(--barh,0px) - 14px);translate:0 -100%}
.cin-bot{bottom:calc(var(--barh,0px)/2);translate:0 50%}
.cin-t{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 40,'wght' 420,'SOFT' 0,'WONK' 0;font-weight:400;
  font-size:clamp(1rem,1.5vw,1.4rem);line-height:1;color:#fff;margin:0}
.cin-t i{font-style:italic;color:#e8b7b9}
.cin-meta{margin:0;color:rgba(255,255,255,.72)}
.cin-meta a{color:#fff;text-decoration:underline;text-underline-offset:3px;pointer-events:auto}
.slate{position:absolute;left:0;top:50%;translate:0 -50%;margin:0;opacity:0;
  font-family:var(--f-machine);font-size:.62rem;letter-spacing:.13em;
  text-transform:uppercase;color:#cfcdc8;white-space:nowrap}
.cin-meta{margin-left:auto}
.cin-count{margin-left:1.2rem;width:min(180px,20vw);height:2px;
  background:rgba(255,255,255,.14)}
.cin-count-i{display:block;height:100%;background:var(--signal);
  transform-origin:left;transform:scaleX(var(--cinp,0))}
/* phone: the cuts render taller with a centre-weighted crop (films are
   reframed for portrait exactly this way), and the bottom bar keeps only the
   slate and the progress line */
@media(max-width:700px){
  .cut img,.cut video{width:auto;height:46svh;max-width:none}
  .cin-meta{display:none}
  .slate{font-size:.56rem;letter-spacing:.1em;max-width:64vw;white-space:normal;line-height:1.5}
  .cin-t{font-size:1rem}
}
/* editorial edition: the same story as composed stills with their captions */
html[data-mode="editorial"] #cinema .stage{background:var(--color-black);color:var(--color-on-black)}
html[data-mode="editorial"] .cin-frame{position:static;display:grid;gap:1.4rem;
  padding:0 var(--gut) 2rem;max-width:1240px;margin:0 auto}
html[data-mode="editorial"] .cut{position:static;visibility:visible;clip-path:none!important}
html[data-mode="editorial"] .cut img,html[data-mode="editorial"] .cut video{
  position:static;transform:none;width:100%;height:auto}
html[data-mode="editorial"] .cut-cap{position:static;width:auto;height:auto;
  clip-path:none;margin-top:.5rem;font-family:var(--f-machine);font-size:.62rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--color-on-dark-dim)}
html[data-mode="editorial"] .cin-top{position:static;translate:none;opacity:1;
  padding:2.4rem var(--gut) 1.4rem;max-width:1240px;margin:0 auto}
html[data-mode="editorial"] .cin-bot{display:none}

/* ══ S6 · STUDIO — "THE REGISTER" ═══════════════════════════════════════
   The unit is a CREDIT standing in a row: index, print, name, role. All five
   are present at once and each sits on its own baseline, so the row reads as a
   composition and not as five identical cards.
   Warm ground — human photography should feel warmer than the cool technology
   scene. Focus is carried by LIGHT: the key travels the register and returns
   colour to the credit it is on. Nothing is ever hidden to create focus. */
#studio .stage{background:radial-gradient(112% 84% at 26% 8%,#fbf7f0 0%,#f5efe4 46%,#efe8db 100%);
  color:#211c15;perspective:none;overflow:clip}
.st-key{position:absolute;left:50%;top:50%;width:150vh;height:150vh;margin:-75vh 0 0 -75vh;
  pointer-events:none;opacity:0;z-index:1;will-change:transform,opacity;
  background:radial-gradient(closest-side,rgba(206,152,86,.15),rgba(196,138,68,.07) 52%,transparent 74%)}
/* the barely-visible red ambient the founder asked for (§23): one soft wash in
   the far corner of the room, nowhere near a glowing blob */
.st-amb{position:absolute;right:-10%;top:-14%;width:min(62vw,900px);height:70svh;
  z-index:0;pointer-events:none;opacity:var(--amb,0);
  background:radial-gradient(closest-side,rgba(218,31,38,.09),transparent 72%);
  filter:blur(30px)}
.st-grain{position:absolute;inset:0;z-index:2;pointer-events:none;opacity:.045;
  mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E")}
.st-pool{position:absolute;left:50%;bottom:-6%;width:min(72vw,980px);height:32svh;
  translate:-50% 0;z-index:0;pointer-events:none;opacity:0;will-change:transform,opacity;
  background:radial-gradient(closest-side,rgba(203,148,88,.16),transparent 76%)}
/* the oversized word the founder asked for: set once, very low contrast, and
   drifting at its own rate behind the people so the room has a back wall */
.st-word{position:absolute;left:50%;bottom:-2%;translate:-50% 0;z-index:0;
  font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:"opsz" 144,"wght" 300,"SOFT" 0,"WONK" 0;
  font-size:clamp(150px,27vw,430px);line-height:.78;letter-spacing:-.05em;
  color:rgba(74,56,34,.055);pointer-events:none;white-space:nowrap;
  will-change:transform}
.st-ghost{position:absolute;right:-6%;top:8%;width:min(46vw,620px);z-index:0;
  opacity:.045;pointer-events:none}
.st-ghost svg{width:100%;height:auto;fill:#7a5a33}

.st-grid{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;
  justify-content:center;padding-top:var(--safe-top);
  gap:clamp(1.2rem,3.2svh,2.4rem)}
.st-head{max-width:52ch}

.st-reg{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(5,1fr);gap:clamp(.7rem,1.7vw,1.7rem);align-items:end}
.st-cr{display:flex;flex-direction:column;gap:.5rem;margin:0;
  will-change:transform,opacity}
/* each credit on its own baseline — the row is a composition, not a grid */
.st-cr:nth-child(2){padding-bottom:clamp(1.1rem,3.2svh,2.7rem)}
.st-cr:nth-child(3){padding-bottom:clamp(.2rem,.8svh,.7rem)}
.st-cr:nth-child(4){padding-bottom:clamp(1.7rem,4.4svh,3.6rem)}
.st-cr:nth-child(5){padding-bottom:clamp(.5rem,1.5svh,1.3rem)}

/* Round 2, §20/§21/§24: the travelling spotlight is GONE. Every credit stays
   fully visible, in colour and properly exposed for the whole section — nobody
   is dimmed so that somebody else can be lit. The only grade left is a light
   shared warm bias, which is what keeps five prints shot on five different days
   against five different backgrounds reading as one set.
   Corners are lightly rounded (12px), not carded. */
.st-pt{margin:0;overflow:hidden;background:#e7e0d3;aspect-ratio:4/5;
  border-radius:12px}
.st-pt img{width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.95) contrast(1.02) sepia(.045);
  transform:scale(1.012);
  transition:transform .9s var(--eo)}
/* the one desktop hover: a very small crop shift. No dark-to-colour reveal,
   because nothing is dark to begin with. */
.st-cr:hover .st-pt img,
.st-cr:focus-within .st-pt img{transform:scale(1.045)}

.st-n{margin:.15rem 0 0;font-family:var(--f-machine);font-size:.64rem;
  letter-spacing:.16em;transition:color .5s var(--eo)}
.st-n{color:var(--signal-text)}   /* LC-UX-011/021: derived red on small text */
.st-name{margin:0;font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:"opsz" 60,"wght" 400,"SOFT" 0,"WONK" 0;
  font-size:clamp(.98rem,1.45vw,1.32rem);line-height:1.06;letter-spacing:-.006em;
  color:#211c15}
.st-role{margin:0;font-family:var(--f-machine);font-size:.6rem;letter-spacing:.13em;
  text-transform:uppercase;color:#6b6053;line-height:1.5}
.st-foot{color:#6b6053}
.st-foot a{color:#211c15;text-decoration:underline;text-underline-offset:4px}

/* ── phones: the register becomes two columns and the word gets out of the way ── */
@media(max-width:900px){
  /* the register has to fit one pinned viewport, so the prints square up and
     the stagger becomes a small offset rather than a full step */
  .st-grid{gap:clamp(.7rem,1.8svh,1.2rem)}
  .st-head .factline{font-size:.86rem;line-height:1.5;max-width:40ch}
  .st-pt{aspect-ratio:1/1}
  .st-reg{grid-template-columns:repeat(2,1fr);gap:clamp(.6rem,2.4vw,1.1rem);
    align-items:start}
  .st-cr{gap:.32rem}
  .st-cr:nth-child(n){padding-bottom:0}
  .st-cr:nth-child(2),.st-cr:nth-child(4){padding-top:clamp(.5rem,1.8svh,1.1rem)}
  /* the fifth credit sits alone on the last row, so it takes the full width and
     runs as a horizontal credit rather than leaving a hole in the grid */
  /* the fifth credit is alone on the last row: it runs horizontally, as a
     credit line with its print, and stops short of the fixed motion toggle */
  .st-cr:nth-child(5){grid-column:1 / -1;display:grid;
    grid-template-columns:24% 1fr;grid-template-rows:auto auto auto;
    align-content:center;column-gap:.9rem;row-gap:.12rem;
    padding-top:clamp(.4rem,1.4svh,.9rem);padding-right:120px}
  .st-cr:nth-child(5) .st-pt{grid-column:1;grid-row:1 / 4;aspect-ratio:4/5}
  .st-cr:nth-child(5) .st-n{grid-column:2;grid-row:1}
  .st-cr:nth-child(5) .st-name{grid-column:2;grid-row:2}
  .st-cr:nth-child(5) .st-role{grid-column:2;grid-row:3}
  .st-word{font-size:clamp(110px,34vw,220px);bottom:2%}
  .st-head{max-width:none}
  .st-ghost{display:none}
}
@media(max-width:520px){
  .st-name{font-size:.92rem}
  .st-role{font-size:.55rem;letter-spacing:.1em}
}

/* EDITORIAL EDITION — the register as a plain, composed credit list */
html[data-mode="editorial"] .st-grid{position:static;padding:0 var(--gut);display:block}
html[data-mode="editorial"] .st-reg{margin-top:1.8rem}
html[data-mode="editorial"] .st-cr{opacity:1!important;transform:none!important;
  padding-bottom:0!important;padding-top:0!important}
html[data-mode="editorial"] .st-pt img{filter:none;transform:none}
/* .st-amb belongs with these: in the editorial edition the stage is static,
   so an absolutely positioned wash at right:-10% resolves against a different
   containing block, escapes, and pushes the document 144px wide. It was the
   only source of horizontal overflow on the site. */
html[data-mode="editorial"] .st-key,
html[data-mode="editorial"] .st-pool,
html[data-mode="editorial"] .st-amb,
html[data-mode="editorial"] .st-word,
html[data-mode="editorial"] .st-ghost{display:none}
html[data-mode="editorial"] .st-foot{margin-top:1.6rem}
/* ══ S7 · CONVERSION — "The Table" ══════════════════════════════════════
   Rejected twice as a cream rectangle with type and buttons. So the light plane
   is no longer the scene — it is an OBJECT IN A DARK ROOM. It occupies a little
   over half the frame, tilted in perspective, and the five projects the visitor
   has just seen drift in around it and converge toward the CTA. The room is
   dark, which is also what connects this scene to the ones on either side. */
/* ══ S7 · CONVERSION — "The Convergence" ═════════════════════════════════
   Founder scored the deck 0/10 twice. No card, no cream, no white field: the
   room IS the composition. The five projects the visitor has just seen fly out
   of depth, align along one axis and compress into the red thread — the work
   literally resolves into the line under the ask. The type then sets around
   that line, and the controls arrive on the same axis. Dark, dimensional,
   continuous with the studio before it and the finale after it. */
#engage .stage{background:radial-gradient(130% 90% at 50% 118%,#efece6 0%,#f5f3ef 48%,var(--void) 100%);
  overflow:clip}
.cv-room{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:var(--room,0)}
.cv-room .hz{position:absolute;left:8%;right:8%;top:var(--hzy,58%);height:1px;
  background:linear-gradient(90deg,transparent,rgba(28,27,26,.14) 22%,rgba(28,27,26,.14) 78%,transparent)}
.cv-room .fl{position:absolute;left:-18%;right:-18%;top:var(--hzy,58%);bottom:-4%;
  background:repeating-linear-gradient(to right,rgba(28,27,26,.07) 0 1px,transparent 1px 96px);
  transform:perspective(820px) rotateX(72deg);transform-origin:50% 0;
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 36%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 36%)}
.cv-frags{position:absolute;inset:0;z-index:2;pointer-events:none}
.cv-frag{position:absolute;left:50%;top:50%;width:clamp(116px,12vw,186px);
  will-change:transform,opacity;opacity:0}
.cv-frag img{width:100%;height:clamp(74px,8vw,118px);object-fit:cover;display:block;
  border-radius:8px;box-shadow:0 16px 38px rgba(28,25,20,.16)}
.cv-frag b{display:block;margin-top:.4rem;font-family:var(--f-machine);font-size:.54rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);white-space:nowrap;
  text-align:center}
.cv-core{position:relative;z-index:3;height:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding-top:var(--safe-top)}
.cv-head{font-size:clamp(2rem,4.6vw,3.9rem)}
.cv-head .ln{display:block;overflow:clip}
.cv-head .ln i{display:block;font-style:normal;will-change:transform;transform:translateY(112%);transition:transform 560ms var(--ease)}
.cv-head .ln i.set{transform:none}
.cv-yours{transition:color 420ms var(--ease)}
.cv-yours.on{color:var(--signal)}
.cv-thread{display:block;width:min(46vw,560px);height:2px;background:var(--signal);
  transform:scaleX(var(--cvt,0));transform-origin:50% 50%;margin-top:1.2rem;
  box-shadow:0 0 9px rgba(218,31,38,.22)}
.cv-sub{margin-top:1.2rem;max-width:52ch}
.cv-actions{display:flex;gap:.8rem;margin-top:1.5rem;justify-content:center;flex-wrap:wrap}
.cv-note{margin-top:1rem;color:var(--dim);max-width:44ch;line-height:1.5}
.cv-lines{margin-top:1.7rem;color:var(--muted);letter-spacing:.18em}
.cv-mail{margin-top:.45rem}
.cv-mail a{color:var(--fg);text-decoration:underline;text-underline-offset:4px}
@media(max-width:700px){.cv-frag{width:clamp(78px,21vw,104px)}
  .cv-frag img{height:clamp(50px,13vw,66px)}
  .cv-thread{width:min(72vw,560px)}}
html[data-mode="editorial"] #engage .stage{background:var(--void);color:var(--fg)}
html[data-mode="editorial"] .cv-room,html[data-mode="editorial"] .cv-frags{display:none}
html[data-mode="editorial"] .cv-core{height:auto;padding:3rem var(--gut)}
html[data-mode="editorial"] .cv-head .ln i{transform:none;transition:none}
html[data-mode="editorial"] .cv-thread{transform:scaleX(1)}

/* ══ S8 · FINALE — "The Aperture Closes" ════════════════════════════════
   The founder scored the old finale 0/10. This is a three-act arrival: blades
   fly home along their own centroid rays carrying the names of the scenes just
   passed, the ground changes from the conversion deck's cream to void, the mark
   LOCKS to exact canonical geometry and holds, then the statement prints and
   the gate opens. Closing type is deliberately unlike the hero. */
#finale .stage{background:var(--void);overflow:clip}
/* the stage the mark arrives onto: a floor with a horizon, atmospheric falloff
   and a receding plane grid. Restrained — no particles, no screensaver. */
.fin-stage{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:var(--stage-o,0)}
.fin-stage{will-change:transform}
.fin-stage .floor{position:absolute;left:-20%;right:-20%;bottom:-6%;height:58%;
  background:
    repeating-linear-gradient(to right,rgba(28,27,26,.07) 0 1px,transparent 1px 90px),
    linear-gradient(180deg,rgba(28,27,26,.05) 0%,rgba(28,27,26,0) 72%);
  transform:perspective(760px) rotateX(74deg);transform-origin:50% 100%}
/* the red in the room comes from the red plane itself: a pool of its light on
   the floor under the mark — shaped, placed, and small. Not a blob. */
.fin-stage .pool{position:absolute;left:4%;bottom:2%;width:min(48vh,440px);height:min(22vh,200px);
  background:radial-gradient(58% 74% at 50% 100%,rgba(218,31,38,.11),transparent 72%)}
.fin-stage .horizon{position:absolute;left:0;right:0;top:42%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(28,27,26,.16) 22%,rgba(28,27,26,.16) 78%,transparent)}
.fin-mark::after{content:"";position:absolute;left:6%;right:6%;bottom:-14%;height:16%;
  background:radial-gradient(ellipse at 50% 0%,rgba(28,25,20,.13),transparent 70%);
  filter:blur(8px);z-index:0}
html[data-mode="editorial"] .fin-stage{display:none}
.fin-plate{position:relative;z-index:2;display:grid;grid-template-columns:1fr;
  gap:clamp(1.2rem,3vh,2.2rem);align-content:center}
@media(min-width:960px){
  .fin-plate{grid-template-columns:repeat(12,1fr);column-gap:clamp(16px,1.6vw,28px);
    row-gap:clamp(1.1rem,2.6vh,2rem)}
  .fin-mark{grid-column:1/5;grid-row:1;justify-self:start;align-self:center}
  .fin-words{grid-column:6/13;grid-row:1;align-self:center}
  .fin-gate{grid-column:6/13;grid-row:2}
  .fin-meta{grid-column:6/13;grid-row:3}
}
.fin-mark{position:relative;width:clamp(150px,17vw,244px);aspect-ratio:1}
.fin-mark svg{width:100%;height:100%;overflow:visible;position:relative;z-index:2}
.fin-mark polygon{fill:var(--markink,var(--fg));transform-box:fill-box;transform-origin:center;
  will-change:transform,opacity}
.fin-mark polygon:nth-child(3){fill:var(--signal)}
.fin-core{position:absolute;inset:-12%;z-index:1;pointer-events:none;opacity:0;
  background:radial-gradient(circle at 50% 50%,rgba(218,31,38,.14),transparent 58%)}
/* the mark stands ON the floor: a mirrored trace below the baseline. The blur
   lives on the reflection only — never on the mark. */
.fin-reflect{position:absolute;left:0;top:99%;width:100%;aspect-ratio:1;z-index:0;
  pointer-events:none;transform:scaleY(-1);opacity:0;filter:blur(3px);
  -webkit-mask-image:linear-gradient(0deg,transparent 46%,rgba(0,0,0,.22) 100%);
  mask-image:linear-gradient(0deg,transparent 46%,rgba(0,0,0,.22) 100%)}
.fin-reflect svg{width:100%;height:100%}
.fin-reflect polygon{fill:var(--fg)}
.fin-reflect polygon:nth-child(3){fill:var(--signal)}
/* each blade carries the name of a scene the visitor has passed */
.fin-tag{position:absolute;left:50%;top:50%;z-index:3;pointer-events:none;opacity:0;
  font-family:var(--f-machine);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);white-space:nowrap;will-change:transform,opacity}

/* the closing statement — three authored lines, not a centred sentence */
.fin-words h2{margin:0}
.fin-words .l1,.fin-words .l2,.fin-words .l3{display:block;overflow:clip}
.fin-words .l1 i,.fin-words .l2 i,.fin-words .l3 i{display:block;font-style:normal;will-change:transform;transform:translateY(110%);transition:transform 620ms var(--ease)}
.fin-words i.set{transform:none}
.fin-words .l1,.fin-words .l2{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 144,'wght' 300,'SOFT' 40,'WONK' 0;font-weight:300;
  font-size:clamp(2.6rem,7vw,6.4rem);line-height:.94;letter-spacing:-.032em;color:var(--fg)}
.fin-words .l3 i{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 400,'SOFT' 40,'WONK' 0;font-style:italic;
  font-size:clamp(1.9rem,4.8vw,4.2rem);line-height:1;letter-spacing:-.016em;color:var(--signal)}
.fin-words .l3{margin-left:clamp(14px,2.2vw,42px);margin-top:.08em}
.fin-seam{display:block;height:1px;background:var(--signal);transform-origin:left;
  transform:rotate(-4.8deg) scaleX(var(--seam,0));margin-top:clamp(.9rem,2vh,1.5rem);max-width:340px}

/* the gate — APERTURE geometry, obviously a control, not a pill */
.fin-gate{display:flex;align-items:center;gap:1.1rem;flex-wrap:wrap;visibility:hidden}
.fin-gate.on{visibility:visible}
.gate{display:inline-flex;align-items:stretch;border:1px solid var(--fg);color:var(--fg);
  min-height:52px;position:relative;overflow:hidden;
  clip-path:polygon(0 0,100% 0,100% 100%,14px 100%,0 calc(100% - 14px));
  transition:color 200ms var(--ease),border-color 200ms var(--ease)}
.gate::before{content:"";position:absolute;inset:0;background:var(--signal);z-index:0;
  transform:scaleX(var(--gate,0));transform-origin:left;transition:transform 420ms var(--ease)}
.gate:hover::before,.gate:focus-visible::before{transform:scaleX(1)}
.gate:hover,.gate:focus-visible{border-color:var(--signal);color:#fff}
/* the gate's tick divider carries the accent at rest - a tiny red detail (S4) */
.gate .gate-tick{color:var(--signal-text)}
.gate:hover .gate-tick,.gate:focus-visible .gate-tick{color:inherit}
.gate-verb{position:relative;z-index:1;display:flex;align-items:center;padding:.9rem 1.4rem;
  font-family:var(--f-work);font-stretch:88%;font-weight:700;font-size:1.05rem;
  letter-spacing:.02em;text-transform:uppercase}
.gate-tick{position:relative;z-index:1;display:flex;align-items:center;padding:0 1rem;
  border-left:1px solid currentColor;font-family:var(--f-machine)}
.gate-sub{color:var(--dim)}
.fin-meta{display:flex;justify-content:space-between;gap:1.2rem;flex-wrap:wrap;align-items:baseline;
  border-top:1px solid var(--hair);padding-top:clamp(.8rem,1.8vh,1.2rem)}
.fin-mail{color:var(--fg);text-decoration:underline;text-decoration-color:var(--signal);
  text-underline-offset:5px;text-decoration-thickness:2px}

/* ══ EDITORIAL EDITION — the composed no-JS / reduced-motion document ════ */
html[data-mode="editorial"] .scene{padding:clamp(3rem,8vh,6rem) 0;min-height:0}
html[data-mode="editorial"] .scene .stage{position:static;height:auto;display:block;
  padding-top:0;overflow:visible}
/* the V2 editorial hero sets this ratio itself (1600/720 — the film's ACTIVE
   picture area, which crops the source's baked-in letterbox); 16/9 here put
   the bars back. Left as a no-op so the rule's intent stays documented. */
html[data-mode="editorial"] .hero-film{clip-path:none!important}
html[data-mode="editorial"] .reel{transform:none!important;opacity:1!important}
/* the two fact lines are stacked and crossfaded by the focus handoff in the
   cinematic edition; with no JS they must simply sit one after the other */
html[data-mode="editorial"] .rc-facts{min-height:0}
html[data-mode="editorial"] .rc-f{position:static;opacity:1!important;margin-bottom:.7rem;max-width:38ch}
html[data-mode="editorial"] .rc-name{opacity:1!important}
html[data-mode="editorial"] .rc-thread{display:none}
html[data-mode="editorial"] .reel-centre{opacity:1!important}
html[data-mode="editorial"] .reel-wall{grid-template-columns:1fr;gap:1.4rem}
html[data-mode="editorial"] .dun-surface{width:100%!important}
html[data-mode="editorial"] .dun-view{height:auto!important;overflow:visible}
html[data-mode="editorial"] .dun-view img{position:static;transform:none!important;
  opacity:1!important;width:100%!important}
html[data-mode="editorial"] .dun-view img+img{margin-top:1rem}
html[data-mode="editorial"] .pt-fig img{height:auto!important;width:min(320px,44vw)}
html[data-mode="editorial"] .pt-fig.lift,html[data-mode="editorial"] .pt-fig.drop{margin:0}
html[data-mode="editorial"] .pt-gutter{display:none}
html[data-mode="editorial"] #engage .stage{background:var(--field);color:var(--ink)}
html[data-mode="editorial"] .fin-mark polygon{transform:none!important;opacity:1!important}
html[data-mode="editorial"] .tech-rule{transform:scaleX(1)}

@media print{
  .nav,.menu,.loader,.motion-toggle,.film-audio{display:none!important}
  body{background:#fff;color:#000}
}

/* ══ MOBILE RE-AUTHORING (founder §43) ═══════════════════════════════════
   Not inherited desktop timing. On a short viewport the absolutely-positioned
   scene heads have nowhere to go, so they are returned to normal flow and each
   stage becomes a centred column. Media is resized so head + media + caption
   fit one viewport with the header safe zone intact — which is what stops type
   landing on a face at 390px. */
@media (max-width:900px){
  html[data-mode="cinematic"] .scene[data-len] .stage{
    display:flex;flex-direction:column;justify-content:center;gap:.9rem;
    padding-inline:0;padding-bottom:1rem}
  .com-head,.tech-hud,.field-head,.field-note{position:static;left:auto;top:auto;
    bottom:auto;right:auto;max-width:none;width:100%;padding-inline:var(--gut)}
  .tech-hud{flex-wrap:wrap;gap:.4rem .9rem;padding-bottom:.5rem}
  .tech-hud .rd{margin-left:0;width:100%;justify-content:space-between}
  .field-note{order:9;font-size:.6rem}

  .hero-rail{margin-bottom:.9rem}

  /* S2 reels — ORIGINAL mobile interpretation. The reference simply hides this
     section below md, so there is nothing to copy. Two 9:16 reels cannot sit
     side by side at 390px and stay legible, so the same idea is compressed:
     the pair OVERLAPS in staggered depth, keeps the opposing tilt at a reduced
     angle, and the focus handoff swaps which one is in front. */
  .reel-wall{grid-template-columns:1fr;grid-template-rows:auto auto;gap:1rem}
  .reel{--reel-h:min(44svh,380px)}
  .reel-a{grid-area:1/1;justify-self:start}
  .reel-b{grid-area:1/1;justify-self:end;margin-top:7svh}
  .reel-centre{grid-area:2/1}
  .reel-centre{text-align:left;align-items:flex-start;padding-inline:var(--gut)}
  .rc-facts{min-height:6.4em}
  .rc-f{text-align:left;max-width:none}

  /* S3 the surface leads; copy sits beneath it.
     LC-UX-003: tightened vertical spend so the WHOLE copy block — including the
     "Visit the live site" close — fits the pinned stage with the JS surface
     budget. Nothing here may push content past 100svh. */
  .tech-body{display:flex;flex-direction:column-reverse;gap:.55rem;padding-top:0}
  .tech-copy .factline{max-width:none;font-size:.9rem;line-height:1.5}
  .tech-copy .t-tech{font-size:clamp(1.3rem,6.6vw,1.9rem)}
  .tech-copy .t-tech br{display:none}
  .tech-rule{margin:.55rem 0 .7rem}
  .route-ribbon{margin-top:.5rem}
  .tech-copy [data-beat="tech-note"] .spec{margin-top:.45rem!important}
  .tech-facts{margin-top:.55rem}
  .tech-hud{gap:.3rem .9rem;padding-bottom:.4rem}
}
@media (max-width:380px){
  .tech-copy .factline{font-size:.84rem}

  /* S4 photography: shorter frames so captions clear the fold */
  .pt-fig.tall img{height:min(46svh,420px)}
  .pt-fig.mid img,.pt-fig.wide img{height:min(34svh,320px)}
  .pt-fig.small img{height:min(26svh,250px)}
  .pt-fig.hero-wide img{height:min(40svh,380px)}
  .pt-fig.lift,.pt-fig.drop{align-self:center;margin:0}
  .pt-plate{width:76vw;min-width:0}


  /* S7 conversion */

  /* S8 finale */
  .fin-body{gap:1rem}
  .fin-mark{width:clamp(96px,26vw,150px)}
  .fin-base{gap:.8rem}
}
@media (max-width:520px){
  .reel-rig{gap:10px}
  .reel{--reel-h:min(34svh,290px)}
  .t-display{font-size:clamp(2.1rem,10vw,3rem)}
}

/* ══ FOOTER — practical utility, kept distinct from the emotional finale ══ */
.foot{display:grid;gap:2rem;padding:clamp(2.4rem,6vw,4.5rem) var(--gut) 2rem;
  border-top:0;align-items:start;
  /* V2: the footer is structural black on every route. It is the single
     largest black region on the site and the main reason the 30% reads as
     architecture rather than as scattered dark panels. */
  background:var(--color-black);color:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --hair:var(--color-hairline-on-black);--line:var(--color-hairline-on-black);
  --signal-text:var(--signal-text-media);
  position:relative}
.foot::before{content:"";position:absolute;inset:0 0 auto;height:2px;
  pointer-events:none;background:var(--signal);width:clamp(120px,26vw,384px);left:var(--gut)}
.foot-mark svg{fill:var(--color-on-black)}
.foot a{color:var(--color-on-black)}
.foot .soc-note{color:var(--color-on-black-dim)}
.foot-links a{color:var(--color-on-black-muted)}
.foot-links a:hover,.foot-links a:focus-visible{color:var(--color-on-black);border-bottom-color:var(--signal)}
.foot-links i{color:var(--color-on-black-dim)}
@media(min-width:820px){.foot{grid-template-columns:1.5fr 1fr 1fr}}
.foot-mark{display:block;width:34px;margin-bottom:.9rem}
.foot-mark svg{width:100%;height:auto;fill:var(--fg)}
.foot-mark svg polygon:nth-child(3){fill:var(--signal)}
.foot ul{list-style:none;margin:.6rem 0 0;padding:0;display:grid;gap:.4rem}
.foot a:hover{color:var(--signal)}
.foot .social{display:flex;gap:.7rem;margin-top:.8rem}
.soc{display:grid;place-items:center;width:38px;height:38px;border:1px solid var(--hair);
  color:var(--muted);transition:color 200ms var(--ease),border-color 200ms var(--ease)}
.soc svg{width:19px;height:19px;display:block}
/* pending state: inert on purpose — nothing here pretends to be a link */
.soc-note{margin-top:.7rem;color:var(--dim);max-width:30ch;line-height:1.5}
/* when real URLs arrive these become <a class="soc"> and light up on hover */
a.soc:hover,a.soc:focus-visible{color:var(--fg);border-color:var(--signal)}

/* the studio key light and grain are decoration for the pinned scene only. In the
   editorial edition the stage is static, so an absolutely-positioned 118vh light
   resolves against a different containing block and pushes the page sideways. */
html[data-mode="editorial"] .st-key,
html[data-mode="editorial"] .st-grain{display:none}
html[data-mode="editorial"] .st-prints{height:auto;display:flex;flex-wrap:wrap;gap:.8rem}
html[data-mode="editorial"] .fin-core{display:none}
html[data-mode="editorial"] .fin-mark polygon{transform:none!important;opacity:1!important;fill:var(--fg)}
html[data-mode="editorial"] .fin-mark polygon:nth-child(3){fill:var(--signal)}
html[data-mode="editorial"] .fin-words i{transform:none!important;transition:none}
html[data-mode="editorial"] .fin-gate{visibility:visible}
html[data-mode="editorial"] .fin-seam{transform:scaleX(1)}

/* ═══════════════════════════════════════════════════════════════════════════
   V12 · SITE DOCUMENT LAYER (LC-UX-001)
   One language for every route. The homepage above is untouched; everything
   below gives the document pages (Work / Services / Engagements / Studio /
   Contact / Case study) the same V11 voice: three type families, one token
   set, one chrome, one control grammar. Compositions stay page-appropriate —
   the SYSTEM propagates, not the homepage's scenes.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── compat tokens: sub-page markup speaks these names ── */
:root{
  --chalk:var(--fg);
  --line:var(--hair);
  --max:1500px;                     /* container authority resolved: V11's 1500 */
  --measure:66ch;
  --sec:clamp(4rem,8.5vw,8.5rem);
  --t-lede:clamp(1.05rem,1.5vw,1.25rem);
  --t-h4:1.05rem;
  --t-label:.7rem;
  /* motion tokens (LC-UX-001/028): the V11 easings, now with named durations */
  --d-micro:180ms;
  --d-reveal:720ms;
  --d-nav:420ms;
  --d-trans:620ms;
  /* accessible derived reds (LC-UX-011/021): small interactive text only.
     Canonical --signal stays for marks, rules, large display and emitted light. */
  /* V1: the light environment is now the default, so the derived red that
     small interactive text uses is the ON-LIGHT one. The on-dark red keeps
     its own name for the type that sits over film and on the anchor. */
  --signal-text-media:#ff6b6e;                 /* over film / on the anchor */
  --signal-text:var(--color-brand-text);            /* on void/plane ≥6:1 */
  --signal-text-ink:var(--color-brand-text);        /* on the light field ≥6:1 */
}

/* ── skip link: visible when focused (found during LC-UX-001) ── */
.sr-only:focus-visible,a.sr-only:focus{
  position:fixed;left:1rem;top:1rem;width:auto;height:auto;margin:0;
  clip:auto;clip-path:none;white-space:normal;overflow:visible;
  background:var(--signal);color:#fff;padding:.7rem 1.1rem;z-index:300;
  font-family:var(--f-machine);font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase}

/* ── document scaffold ── */
.pg section{padding-block:var(--sec);position:relative;background:var(--pg-bg,var(--void));color:var(--pg-fg,var(--fg))}
.pg .wrap{max-width:var(--max)}
.wrap-narrow{max-width:940px;margin-inline:auto;padding-inline:var(--gut);width:100%}
.grid{display:grid;gap:clamp(1.4rem,3vw,3rem)}
.g-2{grid-template-columns:1fr}
@media(min-width:820px){.g-2{grid-template-columns:1fr 1fr}}
.rule{height:1px;background:var(--line);border:0;margin:0}
.measure{max-width:var(--measure)}

/* fields — CUT's authored surfaces, in V11 values */
/* ══ THE BLACK BAND (V2) ══════════════════════════════════════════════════
   The structural black, as a section any page can use. It is a full-bleed
   region with its own type ramp, its own hairlines and its own controls —
   not a light section with a dark background bolted on. Every page gets one
   or two, which is what moves the site to roughly 60/30/10 without turning
   anything into a dark theme. */
.band-black{
  --pg-bg:var(--color-black);--pg-fg:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --line:var(--color-hairline-on-black);--hair:var(--color-hairline-on-black);
  --edge:var(--color-border-on-black);
  --signal-text:var(--signal-text-media);
  background:var(--color-black);color:var(--color-on-black);position:relative}
/* the editorial rule that marks where the architecture changes */
.band-black::before{content:"";position:absolute;inset:0 0 auto;height:2px;
  pointer-events:none;background:var(--signal);width:clamp(120px,26vw,384px);
  left:var(--gut)}
.band-black h1,.band-black h2,.band-black h3{color:var(--color-on-black)}
.band-black .lede{color:var(--color-on-black-muted)}
.band-black .eyebrow .n{color:var(--color-on-black)}
.band-black .cap{color:var(--color-on-black-muted)}
.band-black em{text-decoration-color:var(--signal-text-media)}
.band-black .rule{background:var(--color-hairline-on-black)}
/* controls on the black invert: warm white plate, red arrow, charcoal sweep */
.band-black .btn{border-color:var(--color-on-black);color:var(--color-on-black)}
.band-black .btn::before{background:var(--color-on-black)}
.band-black .btn:hover,.band-black .btn:focus-visible{color:var(--color-black);border-color:var(--color-on-black)}
.band-black .btn-solid{background:var(--color-on-black);border-color:var(--color-on-black);color:var(--color-black)}
.band-black .btn-solid::before{background:var(--signal)}
.band-black .btn-solid:hover,.band-black .btn-solid:focus-visible{color:#fff;border-color:var(--signal)}
.band-black .btn-solid .tick{color:var(--signal)}
.band-black a.soc{color:var(--color-on-black-muted);border-color:var(--color-hairline-on-black)}
.band-black a.soc:hover,.band-black a.soc:focus-visible{color:var(--color-on-black);border-color:var(--signal)}

/* THE MASTHEAD. Every document route opens on the structural black. It is the
   single change that stops the pages reading as different websites, and it is
   where most of the 30% comes from. The red rule sits on the masthead's LOWER
   edge — the top edge is under the fixed nav, and the bottom edge is where the
   architecture actually changes. */
.masthead::before{display:none}
.masthead::after{content:"";position:absolute;inset:auto auto 0 var(--gut);
  height:2px;width:clamp(120px,26vw,384px);background:var(--signal);pointer-events:none}
.masthead{padding-bottom:clamp(2.6rem,6vw,4.4rem)}
.masthead h1{color:var(--color-on-black)}
.masthead .lede{color:var(--color-on-black-muted)}
.masthead .eyebrow .n{color:var(--color-on-black)}
.masthead .eyebrow .label{color:var(--color-on-black-dim)}

/* THE THREE LIGHT GROUNDS. Adjacent sections differ by a luminance ratio of
   1.05-1.19 - enough that the layering is felt, not enough to stripe. */
.field-light{--pg-bg:var(--color-bg-secondary);--pg-fg:var(--color-text-primary)}
.field-plane{--pg-bg:var(--color-surface)}
/* an emphatic band that is NOT black: the deepest light ground plus the same
   red rule. Used where a route already carries enough black that a second
   field would tip it past 30% — the emphasis comes from the rule and the
   tonal step, which is what emphasis is for. */
.emphatic{--pg-bg:var(--color-surface-muted)}
.emphatic::before{content:"";position:absolute;inset:0 0 auto;height:2px;
  pointer-events:none;background:var(--signal);
  width:clamp(120px,26vw,384px);left:var(--gut)}
/* THE ANCHOR. Was a full-bleed field of brand red, one per page; V1 made it
   charcoal with a red rule; V2 aligns it with the structural black so every
   dark region on the site is the same black. */
.field-signal{--pg-bg:var(--color-black);--pg-fg:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --line:var(--color-hairline-on-black);--hair:var(--color-hairline-on-black);
  --edge:var(--color-border-on-black);
  --signal-text:var(--signal-text-media)}
.field-signal,.red-band{position:relative}
.field-signal::before,.red-band::before{content:"";position:absolute;
  inset:0 0 auto;height:2px;pointer-events:none;
  background:linear-gradient(90deg,var(--signal) 0%,var(--signal) 26%,rgba(218,31,38,0) 62%)}
/* --pg-bg / --pg-fg, not background / color: `.pg section` is (0,1,1) and
   outranks a bare `.red-band` (0,1,0), so a background declared here never
   reached the page. That was already true of the old red value - these bands
   have been rendering as plain page ground, not as red - so the fix belongs
   with the colour pass. The direct properties stay for any .red-band that
   ever sits outside a .pg document. */
.red-band{--pg-bg:var(--color-black);--pg-fg:var(--color-on-black);
  background:var(--color-black);color:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --line:var(--color-hairline-on-black);--hair:var(--color-hairline-on-black);
  --edge:var(--color-border-on-black);
  --signal-text:var(--signal-text-media);
  padding-block:clamp(3rem,7vw,5.5rem)}
.red-band .wrap{display:grid;gap:1.6rem;align-items:center;grid-template-columns:1fr;padding-block:.4rem}
@media(min-width:860px){.red-band .wrap{grid-template-columns:1.4fr auto}}
.red-band h2{color:var(--color-on-black);max-width:18ch}
.red-band .label{color:var(--color-on-black-muted)}

/* ── document type roles: the V11 voices on reading pages ── */
.pg h1{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 144,'wght' 320,'SOFT' 0,'WONK' 0;font-weight:320;
  font-size:clamp(2.5rem,6vw,4.9rem);line-height:.98;letter-spacing:-.026em;
  margin:0;text-wrap:balance}
.pg h1 em{font-style:italic;color:var(--signal);text-decoration:none}
.pg h2 em{font-style:italic;color:var(--signal);text-decoration:none}
.pg .mega{font-size:clamp(2.7rem,7vw,6rem);line-height:.95;letter-spacing:-.03em}
.pg h2{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 420,'SOFT' 20,'WONK' 0;font-weight:420;
  font-size:clamp(1.65rem,3.3vw,2.7rem);line-height:1.06;letter-spacing:-.014em;
  margin:0;text-wrap:balance}
.pg h3{font-family:var(--f-work);font-stretch:94%;font-weight:650;
  font-size:var(--t-h4);line-height:1.25;letter-spacing:.002em;margin:0}
.pg p{margin:0 0 1.05em}
.pg .lede{font-family:var(--f-work);font-size:var(--t-lede);line-height:1.5;
  color:var(--pg-fg,var(--fg));max-width:58ch}
.field-signal .lede{color:var(--color-on-black)}
.pg em{font-style:normal;font-weight:600;text-decoration:underline;
  text-decoration-color:var(--signal);text-decoration-thickness:2px;text-underline-offset:3px}
.field-signal em{text-decoration-color:var(--signal-text-media)}
.pg strong{font-weight:650}
.num{font-variant-numeric:tabular-nums;font-family:var(--f-machine)}
.cap{font-family:var(--f-machine);font-size:.66rem;letter-spacing:.12em;
  text-transform:uppercase;border:1px solid var(--line);padding:.34rem .6rem;
  color:var(--muted);display:inline-block}
a.cap:hover,a.cap:focus-visible{border-color:var(--signal);color:var(--pg-fg,var(--fg))}
.field-signal .cap,.red-band .cap{color:var(--color-on-black-muted)}

/* eyebrow → the V11 label-sig grammar */
.eyebrow{display:flex;gap:.9rem;align-items:baseline;margin-bottom:1.5rem}
.eyebrow .n{font-family:var(--f-machine);font-size:.7rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--pg-fg,var(--fg));
  border-left:2px solid var(--signal);padding-left:.62em}
.eyebrow .label{color:var(--dim)}
.field-signal .eyebrow .n{border-left-color:var(--signal);color:var(--color-on-black)}

/* notices + provisional truth chips */
.notice{border-left:2px solid var(--signal);padding:.9rem 0 .9rem 1.1rem;margin:1.6rem 0;
  background:linear-gradient(90deg,rgba(218,31,38,.08),transparent 72%)}
.notice p:last-child{margin-bottom:0}
.provisional{display:inline-block;font-family:var(--f-machine);font-size:.58rem;
  letter-spacing:.13em;text-transform:uppercase;background:var(--signal);color:#fff;
  padding:.24rem .5rem}

/* ── reveals: clip-not-fade, armed late (ported architecture, V11 easing) ── */
.reveal-type{display:block;overflow:hidden;padding-bottom:.12em;margin-bottom:-.12em}
.reveal-type>span{display:block;transform:none;transition:transform var(--d-reveal) var(--ease)}
.rv-armed .reveal-type>span,.reveal-type.rv-armed>span{transform:translateY(102%)}
.rv-armed.revealed .reveal-type>span,.reveal-type.rv-armed.revealed>span,
.revealed .reveal-type>span,.reveal-type.revealed>span{transform:translateY(0)}
.rv{clip-path:none;transition:clip-path 860ms var(--ease)}
.rv.rv-armed{clip-path:inset(0 0 100% 0)}
.rv.rv-armed.revealed,.rv.revealed{clip-path:inset(0 0 0 0)}
.rv-safe{clip-path:none!important}
.fstep,.fnav,form{scroll-margin-top:100px}

/* ── media ── */
.media{position:relative;width:100%;height:100%;overflow:hidden;background:var(--edge)}
.media.real{background:var(--color-media-backing)}
.media.real img,.media.real video{width:100%;height:100%;object-fit:cover;display:block}
.rm-poster{display:none;width:100%;height:100%;object-fit:cover}
@media(prefers-reduced-motion:reduce){
  .pg video[data-auto]{display:none}
  .pg .rm-poster{display:block}
}
/* the aperture crop — the mark's own two ratios, unchanged geometry */
.ap-mask{position:relative;overflow:hidden}
.ap-mask>.media{clip-path:polygon(0 9%,100% 0,100% 96%,0 100%);
  transition:clip-path var(--d-reveal) var(--ease)}
.ap-mask:hover>.media{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
@media(hover:none){.ap-mask:hover>.media{clip-path:polygon(0 9%,100% 0,100% 96%,0 100%)}}
.ap-plane{position:relative;overflow:hidden}
.ap-plane .sheet{position:absolute;inset:-2px;background:var(--plane);
  transform:translateX(-102%);transition:transform 900ms var(--ease)}
.ap-plane.rv-armed .sheet{transform:translateX(0)}
.ap-plane.rv-armed.revealed .sheet,.ap-plane.revealed .sheet{transform:translateX(-102%) skewX(-7deg)}
/* placeholder media: honest, labelled, and quiet (no gradient theatrics) */
.ph{position:absolute;inset:0;background:
  repeating-linear-gradient(101deg,rgba(28,27,26,.055) 0 1px,transparent 1px 42px),var(--color-bg-secondary)}
.ph::after{content:attr(data-ph);position:absolute;left:.9rem;bottom:.75rem;
  font-family:var(--f-machine);font-size:.56rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--color-text-muted);background:rgba(255,255,255,.72);padding:.28rem .5rem}

/* ── shared reel grid (services, decks) ── */
.commercial{display:grid;gap:clamp(1rem,2.4vw,2rem);grid-template-columns:minmax(0,1fr)}
@media(min-width:940px){.commercial{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ── services / engagements structures ── */
.pillar{border-top:1px solid var(--line);padding-block:clamp(1.5rem,3vw,2.6rem);position:relative}
.pillar-head{display:grid;grid-template-columns:1fr;gap:.8rem;align-items:baseline;cursor:pointer}
@media(min-width:760px){.pillar-head{grid-template-columns:3.2rem 1fr 1.6rem}}
.pillar-verb{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 440,'SOFT' 20,'WONK' 0;font-weight:440;
  font-size:clamp(1.55rem,3.2vw,2.5rem);letter-spacing:-.014em;line-height:1.02;margin:0}
.pillar-sub{color:var(--muted);font-size:.95rem;margin:.5rem 0 0}
.pillar-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--d-trans) var(--ease)}
.pillar[data-open="true"] .pillar-body{grid-template-rows:1fr}
.pillar-body>div{overflow:hidden}
.pillar-open{font-family:var(--f-machine);font-size:1.5rem;line-height:1;color:var(--signal);
  transition:transform 400ms var(--ease);justify-self:end}
.pillar[data-open="true"] .pillar-open{transform:rotate(45deg)}
.bands{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);margin-top:2rem}
@media(min-width:900px){.bands{grid-template-columns:repeat(4,1fr)}}
.band{background:var(--pg-bg,var(--void));padding:clamp(1.2rem,2.2vw,1.8rem);
  display:flex;flex-direction:column;gap:.75rem;position:relative;overflow:hidden}
.band .aperture-bar{height:3px;background:var(--signal);width:var(--w,25%)}
.band h3{font-family:var(--f-work);font-stretch:112%;font-weight:650;font-size:1.02rem;letter-spacing:-.008em}
.band dl{margin:0;display:grid;gap:.5rem}
.band dt{font-family:var(--f-machine);font-size:.56rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.band dd{margin:0;font-size:.88rem;line-height:1.45}
.stat-rail{display:grid;gap:0;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));border-top:1px solid var(--hair)}
.stat-rail>div{padding:1.2rem 1.2rem 0 0;border-right:1px solid var(--hair)}
.stat-rail>div:last-child{border-right:0}
.stat-rail dt{font-family:var(--f-machine);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.stat-rail dd{margin:.5rem 0 0;font-size:1.05rem}

/* ── team (Studio page · LC-UX-002): the homepage's credit-row thesis,
      restated for a document page — row + print, all five identical ── */
.team{margin-top:2.4rem;border-top:1px solid var(--line)}
.team-member{display:grid;grid-template-columns:2.6em minmax(0,1fr) auto;
  gap:.2rem 1.2rem;align-items:center;padding:clamp(.9rem,2vw,1.3rem) 0;
  border-bottom:1px solid var(--line)}
.team-member .idx{font-family:var(--f-machine);font-size:.7rem;letter-spacing:.1em;
  color:var(--dim);font-variant-numeric:tabular-nums;grid-row:span 2;align-self:center}
.team-member h3{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 400,'SOFT' 40,'WONK' 0;font-weight:400;
  font-size:clamp(1.4rem,3vw,2.3rem);line-height:1.05;letter-spacing:-.016em;margin:0}
.team-member .role{font-family:var(--f-machine);font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin:.3rem 0 0}
.team-portrait{grid-row:span 2;width:clamp(84px,12vw,132px);margin:0}
.team-portrait img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  border-radius:12px;background:var(--color-media-backing);box-shadow:0 14px 34px rgba(28,25,20,.13)}

/* ── forms (contact) — hairline inputs in V11 tokens ── */
.steps{display:flex;gap:.5rem;margin-bottom:2rem;flex-wrap:wrap}
.step-pip{display:flex;align-items:center;gap:.55rem;font-family:var(--f-machine);
  font-size:.62rem;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.step-pip .bar{width:clamp(38px,7vw,72px);height:2px;background:var(--line)}
.step-pip[aria-current="step"]{color:var(--pg-fg,var(--fg))}
.step-pip[aria-current="step"] .bar{background:var(--signal)}
.step-pip[data-state="done"] .bar{background:var(--muted)}
.fstep{display:none}
.fstep[data-active="true"]{display:block}
.fgroup{margin-bottom:1.5rem}
.fgroup label{display:block;font-family:var(--f-machine);font-size:.64rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin-bottom:.55rem}
.fgroup .req{color:var(--signal-text-ink)}
.fgroup input,.fgroup select,.fgroup textarea{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--line);
  border-radius:0;padding:.72rem 0;font:inherit;font-size:1rem;color:var(--pg-fg,var(--fg));
  transition:border-color var(--d-micro) var(--ease)}
.fgroup input:focus,.fgroup select:focus,.fgroup textarea:focus{border-bottom-color:var(--signal)}
.fgroup select{cursor:pointer}
.fgroup select option{background:var(--plane);color:var(--fg)}
.field-light .fgroup select option{background:var(--field);color:var(--ink)}
.fgroup textarea{resize:vertical;min-height:104px}
.err{display:block;color:var(--signal-text);font-size:.8rem;margin-top:.45rem;min-height:1.1em}
.field-light .err{color:var(--signal-text-ink)}
.fgroup[data-invalid="true"] input,.fgroup[data-invalid="true"] select,
.fgroup[data-invalid="true"] textarea{border-bottom-color:var(--signal)}
.fnav{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:2rem;align-items:center}
.success{border:1px solid var(--signal);padding:clamp(1.4rem,3vw,2.2rem);display:none}
.success[data-shown="true"]{display:block}

/* ── enquiry: spam trap + real sending/failure states ────────────────────
   The success block above is now reached ONLY on a 2xx from /api/enquiry.
   These two states cover the rest of the truth. */
.enq-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.enq-note{display:none;margin-top:1.6rem;border:1px solid var(--line);
  padding:clamp(1rem,2.2vw,1.35rem) clamp(1.1rem,2.4vw,1.5rem)}
.enq-note[data-state="sending"],.enq-note[data-state="error"]{display:block}
.enq-note[data-state="error"]{border-color:var(--signal)}
.enq-note>*{display:none}
.enq-note[data-state="sending"] .enq-note-sending{display:block}
.enq-note[data-state="error"] .enq-note-error{display:block}
.enq-note p{margin:0;max-width:52ch}
.enq-note p+p{margin-top:.6rem}
.enq-note .label{color:var(--signal-text)}
.field-light .enq-note .label{color:var(--signal-text-ink)}
.enq-note a{border-bottom:1px solid var(--signal)}
.enq-note-sending,.enq-note-keep{color:var(--muted);font-size:.9rem}
/* in flight: the form stays put and stays filled — only the controls lock */
#enquiry[data-sending="true"] .fnav .btn{opacity:.45;pointer-events:none}

/* red-band + field-signal button variants (V11 grammar on loud grounds) */
/* on the black the plate inverts to warm white; red stays in the action square */
.red-band .btn,.field-signal .btn{border-color:var(--color-on-black);color:var(--color-on-black)}
.red-band .btn::before,.field-signal .btn::before{background:var(--color-on-black)}
.red-band .btn:hover,.red-band .btn:focus-visible,
.field-signal .btn:hover,.field-signal .btn:focus-visible{color:var(--color-black);border-color:var(--color-on-black)}
.red-band .btn-solid,.field-signal .btn-solid{background:var(--color-on-black);
  border-color:var(--color-on-black);color:var(--color-black)}
.red-band .btn-solid::before,.field-signal .btn-solid::before{background:var(--signal)}
.red-band .btn-solid:hover,.red-band .btn-solid:focus-visible,
.field-signal .btn-solid:hover,.field-signal .btn-solid:focus-visible{color:#fff;border-color:var(--signal)}
/* the light grounds share the base grammar; only the sweep target moves */
.field-light .btn,.field-plane .btn{color:var(--color-text-primary)}
.field-light .btn:hover,.field-light .btn:focus-visible,
.field-plane .btn:hover,.field-plane .btn:focus-visible{color:var(--color-on-dark);border-color:var(--color-text-primary)}
.field-light .btn-solid,.field-plane .btn-solid{color:var(--color-on-dark)}
.field-light .btn-solid:hover,.field-light .btn-solid:focus-visible,
.field-plane .btn-solid:hover,.field-plane .btn-solid:focus-visible{color:#fff;border-color:var(--signal)}

/* ── case-study figures: moderate portrait crop at phone width (LC-UX-025) ── */
.cs-frame{position:relative;aspect-ratio:2.22/1;overflow:hidden;margin:0}
@media(max-width:640px){.cs-frame{aspect-ratio:3/2}
  .cs-frame img{object-fit:cover}}

/* ── no-JS: the document is complete without enhancement ── */
.no-js .loader{display:none}
.no-js .rv{clip-path:none}
.no-js .reveal-type>span{transform:none}
.no-js .ap-plane .sheet{transform:translateX(-102%)}
.no-js .ap-mask>.media{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
.no-js .fstep{display:block!important;border-top:1px solid var(--line);padding-top:1.4rem;margin-top:1.4rem}
.no-js .fstep:first-child{border-top:0;padding-top:0;margin-top:0}
.no-js [data-next],.no-js [data-prev]{display:none}
.no-js .steps{display:none}
.no-js .pillar-body{grid-template-rows:1fr}
@media(max-width:899px){
  .no-js .menu-btn{display:none}
  .no-js .menu{position:static;inset:auto;clip-path:none;visibility:visible;
    flex-direction:column;justify-content:flex-start;padding:5.2rem var(--gut) 1rem;
    border-bottom:1px solid var(--hair)}
  .no-js .menu nav a{font-size:1.05rem}
  .no-js .menu-close{display:none}
}
.noscript-note{display:block;padding:.8rem var(--gut);background:var(--plane);
  border-bottom:1px solid var(--hair);font-size:.8rem;color:var(--dim)}

/* ── reduced motion on document pages: composed, not disabled ── */
@media(prefers-reduced-motion:reduce){
  .pg .rv,.pg .rv.rv-armed{clip-path:none}
  .rv-armed .reveal-type>span,.reveal-type.rv-armed>span{transform:none}
  .ap-plane.rv-armed .sheet{transform:translateX(-102%)}
}

/* ── print ── */
@media print{
  .rv,.rv.rv-armed{clip-path:none!important}
  .reveal-type>span{transform:none!important}
  .ap-plane .sheet{display:none!important}
  video[data-auto]{display:none!important}
  .rm-poster{display:block!important}
}

/* ── EXPRESSION F · the route shutter (LC-UX-004) ──
   The cinema edit's diagonal blade, covering the viewport between routes.
   Sits above everything including the menu; inert to input; hidden at rest. */
.route-shutter{position:fixed;inset:0;z-index:240;background:var(--void);
  pointer-events:none;visibility:hidden;will-change:clip-path}
html[data-mode="editorial"] .route-shutter{display:none}

/* ── unified menu details (LC-UX-023/038): the instruments register carries a
   quiet index; the lower half holds the two facts a lost visitor needs. ── */
.menu nav a .idx{font-family:var(--f-machine);font-size:.64rem;color:var(--dim);
  vertical-align:.55em;margin-right:.7rem;letter-spacing:.1em}
.menu nav a[aria-current="page"]{color:var(--fg)}
.menu nav a[aria-current="page"] .idx{color:var(--signal)}
.menu-contact{margin-top:2.2rem;border-top:1px solid var(--hair);padding-top:1.1rem}
.menu-contact a{text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--signal)}
/* social chips: 44px touch floor now that one is live (LC-UX-033) */
.soc{width:44px;height:44px}
.soc svg{width:20px;height:20px}
.soc-pending{opacity:.5}
a.soc{color:var(--muted)}
a.soc:hover,a.soc:focus-visible{color:var(--fg);border-color:var(--signal)}

/* ══ P1 CORRECTIONS ═══════════════════════════════════════════════════════ */

/* LC-UX-007 · pressed states: every pressable acknowledges the pointer at
   press time — ~120ms, restrained, no bounce. */
.btn,.gate,.soc{transition-property:color,border-color,background-color,transform;
  transition-duration:180ms,180ms,180ms,120ms;
  transition-timing-function:var(--ease)}
.btn:active,.gate:active,a.soc:active,.menu-btn:active{transform:scale(.98)}
.nav-links a:active{opacity:.55}
.foot a:active{opacity:.6}
.pillar-head:active .pillar-verb{transform:translateY(1px)}
.pillar-verb{transition:transform 120ms var(--ease)}

/* LC-UX-011/021 · derived reds for small interactive text; canonical red
   stays on marks, rules, large display and the emitted-light thread. */
.foot a:hover,.foot a:focus-visible{color:var(--signal-text)}
.menu nav a[aria-current="page"] .idx{color:var(--signal-text)}
.fin-mail:hover{color:var(--fg)}   /* underline carries the red */

/* LC-UX-006 · the motion control's designed home: safe-area aware, under the
   menu, dimming when idle, docking above the footer (JS drives .docked). */
.motion-toggle{z-index:115;
  right:calc(1rem + env(safe-area-inset-right,0px));
  bottom:calc(1rem + env(safe-area-inset-bottom,0px));
  transition:opacity 300ms var(--ease),transform 120ms var(--ease)}
.motion-toggle:active{transform:scale(.98)}
/* it is a control with a word on it, not a watermark: .4 over a film left
   the label at roughly 2:1 */
.motion-toggle[data-idle="true"]:not(:hover):not(:focus-visible){opacity:.76}
.motion-toggle.docked{position:absolute}
@media(max-width:700px){.motion-toggle{font-size:.6rem;padding:.5rem .65rem;letter-spacing:.1em}}

/* LC-UX-009 · the payoff on portrait viewports: the whole group, letterboxed
   between void bars — the neighbour scene's language — never a two-face crop. */

/* LC-UX-012 · editorial Dunamis: three designed excerpts instead of the
   full-height capture walls. Cinematic mode never shows this block. */
.dun-editorial{display:none}
html[data-mode="editorial"] .dun-surface{display:none}
html[data-mode="editorial"] .dun-editorial{display:grid;gap:1.2rem;margin-top:1rem}
html[data-mode="editorial"] .dun-editorial figure{margin:0;border:1px solid rgba(150,175,225,.30);background:#0a0e16}
html[data-mode="editorial"] .dun-editorial img{width:100%;height:auto;display:block}
html[data-mode="editorial"] .dun-editorial figcaption{font-family:var(--f-machine);font-size:.62rem;
  letter-spacing:.12em;text-transform:uppercase;color:#8e9bb5;padding:.55rem .7rem;
  border-top:1px solid rgba(150,175,225,.22)}
@media(min-width:700px){html[data-mode="editorial"] .dun-editorial{grid-template-columns:1fr 1fr}
  html[data-mode="editorial"] .dun-editorial figure:first-child{grid-column:1/-1}}

/* ══ P2 CORRECTIONS ═══════════════════════════════════════════════════════ */

/* LC-UX-018 · one restrained scroll instrument in the hero: a hairline that
   fills downward at reading pace. Gone on first scroll; absent in editorial. */
.scroll-cue{position:absolute;left:var(--gut);bottom:clamp(1.2rem,4svh,2.6rem);
  display:flex;align-items:center;gap:.55rem;margin:0;
  font-family:var(--f-machine);font-size:.6rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--dim);z-index:4;
  transition:opacity 500ms var(--ease)}
.scroll-cue i{display:block;width:1px;height:30px;background:var(--hair);position:relative;overflow:hidden}
.scroll-cue i::after{content:"";position:absolute;left:0;top:0;width:100%;height:38%;
  background:var(--signal);animation:cueDrop 2.8s var(--ease-io) infinite}
@keyframes cueDrop{0%{transform:translateY(-110%)}55%{transform:translateY(180%)}100%{transform:translateY(180%)}}
.scroll-cue.off{opacity:0;pointer-events:none}
html[data-mode="editorial"] .scroll-cue{display:none}
@media(prefers-reduced-motion:reduce){.scroll-cue i::after{animation:none;transform:translateY(60%)}}
@media(max-width:999px){.scroll-cue{bottom:auto;top:calc(var(--safe-top) + 2svh)}}

/* LC-UX-019 · platform integration */
html{color-scheme:light;-webkit-tap-highlight-color:transparent}
a,button,.btn,.menu-btn,.motion-toggle{touch-action:manipulation}
.menu{overscroll-behavior:contain;
  padding-left:max(var(--gut),env(safe-area-inset-left,0px));
  padding-right:max(var(--gut),env(safe-area-inset-right,0px));
  padding-bottom:max(var(--gut),env(safe-area-inset-bottom,0px))}
.nav{padding-left:max(var(--gut),env(safe-area-inset-left,0px));
  padding-right:max(var(--gut),env(safe-area-inset-right,0px))}
.foot{padding-bottom:max(2rem,env(safe-area-inset-bottom,0px))}

/* ── LC-UX-031 · user display preferences: materials go solid, edges harden ── */
@media (prefers-reduced-transparency: reduce){
  .nav.scrolled{background:var(--color-bg-primary);backdrop-filter:none}
  .motion-toggle{background:var(--color-bg-primary);backdrop-filter:none}
  .dun-chrome{backdrop-filter:none}
  .screen .cap{background:var(--color-bg-primary);backdrop-filter:none}
  .wk-rail{background:var(--color-bg-primary);backdrop-filter:none}
}
@media (prefers-contrast: more){
  :root{--color-text-secondary:#3d3b37;--color-text-muted:#46443f;
    --color-hairline:rgba(28,27,26,.34);--color-border:#b6b1a8}
  .nav.scrolled{background:var(--color-bg-primary);backdrop-filter:none;border-bottom-color:rgba(28,27,26,.42)}
  .btn{border-width:2px}
  .field-signal,.red-band{--muted:#e4e3e0;--dim:#cfcecb;
    --hair:rgba(255,255,255,.34);--line:rgba(255,255,255,.34)}
}

/* ══ LEGAL ROUTES — privacy.html · terms.html ════════════════════════════
   Set as documents, not as a wall of small print: the same editorial grid the
   rest of the site uses, so the pages read like part of the studio rather
   than something pasted in from a generator. */
.legal-flag{margin-top:1.6rem;max-width:64ch;padding:.9rem 1.1rem;
  border-left:2px solid var(--signal);background:rgba(218,31,38,.06);
  font-family:var(--f-work);font-size:.88rem;line-height:1.6;color:var(--muted)}
.legal-list{list-style:none;margin:1.8rem 0 0;padding:0;
  display:grid;gap:1.4rem;max-width:74ch}
.legal-list li{display:grid;grid-template-columns:auto 1fr;gap:1.1rem;
  align-items:start;padding-top:1.1rem;border-top:1px solid var(--hair)}
.ll-n{font-family:var(--f-machine);font-size:.7rem;letter-spacing:.14em;
  color:var(--signal);padding-top:.18em}
.legal-list b{display:block;font-family:var(--f-work);font-stretch:104%;
  font-weight:600;font-size:1rem;color:var(--fg);margin-bottom:.3rem}
.legal-list p{margin:0;color:var(--muted);max-width:60ch}
.legal-nots{list-style:none;margin:0;padding:0;display:grid;gap:.7rem}
.legal-nots li{position:relative;padding-left:1.5rem;color:var(--muted);
  font-size:.94rem;line-height:1.55}
/* a struck diagonal reads as "we do not" without spending a word on it */
.legal-nots li::before{content:"";position:absolute;left:0;top:.55em;
  width:9px;height:9px;border:1px solid var(--edge);rotate:45deg}
.legal-nots li::after{content:"";position:absolute;left:2px;top:calc(.55em + 4px);
  width:11px;height:1px;background:var(--signal);rotate:-45deg}
.mono{font-family:var(--f-machine);font-size:.86em;color:var(--fg)}

/* the legal routes in the footer bar */
.foot-links{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.foot-links a{color:var(--muted);text-decoration:none;
  border-bottom:1px solid transparent;transition:color .3s,border-color .3s}
.foot-links a:hover,.foot-links a:focus-visible{color:var(--fg);border-bottom-color:var(--signal)}
.foot-links i{color:var(--dim);font-style:normal}

/* ══ WORK V2 — ONE CONTINUOUS SCROLL ═══════════════════════════════════════
   Three chapters, each a pinned scene, then a flow index and the ask. The
   engine writes transforms, opacity, clip-paths and custom properties; this
   file decides what those mean. See 04-Design/WORK-V2-DESIGN.md.

   The chapter rail lives under the site header, so on this page the header
   safe zone is 40px deeper than elsewhere. */
html.page-work{--safe-top:calc(var(--nav-h) + 40px + clamp(14px,2.4vh,30px))}

/* ── CHAPTER RAIL ─────────────────────────────────────────────────────── */
.wk-rail{position:fixed;left:0;right:0;top:var(--nav-h);z-index:105;height:40px;
  padding:0 var(--gut);display:flex;align-items:center;
  /* the rail travels over the light room AND over full-bleed film, so it now
     carries the nav's own material instead of a shadow under light type */
  background:rgba(250,249,247,.82);backdrop-filter:blur(14px) saturate(1.05);
  -webkit-backdrop-filter:blur(14px) saturate(1.05);
  border-bottom:1px solid var(--color-hairline);
  opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}
.wk-rail[data-on="1"]{opacity:1;pointer-events:auto}
.wk-rail ol{list-style:none;margin:0;padding:0;display:flex;gap:clamp(1.1rem,3vw,2.6rem)}
.wk-rail a{position:relative;display:inline-flex;gap:.6em;align-items:baseline;padding:.6rem 0 .55rem;
  font-family:var(--f-machine);font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);transition:color .3s var(--ease)}
.wk-rail a .n{color:var(--signal-text)}
.wk-rail a:hover,.wk-rail a:focus-visible,.wk-rail a[aria-current="true"]{color:var(--fg)}
.wk-rail a:focus-visible{outline-offset:2px}
/* the active item's underline is a live readout: it fills with the chapter */
.wk-rail .bar{position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--hair);
  transform:scaleX(0);transform-origin:left;transition:transform .45s var(--ease)}
.wk-rail a[aria-current="true"] .bar{transform:scaleX(1)}
.wk-rail .bar::after{content:"";position:absolute;inset:0;background:var(--signal);
  transform:scaleX(var(--chp,0));transform-origin:left}
.wk-rail .short{display:none}
@media(max-width:640px){
  .wk-rail{padding:0 var(--gut)}
  .wk-rail a{font-size:.56rem;letter-spacing:.13em}
  .wk-rail .long{display:none} .wk-rail .short{display:inline}
}
html[data-mode="editorial"] .wk-rail{opacity:1;pointer-events:auto}

/* ── 01 · THE FILM SCENE (prologue + chapter one) ─────────────────────── */
#film .stage{background:var(--color-black);overflow:clip}

/* the statement */
.wk-say{position:absolute;left:0;top:var(--safe-top);bottom:0;z-index:5;
  width:min(48vw,680px);padding-inline:var(--gut);
  display:flex;flex-direction:column;justify-content:center;pointer-events:none}
.wk-say>*{pointer-events:auto}
.wk-h1{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 144,'wght' 300,'SOFT' 0,'WONK' 0;font-weight:300;
  font-size:clamp(2.55rem,6.4vw,6.3rem);line-height:.94;letter-spacing:-.03em;
  margin:.9rem 0 0;color:var(--fg)}
.wk-h1 span{display:block;white-space:nowrap}
.wk-h1 i{font-style:normal;color:var(--signal)}
.wk-lede{margin-top:1.3rem;max-width:32ch}
.wk-cue{opacity:var(--wkui,1);transition:opacity .3s}
.wk-cue.off{pointer-events:none}

/* the deck: four real pieces of work, one composed stack */
.wk-deck{position:absolute;inset:0;z-index:2;perspective:1600px;perspective-origin:62% 46%}
/* the film window is the WHOLE viewport, clipped — so the full-bleed state is
   truly edge to edge and the stacked state is a crop of the same picture */
.wk-fr{position:absolute;inset:0;margin:0;overflow:hidden;background:var(--color-media-backing);
  will-change:clip-path,transform}
.wk-fr video,.wk-fr .rm-poster{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;will-change:transform}
/* the poster sits UNDER the film and stays; the film fades up only once it
   has a real frame (.live, set by the page), so a buffering stream never
   shows as a black window */
.wk-fr .rm-poster{display:block;z-index:0}
.wk-fr video{z-index:1;opacity:0;transition:opacity .45s var(--ease)}
.wk-fr.live video{opacity:1}
.wk-fr::after{content:"";position:absolute;inset:0;background:var(--void);
  opacity:var(--wdim,0);pointer-events:none;z-index:2}
.f-proposal{z-index:1}
.f-proposal.covered{visibility:hidden}
.wk-fr.parked,.wk-reel.parked{visibility:hidden}

.wk-layer{position:absolute;left:50%;top:50%;margin:0;display:block;width:var(--lw);
  color:inherit;text-decoration:none;transform-origin:50% 50%;will-change:transform}
.wk-layer.gone{pointer-events:none}
.l-photo{--lw:16vw;z-index:4}
.l-ui{--lw:34vw;z-index:3}
.l-reel{--lw:12vw;z-index:5}
.wk-lw{display:block;overflow:hidden;background:var(--color-media-backing);border-radius:10px;
  box-shadow:0 20px 48px rgba(28,25,20,.16);aspect-ratio:var(--la);
  border:1px solid var(--color-hairline)}
.l-photo .wk-lw{--la:9/16} .l-ui .wk-lw{--la:16/10} .l-reel .wk-lw{--la:9/16}
.wk-lw img{width:100%;height:100%;object-fit:cover;display:block}
/* layer captions print once the layers have separated — the work as interface */
.wk-lc{position:absolute;left:0;top:calc(100% + .65rem);display:flex;gap:.55em;
  align-items:baseline;white-space:nowrap;font-family:var(--f-machine);font-size:.6rem;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  opacity:var(--lcap,0);transform:translateY(calc((1 - var(--lcap,0)) * 8px));
  transition:color .3s}
.wk-lc .n{color:var(--signal-text)}
.wk-layer:hover .wk-lc,.wk-layer:focus-visible .wk-lc,
.lc-film:hover,.lc-film:focus-visible{color:var(--fg)}
.wk-layer:focus-visible{outline:none}
.wk-layer:focus-visible .wk-lw{outline:2px solid var(--signal);outline-offset:4px}
/* the film window's own caption sits under the window; the engine places it */
.lc-film{left:var(--fw-l,44vw);top:calc(var(--fw-t,60svh) + .65rem);z-index:6}
.lc-film.gone{pointer-events:none}

/* the acts: reels and the second film */
.wk-films{position:absolute;inset:0;z-index:3;pointer-events:none}
.wk-films>*{pointer-events:auto}
.f-ceremony{z-index:3;will-change:clip-path,transform,opacity}
.wk-reel{position:absolute;left:50%;top:50%;margin:0;height:var(--rh,74svh);
  aspect-ratio:9/16;width:auto;border-radius:14px;overflow:hidden;background:var(--color-media-backing);
  box-shadow:0 24px 62px rgba(28,25,20,.18);will-change:transform,opacity;
  transform:translate3d(-50%,calc(-50% + 120svh),0)}
.r-ria{z-index:7} .r-lia{z-index:8}
.wk-reel video,.wk-reel .rm-poster,.wk-still{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.wk-reel .rm-poster{display:block;z-index:0}
.wk-reel video{z-index:1;opacity:0;transition:opacity .45s var(--ease)}
.wk-reel.live video{opacity:1}
.wk-reel::after{content:"";position:absolute;inset:0;background:var(--void);
  opacity:var(--wdim,0);pointer-events:none;z-index:3}
/* the photograph the film becomes: same rectangle, same radius as the reel */
.wk-still{opacity:var(--still,0);object-position:50% 26%;z-index:4}
.wk-reel .film-audio{left:.7rem;bottom:.7rem;width:40px;height:40px;z-index:5}
.wk-reel .film-audio svg{width:15px;height:15px}
.wk-fr .film-audio{right:var(--gut);bottom:clamp(1.3rem,4.6svh,2.6rem);z-index:5}
.film-audio{transition:opacity .3s,visibility .3s,border-color .2s,background-color .2s}
/* scoped to THIS page's frames: the home page's reels share the .frame class
   and their keys must stay visible */
.wk-fr:not(.keyed) .film-audio,.wk-reel:not(.keyed) .film-audio{opacity:0;visibility:hidden}
.wk-film.handed .r-lia,.wk-film.handed .wk-slate[data-slate="p"]{visibility:hidden}
@media(max-width:900px){.wk-reel{--rh:62svh}}

/* legibility over full-bleed film: a top band for the chrome, a bottom band
   for the slates. It only exists once the film owns the frame. */
.wk-scrim{position:absolute;inset:0;z-index:6;pointer-events:none;opacity:var(--scrim,0);
  background:linear-gradient(180deg,rgba(10,10,11,.58) 0%,rgba(10,10,11,0) 24%,
    rgba(10,10,11,0) 56%,rgba(10,10,11,.84) 100%)}

/* the chapter title: a light numeral, the name beneath, a red mark */
.wk-chap{position:absolute;left:var(--gut);bottom:clamp(1.4rem,5svh,3.2rem);z-index:9;
  opacity:var(--chap,0);transform:translateY(calc((1 - var(--chap,0)) * 18px));
  pointer-events:none}
.wk-num{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 144,'wght' 200,'SOFT' 0,'WONK' 0;font-weight:200;
  font-size:clamp(4.2rem,11vw,10rem);line-height:.8;letter-spacing:-.045em;margin:0;
  color:var(--color-on-dark)}
.wk-cht{display:flex;align-items:center;gap:.7rem;margin:.7rem 0 0 .25rem;
  font-family:var(--f-work);font-stretch:118%;font-weight:600;
  font-size:clamp(1rem,1.6vw,1.4rem);color:var(--color-on-dark)}
.wk-cht::before{content:"";width:8px;height:8px;background:var(--signal);flex:none}

.wk-acts{position:absolute;right:var(--gut);top:var(--safe-top);z-index:9;list-style:none;
  margin:0;padding:0;display:grid;gap:.4rem;text-align:right;opacity:var(--acts,0);
  font-family:var(--f-machine);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);pointer-events:none}
.wk-acts{color:var(--color-on-dark-dim)}
.wk-acts li{transition:color .35s var(--ease)}
.wk-acts li.on{color:var(--color-on-dark)}
.wk-acts .n{color:var(--signal-text-media);margin-right:.55em}
@media(max-width:900px){.wk-acts{display:none}}

/* slates: the project's own identification, printed on the lower band */
.wk-slates{position:absolute;left:var(--gut);right:var(--gut);bottom:clamp(1.4rem,5svh,3.2rem);
  z-index:9;pointer-events:none;height:0}
.wk-slate{position:absolute;left:0;bottom:0;max-width:min(62vw,560px);
  opacity:var(--sl,0);transform:translateY(calc((1 - var(--sl,0)) * 12px));pointer-events:none}
.wk-slate.on{pointer-events:auto}
.wk-slate .proj-name{margin-top:.55rem;font-size:clamp(1.15rem,1.9vw,1.7rem)}
.wk-slate{color:var(--color-on-dark)}
.wk-slate .spec{margin-top:.6rem;letter-spacing:.11em;text-transform:uppercase;line-height:1.7;
  color:rgba(247,246,244,.78)}
.wk-slate .spec a{color:var(--color-on-dark);text-decoration:underline;text-underline-offset:4px;
  text-decoration-color:var(--signal)}
@media(max-width:900px){
  .wk-say{width:auto;right:0;justify-content:flex-start;padding-top:clamp(.6rem,2svh,1.4rem)}
  .wk-h1{font-size:clamp(2.35rem,10.6vw,3.6rem)}
  .wk-lede{max-width:40ch;font-size:.94rem}
  .wk-deck{perspective-origin:50% 60%}
  .l-photo{--lw:30vw} .l-ui{--lw:56vw} .l-reel{--lw:20vw}
  .l-reel .wk-lc{left:auto;right:0}
  .wk-lw{border-radius:8px}
  .wk-slate{max-width:calc(100vw - 2 * var(--gut) - 56px)}
  .wk-slate .spec{font-size:.62rem}
  .wk-fr .film-audio{bottom:clamp(1.3rem,4.6svh,2.6rem)}
}

/* ── 02 · PHOTOGRAPHY ─────────────────────────────────────────────────── */
/* overflow:visible is LOAD-BEARING: the lead frame is drawn above this stage
   while the stage is still rising. The plates that do need clipping live in
   .wk-book, which clips them itself. */
#photography .stage{background:var(--color-black);overflow:visible}
.wk-lead{position:absolute;left:50%;top:50%;height:var(--rh,74svh);aspect-ratio:9/16;width:auto;
  object-fit:cover;object-position:50% 26%;border-radius:14px;z-index:9;display:none;
  transform:translate3d(-50%,-50%,0);will-change:transform;box-shadow:0 24px 62px rgba(28,25,20,.18)}
.wk-lead.on{display:block}
.wk-book{position:absolute;inset:0;overflow:clip;z-index:2}
.wk-pl{position:absolute;left:50%;top:50%;margin:0;width:var(--pw);
  transform-origin:50% 50%;will-change:transform,opacity;opacity:0;visibility:hidden}
.wk-pl.on{visibility:visible}
.wk-win{display:block;position:relative;overflow:hidden;background:var(--color-media-backing);aspect-ratio:var(--pa);
  will-change:clip-path}
.wk-win img{width:100%;height:100%;object-fit:cover;display:block}
.wk-win::after{content:"";position:absolute;inset:0;background:var(--void);
  opacity:var(--wdim,0);pointer-events:none}
.wk-pl figcaption{display:none}
.wk-pl[data-pl="0"]{--pa:9/16;z-index:3}
.wk-pl[data-pl="0"] img{object-position:50% 26%}
.wk-pl[data-pl="1"]{--pw:34vw;--pa:16/9;z-index:7}
.wk-pl[data-pl="1"] img{object-position:50% 34%}
.wk-pl[data-pl="2"]{--pw:26vw;--pa:9/16;z-index:5}
.wk-pl[data-pl="2"] img{object-position:50% 22%}
.wk-pl[data-pl="3"]{--pw:78vw;--pa:16/9;z-index:6}
.wk-pl[data-pl="3"] img{object-position:50% 32%}
.wk-pl[data-pl="4"]{--pw:100vw;--pa:16/9;z-index:8}
.wk-pl[data-pl="4"] img{object-position:50% 42%}
@media(max-width:900px){
  .wk-pl[data-pl="1"]{--pw:56vw}
  .wk-pl[data-pl="2"]{--pw:40vw}
  .wk-pl[data-pl="3"]{--pw:96vw}
  .wk-pl[data-pl="4"]{--pa:4/5}
}
/* captions beside the pictures, never on them */
.wk-pcap{position:absolute;z-index:9;pointer-events:none;
  opacity:var(--cap,0)}
.wk-pcap-a{left:calc(50% + var(--pcap-x,18vw));top:50%;max-width:min(30vw,380px);
  transform:translate3d(0,calc(-50% + (1 - var(--cap,0)) * 12px),0)}
.wk-pcap-a .t-scene{margin-top:.7rem;font-size:clamp(1.5rem,2.6vw,2.4rem)}
.wk-pcap-a .factline{margin-top:.9rem;max-width:30ch}
.wk-pcap-a .spec{margin-top:1.1rem;text-transform:uppercase;letter-spacing:.14em}
.wk-pcap-b{left:calc(50% + 4vw);top:50%;max-width:min(30vw,380px);
  transform:translate3d(0,calc(-50% + (1 - var(--cap,0)) * 12px),0)}
.wk-pcap-b .t-editorial{margin-top:.5rem}
.wk-pcap-c{left:var(--gut);bottom:clamp(1.4rem,5svh,3.2rem);
  transform:translate3d(0,calc((1 - var(--cap,0)) * 12px),0)}
.wk-pcap .spec{text-transform:uppercase;letter-spacing:.14em;color:var(--color-text-muted)}
/* -a and -b stand beside the plate on the room; -c is printed on the
   full-bleed plate, under its own scrim, and keeps the light treatment */
.wk-pcap-c,.wk-pcap-c .spec{color:var(--color-on-dark)}
.wk-pscrim{position:absolute;inset:0;z-index:8;pointer-events:none;opacity:var(--pscrim,0);
  background:linear-gradient(180deg,rgba(10,10,11,.5) 0%,rgba(10,10,11,0) 22%,
    rgba(10,10,11,0) 60%,rgba(10,10,11,.8) 100%)}
@media(max-width:900px){
  .wk-pcap-a{left:var(--gut);right:var(--gut);top:auto;bottom:clamp(1.2rem,4svh,2.4rem);
    max-width:none;transform:translate3d(0,calc((1 - var(--cap,0)) * 12px),0)}
  .wk-pcap-a .t-scene{font-size:clamp(1.3rem,5.4vw,1.8rem)}
  .wk-pcap-a .factline{display:none}
  .wk-pcap-b{left:var(--gut);right:var(--gut);top:auto;bottom:clamp(1.2rem,4svh,2.4rem);
    max-width:none;transform:translate3d(0,calc((1 - var(--cap,0)) * 12px),0)}
}
/* the screen the photograph becomes: the technology surface's exact rectangle */
.wk-screen{position:absolute;left:var(--sx,0);top:var(--sy,0);width:var(--sw,0);height:var(--sh,0);
  z-index:10;opacity:var(--scr,0);border:1px solid rgba(44,72,124,.24);background:transparent;
  overflow:hidden;pointer-events:none;box-sizing:border-box}
.wk-screen .dun-chrome{transform:translateY(calc((var(--chr,0) - 1) * 100%))}
.wk-screen-view{position:relative;overflow:hidden;height:calc(100% - 34px);background:rgba(255,255,255,var(--capt,0))}
.wk-screen-view img{position:absolute;top:0;left:0;width:100%;height:auto;display:block;
  opacity:var(--capt,0)}
.wk-photo.handed .wk-screen,.wk-photo.handed .wk-pl[data-pl="4"]{visibility:hidden}

/* ── 03 · BRAND & TECHNOLOGY ──────────────────────────────────────────── */
/* overflow:visible for the same reason as photography: the surface is the
   lead, drawn above the stage while it rises. align-items:start keeps the
   surface's natural position independent of its own (engine-written) height,
   which is what lets the photograph target it exactly. */
#technology .stage{background:var(--tech-ground,var(--color-ground-cool));overflow:visible;align-items:start}
#technology .stage::before{content:"";position:absolute;inset:0;pointer-events:none;
  opacity:var(--grid-o,0);transition:opacity 300ms linear;
  background:
    repeating-linear-gradient(to right,rgba(44,72,124,.11) 0 1px,transparent 1px 64px),
    repeating-linear-gradient(to bottom,rgba(44,72,124,.11) 0 1px,transparent 1px 64px)}
.wk-tech-body{display:grid;grid-template-columns:1fr;gap:1.2rem;align-items:start;
  padding-top:3rem}
@media(min-width:901px){
  .wk-tech-body{grid-template-columns:minmax(0,1fr) minmax(0,29%);gap:clamp(1.6rem,3vw,3rem)}
}
.wk-tech-copy{position:relative;z-index:4;padding-top:.3rem}
.wk-tech-copy .t-tech{color:#1b2029;font-size:clamp(1.35rem,2.3vw,2rem)}
.wk-tech-copy .factline{color:#59636f;max-width:34ch}
.wk-tech-copy .spec{color:#5f6a78;margin-top:.7rem;text-wrap:balance}
.wk-tech-copy .spec a{color:#1b2029;text-decoration:underline;text-underline-offset:4px}
.wk-tech-facts{margin-top:1rem}
.dun-surface{will-change:width,transform}
#technology .tech-hud{color:#59636f}

/* ── SELECTED WORK · THE INDEX ────────────────────────────────────────── */
.wk-index-s{padding-block:clamp(4rem,9vw,7rem) clamp(3rem,7vw,5.5rem);position:relative}
.wk-index-h{margin-top:.9rem;max-width:18ch}
.wk-index-h i{font-style:italic}
.wk-index-s .factline{margin-top:1rem;max-width:52ch}
.wk-ix{list-style:none;margin:clamp(1.8rem,4vw,3rem) 0 0;padding:0;border-top:1px solid var(--hair)}
.wk-ix li{border-bottom:1px solid var(--hair);position:relative}
.wk-ix a{display:grid;align-items:baseline;gap:.25rem 1.4rem;
  grid-template-columns:auto minmax(0,1fr) auto;
  padding:clamp(1rem,2.6vw,1.7rem) 0;color:inherit;text-decoration:none;
  transition:padding-left .45s var(--ease)}
.wk-ix a:hover,.wk-ix a:focus-visible{padding-left:.9rem}
.ix-n{font-family:var(--f-machine);font-size:.64rem;letter-spacing:.16em;color:var(--signal-text)}
.ix-name{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 90,'wght' 320,'SOFT' 0,'WONK' 0;font-weight:320;
  font-size:clamp(1.55rem,3.6vw,2.8rem);line-height:1;letter-spacing:-.018em;color:var(--fg)}
.ix-cat{grid-column:2;font-family:var(--f-work);font-size:.86rem;color:var(--muted);line-height:1.5}
.ix-meta{grid-column:2;font-family:var(--f-machine);font-size:.6rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim);margin-top:.15rem}
.ix-go{grid-column:3;grid-row:1;font-family:var(--f-machine);font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;align-self:center;
  transition:color .3s}
.ix-go i{font-style:normal;display:inline-block;transition:transform .4s var(--ease)}
.wk-ix a:hover .ix-go,.wk-ix a:focus-visible .ix-go{color:var(--fg)}
.wk-ix a:hover .ix-go i,.wk-ix a:focus-visible .ix-go i{transform:translateX(.35em)}
/* a poster on hover — quiet, and only where a pointer can hover */
.ix-thumb{position:absolute;right:clamp(4rem,9vw,8rem);top:50%;width:150px;aspect-ratio:3/2;
  object-fit:cover;border-radius:6px;transform:translateY(-50%) scale(.96);opacity:0;
  pointer-events:none;transition:opacity .35s var(--ease),transform .5s var(--ease);
  box-shadow:0 14px 34px rgba(28,25,20,.17)}
.ix-thumb.tall{aspect-ratio:9/16;width:84px}
@media(hover:hover) and (pointer:fine){
  .wk-ix li:hover .ix-thumb,.wk-ix li:focus-within .ix-thumb{opacity:1;transform:translateY(-50%) scale(1)}
}
@media(max-width:700px){
  .wk-ix a{grid-template-columns:auto minmax(0,1fr)}
  .ix-go{grid-column:2;grid-row:auto;margin-top:.4rem}
  .ix-thumb{display:none}
}

/* ── CASCADE: this page carries the document scaffold (.pg), whose p / h2 /
   h3 / section rules outrank single-class type roles. Restated here at
   higher specificity so the scene type and spacing are what was designed. */
.pg .scene{padding-block:0}
.wk-film p,.wk-photo p,.wk-tech p,.wk-rail p{margin:0}
.wk-chap .wk-num{margin:0}
.wk-chap .wk-cht{font-family:var(--f-work);font-stretch:118%;font-weight:600;
  font-size:clamp(1rem,1.6vw,1.4rem);line-height:1.15;letter-spacing:.002em}
.wk-slate .proj-name{font-family:var(--f-work);font-stretch:118%;font-weight:600;
  line-height:1.15;letter-spacing:.002em;color:var(--color-on-dark)}
.wk-say .wk-lede{color:var(--muted);font-size:clamp(1rem,1.35vw,1.16rem);line-height:1.55;max-width:30ch}
.wk-pcap-a .t-scene,.wk-index-s .t-scene{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 60,'wght' 400,'SOFT' 0,'WONK' 0;font-weight:400;
  line-height:1.02;letter-spacing:-.018em}
.wk-index-s .t-scene{font-size:clamp(1.9rem,4vw,3.3rem)}
.wk-pcap-b .t-editorial{font-family:var(--f-studio);font-optical-sizing:none;
  font-variation-settings:'opsz' 30,'wght' 400,'SOFT' 40,'WONK' 0;font-weight:400;
  font-size:clamp(1.25rem,2.1vw,1.85rem);line-height:1.28;letter-spacing:-.008em}
.wk-tech-copy .t-tech{font-family:var(--f-work);font-stretch:88%;font-weight:700;
  line-height:1.04;letter-spacing:-.005em;text-transform:uppercase}
.wk-tech-copy .factline{margin-top:.2rem}
.wk-tech-copy .spec{margin-top:.7rem}

/* phones: nothing may run under the motion toggle in the lower-right corner */
@media(max-width:900px){
  .wk-pcap-a,.wk-pcap-b,.wk-pcap-c{right:calc(var(--gut) + 112px)}
  .wk-slate{max-width:calc(100vw - 2 * var(--gut) - 112px)}
}
@media(max-width:640px){
  .dun-chrome .cap-chip{font-size:.5rem;letter-spacing:.06em;padding:.1rem .3rem;white-space:nowrap}
}

/* phones: the engine turns every stage into a centred flex column. This
   stage's column is taller than the frame (rail + hud + surface + honest
   copy), and centring an over-tall column pushes the hud up under the rail —
   so on this page the column starts at the safe zone instead. */
@media(max-width:900px){
  html[data-mode="cinematic"] #technology .stage{justify-content:flex-start;gap:.6rem}
  .wk-tech-body{padding-top:0;gap:.9rem}
  .wk-tech-copy .factline{font-size:.86rem;max-width:none}
  .wk-tech-copy .spec{font-size:.62rem;margin-top:.5rem}
  .wk-tech-copy .t-tech{font-size:clamp(1.2rem,5.6vw,1.6rem)}
  .wk-tech-facts{margin-top:.6rem}
}

.wk-brand-short{display:none}
/* phones: the same honesty in fewer lines, and a tighter column, so the
   surface, the copy and the live-site link all fit one 390x844 frame */
@media(max-width:640px){
  html.page-work{--safe-top:calc(var(--nav-h) + 34px + clamp(10px,1.6vh,18px))}
  .wk-rail{height:34px}
  .wk-brand-long{display:none} .wk-brand-short{display:block}
  #technology .tech-hud>.label:nth-child(2){display:none}
  .wk-tech-copy .factline{font-size:.82rem;line-height:1.45}
  .wk-tech-copy .t-tech{font-size:1.35rem}
  .wk-tech-copy .tech-rule{margin:.45rem 0 .55rem}
  .wk-tech-copy .route-ribbon{margin-top:.4rem}
  .wk-tech-copy .spec{font-size:.58rem;margin-top:.4rem;line-height:1.5}
  .wk-tech-facts{margin-top:.5rem}
  html[data-mode="cinematic"] #technology .stage{gap:.4rem}
  .wk-tech-body{gap:.7rem}
}

@media(max-width:380px){
  #technology .tech-hud .rd{display:none}
  .wk-tech-copy .factline{font-size:.78rem;line-height:1.4}
}

/* ── EDITORIAL EDITION (prefers-reduced-motion / no JS) ───────────────── */
html[data-mode="editorial"] #film .stage,
html[data-mode="editorial"] #photography .stage,
html[data-mode="editorial"] #technology .stage{overflow:visible;padding-top:var(--safe-top)}
html[data-mode="editorial"] #film .stage{display:flex;flex-direction:column;gap:2rem;padding-bottom:3rem}
html[data-mode="editorial"] .wk-say{position:static;width:auto;padding:0 var(--gut);display:block;order:1}
html[data-mode="editorial"] .wk-cue{display:none}
html[data-mode="editorial"] .wk-chap{position:static;opacity:1;transform:none;padding:0 var(--gut);order:2}
html[data-mode="editorial"] .wk-deck{position:static;order:3;display:grid;gap:1.2rem;
  grid-template-columns:repeat(2,minmax(0,1fr));padding:0 var(--gut);max-width:1240px;margin:0 auto;width:100%;perspective:none}
html[data-mode="editorial"] .wk-fr{position:relative;inset:auto;aspect-ratio:16/9;grid-column:1/-1;
  clip-path:none!important;visibility:visible!important;transform:none!important;opacity:1!important;
  border-radius:10px}
html[data-mode="editorial"] .wk-fr video{display:none}
html[data-mode="editorial"] .wk-fr .rm-poster{display:block;transform:none!important}
html[data-mode="editorial"] .wk-layer{position:static;width:auto;transform:none!important;opacity:1!important;max-width:420px}
html[data-mode="editorial"] .l-ui{max-width:none}
html[data-mode="editorial"] .wk-lw{aspect-ratio:auto;box-shadow:none}
html[data-mode="editorial"] .wk-lw img{height:auto}
html[data-mode="editorial"] .wk-lc,html[data-mode="editorial"] .lc-film{position:static;opacity:1;transform:none;margin-top:.6rem}
html[data-mode="editorial"] .wk-films{position:static;order:5;display:grid;gap:1.6rem;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));padding:0 var(--gut);max-width:1240px;margin:0 auto;width:100%}
html[data-mode="editorial"] .f-ceremony{grid-column:1/-1}
html[data-mode="editorial"] .wk-reel{position:relative;left:auto;top:auto;height:auto;width:100%;max-width:340px;
  transform:none!important;opacity:1!important;visibility:visible!important}
html[data-mode="editorial"] .wk-reel video{display:none}
html[data-mode="editorial"] .wk-reel .rm-poster{display:block;position:static}
html[data-mode="editorial"] .wk-still,html[data-mode="editorial"] .wk-scrim,
html[data-mode="editorial"] .wk-acts{display:none}
html[data-mode="editorial"] .wk-slates{position:static;height:auto;order:4;padding:0 var(--gut);
  display:grid;gap:1.4rem;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));max-width:1240px;margin:0 auto;width:100%}
html[data-mode="editorial"] .wk-slate{position:static;opacity:1;transform:none;max-width:none;pointer-events:auto}
html[data-mode="editorial"] .wk-slate[data-slate="p"]{display:none}
/* returned to normal flow on the light ground - so is their colour */
html[data-mode="editorial"] .wk-num,
html[data-mode="editorial"] .wk-cht,
html[data-mode="editorial"] .wk-slate,
html[data-mode="editorial"] .wk-slate .proj-name,
html[data-mode="editorial"] .wk-slate .spec a{color:var(--color-text-primary)}
html[data-mode="editorial"] .wk-slate .spec{color:var(--color-text-secondary)}
html[data-mode="editorial"] .wk-lead,html[data-mode="editorial"] .wk-screen,
html[data-mode="editorial"] .wk-pscrim{display:none}
html[data-mode="editorial"] .wk-book{position:static;display:grid;gap:1.6rem;padding:0 var(--gut);
  max-width:1240px;margin:0 auto;overflow:visible;grid-template-columns:repeat(2,minmax(0,1fr))}
html[data-mode="editorial"] .wk-pl[data-pl="1"],html[data-mode="editorial"] .wk-pl[data-pl="3"],
html[data-mode="editorial"] .wk-pl[data-pl="4"]{grid-column:1/-1}
@media(max-width:640px){html[data-mode="editorial"] .wk-book{grid-template-columns:1fr}}
html[data-mode="editorial"] .wk-pl{position:static;width:auto;transform:none!important;opacity:1!important;visibility:visible!important}
html[data-mode="editorial"] .wk-win{aspect-ratio:auto;clip-path:none!important;border-radius:10px}
html[data-mode="editorial"] .wk-win img{height:auto;object-fit:contain}
html[data-mode="editorial"] .wk-pl figcaption{display:block;margin-top:.6rem;font-family:var(--f-machine);
  font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
html[data-mode="editorial"] .wk-pcap{position:static;opacity:1;transform:none;max-width:none;padding:0 var(--gut)}
html[data-mode="editorial"] .wk-pcap-a{padding-bottom:1.6rem}
html[data-mode="editorial"] .wk-pcap-b,html[data-mode="editorial"] .wk-pcap-c{display:none}
html[data-mode="editorial"] .wk-tech-body{grid-template-columns:1fr}
html[data-mode="editorial"] #technology .stage{display:block}
html[data-mode="editorial"] #technology .tech-hud,
html[data-mode="editorial"] #tech .tech-hud{position:static;margin-bottom:1rem}

/* ═══════════════════════════════════════════════════════════════════════════
   V3 · THE FOUNDATION
   Typography, motion, shape and chrome, rebuilt from zero against the Apple
   quality bar. Everything below overrides the V1/V2 layers deliberately; the
   older rules are left in place because the locked reel section still depends
   on some of them, and because a diff you can read is worth more than a file
   you cannot.

   THE ONE RULE THAT SHAPES ALL OF THIS: one typeface family across the whole
   scale, with size-specific tracking and leading. Apple ships SF Pro Display
   and SF Pro Text as one superfamily and changes its shape with size; three
   competing families (a serif, a grotesk and a mono) is the opposite of that
   discipline. V3 uses Geist — a variable neo-grotesk built for technology
   products — with Geist Mono as the instrument voice. Fraunces is gone.

   ARCHIVO SURVIVES IN EXACTLY ONE PLACE: inside #commercial, the founder's
   locked reel section, whose typography must not change. That pin is at the
   bottom of this block and is the only reason the family is still loaded.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── the two voices ── */
  --f-display:'Geist','SF Pro Display',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --f-mono:'Geist Mono',ui-monospace,SFMono-Regular,'SF Mono',Menlo,monospace;

  /* legacy names re-pointed: every existing selector speaks these */
  --f-studio:var(--f-display);
  --f-work:var(--f-display);
  --f-machine:var(--f-mono);

  /* ── THE SCALE ──
     Tracking is size-specific and never one value: large text reads too loose
     as it grows, small text too tight. Leading moves inversely to size. */
  --t-hero-size:clamp(2.5rem,5.6vw,4.9rem);
  --t-hero-lh:.94;   --t-hero-ls:-.045em; --t-hero-w:600;
  --t-display-size:clamp(2.25rem,5vw,4.2rem);
  --t-display-lh:1.02; --t-display-ls:-.036em; --t-display-w:600;
  --t-title-size:clamp(1.65rem,3vw,2.5rem);
  --t-title-lh:1.1;  --t-title-ls:-.026em; --t-title-w:600;
  --t-head-size:clamp(1.2rem,1.8vw,1.5rem);
  --t-head-lh:1.24;  --t-head-ls:-.015em; --t-head-w:600;
  --t-lede-size:clamp(1.06rem,1.32vw,1.28rem);
  --t-lede-lh:1.5;   --t-lede-ls:-.008em;
  --t-body-size:1rem; --t-body-lh:1.62;   --t-body-ls:0;
  --t-small-size:.875rem; --t-small-lh:1.55; --t-small-ls:.002em;
  --t-label-size:.6875rem; --t-label-ls:.14em;

  /* ── SPACING · a 4px base, and one chapter rhythm ── */
  --s-1:.25rem; --s-2:.5rem;  --s-3:.75rem; --s-4:1rem;
  --s-5:1.25rem; --s-6:1.5rem; --s-8:2rem;  --s-10:2.5rem;
  --s-12:3rem;  --s-16:4rem;  --s-20:5rem;  --s-24:6rem;
  --chapter:clamp(4.5rem,11vw,9rem);
  --gut:clamp(1.25rem,4.4vw,4.5rem);
  --max:1440px;
  --measure:64ch;

  /* ── MOTION ──
     Four durations and three curves. --e-out is the decelerating curve almost
     everything uses: fast to start, long settle, no overshoot. Bounce is
     reserved for motion a gesture actually threw. */
  --e-out:cubic-bezier(.16,1,.3,1);
  --e-io:cubic-bezier(.65,0,.35,1);
  --e-std:cubic-bezier(.4,0,.2,1);
  --d-press:120ms;
  --d-state:220ms;
  --d-move:420ms;
  --d-reveal:760ms;
  --d-cine:1200ms;

  /* ── SHAPE ──
     Almost nothing is a box. A capsule for a filled control, a small radius
     for media, and nothing else. */
  --r-capsule:999px;
  --r-media:10px;
  --r-chip:6px;
}

html{-webkit-tap-highlight-color:transparent}
body{
  font-family:var(--f-display);
  font-size:var(--t-body-size);line-height:var(--t-body-lh);letter-spacing:var(--t-body-ls);
  font-weight:400;font-stretch:normal;font-variation-settings:normal;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

/* ══ THE TYPE ROLES ══════════════════════════════════════════════════════
   Every heading is the same family at a different size, weight and tracking.
   font-variation-settings is reset everywhere the old system set Fraunces
   axes that Geist does not have, and font-stretch is reset everywhere the old
   system asked Archivo for a width it no longer offers. */
.t-display,.t-scene,.t-editorial,.t-tech,.proj-name,.hero-l1,.hero-l2,
.pg h1,.pg h2,.pg h3,.pg .mega,.wk-h1,.wk-num,.wk-cht,.ix-name,
.st-name,.cv-head,.fin-words .l1,.fin-words .l2,.fin-words .l3,
.ph2-h,.pillar-verb,.team-member h3,.claim-l,.band h3{
  font-family:var(--f-display);font-variation-settings:normal;
  font-stretch:normal;font-optical-sizing:auto;font-style:normal}

.t-display,.pg .mega{
  font-size:var(--t-hero-size);line-height:var(--t-hero-lh);
  letter-spacing:var(--t-hero-ls);font-weight:var(--t-hero-w);
  margin:0;text-wrap:balance}
.t-scene,.pg h1,.ph2-h{
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  margin:0;text-wrap:balance}
.t-tech,.pg h2,.pillar-verb{
  font-size:var(--t-title-size);line-height:var(--t-title-lh);
  letter-spacing:var(--t-title-ls);font-weight:var(--t-title-w);
  margin:0;text-transform:none;text-wrap:balance}
.t-editorial{
  font-size:var(--t-head-size);line-height:var(--t-head-lh);
  letter-spacing:var(--t-head-ls);font-weight:500;margin:0}
.pg h3,.proj-name,.band h3,.team-member h3{
  font-size:var(--t-head-size);line-height:var(--t-head-lh);
  letter-spacing:var(--t-head-ls);font-weight:var(--t-head-w);margin:0}
.lede,.pg .lede{
  font-size:var(--t-lede-size);line-height:var(--t-lede-lh);
  letter-spacing:var(--t-lede-ls);font-weight:400;
  max-width:var(--measure);margin:0}
.factline:not(#commercial *){
  font-size:var(--t-small-size);line-height:var(--t-small-lh);
  letter-spacing:var(--t-small-ls);font-weight:400;max-width:52ch;margin-block:0}
.pg p{font-size:var(--t-body-size);line-height:var(--t-body-lh);margin:0 0 1.05em}

/* the instrument voice: chapter numbers, labels, specs, data */
:is(.label,.spec,.cap,.step-pip,.ix-n,.ix-meta,.ix-go,.st-n,.st-role,
.ph2-marker,.ph2-cap .n,.ph2-cap span,.ph2-count,.wk-acts,.wk-lc,.hs-index):not(#commercial *){
  font-family:var(--f-mono);font-variation-settings:normal;font-stretch:normal}
.label:not(#commercial *){font-size:var(--t-label-size);letter-spacing:var(--t-label-ls);
  font-weight:400;text-transform:uppercase;line-height:1.4;margin-block:0}
/* margin-BLOCK, not margin: this is a voice rule and it has no business
   resetting a layout margin. `.spec{margin:0}` outran `.cin-meta{margin-left:
   auto}` by source order and drew the cinema bar’s two captions on top of
   each other; the same trap sits under every component that positions a
   .spec / .label / .factline horizontally. */
.spec{font-size:var(--t-label-size);letter-spacing:.1em;font-weight:400;
  font-variant-numeric:tabular-nums slashed-zero;margin-block:0}

/* em / strong, restated for the new family */
.pg em{font-style:normal;font-weight:500;text-decoration:underline;
  text-decoration-color:var(--signal);text-decoration-thickness:2px;
  text-underline-offset:4px}
.pg strong{font-weight:600}

/* ══ THE CHROME ══════════════════════════════════════════════════════════
   A translucent material the content scrolls under, with a scroll EDGE rather
   than a hard rule. Apple never draws a 1px border under a floating bar. */
.nav{padding-block:var(--s-4);gap:var(--s-6);
  transition:background var(--d-move) var(--e-std),
             backdrop-filter var(--d-move) var(--e-std)}
.nav.scrolled{
  background:rgba(250,249,247,.72);
  backdrop-filter:blur(24px) saturate(180%);
  -webkit-backdrop-filter:blur(24px) saturate(180%);
  border-bottom:0}
/* the edge is a fade, not a line */
.nav.scrolled::after{content:"";position:absolute;left:0;right:0;top:100%;
  height:22px;pointer-events:none;
  background:linear-gradient(180deg,rgba(250,249,247,.5),rgba(250,249,247,0))}
html[data-ground="dark"] .nav.scrolled{background:rgba(12,12,14,.62)}
html[data-ground="dark"] .nav.scrolled::after{
  background:linear-gradient(180deg,rgba(12,12,14,.45),rgba(12,12,14,0))}
@media(prefers-reduced-transparency:reduce){
  .nav.scrolled{backdrop-filter:none;background:var(--color-bg-primary)}
  .nav.scrolled::after{display:none}
  html[data-ground="dark"] .nav.scrolled{background:var(--color-black)}
}

.nav-mark{gap:var(--s-3);font-family:var(--f-display);font-stretch:normal;
  font-variation-settings:normal;font-weight:600;font-size:1.0625rem;
  letter-spacing:-.012em}
.nav-mark svg{width:26px;height:26px}
.nav-links{gap:clamp(1.1rem,2.4vw,2.2rem)}
.nav-links a{font-family:var(--f-display);font-stretch:normal;
  font-variation-settings:normal;font-weight:400;font-size:.9375rem;
  letter-spacing:-.006em;opacity:1;color:var(--fg);position:relative;
  transition:color var(--d-state) var(--e-std)}
.nav-links a:hover{color:var(--fg)}
/* the indicator is a rule that wipes from the left, not an opacity change */
.nav-links a::after{content:"";position:absolute;left:0;right:0;bottom:-.42em;
  height:1.5px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.nav-links a:hover::after,.nav-links a:focus-visible::after{transform:scaleX(1)}
.nav-links a[aria-current="page"]::after{transform:scaleX(1)}

/* ══ THE CONTROLS ════════════════════════════════════════════════════════
   Two shapes, and only two. A filled CAPSULE for the one primary action on a
   view, and a TEXT LINK with a chevron for everything else. No outlined
   rectangles, no divided action squares, no borders drawn for their own sake. */
.btn{display:inline-flex;align-items:center;gap:.5em;border:0;background:none;
  padding:0;min-height:0;overflow:visible;position:relative;cursor:pointer;
  font-family:var(--f-display);font-stretch:normal;font-variation-settings:normal;
  font-weight:500;font-size:.9375rem;letter-spacing:-.006em;text-transform:none;
  color:var(--fg);
  transition:color var(--d-state) var(--e-std),opacity var(--d-state) var(--e-std)}
.btn::before{display:none}
.btn>span{padding:0;display:inline;position:relative}
/* the underline wipes in from the left on hover — the whole affordance */
.btn>span::after{content:"";position:absolute;left:0;right:0;bottom:-.28em;
  height:1.5px;background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.btn:hover>span::after,.btn:focus-visible>span::after{transform:scaleX(1)}
.btn .tick{border:0;padding:0;display:inline-flex;align-items:center;
  color:var(--signal-text);font-family:var(--f-display);font-style:normal;
  transition:transform var(--d-move) var(--e-out)}
.btn:hover .tick,.btn:focus-visible .tick{transform:translateX(.28em)}
.btn:active{transform:none}
.btn:active>span{opacity:.6}

/* the one filled control. A capsule, because a rectangle with a 0 radius and
   a 1px border is the shape the founder named as dated. */
.btn.btn-solid{
  background:var(--fg);color:var(--color-on-dark);border:0;
  padding:.72em 1.35em;border-radius:var(--r-capsule);min-height:44px;
  font-weight:500;
  transition:background var(--d-state) var(--e-std),transform var(--d-press) var(--e-out)}
.btn.btn-solid>span::after{display:none}
.btn.btn-solid .tick{color:var(--color-on-dark);opacity:.72}
.btn.btn-solid:hover{background:#31302c;color:#fff}
.btn.btn-solid:active{transform:scale(.97)}
/* the capsule inverts on every dark ground. .foot was missing from this list
   and rendered a white capsule with warm-white type inside it. */
html[data-ground="dark"] .nav .btn.btn-solid,
.band-black .btn.btn-solid,.red-band .btn.btn-solid,.field-signal .btn.btn-solid,
.foot .btn.btn-solid,.masthead .btn.btn-solid,#cinema .btn.btn-solid{
  background:var(--color-on-black);color:var(--color-black)}
html[data-ground="dark"] .nav .btn.btn-solid:hover,
.band-black .btn.btn-solid:hover,.red-band .btn.btn-solid:hover,
.field-signal .btn.btn-solid:hover,.foot .btn.btn-solid:hover,
.masthead .btn.btn-solid:hover{background:#fff;color:var(--color-black)}
html[data-ground="dark"] .nav .btn.btn-solid .tick,
.band-black .btn.btn-solid .tick,.red-band .btn.btn-solid .tick,
.field-signal .btn.btn-solid .tick,.foot .btn.btn-solid .tick,
.masthead .btn.btn-solid .tick{color:var(--color-black);opacity:.66}

/* THE GLOBAL CTA. Not a button — a piece of type with a direction. */
.nav-cta{min-height:0;padding:0;border:0;background:none;
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;text-transform:none;color:var(--fg);
  display:inline-flex;align-items:center;gap:.45em}
.nav-cta::before{display:none}
.nav-cta>span{padding:0;position:relative}
.nav-cta>span::after{content:"";position:absolute;left:0;right:0;bottom:-.3em;
  height:1.5px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.nav-cta:hover>span::after,.nav-cta:focus-visible>span::after{transform:scaleX(1)}
.nav-cta .tick{color:var(--signal);transition:transform var(--d-move) var(--e-out)}
.nav-cta:hover .tick,.nav-cta:focus-visible .tick{transform:translate(.22em,-.22em)}
html[data-ground="dark"] .nav-cta{color:var(--color-on-black)}
html[data-ground="dark"] .nav-cta .tick{color:var(--signal-text-media)}

.menu-btn{min-height:0;padding:0;border:0;background:none;color:var(--fg);
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;text-transform:none}
.menu-btn::before{display:none}
.menu-btn>span{padding:0}
html[data-ground="dark"] .menu-btn{color:var(--color-on-black)}

/* the finale gate follows the same law: a capsule, not a cut-cornered plate */
.gate{border:0;background:var(--fg);color:var(--color-on-dark);
  border-radius:var(--r-capsule);min-height:52px;clip-path:none;overflow:visible;
  transition:background var(--d-state) var(--e-std),transform var(--d-press) var(--e-out)}
.gate::before{display:none}
.gate-verb{font-family:var(--f-display);font-stretch:normal;font-weight:500;
  font-size:1.0625rem;letter-spacing:-.012em;text-transform:none;
  padding:.85rem 1.5rem .85rem 1.7rem}
.gate-tick{border:0;padding:0 1.5rem 0 0;color:var(--color-on-dark);opacity:.7;
  font-family:var(--f-display);transition:transform var(--d-move) var(--e-out)}
.gate:hover{background:#31302c;color:#fff}
.gate:hover .gate-tick,.gate:focus-visible .gate-tick{transform:translateX(.28em)}
.gate:active{transform:scale(.98)}

/* ══ CHAPTER MARKERS ═════════════════════════════════════════════════════
   The site's numbering is real information — it is the order of the story —
   so it gets one consistent form: a red numeral, a hairline, a name. */
.chapter{display:flex;align-items:center;gap:var(--s-3);margin:0;
  font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;color:var(--dim)}
.chapter .n{color:var(--signal-text);font-variant-numeric:tabular-nums}
.chapter i{display:block;width:clamp(20px,3vw,40px);height:1px;
  background:currentColor;opacity:.42;flex:none}

/* ══ FOCUS ═══════════════════════════════════════════════════════════════ */
:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:3px}

/* ══ THE LOCKED SECTION ══════════════════════════════════════════════════
   #commercial is the founder's approved reel chapter and its typography must
   not change. Everything above re-points --f-work at Geist; this pins it back
   to Archivo inside that section only, and restores the two shared type roles
   it uses (.label and .factline) to their approved metrics. This pin is the
   ONLY reason Archivo is still loaded by the site. */
#commercial{
  --f-work:'Archivo','Helvetica Neue',Arial,system-ui,sans-serif;
  --f-machine:'Geist Mono','JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  /* the gutter drives this section's own internal spacing, so it keeps the
     value it was approved at rather than the V3 one */
  --gut:clamp(1.2rem,4vw,4rem);
  /* inherited type: re-pointing --f-work is not enough, because everything in
     here inherits its family, size and leading from <body>, not from a token */
  font-family:var(--f-work);font-size:1.02rem;line-height:1.6;
  font-weight:400;font-stretch:100%;letter-spacing:normal}
#commercial *{font-variation-settings:normal}
/* Nothing else is restated here on purpose: every V3 rule that could reach
   this section is excluded with :not(#commercial *) at its own declaration,
   so the locked block's own CSS is the only thing styling it. */

/* ── the V3 .btn sets display, which outranks the responsive hide rules the
   chrome relies on (they are plain .menu-btn / .nav-cta and lose to a later
   .btn). Re-asserted here at a specificity that cannot be lost. ── */
@media(min-width:900px){.menu-btn.btn{display:none}}
@media(max-width:899px){.nav-cta.btn{display:none}}
.nav-links{display:none}
@media(min-width:900px){.nav-links{display:flex}}
.nav-cta{margin-left:auto}
@media(min-width:900px){.nav-cta{margin-left:clamp(1.1rem,2.4vw,2.2rem)}}
.menu-btn.btn{margin-left:auto}

/* ── the chrome stands on the hero's picture before any scroll, so the frame
   carries a top scrim of its own. Apple never lets a wordmark sit unprotected
   on a bright sky. ── */
.hero-top{position:absolute;inset:0 0 auto 0;height:min(34svh,260px);z-index:4;
  pointer-events:none;opacity:var(--film-in,0);
  transition:opacity 1100ms var(--e-std);
  background:linear-gradient(180deg,rgba(6,6,8,.62) 0%,rgba(6,6,8,.28) 46%,rgba(6,6,8,0) 100%)}
html[data-mode="editorial"] .hero-top{display:none}

/* ══ V3 · SHAPE — the site stops being made of containers ═════════════════
   The founder's rule: not every object needs a border, not every section
   needs a card, not every CTA needs a background. What follows removes the
   boxes that were drawn out of habit and leaves the ones that carry meaning
   (a media frame, one filled control, a form field's baseline). */

/* the category chips were outlined rectangles; they are labels, so they are
   set as labels with a hairline under them and nothing around them */
.cap{border:0;padding:0 0 .34em;background:none;display:inline-block;
  font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;
  color:var(--muted);border-bottom:1px solid var(--line);
  transition:color var(--d-state) var(--e-std),border-color var(--d-state) var(--e-std)}
a.cap:hover,a.cap:focus-visible{color:var(--pg-fg,var(--fg));border-bottom-color:var(--signal)}

/* the social chips were 44px squares with borders; they keep the 44px target
   and lose the box */
.soc{border:0;width:auto;min-width:44px;height:44px;justify-content:flex-start;
  place-items:center;color:var(--muted)}
a.soc:hover,a.soc:focus-visible{color:var(--fg);border:0}

/* the "bands" grid was four bordered cells; it becomes four columns divided by
   a single hairline each, which is all the separation they ever needed */
.bands{gap:0;background:none;border:0;border-top:1px solid var(--line)}
.band{background:none;padding:clamp(1.4rem,2.6vw,2rem) clamp(1rem,2vw,1.6rem)
  clamp(1.4rem,2.6vw,2rem) 0;border-bottom:1px solid var(--line)}
@media(min-width:900px){
  .band{border-right:1px solid var(--line);border-bottom:0;
    padding-left:clamp(1rem,2vw,1.6rem)}
  .band:first-child{padding-left:0}
  .band:last-child{border-right:0}
}
.band .aperture-bar{height:2px}

/* notices and enquiry states lose their boxes and keep their red rule */
.enq-note{border:0;border-left:2px solid var(--line);border-radius:0;
  padding:var(--s-3) 0 var(--s-3) var(--s-5)}
.enq-note[data-state="error"]{border-color:var(--signal)}
.success{border:0;border-left:2px solid var(--signal);padding:var(--s-4) 0 var(--s-4) var(--s-6)}

/* form fields were already hairline-underlined; they only needed the new type */
.fgroup label{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);text-transform:uppercase;color:var(--muted)}
.fgroup input,.fgroup select,.fgroup textarea{
  font-family:var(--f-display);font-size:1rem;letter-spacing:-.006em}

/* ══ THE FINAL SCENE ══════════════════════════════════════════════════════
   The footer closes the story: one large statement, one action, and then the
   plain company information underneath at a whisper. It is the last thing the
   visitor reads, so it gets the same care as the first. */
.foot{padding-top:0;background:var(--color-black);color:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --hair:var(--color-hairline-on-black);--line:var(--color-hairline-on-black);
  --fg:var(--color-on-black);--signal-text:var(--signal-text-media)}
.foot::before{display:none}

.foot-close{grid-column:1 / -1;padding:calc(var(--chapter) * .95) 0 var(--chapter);
  border-bottom:1px solid var(--color-hairline-on-black);
  margin-bottom:clamp(2.4rem,5vw,3.6rem)}
.foot-close .chapter{color:var(--color-on-black-muted)}
.foot-close .chapter i{background:var(--color-on-black-muted)}
.foot-close h2{margin:var(--s-6) 0 0;max-width:17ch;
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  color:var(--color-on-black)}
.foot-close p{margin:var(--s-5) 0 0;max-width:44ch;
  font-size:var(--t-lede-size);line-height:var(--t-lede-lh);
  letter-spacing:var(--t-lede-ls);color:var(--color-on-black-muted)}
.foot-close .foot-act{display:flex;align-items:center;gap:clamp(1.2rem,3vw,2.4rem);
  flex-wrap:wrap;margin-top:clamp(2rem,4vw,3rem)}
.foot-close .foot-mailto{display:inline-flex;align-items:center;gap:.45em;
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;color:var(--color-on-black);position:relative}
.foot-close .foot-mailto span{position:relative}
.foot-close .foot-mailto span::after{content:"";position:absolute;left:0;right:0;
  bottom:-.3em;height:1.5px;background:var(--signal);transform:scaleX(0);
  transform-origin:left;transition:transform var(--d-move) var(--e-out)}
.foot-close .foot-mailto:hover span::after,
.foot-close .foot-mailto:focus-visible span::after{transform:scaleX(1)}

.foot ul{gap:var(--s-3)}
.foot li a{font-size:var(--t-small-size);letter-spacing:-.004em;
  color:var(--color-on-black-muted);
  transition:color var(--d-state) var(--e-std)}
.foot li a:hover,.foot li a:focus-visible{color:var(--color-on-black)}
.foot .label{color:var(--color-on-black-dim)}
.foot-mark svg{fill:var(--color-on-black)}
.foot-links a{border-bottom:0;color:var(--color-on-black-dim)}
.foot-links a:hover,.foot-links a:focus-visible{color:var(--color-on-black)}

@media(prefers-reduced-motion:reduce){
  .cap,.soc,.foot li a,.foot-close .foot-mailto span::after{transition:none}
}

/* ══ THE MOTION CONTROL ═══════════════════════════════════════════════════
   It floats over whatever section happens to be beneath it, and deriving its
   colours from a ground probe meant one stale read made it illegible. It is
   now a single translucent dark material with vibrant type, which reads on
   the white grounds and on the black ones without needing to know which it
   is standing on — one less state that can be got wrong. */
.motion-toggle{
  background:rgba(18,18,20,.72);
  backdrop-filter:blur(18px) saturate(180%);
  -webkit-backdrop-filter:blur(18px) saturate(180%);
  color:#f2f1ee;border:0;border-radius:var(--r-capsule);
  padding:.5rem .9rem;font-family:var(--f-mono);font-size:.625rem;
  letter-spacing:.13em;text-transform:uppercase;
  transition:background var(--d-state) var(--e-std),transform var(--d-press) var(--e-out)}
.motion-toggle:hover,.motion-toggle:focus-visible{background:rgba(18,18,20,.88)}
.motion-toggle:active{transform:scale(.96)}
html[data-ground-bottom="dark"] .motion-toggle,
html[data-ground="dark"] .motion-toggle{
  background:rgba(18,18,20,.72);color:#f2f1ee;border:0}
@media(prefers-reduced-transparency:reduce){
  .motion-toggle{background:#121214;backdrop-filter:none}
}

/* the work page's act list sits on unprotected film; its numerals take the
   brighter on-media red so they clear AA against a mid-grey frame */
#film .wk-acts .n,#photography .wk-acts .n{color:#ff9a9c}

/* ══ TWO DEFECTS THE DE-BOXING INTRODUCED ════════════════════════════════
   Removing a control's box also removed the things the box was carrying. */

/* 1 · TOUCH TARGET. The menu button lost its 44px height along with its
   border. The box is gone; the target is not — it is padding now, which is
   invisible and still 44px under a finger. */
.menu-btn.btn,.nav-cta.btn,.hero-cue,.ph2-foot a,.foot-close .foot-mailto{
  min-height:44px;display:inline-flex;align-items:center}
.menu-btn.btn{padding-inline:.25rem;margin-right:-.25rem}

/* 2 · HOVER ON A DARK GROUND. The text link's hover used to invert against a
   sweeping fill; the fill is gone, so inverting the type just painted black
   on black. On a dark ground the link brightens instead. */
.band-black .btn:not(.btn-solid):hover,.band-black .btn:not(.btn-solid):focus-visible,
.red-band .btn:not(.btn-solid):hover,.red-band .btn:not(.btn-solid):focus-visible,
.field-signal .btn:not(.btn-solid):hover,.field-signal .btn:not(.btn-solid):focus-visible,
.masthead .btn:not(.btn-solid):hover,.masthead .btn:not(.btn-solid):focus-visible,
.foot .btn:not(.btn-solid):hover,.foot .btn:not(.btn-solid):focus-visible,
#cinema .btn:not(.btn-solid):hover,#cinema .btn:not(.btn-solid):focus-visible,
html[data-ground="dark"] .nav .btn:not(.btn-solid):hover,
html[data-ground="dark"] .nav .btn:not(.btn-solid):focus-visible{
  color:#ffffff;border-color:transparent}
.btn:not(.btn-solid):hover,.btn:not(.btn-solid):focus-visible{
  color:var(--fg);border-color:transparent}

/* ══════════════════════════════════════════════════════════════════════════
   V4 · THE MEDIA CHAPTER
   The audit measured every viewport of every route. Services carried ZERO
   images across 12 viewports; Engagements ZERO across 11; Studio showed its
   five people at 132px. A film and photography studio was explaining itself
   entirely in prose. That is not a spacing problem — those pages had no proof
   in them, and no amount of typographic care fixes an argument with no
   evidence.

   Three components, so the pages gain evidence without gaining a new
   vocabulary:

     .mch-bleed   one frame edge to edge, ON BLACK — the payoff at the end of
                  an argument, and the structural black these routes lacked
     .mch-split   a statement beside a frame, sides alternating down the page
     .mch-sheet   a contact sheet: three frames at deliberately different
                  heights, which is how a body of work is actually shown

   Each is a full-width band that declares its ground through --pg-bg, the
   architecture's own mechanism, so it sits inside the `.pg section` --sec
   rhythm instead of fighting it. Each carries a museum label rather than a
   caption box, and each reveals with the same mask-and-settle as the homepage
   gallery, so the whole site moves the same way.
   ══════════════════════════════════════════════════════════════════════════ */

.mch{--pg-bg:var(--color-bg-primary);--pg-fg:var(--color-text-primary);
  position:relative;overflow:clip}
.mch figure{margin:0}
.mch-in{max-width:1500px;margin-inline:auto;padding-inline:var(--gut);width:100%}

/* the frame */
.mch-win{display:block;position:relative;overflow:hidden;
  background:var(--color-media-backing);border-radius:var(--r-media)}
.mch-win img,.mch-win video{position:absolute;inset:-5% 0;width:100%;height:110%;
  object-fit:cover;display:block;translate:0 var(--pxy,0px);scale:1;
  will-change:translate,scale}

/* the museum label */
.mch-cap{display:flex;flex-direction:column;gap:.28rem;margin:var(--s-4) 0 0}
.mch-cap .n{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);color:var(--signal-text);
  font-variant-numeric:tabular-nums}
.mch-cap b{font-weight:500;font-size:var(--t-small-size);letter-spacing:-.004em;
  color:var(--pg-fg,var(--fg))}
.mch-cap span:last-child{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.11em;text-transform:uppercase;color:var(--dim)}

/* ── the dark variant: the photograph becomes the brightest thing on screen ──
   These three routes carried almost no black, which is where the 60/30/10
   balance was slipping outside the homepage. A frame hung on black is also
   simply how a print is shown. */
.mch-dark{--pg-bg:var(--color-black);--pg-fg:var(--color-on-black);
  --muted:var(--color-on-black-muted);--dim:var(--color-on-black-dim);
  --line:var(--color-hairline-on-black);--hair:var(--color-hairline-on-black);
  --edge:var(--color-border-on-black);
  --color-media-backing:var(--color-black-2);
  --signal-text:var(--signal-text-media)}

/* ── BLEED · one frame, edge to edge ── */
.mch-bleed .mch-win{width:100%;height:min(76svh,760px);border-radius:0}
.mch-bleed .mch-cap{max-width:1500px;margin-inline:auto;padding-inline:var(--gut)}

/* ── SPLIT · a statement beside a frame ── */
.mch-split .mch-in{display:grid;gap:clamp(1.8rem,4vw,3.5rem);align-items:center}
@media(min-width:900px){
  .mch-split .mch-in{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}
  /* the frame keeps its 7fr when it moves to the left: `order` alone would
     hand it the narrow column and the two splits would read as two sizes */
  .mch-split.rev .mch-in{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
  .mch-split.rev .mch-in>figure{order:-1}
}
.mch-split .mch-win{aspect-ratio:4/3}
.mch-split-say h3{font-size:var(--t-title-size);line-height:var(--t-title-lh);
  letter-spacing:var(--t-title-ls);font-weight:var(--t-title-w);
  margin:var(--s-5) 0 0;max-width:16ch;text-wrap:balance}
.mch-split-say p{margin:var(--s-5) 0 0;max-width:42ch;color:var(--muted);
  font-size:var(--t-small-size);line-height:var(--t-small-lh)}

/* ── SHEET · a contact sheet at three deliberate heights ── */
.mch-sheet .mch-strip{display:grid;gap:clamp(.8rem,1.8vw,1.6rem);align-items:end;
  grid-template-columns:repeat(12,1fr)}
.mch-sheet .s-a{grid-column:1 / 5}
.mch-sheet .s-b{grid-column:5 / 10}
.mch-sheet .s-c{grid-column:10 / 13}
.mch-sheet .s-a .mch-win{aspect-ratio:3/4}
.mch-sheet .s-b .mch-win{aspect-ratio:16/9}
.mch-sheet .s-c .mch-win{aspect-ratio:1/1}
.mch-sheet .mch-cap{margin-top:var(--s-5)}
@media(max-width:820px){
  .mch-sheet .mch-strip{grid-template-columns:repeat(6,1fr);gap:1rem}
  .mch-sheet .s-a{grid-column:1 / 4}
  .mch-sheet .s-b{grid-column:1 / 7;order:-1}
  .mch-sheet .s-c{grid-column:4 / 7}
  .mch-sheet .s-b .mch-win{aspect-ratio:16/10}
}

/* ── the reveal: uncovered, then settled — the gallery's motion, reused ── */
html[data-mode="cinematic"] .mch[data-chapter] .mch-win{
  clip-path:inset(0 0 0 0);transition:clip-path 1s var(--e-out)}
html[data-mode="cinematic"] .mch[data-chapter]:not(.on) .mch-win{clip-path:inset(0 0 100% 0)}
html[data-mode="cinematic"] .mch[data-chapter] .mch-win img,
html[data-mode="cinematic"] .mch[data-chapter] .mch-win video{transition:scale 1.4s var(--e-out)}
html[data-mode="cinematic"] .mch[data-chapter]:not(.on) .mch-win img,
html[data-mode="cinematic"] .mch[data-chapter]:not(.on) .mch-win video{scale:1.055}
html[data-mode="cinematic"] .mch[data-chapter] .mch-cap,
html[data-mode="cinematic"] .mch[data-chapter] .mch-split-say{
  transition:opacity .8s var(--e-std) .18s,translate .8s var(--e-out) .18s}
html[data-mode="cinematic"] .mch[data-chapter]:not(.on) .mch-cap,
html[data-mode="cinematic"] .mch[data-chapter]:not(.on) .mch-split-say{opacity:0;translate:0 10px}
/* the sheet's frames arrive in reading order, a beat apart */
html[data-mode="cinematic"] .mch-sheet .s-b .mch-win{transition-delay:.09s}
html[data-mode="cinematic"] .mch-sheet .s-c .mch-win{transition-delay:.18s}
@media(prefers-reduced-motion:reduce){
  .mch[data-chapter] .mch-win{clip-path:none!important;transition:none!important}
  .mch[data-chapter] .mch-win img,.mch[data-chapter] .mch-win video{
    scale:1!important;translate:none!important;transition:none!important}
  .mch[data-chapter] .mch-cap,.mch[data-chapter] .mch-split-say{
    opacity:1!important;translate:none!important;transition:none!important}
}

/* ══ THE TEAM, AT A SIZE YOU CAN SEE A PERSON IN ═══════════════════════════
   Five named people were being shown at 132px in a row of table cells, which
   is a directory, not a portrait. They are the entire argument the Studio
   page makes — "named, so you know who you are dealing with" — so they get
   the page. */
.team{margin-top:clamp(2.6rem,6vw,4.5rem);border-top:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1.8rem,3.4vw,3rem) clamp(1.2rem,2.6vw,2.4rem)}
@media(min-width:760px){.team{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:1120px){.team{grid-template-columns:repeat(5,minmax(0,1fr))}}
.team-member{display:flex;flex-direction:column;align-items:stretch;
  grid-template-columns:none;gap:0;padding:0;border-bottom:0}
.team-portrait{order:-1;grid-row:auto;width:100%;margin:0 0 var(--s-5);
  border-radius:var(--r-media);overflow:hidden;background:var(--color-media-backing)}
.team-portrait img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  border-radius:0;box-shadow:none;background:none;
  transition:scale 900ms var(--e-out)}
.team-member:hover .team-portrait img{scale:1.035}
.team-member .idx{grid-row:auto;align-self:start;display:block;margin-bottom:.35rem;
  font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);color:var(--signal-text)}
.team-member h3{font-size:var(--t-head-size);line-height:1.2;
  letter-spacing:var(--t-head-ls);font-weight:600;text-wrap:balance}
.team-member .role{margin:.35rem 0 0;font-family:var(--f-mono);
  font-size:var(--t-label-size);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim)}
html[data-mode="cinematic"] .team-member{opacity:0;translate:0 14px;
  transition:opacity .7s var(--e-std),translate .7s var(--e-out)}
html[data-mode="cinematic"] .team.on .team-member{opacity:1;translate:none}
html[data-mode="cinematic"] .team.on .team-member:nth-child(2){transition-delay:70ms}
html[data-mode="cinematic"] .team.on .team-member:nth-child(3){transition-delay:140ms}
html[data-mode="cinematic"] .team.on .team-member:nth-child(4){transition-delay:210ms}
html[data-mode="cinematic"] .team.on .team-member:nth-child(5){transition-delay:280ms}
@media(prefers-reduced-motion:reduce){
  .team-member{opacity:1!important;translate:none!important;transition:none!important}
  .team-portrait img{transition:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   V4 · THE SPECIFICATION SHEET  (services #technology)
   Three clusters were three identical `grid g-2` rows: an identity on the
   left that ran out after two lines and left ~500px of nothing beneath it,
   and a right column carrying seven hairline rows of almost exactly equal
   length. Three copies of one shape, and the shape had a hole in it.

   The identity column now carries the argument as well as the name, so it
   has a reason to be as tall as the list beside it, and the list runs two-up
   where there is room — seven equal bars become a ruled table, which is what
   a spec sheet actually looks like.
   ══════════════════════════════════════════════════════════════════════════ */
.tspec-sheet{margin-top:clamp(2.5rem,5vw,4.5rem);border-top:1px solid var(--line)}
.tspec{display:grid;gap:clamp(1.4rem,3vw,3rem);
  padding-block:clamp(2rem,4vw,3.4rem);border-bottom:1px solid var(--line)}
@media(min-width:960px){
  .tspec{grid-template-columns:minmax(0,23rem) minmax(0,1fr);
    gap:clamp(2rem,5vw,5rem)}
}
.tspec-id .label{display:flex;align-items:baseline;gap:.7em}
.tspec-id .label strong{color:var(--fg);font-weight:600}
.tspec-id h3{margin:var(--s-4) 0 0;max-width:14ch;
  font-size:var(--t-head-size);line-height:var(--t-head-lh);
  letter-spacing:var(--t-head-ls);font-weight:var(--t-head-w);text-wrap:balance}
.tspec-say{margin:var(--s-6) 0 0;max-width:38ch;color:var(--muted);
  font-size:var(--t-small-size);line-height:var(--t-small-lh)}

.tspec-list{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:minmax(0,1fr);
  column-gap:clamp(1.5rem,3vw,3rem)}
@media(min-width:1180px){.tspec-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
.tspec-list li{border-top:1px solid var(--hair);padding:.62rem 0;
  font-size:.92rem;line-height:1.45;color:var(--muted)}
/* the first row of each column starts the table, so it keeps its rule; on one
   column the very first item would otherwise double the sheet's own top edge */
@media(min-width:1180px){.tspec-list li:nth-child(-n+2){border-top-color:var(--line)}}

/* ══ THE PRODUCT ITSELF ═══════════════════════════════════════════════════
   The one route that has to prove engineering was carrying no engineering to
   look at. Two full-page captures of the live client platform, each in a
   window the page scrolls through — a still crop of a homepage proves a
   homepage; a whole page proves a build. */
.scr-grid{display:grid;gap:clamp(1.2rem,3vw,2.4rem);margin-top:var(--s-6);
  grid-template-columns:minmax(0,1fr)}
@media(min-width:820px){
  .scr-grid{grid-template-columns:minmax(0,7fr) minmax(0,4fr);align-items:start}
}
.scr-grid figure{margin:0}
.scr-win{height:min(64svh,620px)}
.scr-win img{position:absolute;inset:auto 0 auto 0;top:0;width:100%;height:auto;
  translate:0 var(--pxy,0px);will-change:translate}
.scr-m .scr-win{width:min(100%,300px);margin-inline:auto}
.scr-m .mch-cap{width:min(100%,300px);margin-inline:auto}
.scr-note{margin:var(--s-6) 0 0;font-family:var(--f-mono);
  font-size:var(--t-label-size);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim)}
.scr-note a{color:var(--fg);position:relative;white-space:nowrap}
.scr-note a::after{content:"";position:absolute;left:0;right:0;bottom:-.3em;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.scr-note a:hover::after,.scr-note a:focus-visible::after{transform:scaleX(1)}
.scr-note i{font-style:normal;color:var(--signal-text)}
@media(prefers-reduced-motion:reduce){
  .scr-win img{translate:none!important;transition:none!important}
  .scr-note a::after{transition:none}
}

/* ══ THE DISCLOSURE ROW CARRIES ITS CONDITION ═════════════════════════════
   `Retainer` sat at the left of a 1,240px row with a red plus sign at the
   far edge and nothing at all between them. The row now states the condition
   the way of working applies to, which is the thing a reader is scanning for
   anyway — and the plus stops being a target at the end of a void. */
@media(min-width:760px){
  .pillar-head{grid-template-columns:3.2rem minmax(0,19rem) minmax(0,1fr) 1.6rem;
    align-items:baseline}
}
/* set against the plus, not adrift in the middle: two things aligned to the
   right edge read as a table row; one thing floating reads as a gap */
.pillar-when{margin:0;font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.11em;text-transform:uppercase;color:var(--dim);
  justify-self:end;text-align:right;text-wrap:balance}
@media(max-width:759px){.pillar-when{display:none}}
.pillar-head:hover .pillar-when{color:var(--muted)}

/* ══ THE CONSTRUCTION DRAWING ═════════════════════════════════════════════
   A technical drawing does not need to be put in a frame with a gradient in
   it; the drawing is the object. V3 removed these boxes everywhere else. */
.cx-fig{margin:0;border:0;padding:0;background:none}

/* ══ V4 · THE HOMEPAGE CLOSE ══════════════════════════════════════════════
   Three mono lines stacked centre at three different widths, one of them a
   review note wrapping mid-sentence. One line of information, one footnote
   under the controls it belongs to. */
.cv-note{margin-top:.9rem;color:var(--dim);max-width:58ch;line-height:1.5;
  font-size:.6rem;letter-spacing:.1em}
.cv-lines{margin-top:1.9rem;color:var(--muted);letter-spacing:.16em;
  display:flex;align-items:baseline;justify-content:center;gap:.9em;flex-wrap:wrap}
.cv-lines i{font-style:normal;color:var(--dim)}
.cv-lines a,.cv-lines .cv-mail{color:var(--fg);text-decoration:underline;
  text-underline-offset:4px;letter-spacing:.08em;margin:0}
/* the second action was a bare text link beside a filled capsule and read as
   a caption; it is a control, so it looks like one */
.cv-actions .btn:not(.btn-solid){padding-inline:.2rem}

/* ══ V4 · THE WORK INDEX SHOWS THE WORK ═══════════════════════════
   The index carried a poster per row, revealed on hover, on a pointer device.
   At rest it was five lines of type across 1,376px with a ~700px gap in the
   middle of every one — and on a phone the poster was gone entirely. An index
   of films that shows no film is the same failure as a film studio page with
   no photographs in it.

   The poster is now part of the row, quiet, at a size that reads as a frame
   rather than an icon, and hover brings it forward instead of conjuring it. */
.wk-ix li{display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:center;gap:clamp(1rem,2.6vw,2.4rem)}
.wk-ix li>a{grid-column:1}
/* one height for every poster, so the right-hand column has a rhythm; the
   portrait pieces are simply narrower, which is what they are */
.ix-thumb{position:static;grid-column:2;justify-self:end;
  height:clamp(62px,6.6vw,92px);width:auto;
  aspect-ratio:16/9;object-fit:cover;border-radius:var(--r-chip);
  background:var(--color-media-backing);
  opacity:.9;transform:none;box-shadow:none;
  transition:opacity var(--d-state) var(--e-std),scale var(--d-move) var(--e-out)}
.ix-thumb.tall{aspect-ratio:4/5}
@media(hover:hover) and (pointer:fine){
  .wk-ix li:hover .ix-thumb,.wk-ix li:focus-within .ix-thumb{
    opacity:1;transform:none;scale:1.035}
}
@media(max-width:700px){
  .wk-ix li{gap:1rem}
  .ix-thumb{display:block;height:56px}
}
@media(prefers-reduced-motion:reduce){.ix-thumb{transition:none}}

/* the lede was sitting on the headline’s descenders */
.wk-index-h+.factline:not(#commercial *){margin-top:var(--s-6);max-width:52ch}

/* ══ V4 · CHROME OVER MEDIA ══════════════════════════════════════
   Over a dark ground the navigation turns white and sits on the bare frame.
   The hero is a film: one bright frame and white 16px type has nothing to
   stand on. A soft scrim gives the chrome a ground it carries with it, and
   it is invisible over the black sections where the ground is already dark.
   It retires the moment the bar takes its own material on scroll. */
.nav::after{content:"";position:absolute;inset:0 0 auto 0;height:calc(100% + 3.4rem);
  pointer-events:none;z-index:-1;opacity:0;
  background:linear-gradient(180deg,rgba(6,6,8,.46) 0%,rgba(6,6,8,.28) 46%,rgba(6,6,8,0) 100%);
  transition:opacity 420ms var(--e-std)}
html[data-ground="dark"] .nav:not(.scrolled)::after{opacity:1}
@media(prefers-reduced-transparency:reduce){
  html[data-ground="dark"] .nav:not(.scrolled)::after{
    background:linear-gradient(180deg,rgba(6,6,8,.72) 0%,rgba(6,6,8,.5) 60%,rgba(6,6,8,0) 100%)}
}
@media(prefers-reduced-motion:reduce){.nav::after{transition:none}}

/* ══ V4 · POINTER TARGETS ════════════════════════════════════════
   WCAG 2.2 AA (2.5.8) asks for 24 x 24 CSS pixels on anything that is not a
   word inside a sentence. The sweep across six viewports found three families
   short: the de-boxed category links at 23px, the footer links at 18px, and
   the motion control at 29px. Vertical padding grows the hit area without
   moving a single glyph. */
a.cap{padding-block:.24em .42em;min-height:24px;box-sizing:content-box}
.foot li a,.foot-links a{display:inline-block;padding-block:.22rem;min-height:20px}
.motion-toggle{padding-block:.72rem;min-height:44px;display:inline-flex;
  align-items:center}

/* ══ V4 · THE NAVIGATION ON A PHONE ═══════════════════════════════════════
   At 390px the bar carried the wordmark, a "Start a project" plate and the
   menu button in the same row. Both the wordmark and the plate wrapped to two
   lines, and an 87px bar of ragged two-line type is the first thing a phone
   visitor sees. Zero overflow, and still wrong.

   Below 560px the bar is the mark and the menu, which is what a phone bar is.
   Nothing is lost: "Start a project" is the last and largest entry in the menu
   itself, alongside the address. */
.nav-mark{white-space:nowrap}
@media(max-width:560px){
  .nav .nav-cta{display:none}
  .nav{gap:1rem}
}

/* ══ V4 · THE CLOSING BLOCK SITS ON THE GRID ══════════════════════════════
   `.wrap-narrow` was a 940px box centred in the viewport, so at 1440 its
   content began at x=313 while every other section on the site began at x=63.
   Five closing statements — the last thing a visitor reads on Services,
   Engagements and the case study — sat off the page's own grid, floating
   left-of-centre in a field of white.

   The measure was the right idea; centring the box was not. The outer box is
   now the page box, and the measure is held on the content instead. */
.wrap-narrow{max-width:1500px;margin-inline:auto;padding-inline:var(--gut);width:100%}
.wrap-narrow>*{max-width:min(100%,58rem)}

/* it is the close of the page, so it is drawn as one: a rule above it, and a
   statement at display size rather than at heading size */
.wrap-narrow>h2:first-child{
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  max-width:16ch;text-wrap:balance}
section:has(>.wrap-narrow>h2:first-child){position:relative}
section:has(>.wrap-narrow>h2:first-child)::after{content:"";position:absolute;
  top:0;left:var(--gut);width:clamp(120px,26vw,384px);height:2px;
  background:var(--signal);pointer-events:none}

/* ══════════════════════════════════════════════════════════════════════════
   V5 · THE BAR
   Two problems, one bar. A desktop header carrying the whole navigation AND
   a "Menu" control beside it is offering the same thing twice — the word was
   doing nothing but adding a fifth thing to read. And with the primary action
   set in the same weight, the same colour and the same size as four
   navigation links, the one item that is a business decision disappeared into
   the list.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the menu is a phone control, so it lives on phones ── */
@media(min-width:900px){
  .nav .menu-btn{display:none}
}

/* ── the action ──────────────────────────────────────────────────────────
   ONE treatment, four parts of a single idea: this item is live, it is
   red, and it goes somewhere.

     · full-strength ink where the links sit at .82, and one weight heavier
     · a red arrow, the only red in the bar
     · on hover the arrow travels up and out along its own diagonal
     · a red hairline wipes in beneath the words, left to right

   No plate, no capsule, no fill. The distinction is weight, colour and
   motion — the three things that read instantly at 15px and never look like
   a button bolted onto a header. */
.nav .nav-cta{
  margin-left:clamp(1.4rem,3.4vw,3rem);
  font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;line-height:1;opacity:1;
  display:inline-flex;align-items:center;gap:.42em;
  border:0;background:none;padding-block:.62rem;min-height:44px;
  position:relative}
.nav .nav-cta>span{position:relative;padding:0;display:inline-block}
.nav .nav-cta>span::after{content:"";position:absolute;left:0;right:0;bottom:-.34em;
  height:1.5px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.nav .nav-cta:hover>span::after,
.nav .nav-cta:focus-visible>span::after{transform:scaleX(1)}
.nav .nav-cta .tick{font-style:normal;color:var(--signal-text);
  font-size:.92em;line-height:1;display:inline-block;
  transition:translate var(--d-move) var(--e-out)}
.nav .nav-cta:hover .tick,
.nav .nav-cta:focus-visible .tick{translate:.16em -.16em}
.nav .nav-cta::before{display:none}          /* the old sweep fill */
.nav .nav-cta:active{opacity:.7}
html[data-ground="dark"] .nav .nav-cta{color:var(--color-on-black);border:0}
html[data-ground="dark"] .nav .nav-cta .tick{color:var(--signal-text-media)}
html[data-ground="dark"] .nav .nav-cta:hover,
html[data-ground="dark"] .nav .nav-cta:focus-visible{
  background:none;color:var(--color-on-black)}

/* the four navigation links stay quiet, and the gap before the action is the
   silence that separates a list from a decision */
/* mark left, navigation centred in what is left, action at the right edge */
.nav-links{gap:clamp(1.2rem,2.4vw,1.9rem);margin-inline:auto}
.nav-links a{opacity:.72}
.nav-links a:hover,.nav-links a:focus-visible,
.nav-links a[aria-current="page"]{opacity:1}

@media(prefers-reduced-motion:reduce){
  .nav .nav-cta>span::after,.nav .nav-cta .tick{transition:none}
}

/* ══ V5 · THE SCROLL INDICATOR ═════════════════════════════════════════════
   "See the work ↓" was a second call to action competing with the one in the
   bar, and it read as a button the visitor had to press. What the bottom of
   an opening frame actually needs to say is only: the page continues.

   A mouse outline, centred on the closing baseline of the hero between the
   statement and the film's slate. The wheel falls once and fades; the body
   settles three pixels and tilts just over a degree. Slow enough (2.2s and
   3.6s, offset) that it never reads as an animation asking for attention —
   it is meant to be noticed peripherally and then obeyed.

   It is a real button: click or Enter scrolls to the next chapter. Under
   reduced motion the movement stops and the indicator stays, still legible
   and still operable. */
.hero-cue{position:absolute;left:50%;translate:-50% 0;
  bottom:calc(var(--safe-bottom,1.4rem) + clamp(.6rem,2svh,1.4rem));
  z-index:8;display:grid;place-items:center;gap:0;margin:0;
  width:56px;height:56px;padding:0;background:none;border:0;cursor:pointer;
  color:var(--color-on-black);opacity:var(--meta,0);
  transition:opacity 700ms var(--e-std) 200ms,translate var(--d-state) var(--e-out)}
.hero-cue:hover{translate:-50% 2px}
.hero-cue:active{translate:-50% 3px;opacity:.72}
.hero-cue svg{width:23px;height:37px;display:block;overflow:visible;
  filter:drop-shadow(0 1px 7px rgba(0,0,0,.6))}
.cue-body{fill:none;stroke:currentColor;stroke-width:1.3;opacity:.88;
  transition:opacity var(--d-state) var(--e-std)}
.cue-wheel{fill:currentColor;opacity:.9}
.hero-cue:hover .cue-body,.hero-cue:focus-visible .cue-body{opacity:1}
.hero-cue:focus-visible{outline:2px solid var(--signal);outline-offset:6px;border-radius:6px}

html[data-mode="cinematic"] .cue-mouse{
  animation:cue-settle 3.6s var(--e-io) infinite;transform-origin:50% 20%}
html[data-mode="cinematic"] .cue-wheel{
  animation:cue-fall 2.2s var(--e-io) infinite}
@keyframes cue-settle{
  0%,100%{transform:translateY(0) rotate(0deg)}
  50%{transform:translateY(3px) rotate(1.1deg)}
}
@keyframes cue-fall{
  0%{transform:translateY(0);opacity:0}
  16%{opacity:.95}
  58%{opacity:.95}
  100%{transform:translateY(7px);opacity:0}
}
@media(prefers-reduced-motion:reduce){
  .cue-mouse,.cue-wheel{animation:none!important;transform:none!important;opacity:.9}
  .hero-cue{transition:none}
}
/* the editorial edition has no pinned hero to scroll through, so the prompt
   would be pointing at nothing */
html[data-mode="editorial"] .hero-cue{display:none}
@media(max-width:900px){
  .hero-cue{width:48px;height:48px}
  .hero-cue svg{width:20px;height:32px}
}
/* short landscape phones: the slate and the statement already own the bottom */
@media(max-height:560px){.hero-cue{display:none}}

/* ══════════════════════════════════════════════════════════════════════════
   V5 · THE STUDIO — THE ROSTER
   The section was five headshots in a staggered row with the names set small
   underneath: a "meet the team" strip, and the five portraits were shot on
   five different days against five different backgrounds, so side by side
   they read as five unrelated photographs rather than one studio.

   Shown ONE AT A TIME that stops being a problem — each portrait is simply
   the person you are pointing at — and the names can take the scale they
   deserve. The unit is a credit line at display size, and the photograph is
   the response to reading it.

   The portrait travels. All five are in the frame at once, absolutely
   positioned at the same point and stacked, so moving quickly between names
   cross-fades rather than loading; the whole stack rides one translate that
   follows the active row, which reads as one photograph gliding down the
   list. Nothing is hidden behind hover: at rest the first credit is already
   showing, so the mechanic explains itself without an instruction.
   ══════════════════════════════════════════════════════════════════════════ */

.roster{background:var(--color-bg-primary);color:var(--color-text-primary);
  position:relative;overflow:clip;padding-block:calc(var(--chapter) * 1.05)}
.roster-in{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);width:100%}

/* ── the head ── */
.ro-head{display:grid;gap:var(--s-6);align-items:end}
@media(min-width:900px){
  .ro-head{grid-template-columns:minmax(0,1fr) minmax(0,26rem);
    gap:clamp(2rem,5vw,5rem)}
}
.ro-h{margin:var(--s-6) 0 0;max-width:14ch;
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  text-wrap:balance}
.ro-h i{font-style:normal;color:var(--color-text-muted)}
.ro-note{margin:0;max-width:34ch;color:var(--color-text-secondary);
  font-size:var(--t-small-size);line-height:var(--t-small-lh)}

/* ── the list ── */
.ro-list{list-style:none;margin:clamp(2.6rem,6vw,4.5rem) 0 0;padding:0;
  position:relative;border-top:1px solid var(--color-hairline)}
/* the row must NOT establish a containing block: the five frames are
   positioned against the LIST so they all land on the same point and the
   single translate moves the whole stack. Relative rows made each frame
   land at its own row and the travel compounded down the page. */
.ro-row{border-bottom:1px solid var(--color-hairline)}
.ro-hit{display:grid;width:100%;align-items:center;text-align:left;
  grid-template-columns:3.4rem minmax(0,1fr) auto;gap:.2rem var(--s-6);
  padding:clamp(1.1rem,2.6vw,1.9rem) 0;
  background:none;border:0;cursor:pointer;color:inherit;
  transition:translate var(--d-move) var(--e-out)}
.ro-n{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:var(--t-label-ls);color:var(--signal-text);
  font-variant-numeric:tabular-nums;align-self:center}
.ro-name{font-family:var(--f-display);font-weight:600;
  font-size:clamp(1.55rem,4.2vw,3.2rem);line-height:1.04;letter-spacing:-.032em;
  color:var(--color-text-primary);
  transition:color var(--d-state) var(--e-std)}
.ro-role{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.11em;text-transform:uppercase;color:var(--color-text-muted);
  justify-self:end;text-align:right;white-space:nowrap;align-self:center;
  transition:color var(--d-state) var(--e-std)}

/* while a pointer or focus is actually in the list, the one being read comes
   forward and the rest step back. At rest nothing is dimmed — a list that is
   permanently half-faded reads as broken, not as focused. */
.ro-list.live .ro-row:not(.on) .ro-name{color:var(--color-text-muted);opacity:.55}
.ro-list.live .ro-row:not(.on) .ro-role{opacity:.45}
.ro-row.on .ro-hit{translate:10px 0}
.ro-list.live .ro-row.on .ro-name{color:var(--color-brand-text)}
.ro-list.live .ro-row.on .ro-role{color:var(--color-text-secondary)}
.ro-hit:focus-visible{outline:2px solid var(--signal);outline-offset:4px}

/* ── the photograph ── */
.ro-shot{position:absolute;top:0;left:56%;margin:0;z-index:3;
  width:clamp(190px,18vw,272px);
  translate:0 calc(var(--ro-y,0px) - 50%);
  opacity:0;scale:.965;pointer-events:none;
  transition:opacity 300ms var(--e-std),scale 620ms var(--e-out),
             translate 620ms var(--e-out)}
.ro-row.on .ro-shot{opacity:1;scale:1}
.ro-shot img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  object-position:50% 22%;display:block;border-radius:var(--r-media);
  background:var(--color-media-backing);
  box-shadow:0 26px 60px -18px rgba(28,25,20,.34),0 2px 10px rgba(28,25,20,.10)}

/* ── the close ── */
.ro-foot{margin:clamp(2.2rem,5vw,3.4rem) 0 0;display:flex;flex-wrap:wrap;
  align-items:baseline;gap:var(--s-3) var(--s-6);
  font-family:var(--f-mono);font-size:var(--t-label-size);letter-spacing:.11em;
  text-transform:uppercase;color:var(--color-text-muted)}
.ro-foot a{color:var(--color-text-primary);position:relative;white-space:nowrap;
  padding-block:.24rem;display:inline-block}
.ro-foot a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.ro-foot a:hover::after,.ro-foot a:focus-visible::after{transform:scaleX(1)}
.ro-foot i{font-style:normal;color:var(--signal-text)}

/* ── the chapter arrives ── */
html[data-mode="cinematic"] .roster[data-chapter] .ro-row{
  opacity:0;translate:0 16px;
  transition:opacity .68s var(--e-std),translate .68s var(--e-out)}
html[data-mode="cinematic"] .roster[data-chapter].on .ro-row{opacity:1;translate:none}
html[data-mode="cinematic"] .roster[data-chapter].on .ro-row:nth-child(2){transition-delay:70ms}
html[data-mode="cinematic"] .roster[data-chapter].on .ro-row:nth-child(3){transition-delay:140ms}
html[data-mode="cinematic"] .roster[data-chapter].on .ro-row:nth-child(4){transition-delay:210ms}
html[data-mode="cinematic"] .roster[data-chapter].on .ro-row:nth-child(5){transition-delay:280ms}
html[data-mode="cinematic"] .roster[data-chapter]:not(.on) .ro-shot{opacity:0!important}

/* ── phones and tablets: there is no hover, so the photograph opens ──
   The frame stops floating and becomes part of the row it belongs to: tapping
   a name opens it underneath, tapping another closes the first. The
   storytelling survives the loss of the pointer instead of the pictures
   simply being dropped. */
@media(max-width:899px){
  .ro-hit{grid-template-columns:2.6rem minmax(0,1fr);
    padding:clamp(1rem,3.4vw,1.5rem) 0}
  .ro-role{grid-column:2;justify-self:start;text-align:left;margin-top:.42rem;
    white-space:normal}
  .ro-name{font-size:clamp(1.5rem,7vw,2.3rem)}
  .ro-row.on .ro-hit{translate:none}
  .ro-shot{position:static;left:auto;width:min(74%,300px);
    translate:none!important;scale:1;opacity:1;
    display:grid;grid-template-rows:0fr;
    margin:0 0 0 2.6rem;
    transition:grid-template-rows 520ms var(--e-out),opacity 300ms var(--e-std),
               margin-bottom 520ms var(--e-out)}
  .ro-shot>img{min-height:0}
  .ro-shot img{overflow:hidden}
  .ro-row.on .ro-shot{grid-template-rows:1fr;margin-bottom:clamp(1rem,3vw,1.6rem)}
  .ro-shot img{box-shadow:0 14px 34px -12px rgba(28,25,20,.28)}
}

@media(prefers-reduced-motion:reduce){
  .ro-shot,.ro-hit,.ro-name,.ro-role,.roster[data-chapter] .ro-row{
    transition:none!important}
  html[data-mode="cinematic"] .roster[data-chapter] .ro-row{opacity:1;translate:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   V5 · TECHNOLOGY BECOMES THE DARK CHAPTER
   The thesis is a white page and Technology opened onto another one, so the
   page turned from "who we are" to "what we build" without changing rooms.
   Worse, the thing on display is a capture of a bright website, and a bright
   website on a pale blue ground has nothing to be brighter than.

   The chapter goes to the same black every other dark region on this site
   uses — one black, not a new one. The capture then becomes the only lit
   object in the frame: the drafting chrome around it darkens, a cold wash
   sits behind it as though the screen were lighting the room, and the surface
   picks up a real shadow and a bright top edge. Nothing is added to the
   composition; the light is simply moved onto the product.

   The sequence it creates:  thesis (light, the claim) → TECHNOLOGY (dark,
   the machine) → the studio (light, the people) → photography (dark, the
   gallery).
   ══════════════════════════════════════════════════════════════════════════ */

#tech .stage{
  --tech-ground:var(--color-black);
  --fg:var(--color-on-black);--muted:var(--color-on-black-muted);
  --dim:var(--color-on-black-dim);--hair:var(--color-hairline-on-black);
  --line:var(--color-hairline-on-black);--edge:var(--color-border-on-black);
  --void:var(--color-black);--plane:var(--color-black-2);
  --signal-text:var(--signal-text-media);
  color:var(--color-on-black)}

/* the drafting grid, inverted: present, never noisy */
#tech .stage::before{
  background:
    repeating-linear-gradient(to right,rgba(255,255,255,.055) 0 1px,transparent 1px 64px),
    repeating-linear-gradient(to bottom,rgba(255,255,255,.055) 0 1px,transparent 1px 64px)}

/* the screen lights the room. One soft cold wash behind the surface, no
   panel, no card, no glass — the only way you know it is there is that the
   black is not flat any more. */
#tech .stage::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(90% 62% at 72% 46%,
    rgba(126,166,232,.16) 0%,rgba(70,104,166,.07) 38%,rgba(0,0,0,0) 72%);
  opacity:var(--grid-o,0);transition:opacity 420ms linear}

#tech .tech-hud{border-bottom-color:var(--color-hairline-on-black)}
#tech .tech-hud .label{color:var(--color-on-black-muted)}
#tech .tech-hud .label-sig{color:var(--color-on-black)}
#tech .tech-copy .t-tech{color:var(--color-on-black)}
#tech .tech-copy .factline,
#tech .tech-facts .factline{color:var(--color-on-black-muted)}
#tech .spec{color:var(--color-on-black-dim)}
#tech .tech-facts a{color:var(--color-on-black)!important}
#tech .route-ribbon i{background:rgba(255,255,255,.17)}
#tech .route-ribbon i.on{background:var(--signal)}

/* ── the surface: a lit object standing in a dark room ── */
#tech .dun-surface{
  border:1px solid rgba(255,255,255,.11);
  background:var(--color-black-2);
  box-shadow:0 44px 90px -30px rgba(0,0,0,.86),
             0 10px 34px -14px rgba(0,0,0,.6),
             0 0 0 1px rgba(255,255,255,.03),
             0 1px 0 0 rgba(255,255,255,.13) inset}
#tech .dun-chrome{background:#17181c;border-bottom-color:rgba(255,255,255,.09)}
#tech .dun-chrome .u{color:var(--color-on-black-muted)}
#tech .dun-chrome .cap-chip{color:var(--color-on-black-dim);
  border-color:rgba(255,255,255,.16)}
#tech .dun-view{background:var(--color-black-2)}

@media(prefers-reduced-motion:reduce){
  #tech .stage::after{transition:none}
}
@media(prefers-reduced-transparency:reduce){
  #tech .stage::after{display:none}
}

/* the editorial edition renders the same chapter as a document; it needs the
   same room, or the type arrives black-on-black */
html[data-mode="editorial"] #tech .stage{background:var(--color-black)}

/* ══════════════════════════════════════════════════════════════════════════
   V5 · PHOTOGRAPHY — THE WALL
   The gallery was a room: four frames hung far apart on white with a great
   deal of air between them, one picture arriving per screen. It was quiet and
   it was also thin — a photography chapter that showed almost no photography.

   This is the other kind of gallery: eight portraits, one grid, on black,
   close enough together that the body of work is the composition. The frames
   are all cropped to the same 3:4 and lit the same way, because a wall reads
   as curated when the framing is consistent and as a scrapbook when it is
   not. Captions are small, in the corner of the picture, over a scrim that
   exists only where the type is.

   The crop is the point of the lightbox. Every one of these is a 9:16 frame
   shown here at 3:4 — opening one gives you back the picture the crop took
   away, in the same place on the same page.

   The material is one commission: one afternoon, one styled set, natural
   light. The captions say only what is true of it. Nothing here is a client
   name, because there is only one client and their frames are these.
   ══════════════════════════════════════════════════════════════════════════ */

.ph3{background:var(--color-black);color:var(--color-on-black);
  --fg:var(--color-on-black);--muted:var(--color-on-black-muted);
  --dim:var(--color-on-black-dim);--line:var(--color-hairline-on-black);
  --hair:var(--color-hairline-on-black);--signal-text:var(--signal-text-media);
  --color-media-backing:var(--color-black-2);
  position:relative;overflow:clip;padding-block:calc(var(--chapter) * 1.05)}
.ph3-in{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);width:100%}

.ph3-open{display:grid;gap:var(--s-6);align-items:end;
  margin-bottom:clamp(2.2rem,5vw,3.6rem)}
@media(min-width:900px){
  .ph3-open{grid-template-columns:minmax(0,1fr) minmax(0,30rem);
    gap:clamp(2rem,5vw,5rem)}
}
.ph3-h{margin:var(--s-6) 0 0;max-width:15ch;
  font-size:var(--t-display-size);line-height:var(--t-display-lh);
  letter-spacing:var(--t-display-ls);font-weight:var(--t-display-w);
  color:var(--color-on-black);text-wrap:balance}
.ph3-h i{font-style:normal;color:var(--color-on-black-muted)}
.ph3-sub{margin:0;max-width:40ch;color:var(--color-on-black-muted);
  font-size:var(--t-small-size);line-height:var(--t-small-lh)}

/* ── the wall ── */
.ph3-grid{list-style:none;margin:0;padding:0;display:grid;
  gap:clamp(.6rem,1.15vw,1.05rem);
  grid-template-columns:repeat(1,minmax(0,1fr))}
@media(min-width:480px){.ph3-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:820px){.ph3-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:1100px){.ph3-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}

.ph3-cell{display:block;width:100%;padding:0;margin:0;border:0;background:none;
  position:relative;cursor:zoom-in;color:inherit;overflow:hidden;
  border-radius:var(--r-chip);isolation:isolate}
.ph3-win{display:block;position:relative;width:100%;aspect-ratio:3/4;
  overflow:hidden;background:var(--color-black-2);border-radius:var(--r-chip)}
.ph3-win img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 28%;display:block;
  transition:scale 900ms var(--e-out),filter 460ms var(--e-std)}
.ph3-cell::after{content:"";position:absolute;inset:0;border-radius:var(--r-chip);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0);pointer-events:none;z-index:3;
  transition:box-shadow var(--d-state) var(--e-std)}
@media(hover:hover) and (pointer:fine){
  .ph3-cell:hover .ph3-win img{scale:1.045}
  .ph3-cell:hover::after{box-shadow:inset 0 0 0 1px rgba(255,255,255,.30)}
  .ph3-cell:hover .ph3-cap{translate:0 -2px}
  .ph3-grid:hover .ph3-cell:not(:hover) .ph3-win img{filter:brightness(.72)}
}
.ph3-cell:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
.ph3-cell:focus-visible::after{box-shadow:inset 0 0 0 1px rgba(255,255,255,.30)}

/* the label sits in the corner of the picture, on a scrim that only exists
   where the type is — never a bar across the image */
.ph3-cap{position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:2.6rem .72rem .62rem;display:grid;gap:.14rem;text-align:left;
  background:linear-gradient(180deg,rgba(6,6,8,0) 0%,rgba(6,6,8,.52) 62%,rgba(6,6,8,.78) 100%);
  transition:translate var(--d-move) var(--e-out)}
.ph3-cap b{font-family:var(--f-display);font-weight:500;font-size:.8125rem;
  letter-spacing:-.004em;color:#fff;line-height:1.25}
.ph3-cap i{font-style:normal;font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.7)}

.ph3-foot{margin:clamp(2rem,4.4vw,3.2rem) 0 0;padding-top:var(--s-5);
  border-top:1px solid var(--color-hairline-on-black);
  display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s-4) var(--s-8);flex-wrap:wrap;
  font-family:var(--f-mono);font-size:var(--t-label-size);letter-spacing:.11em;
  text-transform:uppercase;color:var(--color-on-black-dim)}
.ph3-foot .n{color:var(--signal-text-media)}
.ph3-foot a{color:var(--color-on-black);position:relative;white-space:nowrap;
  padding-block:.24rem;display:inline-block}
.ph3-foot a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-move) var(--e-out)}
.ph3-foot a:hover::after,.ph3-foot a:focus-visible::after{transform:scaleX(1)}
.ph3-foot i{font-style:normal;color:var(--signal-text-media)}

/* the wall builds, four frames at a time, in reading order */
html[data-mode="cinematic"] .ph3[data-chapter] .ph3-cell{
  opacity:0;translate:0 18px;
  transition:opacity .7s var(--e-std),translate .7s var(--e-out)}
html[data-mode="cinematic"] .ph3[data-chapter].on .ph3-cell{opacity:1;translate:none}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(2) .ph3-cell{transition-delay:60ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(3) .ph3-cell{transition-delay:120ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(4) .ph3-cell{transition-delay:180ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(5) .ph3-cell{transition-delay:150ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(6) .ph3-cell{transition-delay:210ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(7) .ph3-cell{transition-delay:270ms}
html[data-mode="cinematic"] .ph3[data-chapter].on li:nth-child(8) .ph3-cell{transition-delay:330ms}

@media(prefers-reduced-motion:reduce){
  .ph3-cell,.ph3-win img,.ph3-cap,.ph3-cell::after{transition:none!important}
  html[data-mode="cinematic"] .ph3[data-chapter] .ph3-cell{opacity:1;translate:none}
}

/* ══ THE VIEWER ═══════════════════════════════════════════════════════════
   The picture opens where it already is. The frame you clicked is measured,
   a copy is placed exactly over it, and that copy is animated to the centre
   of the viewport while the room goes dark behind it — so the crop opening
   into the full 9:16 reads as the same photograph, not as a modal that
   replaced it. Closing runs the same move backwards, to whichever frame is
   now current.

   Nothing navigates. The URL never changes. */
.lb{position:fixed;inset:0;z-index:400;display:none;
  align-items:center;justify-content:center;padding:clamp(1rem,4vw,3rem)}
.lb.open{display:flex}
.lb-scrim{position:absolute;inset:0;background:rgba(6,6,8,.94);
  backdrop-filter:blur(18px) saturate(.9);-webkit-backdrop-filter:blur(18px) saturate(.9);
  opacity:0;transition:opacity 340ms var(--e-std);cursor:zoom-out}
.lb.in .lb-scrim{opacity:1}

.lb-fig{position:relative;margin:0;z-index:2;pointer-events:none;
  display:grid;justify-items:center;gap:.9rem}
.lb-img{display:block;max-width:min(92vw,calc((100svh - 9rem) * .5625));
  max-height:calc(100svh - 9rem);width:auto;height:auto;
  border-radius:var(--r-media);background:var(--color-black-2);
  box-shadow:0 40px 110px -30px rgba(0,0,0,.9)}
.lb-cap{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;
  justify-content:center;opacity:0;transition:opacity 300ms var(--e-std) 120ms}
.lb.in .lb-cap{opacity:1}
.lb-cap b{font-family:var(--f-display);font-weight:500;font-size:.9375rem;
  letter-spacing:-.006em;color:#fff}
.lb-cap i{font-style:normal;font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.lb-cap .n{font-family:var(--f-mono);font-size:var(--t-label-size);
  letter-spacing:.12em;color:var(--signal-text-media);font-variant-numeric:tabular-nums}

/* the flying copy: one image, absolutely placed, animated from the thumb's
   rectangle to the viewer's */
.lb-fly{position:fixed;margin:0;z-index:3;object-fit:cover;
  object-position:50% 28%;border-radius:var(--r-chip);pointer-events:none;
  will-change:top,left,width,height,border-radius,object-position}

/* controls: minimal, and never over the middle of the picture */
.lb-btn{position:absolute;z-index:4;display:grid;place-items:center;
  width:48px;height:48px;border-radius:50%;border:0;cursor:pointer;
  background:rgba(255,255,255,.1);color:#fff;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  opacity:0;transition:opacity 300ms var(--e-std) 100ms,
    background var(--d-state) var(--e-std),transform var(--d-press) var(--e-out)}
.lb.in .lb-btn{opacity:1}
.lb-btn:hover,.lb-btn:focus-visible{background:rgba(255,255,255,.22)}
.lb-btn:active{transform:scale(.93)}
.lb-btn:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
.lb-btn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.lb-close{top:clamp(.8rem,2.4vw,1.6rem);right:clamp(.8rem,2.4vw,1.6rem)}
.lb-prev{left:clamp(.5rem,2vw,1.6rem);top:50%;margin-top:-24px}
.lb-next{right:clamp(.5rem,2vw,1.6rem);top:50%;margin-top:-24px}
.lb-count{position:absolute;left:50%;translate:-50% 0;
  bottom:clamp(.8rem,2.4vw,1.5rem);z-index:4;
  font-family:var(--f-mono);font-size:var(--t-label-size);letter-spacing:.14em;
  color:rgba(255,255,255,.6);font-variant-numeric:tabular-nums;
  opacity:0;transition:opacity 300ms var(--e-std) 100ms}
.lb.in .lb-count{opacity:1}
@media(max-width:700px){
  .lb-prev,.lb-next{display:none}      /* swipe carries this on a touchscreen */
  .lb-btn{width:44px;height:44px}
}
/* the root holds the scroll position; the body only compensates for the width
   the scrollbar hands back, which is set in script from the real measurement */
html.lb-locked{overflow:hidden}

@media(prefers-reduced-motion:reduce){
  .lb-scrim,.lb-cap,.lb-btn,.lb-count{transition-duration:1ms!important}
  .lb-fly{display:none!important}
}
@media(prefers-reduced-transparency:reduce){
  .lb-scrim{background:rgba(6,6,8,.985);backdrop-filter:none;-webkit-backdrop-filter:none}
  .lb-btn{background:rgba(40,40,44,.96);backdrop-filter:none;-webkit-backdrop-filter:none}
}

/* ══ V5 · TWO TARGETS UNDER THE FLOOR ════════════════════════════
   The roster's closing link came out at 23px and the films chapter carried a
   14px "case study" link in its caption bar — both under the WCAG 2.2 AA
   24×24 floor (2.5.8). Padding only: not one glyph moves, and the films
   chapter is otherwise untouched in this pass. */
.ro-foot a,.ph3-foot a{padding-block:.28rem;min-height:24px}
.cin-meta a{display:inline-block;padding-block:.42rem;min-height:24px}

/* ══ V5 · TECHNOLOGY, LARGER ═══════════════════════════════════════════════
   Two problems with one answer.

   The brief asks this chapter to feel immersive — "large product interface
   crops … Simple. Large. Clear." — and the surface was sitting at about 60%
   of the frame with a column of copy beside a great deal of empty ground.

   And the measurement: with the films, the reels and the hero all dark, and
   Photography now dark too, the homepage had gone to 53.9% black by area
   against 23.6% paper. The founder's constraint is explicit — the page must
   not become predominantly dark. Most of that weight was not the pictures.
   It was this chapter: three and a half viewports of FLAT black with a small
   lit rectangle in it, the one dark chapter with almost no picture in it.

   Making the product bigger fixes both. The surface takes the frame, the copy
   sits under its own chapter rule rather than beside it in a column, and the
   flat ground that was doing nothing becomes the thing the visitor came to
   see. The chapter is also a viewport shorter: the same choreography, less
   scroll spent on an empty room.
   ══════════════════════════════════════════════════════════════════════════ */

@media(min-width:1050px){
  /* the copy no longer takes a third of the frame from the product */
  #tech .tech-body{grid-template-columns:minmax(0,22.5rem) minmax(0,1fr);
    gap:clamp(1.6rem,3.4vw,3.4rem);align-items:center}
}
/* the tighter measure exists to hand width to the product, and there is no
   product beside the copy below 1050px — applied there it only forces extra
   line wraps, which grew the copy column by 49px on a 375x667 phone and
   pushed the closing beat out of the bottom of its own stage */
@media(min-width:1050px){
  #tech .tech-copy .t-tech{max-width:11ch}
  #tech .tech-copy .factline{max-width:32ch}
}

/* NOT a bleed to the right edge. This scene animates the surface from 1440
   down to 390 to show the responsive system working, and a right-anchored
   surface slid half off the frame as it narrowed — the payoff of the whole
   demonstration was clipped, and the middle of the viewport went empty. It
   stays centred in its column, so narrowing reads as narrowing. */
@media(min-width:1400px){
  #tech .tech-body{grid-template-columns:minmax(0,24rem) minmax(0,1fr)}
}

/* ══ V5 · THE EDITORIAL EDITION OF THE TWO NEW CHAPTERS ════════════════
   Both new chapters are built on an interaction, and the editorial edition
   has none: no hover to reveal a portrait, and with scripting off, no viewer
   to open a photograph into. Measured with JavaScript disabled, the roster
   showed five names and NOT ONE face, and every frame in the wall was a
   button that did nothing.

   So the edition simply gives everything at once, which is what the editorial
   edition is for. Each credit carries its own portrait in the row, and the
   wall shows the frames uncropped — there is nothing left to open, so nothing
   is lost by not being able to open it. */
html[data-mode="editorial"] .ro-list{--ro-y:0px}
html[data-mode="editorial"] .ro-shot{position:static;left:auto;width:min(58%,240px);
  translate:none!important;scale:1;opacity:1;
  margin:0 0 clamp(1rem,2.4vw,1.6rem) 3.4rem;display:block}
html[data-mode="editorial"] .ro-shot img{box-shadow:0 14px 34px -14px rgba(28,25,20,.26)}
html[data-mode="editorial"] .ro-hit{cursor:default}
html[data-mode="editorial"] .ro-row.on .ro-hit{translate:none}

html[data-mode="editorial"] .ph3-win{aspect-ratio:9/16}
html[data-mode="editorial"] .ph3-cell{cursor:default}
html[data-mode="editorial"] .ph3-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
@media(min-width:900px){
  html[data-mode="editorial"] .ph3-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* ══ V5 · TWO FIXES THE PHONE BUILD NEEDED ════════════════════════
   1. The V5 treatment of the header action re-declared `.nav .nav-cta` at the
      same weight as V4’s phone rule and later in the file, which switched the
      action back on at 390 — where the wordmark and the plate each wrap to two
      lines. The phone bar is the mark and the menu; the action is the last
      entry inside the menu.
   2. The roster’s accordion animates grid-template-rows 0fr → 1fr, and a row
      of zero height only HIDES the picture if the grid container clips. It did
      not, so a closed portrait was painted straight over the next credit. */
@media(max-width:560px){
  .nav .nav-cta{display:none}
}
@media(max-width:899px){
  .ro-shot{overflow:hidden}
}

/* ══ V5 · THE BOTTOM OF THE HERO ON A PHONE ═══════════════════════
   At 390 the closing baseline had three things competing for it: the
   statement running to the bottom edge, the new scroll indicator centred on
   it, and the sound key parked bottom-right beside the motion control. The
   indicator was drawn straight through the second line of the sub-copy.

   The statement gives up a band for the indicator, and the sound key goes
   back to the top right where it sits on every other width — which also
   stops it crowding the motion control. */
@media(max-width:900px){
  .hero-say{padding-bottom:clamp(4.4rem,11svh,5.8rem)}
  .hero-controls{right:var(--gut);left:auto;
    top:calc(var(--safe-top) + .4rem);bottom:auto}
}
