/* ==========================================================================
   Kickstart Media, home page stylesheet
   Module: css (owns this file only)

   Table of contents
   01 Tokens
   02 Base and reset
   03 Type utilities
   04 Skip link and hidden helpers
   05 Loader
   06 Ambient layers (sky, aurora, grain)
   07 Cursor
   08 Nav
   09 Menu overlay
   10 Buttons and the roll
   11 Hero (stage, video, scrim, bands, entrances, hud, static hero, gates)
   12 (removed: the tower aside)
   13 Sections, common
   14 Stages
   15 Services
   16 Work
   17 Clients
   18 Bar (hold to walk the tower)
   19 FAQ
   20 Contact
   21 Footer
   22 Choreography (.in), paused, toast
   23 Reduced motion
   24 Responsive
   25 Print

   Rules of the house: animation touches transform and opacity only
   (filter is static, never tweened). Every transition uses --ease-out
   or --ease-inout. No dashes other than the hyphen anywhere in this file.
   ========================================================================== */


/* --------------------------------------------------------------------------
   01 Tokens
   -------------------------------------------------------------------------- */
:root{
  /* night end */
  --n-canvas:#0B0D12;  --n-panel:#141821;  --n-text:#E9ECF1;  --n-text-2:#9BA3B2;  --n-line:rgba(233,236,241,.14);
  /* day end (dawn light) */
  --d-canvas:#ECEFF3;  --d-panel:#F8F9FB;  --d-text:#0F1218;  --d-text-2:#4B5563;  --d-line:rgba(15,18,24,.14);
  /* constants */
  --accent:#FF8A00;        /* the CTA and rare emphasis, the rocket A */
  --accent-hover:#FFA033;
  --accent-muted:rgba(255,138,0,.18);
  --blue:#1A81A1;          /* the wordmark blue, cold floodlight, aurora */
  --blue-bright:#10AADC;
  --night:1;               /* written by JS from local time; 0..1 */
  /* live tokens */
  --canvas:color-mix(in oklab,var(--d-canvas),var(--n-canvas) calc(var(--night)*100%));
  --panel:color-mix(in oklab,var(--d-panel),var(--n-panel) calc(var(--night)*100%));
  --text-primary:color-mix(in oklab,var(--d-text),var(--n-text) calc(var(--night)*100%));
  --text-secondary:color-mix(in oklab,var(--d-text-2),var(--n-text-2) calc(var(--night)*100%));
  --line:color-mix(in oklab,var(--d-line),var(--n-line) calc(var(--night)*100%));

  /* derived: a stronger hairline for interactive borders (hairlines fail 3:1) */
  --line-strong:color-mix(in oklab,var(--text-primary) 34%,transparent);
  /* the wordmark blue brightens as the night deepens */
  --brand-blue:color-mix(in oklab,var(--blue),var(--blue-bright) calc(var(--night)*70%));
  /* text over the footage is always light: the footage is always dark */
  --hero-ink:#EEF1F6;
  --hero-ink-2:rgba(238,241,246,.8);
  /* the accent as ink: pure at night, pulled toward the dark text by day so
     small orange labels still clear 4.5:1 on the light canvas */
  --accent-ink:color-mix(in oklab,var(--accent),var(--d-text) calc((1 - var(--night)) * 55%));

  /* motion */
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-inout:cubic-bezier(.65,0,.35,1);
  --t-fast:.35s var(--ease-out);
  --t-mid:.6s var(--ease-out);
  --t-slow:1s var(--ease-out);

  /* legibility */
  --tshadow:0 1px 2px rgba(5,5,10,.95),0 3px 12px rgba(5,5,10,.78),0 10px 44px rgba(5,5,10,.8);

  /* type: 01-type.md v3 (Satoshi with the deck's accent), 2026-09-08. Satoshi
     for every reading role, a heading at 300 with its emphasised word at 900
     (the split-weight device, never italic), Pramukh Rounded 800 italic once
     per screen, a true mono for every label and readout. */
  --font-display:"Satoshi",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-sub:"Satoshi",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-italic:"Pramukh Rounded","Satoshi",sans-serif;
  --font-body:"Satoshi",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-mono:"Geist Mono","SF Mono",Menlo,Consolas,monospace;
  --track-display:-0.03em;
  --weight-italic:800;
  --t-display:300 clamp(3rem,7vw,6.2rem)/1 var(--font-display);
  --t-h1:300 clamp(2.2rem,5vw,4rem)/1.04 var(--font-display);
  --t-h2:300 clamp(2rem,4vw,3.4rem)/1.06 var(--font-display);
  --t-h3:700 1.2rem/1.25 var(--font-sub);
  --t-sub:400 clamp(1.1rem,1.6vw,1.4rem)/1.4 var(--font-sub);
  --t-accent:italic var(--weight-italic) clamp(1.6rem,3vw,2.6rem)/1.12 var(--font-italic);
  --t-body:400 1.0625rem/1.6 var(--font-body);
  --t-small:400 0.875rem/1.5 var(--font-body);
  --t-label:400 0.72rem/1.4 var(--font-mono);
  --t-data:500 clamp(1.75rem,3.6vw,3rem)/1.05 var(--font-mono);

  /* tracking per role, from the v3 table: H1 and H2 at -0.025em, the plain H1
     sentences of bands 2 to 4 at -0.02em, the accent at -0.01em, card titles at
     -0.01em, labels at .14em */
  --track-head:-0.025em;
  --track-plain:-0.02em;
  --track-accent:-0.01em;
  --track-h3:-0.01em;
  --track-label:.14em;

  /* rhythm */
  --gutter:clamp(20px,5.5vw,88px);
  --section-pad:clamp(96px,14vh,176px);
  --radius:20px;
  --nav-h:72px;

  /* stacking */
  --z-sky:0;
  --z-aurora:1;
  --z-main:2;
  --z-grain:40;
  --z-menu:55;
  --z-nav:60;
  --z-hint:65;
  --z-cursor:90;
  --z-loader:100;
}

/* colour-scheme follows the discrete phase so form controls and scrollbars match */
html{color-scheme:dark}
html[data-phase="day"],
html[data-phase="dawn"]{color-scheme:light}


/* --------------------------------------------------------------------------
   02 Base and reset
   -------------------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}

html{
  overflow-x:hidden;
  overflow-x:clip;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--nav-h) + 12px);
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
}

body{
  margin:0;
  min-height:100vh;
  min-height:100svh;
  overflow-x:hidden;
  overflow-x:clip;
  background-color:var(--canvas);
  /* the slow two-colour fog is its own fixed layer (.fog), transform-driven */
  color:var(--text-primary);
  font:var(--t-body);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

/* scroll lock while the loader or the menu holds the screen */
html:has(body.is-loading),
html:has(body.menu-open),html.menu-open{overflow-y:hidden}

::selection{background:var(--accent-muted);color:var(--text-primary)}

img,svg,video,canvas{display:block;max-width:100%}
img{height:auto}
button,input,textarea,select{font:inherit;color:inherit;margin:0}
button{background:none;border:0;padding:0;cursor:pointer;text-align:inherit}
a{color:inherit;text-decoration:none}
ul,ol{margin:0;padding:0;list-style:none}
h1,h2,h3,h4,p,figure,blockquote{margin:0}
h1,h2,h3,h4{text-wrap:balance}
p{text-wrap:pretty}
address{font-style:normal}
kbd{
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  padding:3px 6px;
  border:1px solid var(--line-strong);
  border-radius:4px;
  vertical-align:middle;
}

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

main{position:relative;z-index:var(--z-main)}
main:focus{outline:none}


/* --------------------------------------------------------------------------
   03 Type utilities
   -------------------------------------------------------------------------- */
/* the roles, one token each; .display is the face utility the markup carries
   on section headings and stage names, every use of it is narrowed by a role
   rule below (H2 on section h2, H3 on .stage-name, H1 on .shipped-line,
   Subtitle on .foot-line) */
.display,.h1{font:var(--t-h1);letter-spacing:var(--track-head)}
.h2{font:var(--t-h2);letter-spacing:var(--track-head)}
.h3{font:var(--t-h3);letter-spacing:var(--track-h3)}
/* the emphasis device is weight, never italic: a heading sits at 300 and its
   one emphasised word (the <b>, or the .c.em characters hero.js builds) at 900 */
h1 b,h2 b,.display b,.h1 b,.h2 b,.split b,.split .em{font-style:normal;font-weight:900}

/* every label and counting readout: Geist Mono, tabular figures */
.mono{
  font-family:var(--font-mono);
  font-weight:400;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
}

.kicker{
  display:inline-flex;
  align-items:center;
  gap:12px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-secondary);
}
.kicker::before{
  content:"";
  width:24px;
  height:1px;
  background:var(--blue-bright);
  flex:0 0 auto;
}

.lede{
  font:var(--t-sub);
  color:var(--text-secondary);
  max-width:52ch;
}

.num{
  font:var(--t-data);
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
}


/* --------------------------------------------------------------------------
   04 Skip link and hidden helpers
   -------------------------------------------------------------------------- */
.skip{
  position:fixed;
  top:12px;
  left:12px;
  z-index:calc(var(--z-loader) + 1);
  display:inline-flex;
  align-items:center;
  min-height:44px;
  padding:12px 18px;
  border-radius:999px;
  background:var(--accent);
  color:#0B0D12;
  font:700 .95rem/1 var(--font-sub);
  transform:translateY(-200%);
  transition:transform var(--t-fast);
}
.skip:focus-visible{transform:none;outline-offset:2px}

.sr,
.visually-hidden{
  position:absolute !important;
  width:1px;
  height:1px;
  margin:-1px;
  padding:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

[hidden]{display:none !important}


/* ---- No opening. The page fades in from black over its first second
   (launch.js lifts body.is-dark on the second frame). The scrollbar is
   hidden: the deck is scrolled by hand and the film is the only measure of
   where you are. */
html{background:#05070c}
/* 16l: the cover. Black over everything until the page has loaded what it needs (launch.js), then a 1.1 s
   fade; the body itself no longer fades, so the loader's own line can sit on the black. */
.ks-cover{position:fixed;inset:0;z-index:calc(var(--z-loader) + 2);background:#05070c;display:grid;align-content:end;padding:0 var(--gutter) clamp(28px,5vh,56px);pointer-events:none;opacity:0;visibility:hidden;transition:opacity 1.1s var(--ease-out),visibility 0s linear 1.1s}
body.is-dark .ks-cover{opacity:1;visibility:visible;transition:none}
.ks-cover-line{margin:0;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-secondary);opacity:.7;font-variant-numeric:tabular-nums}
.ks-cover-bar{display:block;position:relative;width:min(320px,50vw);height:1px;background:rgba(238,241,246,.14);margin-top:10px}
.ks-cover-bar b{position:absolute;left:0;top:-1px;height:3px;width:calc(100% * var(--p,0));background:var(--accent);box-shadow:0 0 12px rgba(255,138,0,.6);transition:width .25s linear}
html{scrollbar-width:none;-ms-overflow-style:none}
html::-webkit-scrollbar{width:0;height:0;display:none}

body.is-loading .nav{opacity:0;visibility:hidden}


/* --------------------------------------------------------------------------
   06 Ambient layers
   -------------------------------------------------------------------------- */
.sky{
  position:fixed;
  inset:0;
  z-index:var(--z-sky);
  width:100%;
  height:100%;
  pointer-events:none;
  /* a cold floodlight tint that lets the body fog read through */
  background:radial-gradient(90% 70% at 30% 14%,color-mix(in oklab,var(--blue) 16%,transparent),transparent 70%);
}

/* three soft aurora ribbons, blue, teal and a thread of orange; they exist
   only when the night is deeper than .6 (ambient.js writes data-aurora from
   the same gate, so below it the layer is not composited at all). The
   softness is baked into radial gradients: no filter, no blend mode, so a
   weak compositor moves three small textures and nothing else. */
.aurora{
  position:fixed;
  inset:0;
  z-index:var(--z-aurora);
  pointer-events:none;
  overflow:hidden;
  contain:strict;
  opacity:calc(clamp(0,(var(--night) - .6) * 2.5,1) * .6);
}
.aurora i{
  position:absolute;
  left:-10%;
  width:120%;
  height:46vh;
  background-repeat:no-repeat;
  will-change:transform;
  animation:aurora-drift 50s var(--ease-inout) infinite alternate;
}
.aurora i:nth-child(1){
  top:-14vh;
  background:
    radial-gradient(ellipse 34% 42% at 36% 52%,rgba(16,170,220,.5),rgba(16,170,220,.18) 45%,transparent 72%),
    radial-gradient(ellipse 36% 38% at 66% 46%,rgba(26,129,161,.42),rgba(26,129,161,.14) 48%,transparent 74%);
  animation-delay:-12s;
}
.aurora i:nth-child(2){
  top:6vh;
  height:38vh;
  background:
    radial-gradient(ellipse 32% 40% at 40% 50%,rgba(26,129,161,.44),rgba(26,129,161,.14) 46%,transparent 72%),
    radial-gradient(ellipse 30% 36% at 68% 54%,rgba(64,220,200,.3),rgba(64,220,200,.1) 48%,transparent 74%);
  animation-delay:-31s;
  animation-duration:64s;
}
.aurora i:nth-child(3){
  top:30vh;
  height:26vh;
  background:radial-gradient(ellipse 30% 34% at 52% 50%,rgba(255,138,0,.2),rgba(255,138,0,.07) 50%,transparent 76%);
  animation-delay:-45s;
  animation-duration:78s;
}
@keyframes aurora-drift{
  0%  {transform:translate3d(-6%,0,0) skewX(-8deg) scaleY(1)}
  50% {transform:translate3d(3%,-3vh,0) skewX(4deg) scaleY(1.12)}
  100%{transform:translate3d(8%,1vh,0) skewX(10deg) scaleY(.94)}
}
/* by day there is nothing to draw, so the layer rests entirely; below the
   night gate ambient.js says the same through data-aurora */
html[data-phase="day"] .aurora,
html[data-aurora="off"] .aurora{display:none}

/* the slow two-colour fog behind everything: one oversized layer painted once,
   moved by a transform-only keyframe (120 s), so the ambient loop never touches
   a root custom property. The body carries only the flat canvas colour. The
   layer is 130 percent of the viewport with a 15 percent margin each side,
   which covers the largest drift (8vw, 9vh) without the old 160 percent texture. */
.fog{
  position:fixed;
  left:-15vw;
  top:-15vh;
  z-index:-1;
  width:130vw;
  height:130vh;
  pointer-events:none;
  contain:strict;
  background:radial-gradient(ellipse 42% 37% at 40% 33%,color-mix(in oklab,var(--blue) 14%,transparent),transparent 70%);
  will-change:transform;
  animation:fog-drift 120s var(--ease-inout) infinite;
  animation-delay:-40s;
}
@keyframes fog-drift{
  0%  {transform:translate3d(0,0,0)}
  25% {transform:translate3d(7vw,5vh,0)}
  50% {transform:translate3d(-3vw,9vh,0)}
  75% {transform:translate3d(-8vw,2vh,0)}
  100%{transform:translate3d(0,0,0)}
}

/* while nobody is there (ambient.js: no input for 2 s) the whisper layers
   hold their pose; they resume mid cycle on the next input, so nothing jumps */
html[data-sky="rest"] .fog,
html[data-sky="rest"] .aurora i,
html[data-sky="rest"] .grain::before{animation-play-state:paused}

/* film grain: one SVG feTurbulence tile, jittered by transform in steps. The
   tile is a plain low-opacity overlay (no blend mode, so the compositor never
   re-blends the whole viewport) with just enough headroom for the 4% jitter. */
.grain{
  position:fixed;
  inset:0;
  z-index:var(--z-grain);
  pointer-events:none;
  overflow:hidden;
  opacity:calc(.05 + var(--night) * .05);
  transition:opacity .4s var(--ease-out);
}
/* While the film is on screen it is the only thing that may cost a frame.
   Every layer under or over it that the compositor would otherwise re-blend
   on every one of its 60 frames a second is taken out of the tree here: the
   grain, the drifting fog and the sky tint are all hidden behind the film
   anyway, and the two backdrop blurs would each force a readback and a blur
   of the moving frame beneath them, every frame. */
/* While the film fills the screen the sky, fog and grain are out of the
   compositor's way; they come back with a soft fade the moment the deck
   starts to leave (hero.js sets data-film from the stage's own coverage). */
.grain,.fog,.sky{transition:opacity .7s var(--ease-out),visibility 0s}
html[data-film="1"] .grain,
html[data-film="1"] .fog,
html[data-film="1"] .sky{opacity:0;visibility:hidden;transition:opacity .35s var(--ease-out),visibility 0s linear .35s}
html[data-film="1"] .chip,
html[data-film="1"] .brand,
html[data-film="1"] .nav-right > *{background:color-mix(in oklab,var(--canvas) 86%,transparent)}
html[data-film="1"] .hud .chip{background:rgba(8,8,15,.78)}
/* the readout changes every frame: keep its reflow inside itself */
/* the altitude chip is its own compositor layer: its text changes while the
   film moves, and without a layer every change repainted the whole stage */
.hud .chip{contain:layout style paint;will-change:transform;transform:translateZ(0)}
.grain::before{
  content:"";
  position:absolute;
  inset:-6%;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='256' height='256'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .65 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size:256px 256px;
  will-change:transform;
  /* 16l: no jitter; the tile is static so the compositor never re-blends the screen for it */
}
@keyframes grain-jitter{
  0%  {transform:translate(0,0)}
  25% {transform:translate(-3%,2%)}
  50% {transform:translate(2%,-4%)}
  75% {transform:translate(-4%,-1%)}
  100%{transform:translate(3%,3%)}
}


/* --------------------------------------------------------------------------
   07 Cursor
   cursor.js positions .cursor-ring and .cursor-dot with transform. The
   drawn ring lives on ::before so state scaling never fights that transform.
   States on #cursor: .is-hover, .is-down, .is-idle, .is-hidden
   -------------------------------------------------------------------------- */
.cursor{
  position:fixed;
  top:0;
  left:0;
  z-index:var(--z-cursor);
  pointer-events:none;
  opacity:0;
  transition:opacity var(--t-fast);
}
html[data-cursor="custom"] .cursor{opacity:1}
/* a coarse pointer never sees the ring, whatever the script decides */
html[data-pointer="coarse"] .cursor{display:none}
html[data-cursor="custom"],
html[data-cursor="custom"] a,
html[data-cursor="custom"] button,
html[data-cursor="custom"] input,
html[data-cursor="custom"] textarea,
html[data-cursor="custom"] summary,
html[data-cursor="custom"] label{cursor:none}

.cursor-ring,
.cursor-dot{
  position:absolute;
  top:0;
  left:0;
  width:0;
  height:0;
  will-change:transform;
}
.cursor-ring::before{
  content:"";
  position:absolute;
  width:36px;
  height:36px;
  border-radius:50%;
  border:1.5px solid var(--text-primary);
  transform:translate(-50%,-50%);
  transition:border-color var(--t-fast),opacity var(--t-fast);
  opacity:.9;
}
/* the idle glint: a small light travelling the rim after 2 s of stillness.
   Three laps (7.2 s) then it fades and the keyframe ends, so a still pointer
   leaves nothing ticking; the next movement drops the class and re-arms it. */
.cursor-ring::after{
  content:"";
  position:absolute;
  width:36px;
  height:36px;
  border-radius:50%;
  transform:translate(-50%,-50%) rotate(0deg);
  background:conic-gradient(from 0deg,transparent 0 78%,var(--blue-bright) 92%,transparent 100%);
  -webkit-mask:radial-gradient(circle,transparent 0 16px,#000 16.5px 18px,transparent 18.5px);
  mask:radial-gradient(circle,transparent 0 16px,#000 16.5px 18px,transparent 18.5px);
  opacity:0;
  will-change:transform,opacity;
}
.cursor-dot::before{
  content:"";
  position:absolute;
  width:5px;
  height:5px;
  border-radius:50%;
  background:var(--text-primary);
  transform:translate(-50%,-50%);
  transition:background-color var(--t-fast),opacity var(--t-fast);
}
.cursor.is-hover .cursor-ring::before{border-color:var(--accent);opacity:1}
.cursor.is-hover .cursor-dot::before{background:var(--accent)}
/* 16n: no idle glint; the blue ring is gone */
.cursor.is-hidden,
html[data-cursor="custom"] .cursor.is-hidden{opacity:0}
@keyframes cursor-glint{
  0%  {opacity:0;transform:translate(-50%,-50%) rotate(0deg)}
  5%  {opacity:1}
  94% {opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) rotate(1080deg)}
}

/* magnetic targets: while held, the JS lerp alone owns the motion (no CSS
   transition fighting it); on release the class eases the element home */
[data-magnetic].is-magnet{transition:none}
[data-magnetic].is-magnet-release{transition:transform .55s var(--ease-out)}


/* --------------------------------------------------------------------------
   08 Nav
   -------------------------------------------------------------------------- */
.nav{
  position:fixed;
  inset:0 0 auto 0;
  z-index:var(--z-nav);
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:clamp(10px,1.2vw,16px) clamp(14px,1.8vw,26px);
  pointer-events:none;
  opacity:1;
  visibility:visible;
  transition:opacity 1s var(--ease-out) .2s,visibility 1s var(--ease-out) .2s;
}
/* slide 1 is the banner alone: the logo, the chips and the readout are never on screen while the wordmark is (hero.js sets deck-first whenever the banner band is visible); they hide at once and return with a fade */
.nav .brand,.nav-right,.hud{transition:opacity .5s var(--ease-out),visibility .5s var(--ease-out)}
body.deck-first .nav .brand,body.deck-first .nav-right,body.deck-first .hud{opacity:0;visibility:hidden;pointer-events:none;transition:none}
.nav > *{pointer-events:auto}

/* the chip scrim shared by every small item riding over footage */
.chip,
.brand,
.nav-right > *{
  background:color-mix(in oklab,var(--canvas) 86%,transparent);
  border:1px solid var(--line);
  border-radius:12px;
  text-shadow:0 1px 3px rgba(5,5,10,.55);
}

.brand{
  display:inline-flex;
  align-items:center;
  min-height:44px;
  padding:9px 14px;
  border-radius:14px;
  transition:background-color var(--t-mid),border-color var(--t-mid);
}

/* while the hero is on screen the chips ride over footage that is always dark,
   whatever the clock says: they keep the night scrim and the hero ink so the
   day theme never paints light stickers on the starfield */
body:has(#hero.on-screen) :is(.brand,.nav-right > *){
  background:rgba(11,13,18,.58);
  border-color:rgba(233,236,241,.14);
  color:var(--hero-ink);
}
body:has(#hero.on-screen) #wm-media,
body:has(#hero.on-screen) #wm-media *{fill:var(--hero-ink)}
.brand svg{
  display:block;
  height:clamp(18px,1.7vw,24px);
  width:auto;
  overflow:visible;
}
#wm-kickstart,
#wm-kickstart *{fill:var(--brand-blue)}
#wm-media,
#wm-media *{fill:var(--text-primary)}
#wm-rocket,
#wm-rocket *{fill:var(--accent)}
#wm-rocket{
  transform-box:fill-box;
  transform-origin:center;
  transition:transform var(--t-mid);
}
.brand:focus-visible #wm-rocket{transform:translateY(-9%)}
@media (hover:hover) and (pointer:fine){.brand:hover #wm-rocket{transform:translateY(-9%)}}

.nav-right{
  display:flex;
  align-items:center;
  gap:8px;
}
.nav-right > *{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  min-height:44px;
  min-width:44px;
  padding:0 14px;
  border-radius:999px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-primary);
  white-space:nowrap;
  transition:transform var(--t-fast),opacity var(--t-fast),color var(--t-fast),background-color var(--t-mid),border-color var(--t-mid);
}
.nav-right > button:hover,.home-link:hover{transform:translateY(-1px)}
.theme-toggle{padding:0 12px}
/* the home icon: the same pill as the toggle, the icon alone inside it */
.home-link{padding:0 12px;text-decoration:none}
.home-link:hover{color:var(--accent-ink)}

/* icons: stroked, currentColor, 20 px inside the 44 px target */
.ico{
  width:20px;
  height:20px;
  flex:0 0 auto;
  fill:none;
  stroke:currentColor;
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
  overflow:visible;
}
/* sun by day, moon by night; theme.js writes data-look on the button */
.ico-sun,
.ico-moon{
  transform-box:fill-box;
  transform-origin:center;
  transition:opacity var(--t-mid),transform var(--t-mid);
}
.ico-sun{opacity:0;transform:rotate(-40deg) scale(.6)}
.ico-moon{opacity:1;transform:none}
.theme-toggle[data-look="day"] .ico-sun{opacity:1;transform:none}
.theme-toggle[data-look="day"] .ico-moon{opacity:0;transform:rotate(40deg) scale(.6)}
.theme-toggle:hover .ico-sun,
.theme-toggle:hover .ico-moon{transform:rotate(18deg)}
.theme-toggle[data-look="day"]:hover .ico-moon{transform:rotate(40deg) scale(.6)}
.theme-toggle:not([data-look="day"]):hover .ico-sun{transform:rotate(-40deg) scale(.6)}

/* menu toggle: the word and the visor ring */
.menu-word{display:inline-block}
.ico-visor{
  width:26px;
  height:16px;
  transition:transform var(--t-mid);
  transform-box:fill-box;
  transform-origin:center;
}
.menu-toggle:hover .ico-visor{transform:scaleX(.8)}
.menu-toggle[aria-expanded="true"] .ico-visor{transform:scale(.7,1.15)}

/* the nav quietens while the menu is open, the toggle stays crisp */
body.menu-open .nav-right > *:not(.menu-toggle){opacity:.5}


/* --------------------------------------------------------------------------
   09 Menu overlay
   menu.js removes [hidden], waits two frames, adds .is-visible, and writes
   --ox/--oy (the toggle's centre) so the visor opens from where it was pressed.
   The elliptical clip-path is a contract-directed exception to the
   transform/opacity rule.
   -------------------------------------------------------------------------- */
.menu{
  position:fixed;
  inset:0;
  z-index:var(--z-menu);
  display:grid;
  grid-template-columns:minmax(0,1fr);
  align-items:center;
  padding:calc(var(--nav-h) + 24px) var(--gutter) clamp(32px,8vh,72px);
  background:color-mix(in oklab,var(--canvas) 97%,transparent);
  color:var(--text-primary);
  overflow:hidden;
  clip-path:ellipse(0% 0% at var(--ox,calc(100% - 64px)) var(--oy,34px));
  transition:clip-path .7s var(--ease-inout);
  will-change:clip-path;
}
.menu.is-visible{clip-path:ellipse(175% 165% at var(--ox,calc(100% - 64px)) var(--oy,34px))}
/* 16n: closed, the visor stays laid out and composited (visibility only), so the first open builds no new layer */
.menu[hidden]{display:grid !important;visibility:hidden;pointer-events:none}

.menu-list{
  position:relative;
  z-index:1;
  display:grid;
  gap:clamp(4px,1vh,12px);
  align-content:center;
}
.menu-list li{
  opacity:0;
  transform:translateY(28px);
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);
  transition-delay:calc(.25s + var(--i,0) * 70ms);
}
.menu.is-visible .menu-list li{opacity:1;transform:none}

.menu-link{
  display:inline-flex;
  align-items:baseline;
  gap:.35em;
  font:var(--t-h1);
  font-size:clamp(2.2rem,6.4vw,5.6rem);
  letter-spacing:var(--track-head);
  color:var(--text-primary);
  min-height:44px;
}
.menu-link .roll > span + span{color:var(--accent)}

/* the astronaut at the laptop, drifting behind at whisper level, held by the visor curve */
.menu-astro{
  position:absolute;
  right:-4vw;
  bottom:-6vh;
  width:min(30vw,420px);
  height:auto;
  pointer-events:none;
  clip-path:ellipse(46% 48% at 50% 52%);
  opacity:0;
  transition:opacity 1.4s var(--ease-out) .3s;
  will-change:opacity;
}
.menu.is-visible .menu-astro{opacity:calc(.64 + var(--night) * .3)}   /* 16s: brighter, more visible */

.menu-close{
  position:fixed;
  right:var(--gutter);
  top:calc(var(--nav-h) / 2 - 22px);
  z-index:3;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:44px;
  height:44px;
  border-radius:50%;
  border:1px solid var(--line-strong);
  color:var(--text-primary);
  opacity:0;
  transition:opacity .8s var(--ease-out) .5s,border-color var(--t-fast);
}
.menu.is-visible .menu-close{opacity:1}
body.menu-open .nav .menu-toggle,body.menu-open .nav .home-link{opacity:0;pointer-events:none}
body.menu-open .nav .nav-right{pointer-events:none}   /* the nav sits above the menu; while it is open its right group must not catch the X underneath */
.menu-close:hover{border-color:var(--accent)}
.menu-close .ico{width:16px;height:16px}
.theme-toggle{display:none}


/* --------------------------------------------------------------------------
   10 Buttons and the roll
   Hover states are pseudo-element opacity and label rolls, never transform,
   so cursor.js's magnetic transform owns the element's transform outright.
   -------------------------------------------------------------------------- */
.btn{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  min-height:50px;
  padding:0 26px;
  border-radius:999px;
  border:1px solid transparent;
  font:700 .95rem/1 var(--font-sub);
  letter-spacing:.005em;
  color:var(--text-primary);
  text-shadow:none;
  white-space:nowrap;
  overflow:hidden;
  isolation:isolate;
  -webkit-tap-highlight-color:transparent;
  transition:opacity var(--t-fast);
}
.btn::before{
  content:"";
  position:absolute;
  inset:-1px;
  border-radius:inherit;
  opacity:0;
  transition:opacity var(--t-fast);
  z-index:-1;
}
.btn:hover::before,
.btn:focus-visible::before{opacity:1}

.btn-primary{
  background:var(--accent);
  color:#0B0D12;
  border-color:var(--accent);
}
.btn-primary::before{background:var(--accent-hover)}

.btn-ghost{
  background:transparent;
  border-color:var(--line-strong);
  color:var(--text-primary);
}
.btn-ghost::before{
  background:color-mix(in oklab,var(--text-primary) 9%,transparent);
  border:1px solid var(--text-primary);
}
/* ghost buttons over footage read in the hero ink */
.band .btn-ghost,
.static-hero .btn-ghost{color:var(--hero-ink);border-color:rgba(238,241,246,.42)}
.band .btn-ghost::before,
.static-hero .btn-ghost::before{background:rgba(238,241,246,.1);border-color:var(--hero-ink)}

.btn .arrow{
  width:14px;
  height:14px;
  transition:transform var(--t-mid);
}
.btn:hover .arrow{transform:translateX(3px)}
.btn[disabled],.btn.is-busy{opacity:.55;pointer-events:none}

/* the roll: two stacked copies, the top slides out as the bottom slides in.
   <span class="roll"><span>Label</span><span aria-hidden="true">Label</span></span> */
.roll{
  position:relative;
  display:inline-block;
  overflow:hidden;
  padding:.25em 0;
  margin:-.25em 0;
  vertical-align:bottom;
}
.roll > span{
  display:block;
  transition:transform .6s var(--ease-out);
}
.roll > span + span{
  position:absolute;
  inset:.25em 0 auto 0;
  /* parked one full line plus the mask's .25em below, so a 700-weight cap top
     never peeks through the breathing room */
  transform:translateY(calc(100% + .25em));
}
:is(a,button,.btn,.menu-links a):is(:hover,:focus-visible) .roll > span:first-child,
.roll.is-on > span:first-child{transform:translateY(calc(-100% - .25em))}
:is(a,button,.btn,.menu-links a):is(:hover,:focus-visible) .roll > span + span,
.roll.is-on > span + span{transform:translateY(0)}
/* per-character variant: each .c carries --i for a 18 ms stagger */
.roll .c{display:inline-block;transition-delay:calc(var(--i,0) * 18ms)}


/* --------------------------------------------------------------------------
   11 Hero
   -------------------------------------------------------------------------- */
.hero{
  --hero-h:500;
  position:relative;
  height:calc(var(--hero-h) * 1vh);
  color:var(--hero-ink);
}
.hero[data-hero-height="500"]{--hero-h:500}
.hero[data-hero-height="800"]{--hero-h:800}
.hero[data-hero-height="1000"]{--hero-h:1000}
.hero[data-hero-height="1200"]{--hero-h:1200}
.hero[data-hero-height="1400"]{--hero-h:1400}

.stage{
  --roll:0deg;
  position:sticky;
  top:0;
  height:100vh;
  height:100svh;
  overflow:hidden;
  background:#0B0D12;
  isolation:isolate;
}

/* the framed footage: the frame sequence on a canvas over the poster, the 4K
   rest still over the canvas while the deck rests. No scale, no filter, no
   blend: the frame is drawn 1:1 into a canvas the size of the stage (times
   the device pixel ratio) so nothing between the frame and the glass softens
   it. hero.js fades the canvas in over the poster on the first frame drawn. */
.film{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  opacity:0;
  pointer-events:none;
  will-change:transform,opacity;
  transform:translateZ(0) rotate(var(--roll));
  transition:opacity .9s var(--ease-out);
}
.stage.film-ready .film{opacity:1}
/* the playback clips: only one is ever visible, and only while a transition runs */
.clip{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:50% 50%;
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transform:translateZ(0) rotate(var(--roll));
  will-change:opacity;
}
.stage.clip-on .clip.on{opacity:1;visibility:visible}
.stage.film-failed .film{display:none}
/* the rest still: blooms in over 700 ms once the deck rests on a slide; .snap
   (set by hero.js the moment the film moves) dissolves it out in 180 ms */
.rest{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:50% 50%;
  opacity:0;
  pointer-events:none;
  will-change:opacity;
  transform:translateZ(0);
  transition:opacity .7s var(--ease-out), visibility 0s;   /* the sharp still blooms in, it does not pop */
}
/* out of the compositor entirely unless the film is resting on this slide */
.rest{visibility:hidden}
.stage.at-rest .rest{opacity:1;visibility:visible}
/* on the first touch the still dissolves over the moving film in 180 ms, so the
   sharp picture becomes the moving one instead of snapping off it */
.rest.snap{transition:opacity .18s linear, visibility 0s linear .18s}

.stage.film-ready .poster{display:none}
.poster{
  position:absolute;
  inset:0;
  background-position:50% 50%;
  background-size:cover;
  background-repeat:no-repeat;
  transform:rotate(var(--roll));
  will-change:transform;
}

/* the global base scrim: no frame is ever raw behind the page. The foot fade
   melts the framed footage into the live canvas token so the hero and the page
   below read as one environment in either theme, not two worlds on a seam. */
.scrim{
  position:absolute;
  inset:0;
  pointer-events:none;
  background:
    linear-gradient(to bottom,transparent 87%,rgba(5,7,12,.92) 100%),
    radial-gradient(ellipse 120% 90% at 50% 45%,rgba(10,10,18,0) 35%,rgba(10,10,18,.62) 100%);
}

/* the loading ring, driven by --ld (126 down to 0) */
.ring{
  position:absolute;
  left:50%;
  bottom:clamp(20px,4vh,36px);
  width:40px;
  height:40px;
  transform:translateX(-50%) rotate(-90deg);
  color:var(--hero-ink-2);
  opacity:.9;
  transition:opacity var(--t-mid);
}
.ring circle{
  fill:none;
  stroke:currentColor;
  stroke-width:2;
  stroke-linecap:round;
  stroke-dasharray:126;
  stroke-dashoffset:var(--ld,126);
}
.stage.film-ready .ring{opacity:0}

/* the honest scroll cue that replaces a dead ring (hero.js builds span.cue) */
.cue{
  position:absolute;
  left:50%;
  bottom:clamp(20px,4vh,36px);
  width:40px;
  height:40px;
  display:flex;
  align-items:center;
  justify-content:center;
  transform:translateX(-50%);
  color:var(--hero-ink-2);
  opacity:.8;
}
.cue svg{width:24px;height:24px}
.hero.in.on-screen .cue svg{animation:cue-bob 2.4s var(--ease-inout) infinite;animation-delay:-1s}
@keyframes cue-bob{
  0%,100%{transform:translateY(-4px);opacity:.5}
  50%    {transform:translateY(4px);opacity:1}
}

/* ---- Bands ------------------------------------------------------------- */
.bands{
  position:absolute;
  inset:0;
  pointer-events:none;
}
.band{
  --k:0;
  position:absolute;
  opacity:0;
  pointer-events:none;
  text-shadow:var(--tshadow);
  color:var(--hero-ink);
  will-change:opacity;
  isolation:isolate;
}
.band .btn{text-shadow:none}

/* the per-band scrim: rides the band's opacity, deepens with --k, dies out by 76%.
   The box grows well past the text (a fixed px margin plus a share of the band)
   and the ellipse is 62% of that box, so the 76% die-out lands inside the box:
   no hard edge on any side, and the whole text zone sits inside the 46% stop.
   Peak alphas per band were tuned against the worst frame of each plateau
   (audit at 1440x900: every band's worst pixel clears 3.5:1). */
.band::before{
  content:"";
  position:absolute;
  inset:calc(-60% - 90px) calc(-24% - 140px);
  z-index:-1;
  pointer-events:none;
  opacity:calc(.25 + .75 * var(--k,1));
  background:radial-gradient(ellipse 62% 62% at 50% 50%,rgba(5,5,10,.74) 0%,rgba(5,5,10,.52) 46%,rgba(5,5,10,0) 76%);
}
.band-2::before{background:radial-gradient(ellipse 62% 62% at 50% 50%,rgba(5,5,10,.72) 0%,rgba(5,5,10,.5) 46%,rgba(5,5,10,0) 76%)}
.band-4::before{background:radial-gradient(ellipse 62% 62% at 50% 50%,rgba(5,5,10,.64) 0%,rgba(5,5,10,.44) 46%,rgba(5,5,10,0) 76%)}   /* Suryam 2026-09-09: slightly lighter than .76/.54, more of the frame shows */
.band-settle::before{background:radial-gradient(ellipse 62% 62% at 50% 50%,rgba(5,5,10,.7) 0%,rgba(5,5,10,.48) 46%,rgba(5,5,10,0) 76%)}

/* slide lanes: the banner sits on the left, its left edge on the nav
   wordmark's left edge (the gutter plus the .brand chip's 14px padding and
   1px border), 52vw wide up to 1100px; slide 2 rides the right third, slides
   3 and 4 the left, the settle band the left third; all vertically centred */
.band-banner{left:50%;width:min(50vw,1060px);top:44%;transform:translate(-50%,-50%)}
.band-banner::before{display:none}
.band-2{left:calc(200% / 3);right:var(--gutter);top:50%;transform:translateY(-50%)}
.band-3,
.band-4{left:clamp(24px,7vw,120px);top:50%;width:min(44vw,720px);transform:translateY(-50%)}
.band-settle{left:clamp(24px,7vw,120px);top:50%;width:min(36vw,560px);transform:translateY(-50%)}

/* every headline: H1, 300 with its emphasised word at 900 */
.band h1,
.band h2,
.band p.split{
  font:var(--t-h1);
  letter-spacing:var(--track-head);
}
.band-2 h1{max-width:10ch}
.band p.split{max-width:16ch}
.band-settle h2{max-width:14ch}
/* the eyebrow: a mono label with a short floodlight rule, above the headline */
/* the subline: Satoshi 400 at the sub clamp, arriving after the headline words */
.band .sub{
  margin-top:clamp(16px,2.8vh,30px);
  font:var(--t-sub);
  color:var(--hero-ink-2);
  max-width:38ch;
  --ks:clamp(0,(var(--k,0) - .5) * 3,1);
  opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 14px));
}
.band-settle .cta-row{
  display:flex;
  flex-wrap:wrap;
  gap:12px;
  margin-top:clamp(20px,3vh,32px);
  pointer-events:none;
}
/* the CTAs take clicks only while their band is on (hero.js toggles .is-on) */
.band.is-on .cta-row{pointer-events:auto}

/* ---- Split text ---------------------------------------------------------
   hero.js splits each .split into an .sr copy plus aria-hidden .w words of
   .c characters, each carrying --th, --jx, --jy, --jr from a seeded rng.
   The blur entrance adds a .split-soft copy under a .split-sharp copy.
   Words keep their own trailing space (white-space:pre). */
.split{position:relative;display:block}
.split .w{display:inline-block;white-space:pre}
.split .c{display:inline-block}
.split .c.em{font-style:normal;font-weight:900}

/* (a) scatter: per-character fly-in from seeded offsets */
[data-entrance="scatter"] .c,
[data-entrance="grid"] .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.6,1);
  opacity:var(--kc);
  transform:translate(calc((1 - var(--kc)) * var(--jx,0px)),calc((1 - var(--kc)) * var(--jy,0px))) rotate(calc((1 - var(--kc)) * var(--jr,0deg)));
}
/* (b) grid snap-align: the same engine, horizontal jitter and ordered thresholds set by JS */
[data-entrance="grid"] .c{
  transform:translate(calc((1 - var(--kc)) * var(--jx,0px)),0);
}

/* (c) blur-to-sharp: the sharp copy fades in with --k, the soft copy with a
   STATIC blur fades out. Two stacked copies, opacity only. */
[data-entrance="blur"] .split-soft{
  position:absolute;
  inset:0;
  filter:blur(10px);
  opacity:calc(1 - var(--k,0));
  transform:scale(calc(1.03 - .03 * var(--k,0)));
  transform-origin:left center;
  pointer-events:none;
  font:inherit;
}
[data-entrance="blur"] .split-sharp{
  position:relative;
  display:block;
  opacity:var(--k,0);
}
[data-entrance="blur"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0) * .5) * 1.6,1);
  transform:translateY(calc((1 - var(--kc)) * 8px));
}

/* (d) punch: word-level pop with overshoot and a slower settle */
[data-entrance="punch"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 3,1);
  --ks:clamp(0,(var(--k,0) - var(--th,0) - var(--sd,.1)) * var(--ss,3.2),1);
  opacity:var(--kc);
  transform:scale(calc(.6 + (.4 + var(--ov,.12)) * var(--kc) - var(--ov,.12) * var(--ks)));
}
[data-entrance="punch"] .w.em{--ov:.24;--sd:.16;--ss:2.6}

/* (e) rise: words rise in reading order, then the subline, then the CTA row */
[data-entrance="rise"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 3,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * .55em));
}
[data-entrance="rise"] .sub{
  --ks:clamp(0,(var(--k,0) - .66) * 4,1);
  opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 14px));
}
[data-entrance="rise"] .cta-row{
  --kb:clamp(0,(var(--k,0) - .78) * 5,1);
  opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb)) * 14px));
}

/* Everything k drives lives on a compositor layer of its own: an opacity or
   transform change on a layer is applied by the compositor with no paint and
   no raster, so the copy assembling in or out costs the film nothing. Without
   this the whole band (scrim included, most of the screen) re-rastered on
   every frame at both ends of a swipe, which is where the film hitched. */
.band::before,
.band .sub,
.band .cta-row,
[data-entrance="scatter"] .c,
[data-entrance="grid"] .c,
[data-entrance="blur"] .split-soft,
[data-entrance="blur"] .split-sharp,
[data-entrance="blur"] .w,
[data-entrance="punch"] .w,
[data-entrance="rise"] .w,
[data-entrance="drift"] .w,
[data-entrance="approach"] .split,
[data-entrance="approach"] .w{will-change:transform,opacity}

/* (f) drift-down: each word starts above its resting spot */
[data-entrance="drift"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.8,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * -24px));
}

/* (g) approach-from-depth: the line grows into place from slightly small */
[data-entrance="approach"] .split{
  --kc:var(--k,0);
  opacity:var(--kc);
  transform:scale(calc(.82 + .18 * var(--kc)));
  transform-origin:left center;
}
[data-entrance="approach"] .w{
  --kw:clamp(0,(var(--k,0) - var(--th,0) * .6) * 1.8,1);
  opacity:var(--kw);
}

/* ---- The banner (slide 1) ----------------------------------------------
   The nav wordmark enlarged: the same fills as .brand (letters in the brand
   blue, the A orange, MEDIA in the light ink at reduced opacity), enhanced a
   little: a linear sheen on the letters from #10AADC at the top to #1A81A1
   at the bottom (the SVG gradient #bn-sheen in the markup) and a soft blue
   glow beneath the wordmark that breathes over 6 s (opacity only). Letters
   rise 24px and fade in on --k with a per-glyph --th stagger (hero.js drives
   --k from the load ramp). No chip box behind it.

   The lens: .bn-lens is a second SVG stacked exactly over the wordmark. It
   carries the drifting montage clipped to the letterforms (the A excluded
   from #bn-clip, so it keeps its orange) and is masked to a circle of --r
   around --mx/--my, which hero.js eases toward the pointer. It fades on
   while the pointer is inside the banner (.is-lens) and off within 250 ms
   of leaving; letters outside the circle keep the blue at all times. The
   mono line under MEDIA appears while the pointer is anywhere over the
   banner. Fine pointers only; touch and reduced motion show no reveal. */
.banner{
  position:relative;
  width:100%;
  pointer-events:none;
}
.band-banner.is-on .banner{pointer-events:auto}
.banner::before{
  content:"";
  position:absolute;
  inset:-70% -16% -84%;
  z-index:-1;
  pointer-events:none;
  /* a wide, soft darkening calms the starfield behind the wordmark; the blue glow sits inside it */
  background:
    radial-gradient(ellipse 58% 48% at 50% 54%,rgba(16,170,220,.2) 0%,rgba(16,170,220,.07) 46%,rgba(16,170,220,0) 72%),
    radial-gradient(ellipse 64% 62% at 50% 52%,rgba(3,6,12,.66) 0%,rgba(3,6,12,.42) 42%,rgba(3,6,12,.14) 66%,rgba(3,6,12,0) 82%);
  opacity:.9;
}
.hero.on-screen .band-banner.is-on .banner::before{animation:bn-glow 6s var(--ease-inout) infinite alternate;animation-delay:-3s}
@keyframes bn-glow{from{opacity:.8}to{opacity:1}}
.bn{
  display:block;
  width:100%;
  height:auto;
  overflow:visible;
  /* a soft shadow lifts the wordmark off the stars */
  filter:drop-shadow(0 10px 26px rgba(0,0,0,.62)) drop-shadow(0 2px 5px rgba(0,0,0,.45));
}
/* KICKSTART a touch heavier: a thin stroke in the same sheen under the fill */
.bn-letters .bn-glyph:not(.bn-media){stroke:url(#bn-sheen);stroke-width:5;stroke-linejoin:round;paint-order:stroke fill}
.bn-glyph{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.2,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 24px));
}
.bn-media{opacity:calc(var(--kc) * .72)}
.bn-lens{
  --r:clamp(110px,9vw,170px);
  --mx:-1000px;
  --my:-1000px;
  position:absolute;
  left:0;
  top:0;
  width:100%;
  height:auto;
  overflow:visible;
  pointer-events:none;
  opacity:0;
  transition:opacity .25s var(--ease-out);
  -webkit-mask-image:radial-gradient(circle var(--r) at var(--mx) var(--my),#000 0 45%,transparent 100%);
  mask-image:radial-gradient(circle var(--r) at var(--mx) var(--my),#000 0 45%,transparent 100%);
}
@media (hover: hover) and (pointer: fine){
  .banner.is-lens .bn-lens{opacity:1}
  .banner.is-lens .bn-drift{animation:bn-drift 60s linear infinite alternate}
}
@keyframes bn-drift{from{transform:translateX(0)}to{transform:translateX(-4000px)}}
/* touch and reduced motion: the banner is static, no reveal, no line */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce){
  .bn-lens{display:none}
}
html[data-motion="reduced"] .bn-lens{display:none}
html[data-motion="reduced"] .banner::before{animation:none;opacity:.9}

/* ---- HUD ---------------------------------------------------------------- */
.hud{
  position:absolute;
  right:var(--gutter);
  bottom:clamp(20px,4vh,36px);
  display:flex;
  gap:8px;
  pointer-events:none;
}
.chip{
  display:inline-flex;
  align-items:center;
  gap:8px;
  min-height:30px;
  padding:0 12px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
  color:var(--hero-ink);
  background:rgba(8,8,15,.82);
  border:1px solid rgba(96,96,126,.3);
  border-radius:10px;
  text-shadow:0 1px 3px rgba(5,5,10,.85);
}
.hud .chip::before{
  content:"";
  width:5px;
  height:5px;
  border-radius:50%;
  background:var(--blue-bright);
}
/* shallow desktop windows keep the scrub but lose the small overlays */
@media (max-height:560px){.hud,.ring,.cue{display:none}}

/* ---- Static hero (phones, reduced motion) ------------------------------- */
.static-hero{
  display:none;
  position:relative;
  min-height:100vh;
  min-height:100svh;
  color:var(--hero-ink);
  text-shadow:var(--tshadow);
}
.static-hero::before{
  content:"";
  position:absolute;
  inset:0;
  background:
    linear-gradient(to top,rgba(5,5,10,.86) 0%,rgba(5,5,10,.5) 38%,rgba(5,5,10,.12) 62%,rgba(5,5,10,.3) 100%);
}
.static-copy{
  position:relative;
  display:flex;
  flex-direction:column;
  gap:clamp(14px,2.6vh,22px);
  padding:calc(var(--nav-h) + 24px) var(--gutter) clamp(40px,10vh,96px);
  min-height:inherit;
}
/* the banner wordmark at 86vw (the same look as the deck banner: sheen,
   orange A, light MEDIA, a soft glow beneath), then the settle lines pushed
   to the foot */
.static-brand{
  position:relative;
  width:86vw;
  max-width:100%;
  margin:clamp(12px,5vh,56px) 0 auto;
}
.static-brand::before{
  content:"";
  position:absolute;
  inset:-46% -8% -60%;
  pointer-events:none;
  background:radial-gradient(ellipse 56% 52% at 50% 58%,rgba(16,170,220,.22) 0%,rgba(16,170,220,.08) 46%,rgba(16,170,220,0) 72%);
  opacity:.55;
}
.static-banner{
  position:relative;
  display:block;
  width:100%;
  height:auto;
}
.static-title{
  font:var(--t-h1);
  letter-spacing:var(--track-head);
  max-width:14ch;
}
.static-sub{
  font:var(--t-sub);
  color:var(--hero-ink-2);
  max-width:34ch;
}
.static-hero .cta-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px}
.static-hero .btn{text-shadow:none}

/* the five static-hero gates, character-identical to GATES in hero.js */
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px), (prefers-reduced-motion: reduce){
  .hero{height:auto !important}
  .stage{display:none}
  .static-hero{
    display:block;
    background:#0B0D12 url("../img/hero-poster.jpg") 32% 50% / cover no-repeat;
  }
}
/* the user's own motion toggle, mirrored so the two paths agree */
html[data-motion="reduced"] .hero{height:auto !important}
html[data-motion="reduced"] .stage{display:none}
html[data-motion="reduced"] .static-hero{
  display:block;
  background:#0B0D12 url("../img/hero-poster.jpg") 32% 50% / cover no-repeat;
}
/* 16v: a phone shows a quarter of the desktop frame, so it gets its own crop of the same picture (same window, a fifth of the bytes) */
@media (max-width: 720px) and (orientation: portrait){
  .static-hero,html[data-motion="reduced"] .static-hero{background-image:url("../img/hero-poster-phone.jpg");background-position:39% 50%}
}
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px){
  .static-hero{background-image:url("../img/hero-poster-1376.jpg")}
}


/* --------------------------------------------------------------------------
   13 Sections, common
   Backgrounds stay transparent so the one ambient layer reads through.
   Each section opens on a hairline horizon with an orange glint that
   travels once on entry.
   -------------------------------------------------------------------------- */
.wrap{
  width:min(1240px,100% - 2 * var(--gutter));
  margin-inline:auto;
}
.wrap-wide{
  width:min(1480px,100% - 2 * var(--gutter));
  margin-inline:auto;
}

.section,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact){
  position:relative;
  padding:var(--section-pad) 0;
}
.section::before,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact)::before{
  content:"";
  position:absolute;
  top:0;
  left:var(--gutter);
  right:var(--gutter);
  height:1px;
  background:var(--line);
}
.section::after,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact)::after{
  content:"";
  position:absolute;
  top:0;
  left:var(--gutter);
  width:160px;
  height:1px;
  background:linear-gradient(90deg,transparent,var(--accent) 50%,transparent);
  opacity:0;
  transform:translateX(-160px);
  pointer-events:none;
}
.section.in::after,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact).in::after{
  animation:glint 2s var(--ease-inout) 1 both;
}
@keyframes glint{
  0%  {opacity:0;transform:translateX(-160px)}
  12% {opacity:1}
  88% {opacity:1}
  100%{opacity:0;transform:translateX(calc(100vw - 2 * var(--gutter)))}
}

.section-head{
  display:grid;
  gap:clamp(14px,2vh,22px);
}
.section-head .kicker{margin-bottom:6px}
.section h2,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact) h2{
  font:var(--t-h2);
  letter-spacing:var(--track-head);
  max-width:18ch;
}
.section h3,
:is(.stages,.services,.work,.descent,.clients,.bar,.faq,.contact) h3{
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
}

/* a glass panel, used sparingly */
.glass{
  background:color-mix(in oklab,var(--panel) 92%,transparent);
  border:1px solid var(--line);
  border-radius:var(--radius);
}

/* backdrops: a Higgsfield frame behind a section. A plain lazy img, object-fit
   cover, no parallax and never background-attachment. The img rides under the
   section's own stacking context (isolation) so the horizon hairline, the
   glint and every child paint above it. Its opacity rides --night: by day the
   canvas is light and the frames are dark, so they drop to a whisper; the
   scrim melts both seams into the canvas and pools it where the copy sits. */
.has-backdrop{isolation:isolate}
.backdrop{
  position:absolute;
  inset:0;
  z-index:-1;
  overflow:hidden;
  pointer-events:none;
}
.backdrop img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  opacity:var(--bd-op,calc(.11 + var(--night) * .21));
}
.backdrop::after{
  content:"";
  position:absolute;
  inset:0;
  background:
    linear-gradient(to bottom,var(--canvas) 0%,transparent 26%,transparent 72%,var(--canvas) 100%),
    radial-gradient(ellipse 110% 90% at 50% 50%,transparent 30%,color-mix(in oklab,var(--canvas) 55%,transparent) 100%);
}
/* the catwalk frame is bright sky: a step quieter, and a left pool under the copy */
.bar .backdrop img{--bd-op:calc(.06 + var(--night) * .2)}
.bar .backdrop::after{
  background:
    linear-gradient(90deg,color-mix(in oklab,var(--canvas) 70%,transparent) 0%,transparent 55%),
    linear-gradient(to bottom,var(--canvas) 0%,transparent 26%,transparent 72%,var(--canvas) 100%);
}
/* deep space behind the contact panel stays at whisper level */
.contact .backdrop img{--bd-op:calc(.05 + var(--night) * .17)}


/* --------------------------------------------------------------------------
   14 Stages
   Kicker and headline, then three cards on one orbital path. sections.js
   draws .orbit-draw with anime and moves the .orbit-dot group along it;
   .is-active moves between the li.stage-card items.
   -------------------------------------------------------------------------- */
.stages{min-height:190vh}
.stages > .wrap{position:sticky;top:0;min-height:100vh;display:flex;flex-direction:column;justify-content:center;padding-top:clamp(56px,8vh,96px);padding-bottom:clamp(40px,6vh,72px)}
.stages .kicker{margin-bottom:18px}
.orbit-wrap{
  position:relative;
  margin-top:clamp(56px,9vh,110px);
  margin-bottom:clamp(24px,4vh,48px);
  aspect-ratio:16 / 8;
}
svg.orbit{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  overflow:visible;
}
.orbit-path{
  fill:none;
  stroke:var(--line-strong);
  stroke-width:1;
  stroke-dasharray:3 9;
  stroke-linecap:round;
}
.orbit-draw{
  fill:none;
  stroke:var(--blue-bright);
  stroke-width:1.5;
  stroke-linecap:round;
}
.orbit-dot{will-change:transform}
.orbit-core{fill:var(--accent)}
.orbit-halo{
  fill:var(--accent-muted);
  transform-box:fill-box;
  transform-origin:center;
  opacity:0;
}
/* the section's one living element: the follower's halo breathes, only while
   the section is on screen (.on-screen is the IntersectionObserver's class) */
.stages.in.on-screen .orbit-halo{animation:halo 4.6s var(--ease-inout) infinite;animation-delay:-2s}
@keyframes halo{
  0%,100%{transform:scale(.6);opacity:.15}
  50%    {transform:scale(1.4);opacity:.6}
}

.stage-list{
  position:absolute;
  inset:0;
}
.stage-card{
  position:absolute;
  width:min(290px,23.5%);
}
/* four steps, low high low high, on the wave the line draws left to right */
.stage-card:nth-child(1){left:0;top:auto;bottom:0}
.stage-card:nth-child(2){left:25.5%;top:0}
.stage-card:nth-child(3){left:51%;top:auto;bottom:0}
.stage-card:nth-child(4){right:0;top:0}

.stage-card article{
  position:relative;
  display:grid;
  gap:10px;
  padding:clamp(20px,2.4vw,30px);
  border-radius:var(--radius);
  background:color-mix(in oklab,var(--panel) 92%,transparent);
  border:1px solid var(--line);
  transition:transform var(--t-mid);
  cursor:default;
  outline-offset:4px;
}
.stage-card article::after{
  content:"";
  position:absolute;
  inset:-1px;
  border-radius:inherit;
  border:1px solid color-mix(in oklab,var(--blue-bright) 55%,transparent);
  opacity:0;
  transition:opacity var(--t-mid);
  pointer-events:none;
}
.stage-name{font:var(--t-h3);letter-spacing:var(--track-h3);text-wrap:balance}
.stage-name b{font-weight:900}
.stage-when{
  display:flex;
  align-items:center;
  gap:10px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-secondary);
}
.stage-when::before{
  content:"";
  flex:0 0 auto;
  width:8px;
  height:8px;
  border-radius:50%;
  border:1px solid var(--text-secondary);
  transition:background-color var(--t-fast),border-color var(--t-fast);
}
.stage-promise{
  font:var(--t-body);
  color:var(--text-secondary);
  max-width:30ch;
}
.stage-card.is-active article,
.stage-card article:hover,
.stage-card article:focus-within{transform:translateY(-6px)}
.stage-card.is-active article::after,
.stage-card article:hover::after,
.stage-card article:focus-within::after{opacity:1}
.stage-card.is-active .stage-when::before{background:var(--accent);border-color:var(--accent)}


/* --------------------------------------------------------------------------
   15 Services
   An instrument panel: eight pillars in a hairline grid. Hover, focus or
   .is-open (sections.js) opens the sub-list through grid-template-rows.
   The row animation is a contract-directed exception to transform/opacity.
   -------------------------------------------------------------------------- */
.services-head{
  display:grid;
  grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(24px,4vw,64px);
  align-items:end;
}
.services-head .lede{max-width:44ch}

/* the list and the panel: hover or focus a name on the left and the one
   panel on the right shows its lines; the panel never changes size */
.svc{
  display:grid;
  grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
  gap:clamp(28px,5vw,80px);
  align-items:start;
  margin-top:clamp(40px,6vh,72px);
}
.svc-list{display:grid}
.svc-item{border-top:1px solid var(--line)}
.svc-item:last-child{border-bottom:1px solid var(--line)}
.svc-name{
  position:relative;
  display:flex;
  align-items:center;
  gap:16px;
  width:100%;
  min-height:44px;
  padding:clamp(14px,1.8vh,20px) 0 clamp(14px,1.8vh,20px) 26px;
  text-align:left;
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
  color:var(--text-secondary);
  border-radius:0;
  outline-offset:4px;
  transition:color var(--t-mid),padding-left var(--t-mid);
}
.svc-name::before{
  content:"";
  position:absolute;
  left:0;
  top:50%;
  width:8px;
  height:8px;
  border-radius:50%;
  border:1px solid var(--line-strong);
  transform:translateY(-50%) scale(.8);
  transition:background-color var(--t-mid),border-color var(--t-mid),transform var(--t-mid),box-shadow var(--t-mid);
}
.svc-item.is-active .svc-name,
.svc-name:hover,
.svc-name:focus-visible{color:var(--text-primary);padding-left:34px}
.svc-item.is-active .svc-name::before{background:var(--accent);border-color:var(--accent);transform:translateY(-50%) scale(1);box-shadow:0 0 10px 2px rgba(255,138,0,.45)}
.svc-detail{
  position:sticky;
  top:clamp(80px,14vh,140px);
  min-height:clamp(320px,38vw,420px);
  padding:clamp(24px,3vw,40px);
  border-radius:var(--radius);
  border:1px solid var(--line);
  background:color-mix(in oklab,var(--panel) 72%,transparent);
  overflow:hidden;
  isolation:isolate;
}
.svc-art{
  position:absolute;
  inset:0;
  z-index:-1;
  background:var(--art,none) 50% 50% / cover no-repeat;
  opacity:calc(.12 + var(--night) * .06);
  mix-blend-mode:screen;
  transition:opacity .6s var(--ease-out);
}
.svc-detail.is-swapping .svc-art{opacity:0}
.svc-detail[data-svc="content"]{--art:url("../img/services/content-creation-production.jpg")}
.svc-detail[data-svc="social"]{--art:url("../img/services/social-media-management.jpg")}
.svc-detail[data-svc="story"]{--art:url("../img/services/design-storytelling.jpg")}
.svc-detail[data-svc="identity"]{--art:url("../img/services/branding-visual-identity.jpg")}
.svc-detail[data-svc="paid"]{--art:url("../img/services/paid-media-digital-pr.jpg")}
.svc-detail[data-svc="consultancy"]{--art:url("../img/services/business-consultancy.jpg")}
.svc-detail[data-svc="tech"]{--art:url("../img/services/tech-development.jpg")}
.svc-detail[data-svc="seo"]{--art:url("../img/services/seo-growth-marketing.jpg")}
.svc-title{
  font:var(--t-h2);
  letter-spacing:var(--track-h2);
  max-width:14ch;
  text-wrap:balance;
  transition:opacity .3s var(--ease-out),transform .4s var(--ease-out);
}
.svc-lines{
  display:grid;
  gap:10px;
  margin-top:clamp(20px,3vh,32px);
  font:var(--t-body);
  color:var(--text-primary);
}
.svc-lines li{
  display:flex;
  align-items:baseline;
  gap:12px;
  opacity:0;
  transform:translateY(6px);
  animation:svc-in .5s var(--ease-out) forwards;
  animation-delay:calc(var(--i,0) * 60ms);
}
.svc-lines li::before{content:"";flex:0 0 auto;width:14px;height:1px;background:var(--blue-bright);transform:translateY(-.35em)}
@keyframes svc-in{to{opacity:1;transform:none}}
.svc-detail.is-swapping .svc-title{opacity:0;transform:translateY(4px)}
@media (max-width:820px){
  .svc{grid-template-columns:1fr}
  .svc-detail{position:static;min-height:0}
}

/* --------------------------------------------------------------------------
   15b The showreel
   One box, the film inside, a quiet bar of controls that shows on hover,
   focus or a pause; a big play button before the first play. reel.js owns
   .is-playing, .has-started, .is-muted, .is-full, .menu-open.
   -------------------------------------------------------------------------- */
.reel-head{
  display:grid;
  grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(24px,4vw,64px);
  align-items:end;
}
.reel-head .lede{max-width:40ch;justify-self:end}
.reel-box{
  position:relative;
  margin-top:clamp(32px,5vh,56px);
  aspect-ratio:16 / 9;
  border-radius:var(--radius);
  overflow:hidden;
  background:#000;
  border:1px solid var(--line);
  outline-offset:4px;
}
.reel-box:fullscreen{border-radius:0;border:0}
.reel-video{position:absolute;inset:0;width:100%;height:100%;display:block;background:#000;cursor:pointer}
.reel-ui{position:absolute;inset:0;pointer-events:none}
.reel-ui > *{pointer-events:auto}
.reel-big{
  position:absolute;
  left:50%;
  top:50%;
  transform:translate(-50%,-50%);
  display:inline-flex;
  align-items:center;
  gap:14px;
  padding:14px 26px 14px 16px;
  border-radius:999px;
  border:1px solid rgba(238,241,246,.35);
  background:rgba(5,7,12,.8);
  color:#eef1f6;
  font:var(--t-body);
  transition:transform var(--t-mid),background-color var(--t-fast),opacity var(--t-mid);
}
.reel-big:hover{transform:translate(-50%,-50%) scale(1.03);background:rgba(5,7,12,.7)}
.reel-big-ico{width:0;height:0;border-style:solid;border-width:9px 0 9px 15px;border-color:transparent transparent transparent var(--accent)}
.reel-box.has-started .reel-big{opacity:0;pointer-events:none}
.reel-bar{
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  display:flex;
  align-items:center;
  gap:10px;
  padding:34px 16px 14px;
  background:linear-gradient(to top,rgba(5,7,12,.82),rgba(5,7,12,0));
  color:#eef1f6;
  opacity:0;
  transform:translateY(6px);
  transition:opacity var(--t-mid),transform var(--t-mid);
}
.reel-box:hover .reel-bar,
.reel-box:focus-within .reel-bar,
.reel-box:not(.is-playing) .reel-bar,
.reel-box.menu-open .reel-bar{opacity:1;transform:none}
.reel-box:not(.has-started) .reel-bar{opacity:0;pointer-events:none}
.reel-btn{
  display:inline-grid;
  place-items:center;
  width:36px;
  height:36px;
  border-radius:10px;
  color:inherit;
  transition:background-color var(--t-fast);
}
.reel-btn:hover{background:rgba(238,241,246,.12)}
.reel-play .ico-play{width:0;height:0;border-style:solid;border-width:7px 0 7px 12px;border-color:transparent transparent transparent currentColor}
.reel-play .ico-pause{display:none;width:11px;height:14px;border-left:4px solid currentColor;border-right:4px solid currentColor}
.reel-box.is-playing .reel-play .ico-play{display:none}
.reel-box.is-playing .reel-play .ico-pause{display:block}
.reel-time{font:var(--t-label);letter-spacing:0;font-variant-numeric:tabular-nums;white-space:nowrap;opacity:.85}
.reel-scrub{position:relative;flex:1 1 auto;height:36px;display:flex;align-items:center}
.reel-scrub::before{content:"";position:absolute;left:0;right:0;height:3px;border-radius:2px;background:rgba(238,241,246,.22)}
.reel-buf,.reel-fill{position:absolute;left:0;right:0;height:3px;border-radius:2px;transform-origin:left;transform:scaleX(0);pointer-events:none}
.reel-buf{background:rgba(238,241,246,.35)}
.reel-fill{background:var(--accent)}
.reel-range{
  position:relative;
  z-index:1;
  width:100%;
  height:36px;
  margin:0;
  background:transparent;
  -webkit-appearance:none;
  appearance:none;
  cursor:pointer;
}
.reel-range::-webkit-slider-runnable-track{height:3px;background:transparent}
.reel-range::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;margin-top:-5.5px;border-radius:50%;background:var(--accent);border:0;opacity:0;transition:opacity var(--t-fast)}
.reel-range::-moz-range-track{height:3px;background:transparent}
.reel-range::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--accent);border:0;opacity:0}
.reel-scrub:hover .reel-range::-webkit-slider-thumb,.reel-range:focus-visible::-webkit-slider-thumb{opacity:1}
.reel-scrub:hover .reel-range::-moz-range-thumb,.reel-range:focus-visible::-moz-range-thumb{opacity:1}
.reel-q{position:relative}
.reel-qbtn{width:auto;padding:0 10px;font:var(--t-label);letter-spacing:var(--track-label);white-space:nowrap}
.reel-menu{
  position:absolute;
  right:0;
  bottom:calc(100% + 8px);
  min-width:120px;
  padding:6px;
  border-radius:12px;
  background:rgba(5,7,12,.92);
  border:1px solid rgba(238,241,246,.14);
}
.reel-mi{
  display:flex;
  align-items:center;
  justify-content:space-between;
  width:100%;
  min-height:34px;
  padding:0 10px;
  border-radius:8px;
  color:#eef1f6;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-align:left;
}
.reel-mi:hover{background:rgba(238,241,246,.1)}
.reel-mi[aria-checked="true"]::after{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent)}
.ico-vol,.ico-full{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ico-vol .vol-body{fill:currentColor}
.ico-vol .vol-off{display:none}
.reel-box.is-muted .ico-vol .vol-wave{display:none}
.reel-box.is-muted .ico-vol .vol-off{display:block}
.reel-big-txt{white-space:nowrap}
@media (max-width:820px){.reel-head{grid-template-columns:1fr}.reel-time .reel-sep,.reel-time .reel-dur{display:none}.reel-big{gap:10px;padding:11px 20px 11px 14px;font-size:15px}.reel-big-ico{border-width:7px 0 7px 12px}}

/* --------------------------------------------------------------------------
   16 What we do: one second after ignition
   A sticky 100vh stage inside a 480vh section. The film pair (fwd, rev) sits
   under two feathered scrims; the time-0 head, eight captions, the rail, the
   closing line and the outro column are each their own compositor layer and
   are written by ignition.js from the presented film frame. Phones, coarse
   pointers and reduced motion get the strip: eight stills, native scroll-snap.
   -------------------------------------------------------------------------- */
.ignition{padding:0}
.ignition.is-film,.ignition.is-stills{min-height:480vh}
.ignition.is-strip{padding:var(--section-pad) 0}
.ignition.is-film .ign-strip-wrap,.ignition.is-stills .ign-strip-wrap{display:none}
.ignition.is-strip .ign-stage{display:none}
.ignition::before,.ignition::after{z-index:2}
.ign-stage{
  position:sticky;
  top:0;
  height:100vh;
  height:100svh;
  overflow:hidden;
  background:#05070c;
  color:#EEF1F6;               /* the frame is always night: the ink stays light in the day theme */
  --text-primary:#EEF1F6;
  --accent-ink:#FFB347;
  --line-strong:rgba(238,241,246,.5);
  cursor:grab;
  touch-action:pan-y;
  user-select:none;
  -webkit-user-select:none;
}
.ign-stage.is-holding{cursor:grabbing}
.ign-rest,.ign-clip,.ign-still{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  pointer-events:none;
}
.ign-clip{opacity:0;will-change:transform}
.ign-clip.is-front{opacity:1}
.ign-still{opacity:0;will-change:opacity}
.is-film .ign-still{display:none}
.is-stills .ign-clip{display:none}
.ign-scrim{
  position:absolute;
  left:0;
  right:0;
  height:18%;
  pointer-events:none;
  z-index:1;
}
.ign-scrim-t{top:0;background:linear-gradient(to bottom,var(--canvas),transparent)}
.ign-scrim-b{bottom:0;background:linear-gradient(to top,var(--canvas),transparent)}
.ign-head{
  position:absolute;
  z-index:3;
  left:var(--gutter);
  top:clamp(96px,15vh,150px);
  max-width:min(600px,46vw);
  will-change:opacity;
}
.ign-head h2{max-width:none}
.ign-head .lede{margin-top:clamp(14px,2vh,22px);max-width:34ch}
.ign-head .accent,.ign-strip-head .accent{font:var(--t-accent);font-style:italic;color:var(--accent-ink)}
.ign-hint{margin-top:18px;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.55}
.ign-cap{
  position:absolute;
  z-index:3;
  width:min(380px,30vw);
  opacity:0;
  will-change:transform,opacity;
  pointer-events:none;
}
.ign-cap-l{left:calc(var(--gutter) + 1vw);top:44%}
.ign-cap-r{right:calc(var(--gutter) + 250px);top:38%;text-align:left}
.ign-cap[data-k="2"],.ign-cap[data-k="4"],.ign-cap[data-k="6"]{top:52%}
.ign-cap[data-k="3"],.ign-cap[data-k="7"]{top:46%}
.ign-cap.is-peek{opacity:.55 !important;transform:none !important;transition:opacity .18s var(--ease-out)}
.ign-anchor{
  display:block;
  width:120px;
  height:1px;
  margin-bottom:14px;
  overflow:visible;
}
.ign-anchor path{
  fill:none;
  stroke:var(--line-strong,rgba(238,241,246,.5));
  stroke-width:1;
  stroke-dasharray:120;
  stroke-dashoffset:120;
  transition:stroke-dashoffset .32s var(--ease-out);
}
.ign-cap.is-on .ign-anchor path{stroke-dashoffset:0}
.ign-name{font:var(--t-h3);font-size:clamp(24px,2.4vw,36px);letter-spacing:var(--track-h3);line-height:1.08}
.ign-lines{margin:14px 0 0;padding:0;list-style:none;display:grid;gap:5px}
.ign-lines li{font:var(--t-body);font-size:15px;line-height:1.4;opacity:.86}
.ign-rail{
  position:absolute;
  z-index:4;
  right:var(--gutter);
  top:50%;
  transform:translateY(-50%);
  contain:layout paint;
  transition:opacity .4s var(--t-mid);
}
.is-closing .ign-rail{opacity:0;pointer-events:none}
.ign-rail ul{margin:0;padding:0;list-style:none;display:grid;gap:6px;text-align:right}
.ign-rail-name{
  position:relative;
  display:block;
  padding:3px 0;
  font:var(--t-body);
  font-size:15px;
  line-height:1.3;
  color:var(--text-primary);
  opacity:.5;
  text-align:right;
  white-space:nowrap;
  transition:opacity .18s var(--ease-out);
}
.ign-rail-name .w3{font-weight:300;transition:opacity .22s var(--ease-out)}
.ign-rail-name .w9{position:absolute;inset:3px 0;font-weight:900;opacity:0;transition:opacity .22s var(--ease-out)}
.ign-rail-name:hover,.ign-rail-name:focus-visible{opacity:1}
.ign-rail-name.is-seen{opacity:.8}
.ign-rail-name.is-active{opacity:1}
.ign-rail-name.is-active .w3{opacity:0}
.ign-rail-name.is-active .w9{opacity:1}
.ign-close{
  position:absolute;
  z-index:3;
  left:var(--gutter);
  bottom:clamp(40px,9vh,96px);
  max-width:min(520px,40vw);
  font:var(--t-body);
  font-size:clamp(18px,1.5vw,22px);
  line-height:1.4;
  opacity:0;
  will-change:opacity;
}
.ign-outro{
  position:absolute;
  z-index:3;
  right:var(--gutter);
  bottom:clamp(40px,9vh,96px);
  width:min(640px,48vw);
  margin:0;
  padding:0;
  list-style:none;
  columns:2;
  column-gap:28px;
  opacity:0;
  will-change:opacity;
}
.ign-out{break-inside:avoid;margin:0 0 14px}
.ign-out-name{font:var(--t-h3);font-size:15px;letter-spacing:0;line-height:1.3}
.ign-out ul{margin:3px 0 0;padding:0;list-style:none}
.ign-out li{font:var(--t-body);font-size:12.5px;line-height:1.35;opacity:.8}
.is-peeking .ign-cap:not(.is-peek){opacity:0 !important}
/* the strip */
.ign-strip-head{display:grid;gap:14px;margin-bottom:clamp(22px,4vh,36px)}
.ign-strip-names{
  display:flex;
  flex-wrap:wrap;
  gap:4px 14px;
  margin:0 0 clamp(18px,3vh,28px);
  padding:0;
  list-style:none;
}
.ign-strip-name{font:var(--t-body);font-size:14px;font-weight:300;color:var(--text-primary);opacity:.6;padding:2px 0}
.ign-strip-name.is-active{font-weight:900;opacity:1}
.ign-strip{
  display:flex;
  gap:16px;
  margin:0 calc(-1 * var(--gutter));
  padding:0 var(--gutter);
  list-style:none;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.ign-strip::-webkit-scrollbar{display:none}
.ign-card{flex:0 0 min(78vw,360px);scroll-snap-align:center}
.ign-card img{display:block;width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:var(--radius);background:#05070c}
.ign-card-name{margin:14px 0 0;font:var(--t-h3);font-size:22px;letter-spacing:var(--track-h3)}
.ign-card-lines{margin:8px 0 0;padding:0;list-style:none;display:grid;gap:4px}
.ign-card-lines li{font:var(--t-body);font-size:14px;line-height:1.4;opacity:.85}
.ign-strip-close{margin:clamp(24px,4vh,40px) 0 0;max-width:34ch;font:var(--t-body);font-size:17px;line-height:1.45}
@media (max-width:1180px){
  .ign-cap-r{right:calc(var(--gutter) + 200px)}
  .ign-rail-name{font-size:13px}
  .ign-outro{width:min(560px,52vw)}
}

/* --------------------------------------------------------------------------
   16c The inner pages: Services, About, Careers, Contact
   -------------------------------------------------------------------------- */
.page-main{padding-top:0}
.page-head{padding-top:clamp(120px,20vh,200px);padding-bottom:clamp(40px,7vh,80px)}
.page-head::before{display:none}
.page-head h1{font:var(--t-h1,var(--t-h2));font-size:clamp(40px,5.6vw,84px);letter-spacing:var(--track-head);line-height:1.02;margin:0;max-width:16ch}
.page-head .lede{margin-top:clamp(16px,2.4vh,26px);max-width:52ch}
.page-head .mono{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.6;margin:0 0 18px}
.page-close .display{font:var(--t-h2);letter-spacing:var(--track-head);max-width:22ch;margin:0 0 26px}
.page-close .btn + .btn{margin-left:10px}
/* services */
.svp-grid{display:grid;grid-template-columns:240px minmax(0,1fr);gap:clamp(28px,5vw,80px);align-items:start}
.svp-index{position:sticky;top:clamp(96px,14vh,140px)}
.svp-index ul{margin:0;padding:0;list-style:none;display:grid;gap:8px}
.svp-index a{font:var(--t-body);font-size:15px;font-weight:300;color:var(--text-primary);opacity:.55;transition:opacity .2s,font-weight .2s}
.svp-index a:hover,.svp-index a.is-active{opacity:1}
.svp-index a.is-active{font-weight:900}
.svp-list{display:grid;gap:clamp(48px,9vh,110px)}
.svp-item{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(20px,3vw,40px);align-items:center;scroll-margin-top:120px}
.svp-item:nth-child(even) .svp-still{order:2}
.svp-still img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;border-radius:var(--radius)}
.svp-body h2{font:var(--t-h2);font-size:clamp(26px,2.8vw,40px);letter-spacing:var(--track-head);margin:0}
.svp-how{margin:14px 0 0;font:var(--t-body);line-height:1.5;max-width:44ch}
.svp-lines{margin:16px 0 0;padding:0;list-style:none;display:grid;gap:6px}
.svp-lines li{font:var(--t-body);font-size:15px;line-height:1.4;opacity:.8;padding-left:14px;position:relative;transition:opacity .24s,font-weight .24s}
.svp-lines li.is-read{font-weight:900;opacity:1}
.svp-lines li::before{content:"";position:absolute;left:0;top:.62em;width:5px;height:5px;border-radius:50%;background:var(--accent)}
/* about and careers */
.about-two{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(28px,5vw,80px);align-items:start}
.about-two h2{font:var(--t-h2);letter-spacing:var(--track-head);margin:0;max-width:12ch}
.about-two .mono{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.6;margin:14px 0 0}
.about-copy{display:grid;gap:18px;max-width:58ch}
.about-copy p{margin:0;font:var(--t-body);font-size:clamp(17px,1.3vw,20px);line-height:1.55}
.minds{margin:clamp(36px,6vh,64px) 0 0;padding:0;list-style:none;display:grid;gap:clamp(20px,3vh,32px);counter-reset:mind}
.minds .mind{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(16px,3vw,48px);padding-top:clamp(18px,3vh,28px);border-top:1px solid var(--line)}
.minds .mind h3{font:var(--t-h3);font-size:clamp(22px,2.2vw,32px);letter-spacing:var(--track-h3);margin:0}
.minds .mind p{margin:0;font:var(--t-body);line-height:1.5;max-width:48ch}
.minds-tight{margin-top:clamp(28px,4vh,44px)}
.memo{max-width:760px}
.memo .mono{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.6;margin:0 0 26px}
.memo-body{display:grid;gap:18px}
.memo-body p{margin:0;font:var(--t-body);font-size:clamp(19px,1.6vw,24px);line-height:1.5}
.memo-sign{margin:32px 0 0;display:grid;gap:4px}
.memo-sign .display{font:var(--t-h3);font-size:clamp(22px,2vw,30px);letter-spacing:var(--track-h3);color:var(--accent-ink)}   /* 16s: the name written larger */
.memo-sign .mono{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.6}
.page-contact .contact{padding-top:clamp(120px,20vh,200px)}
.where{margin:18px 0 0;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;opacity:.55}
.page-contact .contact::before{display:none}
@media (max-width:820px){
  .svp-grid{grid-template-columns:1fr}
  .svp-index{position:static}
  .svp-index ul{display:flex;flex-wrap:wrap;gap:4px 14px}
  .svp-item,.about-two,.minds .mind{grid-template-columns:1fr}
  .svp-item:nth-child(even) .svp-still{order:0}
}

/* --------------------------------------------------------------------------
   16h What we do: the eight titles, and the launch that opens the cards
   -------------------------------------------------------------------------- */
.wwd-grid{
  display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(32px,5vw,96px);
  align-items:center;
}
.wwd-left h2{margin:0}
.wwd-titles{
  margin:clamp(28px,4vh,44px) 0 0;
  padding:0;
  list-style:none;
  counter-reset:svc;
  display:grid;
}
.wwd-title{
  counter-increment:svc;
  position:relative;
  padding:14px 0 14px 52px;
  border-top:1px solid var(--line);
  font:var(--t-h3);
  font-size:clamp(19px,1.6vw,25px);
  letter-spacing:var(--track-h3);
  line-height:1.15;
  transition:color .25s,padding-left .35s var(--ease-out);
}
.wwd-title::before{
  content:counter(svc,decimal-leading-zero);
  position:absolute;
  left:0;
  top:17px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  opacity:.55;
  transition:color .25s,opacity .25s;
}
.wwd-title.is-lit{color:var(--accent-ink);padding-left:60px}
/* 16s: a small icon beside each pointer, and the same icon as a watermark on its card once the hangar opens */
.wwd-ico{display:inline-block;width:.95em;height:.95em;margin-right:.45em;vertical-align:-.12em;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;opacity:.65;transition:opacity .25s}
.wwd-title.is-lit .wwd-ico{opacity:1}
.wwd-wm{position:absolute;right:-10px;bottom:-12px;width:112px;height:112px;fill:none;stroke:currentColor;stroke-width:.8;stroke-linecap:round;stroke-linejoin:round;opacity:.07;pointer-events:none}
.wwd-title.is-lit::before{color:var(--accent-ink);opacity:1}
.wwd-right{display:grid;justify-items:center;gap:18px}
.wwd-launch{
  --p:0;
  position:relative;
  width:min(240px,22vw);
  aspect-ratio:1;
  border-radius:50%;
  color:var(--text-primary);
  background:radial-gradient(closest-side,rgba(255,138,0,calc(.06 + var(--p) * .22)),transparent 78%);
  display:grid;
  place-items:center;
  cursor:pointer;
  user-select:none;
  -webkit-user-select:none;
  touch-action:none;
  transition:transform .3s var(--ease-out);
}
.wwd-launch:active,.wwd.is-holding .wwd-launch{transform:scale(.97)}
/* the rumble behind the ring while it is held: a glow that grows with the
   fill and shivers 1 to 2 px at about 30 Hz (translate only, no layout).
   Section 23 stops the animation under reduced motion. */
.wwd-launch::before{
  content:"";
  position:absolute;
  inset:-14%;
  border-radius:50%;
  background:radial-gradient(closest-side,rgba(255,138,0,.34),rgba(255,138,0,.1) 55%,transparent 74%);
  opacity:0;
  scale:.85;
  pointer-events:none;
  transition:opacity .35s var(--ease-out),scale .35s var(--ease-out);
}
.wwd.is-holding:not(.is-open) .wwd-launch::before{
  opacity:calc(.25 + var(--p) * .75);
  scale:calc(.9 + var(--p) * .3);
  animation:wwd-rumble .13s linear infinite;
}
.wwd.is-open .wwd-launch::before{opacity:.35;scale:1.05}
@keyframes wwd-rumble{
  0%{translate:0 0}
  20%{translate:1.5px -1px}
  40%{translate:-1px 1.5px}
  60%{translate:2px .5px}
  80%{translate:-1.5px -1.5px}
  100%{translate:0 0}
}
.wwd-ring{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
.wwd-ring circle{fill:none;stroke-width:1.5}
.wwd-ring-track{stroke:var(--line)}
.wwd-ring-fill{
  stroke:var(--accent);
  stroke-linecap:round;
  stroke-dasharray:339.3;
  stroke-dashoffset:calc(339.3 * (1 - var(--p)));
  filter:drop-shadow(0 0 6px rgba(255,138,0,.6));
}
/* one line, centred in the ring: the hold instruction, or Launched once the cards are open */
.wwd-launch-text{position:relative;display:grid;justify-items:center;text-align:center;padding:0 12%}
.wwd-launch-line,.wwd-launch-alt,.wwd-launch-done{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;font-size:13px;line-height:1.9}
.wwd-launch-line kbd{font:inherit;padding:2px 7px;border:1px solid var(--line);border-radius:6px;margin:0 2px}
.wwd-launch-alt,.wwd-launch-done{display:none}
@media (pointer:coarse){.wwd-launch-line{display:none}.wwd-launch-alt{display:block}}
.wwd.is-open .wwd-launch-line,.wwd.is-open .wwd-launch-alt{display:none}
.wwd.is-open .wwd-launch-done{display:block;color:var(--accent-ink)}
.wwd-hangar{display:grid;grid-template-rows:0fr;transition:grid-template-rows .65s var(--ease-out)}
.wwd.is-open .wwd-hangar{grid-template-rows:1fr}
.wwd-cards{
  min-height:0;
  overflow:hidden;
  margin:0;
  padding:clamp(28px,5vh,56px) 0 0;
  list-style:none;
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:16px;
}
.wwd-card{
  position:relative;
  overflow:hidden;
  padding:18px 20px 22px;
  border-radius:14px;
  border:1px solid var(--line);
  background:var(--surface-1,rgba(238,241,246,.04));
  display:grid;
  gap:12px;
  align-content:start;
  opacity:0;
  transform:translate3d(0,26px,0);
  transition:opacity .35s var(--ease-out),transform .55s var(--ease-out);
  transition-delay:0s;
}
.wwd.is-open .wwd-card{opacity:1;transform:none;transition-delay:calc(var(--k,0) * 55ms + 120ms)}
.wwd-name{margin:0;font:var(--t-h3);font-size:clamp(17px,1.3vw,20px);letter-spacing:var(--track-h3);line-height:1.15}
.wwd-lines{margin:0;padding:0;list-style:none;display:grid;gap:5px}
.wwd-lines li{font:var(--t-body);font-size:14px;line-height:1.4;opacity:.82}
.wwd .services-close{margin-top:clamp(40px,7vh,80px)}
@media (max-width:1180px){.wwd-cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:820px){.wwd-grid{grid-template-columns:1fr}.wwd-right{margin-top:24px}.wwd-launch{width:min(192px,48vw)}.wwd-cards{grid-template-columns:1fr}}

.services-close{
  margin-top:clamp(48px,8vh,88px);
  font:var(--t-sub);
  max-width:36ch;
}


/* --------------------------------------------------------------------------
   16 Work
   A horizontal rail. sections.js drives .work-track with a transform (anime
   draggable), keyboard and wheel; the Tata tile carries the before/after
   compare, whose --split (0..1) and clip-path are written by JS.
   -------------------------------------------------------------------------- */
.work .wrap h2{max-width:20ch}

.rail{
  position:relative;
  margin-top:clamp(40px,6vh,72px);
  padding:8px max(var(--gutter),calc((100% - 1240px) / 2)) 28px;
  overflow:hidden;
  cursor:grab;
  outline-offset:-4px;
}
.rail:not(.is-scrollable){cursor:auto}
.work-track{
  display:flex;
  align-items:start;
  gap:clamp(16px,2vw,28px);
  width:max-content;
  will-change:transform;
  touch-action:pan-y;
}
.work-track.is-grabbed{cursor:grabbing}
.work-track.is-grabbed a,
.work-track.is-grabbed img{pointer-events:none}

.work .tile{
  position:relative;
  flex:0 0 min(520px,78vw);
  display:grid;
  grid-template-rows:auto 1fr;
  border-radius:calc(var(--radius) + 4px);
  background:var(--panel);
  border:1px solid var(--line);
  overflow:hidden;
}
/* the hover lift lives on the children, never on the .rv tile itself */
.tile-media,
.tile-copy{transition:transform var(--t-mid)}
.work .tile:hover .tile-media,
.work .tile:hover .tile-copy{transform:translateY(-4px)}

/* media masked by the visor curve at its foot */
.tile-media{
  position:relative;
  aspect-ratio:16 / 10;
  overflow:hidden;
  background:color-mix(in oklab,var(--blue) 18%,var(--panel));
  border-radius:0 0 50% 50% / 0 0 40% 40%;
}
.tile-media img{
  width:100%;
  height:100%;
  object-fit:cover;
  transition:transform 1.4s var(--ease-out);
}
.work .tile:hover .tile-media:not(.compare) img{transform:scale(1.03)}

.tile-copy{
  display:grid;
  gap:12px;
  align-content:start;
  padding:clamp(20px,2.4vw,30px);
}
.work .tile-brand{
  display:flex;
  align-items:center;
  gap:10px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-secondary);
}
.tile-brand::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--blue-bright)}
.tile-line{
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
  max-width:26ch;
  color:var(--text-primary);
}
.tile-num{
  margin-top:6px;
  padding-top:14px;
  border-top:1px solid var(--line);
  font:var(--t-body);
  color:var(--text-primary);
}
/* the tile readout is a sentence of figures inside a fixed 520px card: Data face
   and weight, held at the floor of the Data clamp so it stays a readout, not a wall */
.tile-num .num{font-size:1.22rem;line-height:1;vertical-align:-.03em;color:var(--text-primary);padding:0 .06em}

/* before/after: --split is the reveal position 0..1, written by JS and the range */
.compare{
  --split:.5;
  touch-action:pan-y;
  user-select:none;
  -webkit-user-select:none;
  cursor:ew-resize;
}
.compare img{
  position:absolute;
  inset:0;
  pointer-events:none;
}
.compare .after{clip-path:inset(0 0 0 50%)}
.compare-handle{
  position:absolute;
  inset:0 auto 0 0;
  width:100%;
  border-right:1px solid rgba(238,241,246,.9);
  transform:translateX(calc(var(--split) * 100% - 100%));
  pointer-events:none;
}
.compare-handle::after{
  content:"";
  position:absolute;
  top:50%;
  right:0;
  width:40px;
  height:40px;
  border-radius:50%;
  transform:translate(50%,-50%);
  border:1px solid rgba(238,241,246,.9);
  background:rgba(8,8,15,.82);
  background-image:
    linear-gradient(90deg,transparent 0 12px,rgba(238,241,246,.9) 12px 13px,transparent 13px 100%),
    linear-gradient(90deg,transparent 0 26px,rgba(238,241,246,.9) 26px 27px,transparent 27px 100%);
}
.compare-range{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  margin:0;
  opacity:0;
  cursor:ew-resize;
  -webkit-appearance:none;
  appearance:none;
}
.compare:focus-within{outline:2px solid var(--accent);outline-offset:-2px}

.work-foot{margin-top:clamp(20px,3vh,32px)}


/* --------------------------------------------------------------------------
   16b The descent
   The five Higgsfield frames in order, a film strip. A frame is a button:
   press returns the page to that moment while the scrub is on (sections.js
   sets aria-disabled and .scrub-off on the section otherwise); rest on it
   and its segment plays over the still (.is-playing). Below 1024 px the
   strip becomes a snap scroller inside its own overflow box.
   -------------------------------------------------------------------------- */
.descent .kicker{margin-bottom:18px}
.descent .lede{margin-top:clamp(14px,2vh,22px);max-width:50ch}
html[data-scrub="off"] .frame-hint{display:none}
.frames-wrap{
  margin-top:clamp(40px,6vh,72px);
  padding:0 max(var(--gutter),calc((100% - 1480px) / 2));
}
.frames{
  display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:clamp(12px,1.6vw,22px);
}
.frame{display:grid;gap:12px;align-content:start}
.frame-jump{
  position:relative;
  display:block;
  width:100%;
  aspect-ratio:16 / 9;
  border-radius:calc(var(--radius) - 6px);
  overflow:hidden;
  background:var(--panel);
  border:1px solid var(--line);
  outline-offset:3px;
  -webkit-tap-highlight-color:transparent;
  transition:transform var(--t-mid),border-color var(--t-mid);
}
.frame-jump[aria-disabled="true"]{cursor:default}
.frame-jump:hover,
.frame-jump:focus-visible,
.frame-jump.is-playing{transform:translateY(-4px);border-color:var(--line-strong)}
.frame-still,
.frame-clip{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
}
.frame-still{transition:transform 1.4s var(--ease-out)}
.frame-jump:hover .frame-still{transform:scale(1.03)}
.frame-clip{
  opacity:0;
  transition:opacity var(--t-mid);
}
.frame-jump.is-playing .frame-clip{opacity:1}
/* the frame's LED: lit while its shot plays */
.frame-jump::after{
  content:"";
  position:absolute;
  top:12px;
  right:12px;
  width:6px;
  height:6px;
  border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 10px 2px rgba(255,138,0,.55);
  opacity:0;
  transition:opacity var(--t-fast);
}
.frame-jump.is-playing::after{opacity:1}
.frame-cap{
  display:flex;
  align-items:baseline;
  gap:10px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
  color:var(--text-secondary);
  transition:color var(--t-fast);
}
.frame-index{color:var(--accent-ink)}
.frame:hover .frame-cap,
.frame:focus-within .frame-cap{color:var(--text-primary)}


/* --------------------------------------------------------------------------
   17 Clients
   Centred. Eight marks in currentColor, every box the same height; hover
   or focus takes the accent and shows the name in mono.
   -------------------------------------------------------------------------- */
.clients .wrap{text-align:center}
.clients .kicker{margin-bottom:18px}
.clients h2{margin-inline:auto}
.marks{
  --mark-h:44px;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  align-items:center;
  gap:6px clamp(8px,2vw,28px);
  margin-top:clamp(44px,7vh,80px);
  padding:0;
}
/* the brands sit closer to the deck's end and flow straight into the services */
.clients{padding-top:clamp(48px,8vh,96px);padding-bottom:clamp(24px,4vh,48px)}
.mark{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  height:96px;
  padding:0 clamp(12px,2vw,28px);
  color:var(--text-primary);
  opacity:.7;
  transition:color var(--t-mid),opacity var(--t-mid);
  outline-offset:-4px;
  border-radius:12px;
}
.mark-svg{
  display:block;
  height:var(--mark-h);
  width:auto;
  max-width:min(220px,40vw);
  fill:currentColor;
  transition:transform var(--t-mid);
}
.mark-svg *{fill:currentColor}
.mark-name{
  position:absolute;
  left:50%;
  bottom:6px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
  white-space:nowrap;
  color:var(--accent-ink);
  opacity:0;
  transform:translate(-50%,6px);
  transition:opacity var(--t-fast),transform var(--t-fast);
}
/* the compact lockups sit taller so the row reads at one optical weight */
.mark[data-name="Tata Technologies"] .mark-svg{height:calc(var(--mark-h) * 1.3)}
.mark:focus-visible,
.mark.is-hot{color:var(--accent-ink);opacity:1;z-index:3}
@media (hover:hover) and (pointer:fine){.mark:hover{color:var(--accent-ink);opacity:1;z-index:3}}
/* marks only: the colour lifts on hover, nothing else moves (decision 16) */
.mark:focus-visible .mark-svg{transform:translateY(-3px)}
@media (hover:hover) and (pointer:fine){.mark:hover .mark-svg{transform:translateY(-3px)}}
.mark-img{
  position:relative;
  display:block;
  height:calc(var(--mark-h) * var(--mh,1));
  width:calc(var(--mark-h) * var(--mh,1) * var(--ar,3));
  max-width:min(184px,40vw);
  transition:transform var(--t-mid);
}
.mark-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block;opacity:.7;transition:opacity var(--t-mid)}
/* 16s: every mark turns orange on hover; a raster mark does it through its own shape as a mask */
/* 16s: every mark turns orange on hover; a raster mark swaps to its orange copy (assets/logos/*-hot), which loads from disk too */
.mark-img .ink-hot{display:block;opacity:0}
.mark:focus-visible .mark-img .ink-light,.mark:focus-visible .mark-img .ink-dark,.mark.is-hot .mark-img .ink-light,.mark.is-hot .mark-img .ink-dark{opacity:0}
@media (hover:hover) and (pointer:fine){.mark:hover .mark-img .ink-light,.mark:hover .mark-img .ink-dark{opacity:0}}
.mark:focus-visible .mark-img .ink-hot,.mark.is-hot .mark-img .ink-hot{opacity:1}
@media (hover:hover) and (pointer:fine){.mark:hover .mark-img .ink-hot{opacity:1}}
.mark-img .ink-dark,html[data-look="day"] .mark-img .ink-light{display:none}
html[data-look="day"] .mark-img .ink-dark{display:block}
/* the inline vector marks keep their currentColor lift; images lift by opacity */
.mark:focus-visible .mark-img{transform:translateY(-3px)}
@media (hover:hover) and (pointer:fine){.mark:hover .mark-img{transform:translateY(-3px)}}
.mark-word{
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
  white-space:nowrap;
}
.clients-explore{margin:clamp(28px,4vh,44px) 0 0;text-align:center}

.clients-line{
  margin:clamp(32px,5vh,56px) auto 0;
  text-align:center;
  font:var(--t-sub);
  max-width:34ch;
}


/* --------------------------------------------------------------------------
   18 Bar: hold to walk the tower
   Left: the hold button. Right: five fittings on a vertical line that draws
   down as --hold (0..1, written on .bar by sections.js) rises. States:
   .is-holding on .hold and .bar, .lit on .fit, .shipped on .bar.
   -------------------------------------------------------------------------- */
.bar{--hold:0}
.walk{
  display:grid;
  grid-template-columns:minmax(0,.7fr) minmax(0,1.3fr);
  gap:clamp(40px,6vw,96px);
  align-items:start;
  margin-top:clamp(40px,6vh,72px);
}

.hold{
  position:relative;
  width:148px;
  height:148px;
  border-radius:50%;
  border:1px solid var(--line-strong);
  background:color-mix(in oklab,var(--panel) 92%,transparent);
  color:var(--text-primary);
  display:grid;
  place-items:center;
  padding:18px;
  font:700 .95rem/1.3 var(--font-sub);
  letter-spacing:.005em;
  text-align:center;
  touch-action:none;
  user-select:none;
  -webkit-user-select:none;
  -webkit-tap-highlight-color:transparent;
  transition:transform var(--t-fast),border-color var(--t-mid);
  cursor:pointer;
}
.hold-ring{
  position:absolute;
  inset:-1px;
  pointer-events:none;
}
.hold-ring svg{
  width:100%;
  height:100%;
  transform:rotate(-90deg);
  overflow:visible;
}
.hold-ring circle{
  fill:none;
  stroke-width:2;
  stroke-linecap:round;
}
.hold-track{stroke:transparent}
.hold-fill{
  stroke:var(--accent);
  stroke-dasharray:138.2;
  stroke-dashoffset:calc(138.2 * (1 - var(--hold)));
}
.hold-label{position:relative;z-index:1}
/* the section's living element: the ring breathes while it waits */
.hold::before{
  content:"";
  position:absolute;
  inset:-10px;
  border-radius:50%;
  border:1px solid var(--accent-muted);
  opacity:0;
}
.bar.in.on-screen:not(.shipped) .hold:not(.is-holding)::before{animation:hold-breathe 4.8s var(--ease-inout) infinite;animation-delay:-1.4s}
@keyframes hold-breathe{
  0%,100%{transform:scale(.92);opacity:0}
  50%    {transform:scale(1.06);opacity:1}
}
.hold:hover{transform:scale(1.03)}
.hold.is-holding{transform:scale(.95)}
.bar.shipped .hold{border-color:var(--accent);cursor:default}

.walk-col{
  position:relative;
  padding-left:44px;
}
.walk-line{
  position:absolute;
  left:9px;
  top:10px;
  bottom:10px;
  width:8px;
  height:auto;
  overflow:visible;
}
.walk-line path{
  fill:none;
  stroke-width:1;
  stroke-linecap:round;
}
.walk-track{stroke:var(--line)}
.walk-draw{
  stroke:var(--blue-bright);
  stroke-dasharray:1;
  stroke-dashoffset:calc(1 - var(--hold));
}
.fit{
  position:relative;
  padding:clamp(14px,2vh,22px) 0;
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
  color:var(--text-primary);
  max-width:34ch;
}
.fit + .fit{border-top:1px solid var(--line)}
.fit-text{
  display:block;
  opacity:.62;
  transition:opacity var(--t-mid);
}
.fit-dot{
  position:absolute;
  left:-37.5px;
  top:50%;
  width:13px;
  height:13px;
  border-radius:50%;
  border:1px solid var(--text-secondary);
  background:transparent;
  transform:translateY(-50%);
  transition:transform var(--t-fast),border-color var(--t-fast);
}
.fit-dot::after{
  content:"";
  position:absolute;
  inset:-1px;
  border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 12px 3px rgba(255,138,0,.55);
  opacity:0;
  transition:opacity var(--t-fast);
}
.fit.lit .fit-text{opacity:1}
.fit.lit .fit-dot{transform:translateY(-50%) scale(1.2);border-color:var(--accent)}
.fit.lit .fit-dot::after{opacity:1}

/* the earned block; scoped under .walk because #bar itself takes .shipped */
.walk .shipped{
  display:grid;
  gap:18px;
  justify-items:start;
  margin-top:clamp(28px,4vh,44px);
  opacity:0;
  transform:translateY(14px);
  transition:opacity .9s var(--ease-out),transform .9s var(--ease-out);
}
.bar:not(.shipped) .walk .shipped{visibility:hidden}
.shipped-line{
  font:var(--t-h1);
  letter-spacing:var(--track-head);
}
.bar.shipped .walk .shipped{opacity:1;transform:none}


/* --------------------------------------------------------------------------
   19 FAQ
   Two columns: the headline holds still on the left, the questions stack
   on the right. sections.js toggles .is-open and .is-closing on details;
   the answer animates through grid rows.
   -------------------------------------------------------------------------- */
.faq .wrap{display:block}
.faq h2{margin-bottom:clamp(32px,5vh,56px)}
/* the six questions run in two columns of three under the headline, so the
   bar, the questions and the contact panel never stamp the same skeleton */
.qa{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 clamp(24px,4vw,64px);
  border-bottom:1px solid var(--line);
}
.q{border-top:1px solid var(--line)}
.q summary{
  display:flex;
  align-items:baseline;
  gap:18px;
  padding:clamp(20px,2.6vh,30px) 0;
  min-height:44px;
  list-style:none;
  cursor:pointer;
  font:var(--t-h3);
  letter-spacing:var(--track-h3);
  color:var(--text-primary);
  outline-offset:4px;
}
.q summary::-webkit-details-marker{display:none}
.q-index{
  flex:0 0 auto;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
  color:var(--text-secondary);
}
.q-text{flex:1 1 auto}
.q summary::after{
  content:"";
  flex:0 0 auto;
  width:10px;
  height:10px;
  margin-top:.35em;
  border-right:1px solid var(--text-secondary);
  border-bottom:1px solid var(--text-secondary);
  transform:rotate(45deg);
  transition:transform var(--t-mid);
}
.q.is-open summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.q .a{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .5s var(--ease-out);
}
.q.is-open .a{grid-template-rows:1fr}
.q .a > div{
  overflow:hidden;
  min-height:0;
}
.q .a p{
  padding:2px 0 clamp(22px,2.8vh,34px) 0;
  font:var(--t-body);
  line-height:1.6;
  color:var(--text-primary);
  max-width:52ch;
  opacity:0;
  transition:opacity .45s var(--ease-out);
}
.q.is-open .a p{opacity:.92}
/* without the JS toggle, a plain closed <details> still behaves */
.q:not([open]) .a{display:none}


/* --------------------------------------------------------------------------
   20 Contact
   Split: the invitation left, the form in a panel right. Labels float over
   the field; the placeholder appears on focus.
   States on form.lead: .is-sending, .is-sent, .is-error
   -------------------------------------------------------------------------- */
.contact .wrap{
  display:grid;
  grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:clamp(40px,6vw,96px);
  align-items:start;
}
.contact-head{
  position:sticky;
  top:calc(var(--nav-h) + 24px);
  display:grid;
  gap:clamp(14px,2vh,22px);
}

.contact-head .kicker{margin-bottom:18px}
.contact-head .lede{max-width:34ch;margin-top:16px}
/* the direct ways, under the invitation: a label and a link per line */
.ways{
  display:flex;
  flex-wrap:wrap;
  gap:10px;
  margin-top:clamp(24px,4vh,40px);
}
.way{
  display:inline-flex;
  align-items:center;
  gap:10px;
  min-height:44px;
  padding:0 16px 0 10px;
  border-radius:999px;
  border:1px solid var(--line-strong);
  background:color-mix(in oklab,var(--panel) 55%,transparent);
  color:var(--text-primary);
  font:var(--t-small);
  transition:border-color var(--t-fast),color var(--t-fast),transform var(--t-fast);
}
@media (hover:hover) and (pointer:fine){.way:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}}
.way-ico{
  display:inline-grid;
  place-items:center;
  width:26px;
  height:26px;
  border-radius:50%;
  background:color-mix(in oklab,var(--accent) 18%,transparent);
  color:var(--accent);
  font:var(--t-label);
  letter-spacing:0;
  text-transform:lowercase;
}
.lead{
  position:relative;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(18px,2.4vh,26px) clamp(18px,2.4vw,32px);
  padding:clamp(24px,3.4vw,48px) clamp(24px,3.4vw,48px) clamp(40px,5vw,72px);
  /* the visor curve holds the panel's foot: the signature on a resting surface */
  border-radius:calc(var(--radius) + 6px) calc(var(--radius) + 6px) 50% 50% / calc(var(--radius) + 6px) calc(var(--radius) + 6px) 14% 14%;
  background:color-mix(in oklab,var(--panel) 94%,transparent);
  border:1px solid var(--line);
  isolation:isolate;
}
.field-wide,
.field-submit,
.form-status{grid-column:1 / -1}
/* the living element: a soft blue glow that breathes behind the panel */
.lead::before{
  content:"";
  position:absolute;
  inset:-20%;
  z-index:-1;
  border-radius:50%;
  /* the glow's strength rides --night, so by day the light panel carries no blue stain */
  background:radial-gradient(closest-side,color-mix(in oklab,var(--blue) calc(26% * var(--night)),transparent),transparent);
  opacity:0;
  pointer-events:none;
}
.contact.in.on-screen .lead::before{animation:lead-glow 7s var(--ease-inout) infinite alternate;animation-delay:-3s}
@keyframes lead-glow{from{opacity:.25;transform:scale(.9)}to{opacity:.6;transform:scale(1.05)}}

.field{position:relative}
.field input,
.field textarea{
  display:block;
  width:100%;
  padding:28px 0 12px;
  background:transparent;
  border:0;
  border-bottom:1px solid var(--line-strong);
  border-radius:0;
  font:var(--t-body);
  color:var(--text-primary);
  outline:none;
  -webkit-appearance:none;
  appearance:none;
}
.field textarea{min-height:160px;resize:none}
.field input::placeholder,
.field textarea::placeholder{
  color:var(--text-secondary);
  opacity:0;
  transition:opacity var(--t-fast);
}
.field :is(input,textarea):focus::placeholder{opacity:.7}
.field label{
  position:absolute;
  left:0;
  top:28px;
  font:var(--t-body);
  color:var(--text-secondary);
  transform-origin:left top;
  transition:transform var(--t-fast),color var(--t-fast);
  pointer-events:none;
}
.field:has(:is(input,textarea):is(:focus,:not(:placeholder-shown))) label{
  transform:translateY(-24px) scale(.74);
}
.field:has(:is(input,textarea):focus) label{color:var(--text-primary)}
/* the accent underline draws in on focus */
.field:not(.field-submit)::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:var(--accent);
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .5s var(--ease-out);
}
.field:focus-within::after{transform:scaleX(1)}
.field input:user-invalid,
.field textarea:user-invalid{border-bottom-color:var(--accent)}
.field-submit{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  margin-top:6px;
}

.form-status{
  display:block;
  outline:none;
  font:var(--t-sub);
}
.form-status a{border-bottom:1px solid var(--line-strong)}
.form-status a:hover{border-bottom-color:var(--accent)}
.lead.is-sending .btn{opacity:.55;pointer-events:none}
.lead.is-sent .field{display:none}
.lead.is-sent .form-status,
.lead.is-error .form-status{
  padding:18px 20px;
  border-radius:14px;
  border:1px solid var(--line);
}
.lead.is-sent .form-status{border-color:color-mix(in oklab,var(--blue-bright) 50%,var(--line))}
.lead.is-error .form-status{border-color:color-mix(in oklab,var(--accent) 60%,var(--line))}


/* --------------------------------------------------------------------------
   21 Footer
   -------------------------------------------------------------------------- */
.foot{
  position:relative;
  z-index:var(--z-main);
  padding:clamp(56px,8vh,96px) 0 clamp(28px,4vh,44px);
  color:var(--text-secondary);
}
.contact .foot{padding-top:clamp(64px,10vh,120px)}
.foot-grid{
  display:grid;
  grid-template-columns:minmax(0,1.4fr) repeat(2,minmax(0,.8fr));
  grid-template-areas:
    "brand nav social"
    "line  line copy";
  gap:clamp(32px,4vw,64px);
  align-items:start;
}
.foot-brand{grid-area:brand;display:inline-block;width:min(260px,60vw)}
.foot-wm{width:100%;height:auto;opacity:.9;transition:opacity var(--t-fast)}
.foot-brand:hover .foot-wm{opacity:1}
.foot-nav{grid-area:nav}
.foot-links{display:grid;gap:10px}
.foot-links a,
.foot-social a{
  display:inline-flex;
  align-items:center;
  min-height:32px;
  color:var(--text-primary);
  font:var(--t-body);
  transition:color var(--t-fast);
}
@media (hover:hover) and (pointer:fine){.foot-links a:hover,
.foot-social a:hover{color:var(--accent)}}
.foot-social{grid-area:social;display:grid;gap:10px}
.foot-social a{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase}
.foot-line{
  grid-area:line;
  align-self:end;
  margin-top:clamp(20px,3vh,32px);
  padding-top:20px;
  font:var(--t-sub);
  color:var(--text-primary);
}
/* the footer line is Subtitle at 400; its <b> carries the same weight device as the headings, 900 upright */
.foot-line b{font-style:normal;font-weight:900}
.foot-copy{
  grid-area:copy;
  align-self:end;
  margin-top:clamp(20px,3vh,32px);
  padding-top:20px;
  font:var(--t-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";
}


/* --------------------------------------------------------------------------
   22 Choreography, paused, keys hint
   sections.js adds .in to a section when it enters (and .is-settled once the
   entrance has run). Children marked .rv, with --i for order, arrive in
   sequence. The entrance lives on the .rv wrapper; interactive children carry
   their own transitions, so the stagger never lags a hover. The .is-settled
   rule retires the delays and out-specifies the delay rule.
   -------------------------------------------------------------------------- */
.rv{
  opacity:0;
  transform:translateY(28px);
  transition:opacity .95s var(--ease-out),transform .95s var(--ease-out);
  transition-delay:calc(var(--i,0) * 90ms);
}
.in .rv,
.in.rv{opacity:1;transform:none}
.in.is-settled .rv,
.in .rv.is-settled{transition-delay:0s}
/* the reveal wrapper never owns a hover transform: the stage card's lift lives
   on its article and the work tile's lift on its media and copy, so both take
   the full entrance (opacity, rise, stagger) like every other .rv */

/* pauses every loop on a hidden tab; animation-play-state does not inherit */
body.paused *,
body.paused *::before,
body.paused *::after{animation-play-state:paused !important}

/* toast for small confirmations (theme flips, sound state) */
.toast{
  position:fixed;
  left:50%;
  bottom:24px;
  z-index:var(--z-hint);
  transform:translate(-50%,12px);
  opacity:0;
  transition:opacity var(--t-fast),transform var(--t-fast);
  pointer-events:none;
}
.toast.is-on{opacity:1;transform:translate(-50%,0)}


/* --------------------------------------------------------------------------
   23 Reduced motion
   Kill every animation and transition, including pseudo-elements, zero the
   delays and show every choreographed element finished. Positional
   transforms are left alone (no blanket transform:none); the choreography
   states that need it are named explicitly. The block is written twice: once
   for the OS preference, once for the live attribute core.js sets.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation:none !important;
    transition:none !important;
    transition-delay:0s !important;
  }
  .rv,.in .rv{opacity:1;transform:none}
  .menu-list li{opacity:1;transform:none}
  .menu-astro{opacity:.8}
  .grain::before{transform:none}
  .aurora i{transform:none}
  .orbit-draw{stroke-dashoffset:0 !important}
  .orbit-halo{opacity:.3;transform:scale(1)}
  .bar{--hold:1}
  .fit-text{opacity:1}
  .fit-dot::after{opacity:1}
  .walk .shipped{opacity:1;transform:none;visibility:visible}
  .hold-fill{stroke-dashoffset:0}
  .hold::before{opacity:0}
  .pillar-body{grid-template-rows:1fr;padding-top:16px}
  .pillar-sub li{opacity:1;transform:none}
  .lead::before{opacity:.4;transform:none}
  .cursor{display:none}
  html[data-cursor="custom"],
  html[data-cursor="custom"] *{cursor:auto}
  .band .w,.band .c,.band .split,.band .split-sharp,.band .sub,.band .eyebrow,.band .cta-row,.bn-glyph{opacity:1;transform:none}
  .bn-media{opacity:.72}
  .band .split-soft{opacity:0}
}
html[data-motion="reduced"]{scroll-behavior:auto}
html[data-motion="reduced"] *,
html[data-motion="reduced"] *::before,
html[data-motion="reduced"] *::after{
  animation:none !important;
  transition:none !important;
  transition-delay:0s !important;
}
html[data-motion="reduced"] .rv,
html[data-motion="reduced"] .in .rv{opacity:1;transform:none}
html[data-motion="reduced"] .menu-list li{opacity:1;transform:none}
html[data-motion="reduced"] .menu-astro{opacity:.8}
html[data-motion="reduced"] .grain::before{transform:none}
html[data-motion="reduced"] .aurora i{transform:none}
html[data-motion="reduced"] .orbit-draw{stroke-dashoffset:0 !important}
html[data-motion="reduced"] .orbit-halo{opacity:.3;transform:scale(1)}
html[data-motion="reduced"] .bar{--hold:1}
html[data-motion="reduced"] .fit-text{opacity:1}
html[data-motion="reduced"] .fit-dot::after{opacity:1}
html[data-motion="reduced"] .walk .shipped{opacity:1;transform:none;visibility:visible}
html[data-motion="reduced"] .hold-fill{stroke-dashoffset:0}
html[data-motion="reduced"] .hold::before{opacity:0}
html[data-motion="reduced"] .pillar-body{grid-template-rows:1fr;padding-top:16px}
html[data-motion="reduced"] .pillar-sub li{opacity:1;transform:none}
html[data-motion="reduced"] .lead::before{opacity:.4;transform:none}
html[data-motion="reduced"] .cursor{display:none}
html[data-motion="reduced"][data-cursor="custom"],
html[data-motion="reduced"][data-cursor="custom"] *{cursor:auto}
html[data-motion="reduced"] .band .w,
html[data-motion="reduced"] .band .eyebrow,
html[data-motion="reduced"] .bn-glyph,
html[data-motion="reduced"] .band .c,
html[data-motion="reduced"] .band .split,
html[data-motion="reduced"] .band .split-sharp,
html[data-motion="reduced"] .band .sub,
html[data-motion="reduced"] .band .cta-row{opacity:1;transform:none}
html[data-motion="reduced"] .bn-media{opacity:.72}
html[data-motion="reduced"] .band .split-soft{opacity:0}


/* --------------------------------------------------------------------------
   24 Responsive
   -------------------------------------------------------------------------- */
@media (pointer: coarse){
  .btn,
  .nav-right > *,
  .menu-link,
  .foot-links a,
  .foot-social a{min-height:44px}
  .q summary{min-height:56px}
  .mark{min-height:64px}
  .pillar-body{grid-template-rows:1fr;padding-top:16px}
  .pillar-sub li{opacity:1;transform:none}
  .stage-card article,.work .tile{}
  .rail{cursor:auto}
}

@media (max-width:1200px){
  .stage-card{width:min(300px,32%)}
  .pillars{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pillar{min-height:148px}
}

@media (max-width:1024px){
  .services-body{grid-template-columns:1fr;gap:clamp(20px,4vh,32px)}
  .services-art{order:-1;min-height:0}
  .services-art-box{
    min-height:0;
    aspect-ratio:16 / 7;
    -webkit-mask-image:none;
    mask-image:none;
  }
  .services-art img{object-position:56% 42%}
  .frames-wrap{padding:0}
  .frames{
    display:flex;
    gap:clamp(12px,2vw,18px);
    overflow-x:auto;
    overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    scroll-padding-inline:var(--gutter);
    padding:4px var(--gutter) 12px;
    scrollbar-width:none;
  }
  .frames::-webkit-scrollbar{display:none}
  .frame{flex:0 0 min(360px,72vw);scroll-snap-align:start}
  .menu-astro{width:min(50vw,420px);right:-14vw;bottom:-8vh}
  .services-head{grid-template-columns:1fr}
  .contact .wrap,
  .walk{grid-template-columns:1fr;gap:clamp(32px,6vh,56px)}
  .qa{grid-template-columns:1fr}
  .contact-head{position:static}
  .foot-grid{
    grid-template-columns:1fr 1fr;
    grid-template-areas:
      "brand brand"
      "nav   social"
      "line  line"
      "copy  copy";
  }
}

@media (max-width:900px){
  .orbit-wrap{aspect-ratio:auto}
  svg.orbit{display:none}
  .stage-list{position:static;display:grid;gap:14px}
  .stage-card{position:static;width:auto;margin:0}
  .stage-card:nth-child(2){margin-left:0}
  .stage-promise{max-width:none}
}

@media (max-width:720px){
  :root{--nav-h:64px;--section-pad:clamp(72px,12vh,120px)}
  .nav{padding-top:12px;padding-bottom:12px}
  .nav-right{gap:6px}
  .nav-right > *{padding:0 12px}
  .theme-toggle{padding:0 11px}
  .brand{padding:8px 12px}
  .menu-link{font-size:clamp(2rem,10vw,3.4rem)}
  .pillars{grid-template-columns:1fr;border-radius:16px}
  .pillar{min-height:0}
  .work .tile{flex-basis:min(440px,84vw)}
  .services-art-box{aspect-ratio:16 / 9;border-radius:16px}
  .frame{flex-basis:min(300px,78vw)}
  .marks{--mark-h:32px;gap:0 4px}
  .mark{height:80px;padding:0 12px}
  .mark-svg{max-width:120px}
  .hold{width:124px;height:124px;padding:14px}
  .walk-col{padding-left:38px}
  .walk-line{left:6px}
  .fit-dot{left:-31.5px}
  .lead{grid-template-columns:1fr;padding:22px;border-radius:18px}
  .foot-grid{
    grid-template-columns:1fr;
    grid-template-areas:"brand" "nav" "social" "line" "copy";
  }
}

@media (max-width:480px){
  :root{--gutter:18px}
  .static-hero .cta-row .btn{width:100%}
  .btn{padding:0 22px}
  .band-settle .cta-row .btn{width:100%}
  .marks{--mark-h:28px}
}

@media (max-width:360px){
  :root{--gutter:14px}
  .nav-right > *{padding:0 10px}
  .theme-toggle{padding:0 10px}
  .hold{width:108px;height:108px}
}

/* tall narrow desktop windows still get the scrub; only the lanes tighten */
@media (min-width:721px) and (max-width:1100px){
  /* narrower desktops: slide 2 starts further left, the left lanes widen */
  .band-2{left:56%}
  .band-3,
  .band-4{width:min(54vw,720px)}
  .band-settle{width:min(44vw,520px)}
}


/* --------------------------------------------------------------------------
   25 Print
   -------------------------------------------------------------------------- */
@media print{
  .sky,.aurora,.grain,.cursor,.nav,.menu,.stage,.hud,.key-hint,.toast,.backdrop{display:none !important}
  html,body{background:#fff;color:#000}
  .hero{height:auto !important}
  .static-hero{display:block;background:none !important;color:#000;text-shadow:none}
  .static-hero::before{display:none}
  .rv{opacity:1 !important;transform:none !important}
  .pillar-body{grid-template-rows:1fr}
  .q:not([open]) .a{display:block}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:.8em}
}

/* --------------------------------------------------------------------------
   24 The end of the page, one screen (16i). The invitation, the form and the
   footer compose into one viewport: nothing sticks, nothing pushes the
   heading above while the panel stays, and the footer is a slim bar under the
   form rather than a second slide. The same bar closes every inner page.
   -------------------------------------------------------------------------- */
.contact.has-backdrop{
  min-height:100svh;
  display:grid;
  grid-template-rows:minmax(0,1fr) auto;
  align-items:center;
  padding-top:calc(var(--nav-h) + clamp(16px,2vh,24px));
  padding-bottom:0;
}
.contact.has-backdrop > .wrap{align-self:center}
.contact.has-backdrop > .foot{align-self:end}
.contact.has-backdrop > .wrap{
  grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:clamp(32px,5vw,80px);
  align-items:center;
}
.contact .contact-head{position:static;top:auto;gap:clamp(10px,1.6vh,16px)}
.contact .contact-head h2,.contact .contact-head h1{font-size:clamp(30px,3.6vw,54px);line-height:1.02}
.contact .contact-head .lede{margin-top:8px;max-width:32ch}
.contact .ways{margin-top:clamp(14px,2.4vh,22px)}
.contact .way{min-height:38px;padding:0 14px 0 8px;font-size:13px}
.contact .lead{
  gap:clamp(10px,1.6vh,16px) clamp(16px,2vw,24px);
  padding:clamp(18px,2.4vw,28px) clamp(20px,2.6vw,32px) clamp(28px,3.4vw,44px);
}
.contact .field input,.contact .field textarea{padding:22px 0 9px;font-size:15px}
.contact .field label{top:22px;font-size:15px}
.contact .field:has(:is(input,textarea):is(:focus,:not(:placeholder-shown))) label{transform:translateY(-19px) scale(.74)}
.contact .field textarea{min-height:88px}
.contact .field-submit{margin-top:2px}
.contact .field-submit .btn{min-height:44px}
.contact .form-status{margin-top:-4px}
.foot{padding:clamp(18px,2.6vh,28px) 0 clamp(14px,2.2vh,24px)}
.contact .foot{margin-top:clamp(24px,4vh,40px);padding-top:clamp(16px,2.4vh,24px);border-top:1px solid var(--line)}
.foot-grid{
  grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-areas:
    "brand nav line"
    "brand nav copy";
  gap:6px clamp(20px,3.5vw,56px);
  align-items:center;
}
.foot-brand{width:clamp(120px,10vw,150px)}
.foot-links{display:flex;flex-wrap:nowrap;gap:2px 18px;white-space:nowrap}
.foot-links a{min-height:28px;font:var(--t-small)}
@media (max-width:1180px){.foot-links{flex-wrap:wrap}}
.foot-line{margin:0;padding:0;font:var(--t-body);text-align:right;align-self:end}
.foot-copy{margin:0;padding:0;text-align:right;align-self:start}
@media (max-width:900px){
  .contact.has-backdrop{align-content:start;padding-bottom:24px}
  .foot-grid{grid-template-columns:1fr;grid-template-areas:"brand" "nav" "line" "copy";gap:12px}
  .foot-line,.foot-copy{text-align:left}
}


/* --------------------------------------------------------------------------
   26 Phones and touch (16v)
   The fixes from the phone audit (review/spec/briefs/2026-10-01-phone-audit.json).
   Each rule sits behind a width, orientation, pointer or hover query, or resolves
   to the value it replaces when there is no notch, so the desktop page is unchanged.
   -------------------------------------------------------------------------- */

/* safe areas: viewport-fit=cover runs the page under the notch in landscape; with no inset these equal the rules they follow */
.nav{padding-left:max(clamp(14px,1.8vw,26px),env(safe-area-inset-left,0px));padding-right:max(clamp(14px,1.8vw,26px),env(safe-area-inset-right,0px))}
.wrap{width:min(1240px,100% - 2 * max(var(--gutter),env(safe-area-inset-left,0px),env(safe-area-inset-right,0px)))}
.menu{padding-left:max(var(--gutter),env(safe-area-inset-left,0px));padding-right:max(var(--gutter),env(safe-area-inset-right,0px))}
.menu-close{right:max(var(--gutter),env(safe-area-inset-right,0px))}
.foot{padding-bottom:max(clamp(14px,2.2vh,24px),env(safe-area-inset-bottom,0px))}

/* the contact panel: one column on a phone (the two-column rule above outranked the old collapse and the form ran off the screen) */
@media (max-width:720px){
  .contact.has-backdrop > .wrap{grid-template-columns:minmax(0,1fr);gap:clamp(24px,4vh,36px);align-items:start}
  .contact .lead{grid-template-columns:minmax(0,1fr)}
  .contact .contact-head h1{font-size:clamp(34px,9.4vw,40px)}
  .brand svg{height:22px}
  .clients .rv{transition-duration:.6s;transition-delay:calc(var(--i,0) * 40ms)}
}
@media (max-width:480px){
  .contact .field-submit .btn{width:100%}
  .wwd-title{padding-left:44px}
  .wwd-title.is-lit{padding-left:50px}
}
@media (max-width:359px){.page-head h1{font-size:34px}}
/* the message box grows with what is typed and its text no longer slides under its own label */
@media (max-width:720px),(pointer:coarse){.contact .field textarea{padding-top:0;margin-top:22px;min-height:98px;max-height:42svh;field-sizing:content}}
@media (max-width:820px),(pointer:coarse){.contact .field :is(input,textarea){scroll-margin-top:calc(var(--nav-h) + 28px);scroll-margin-bottom:24px}}
@media (max-width:820px),(pointer:coarse){.field :is(input,textarea)[aria-invalid="true"]{border-bottom-color:var(--accent)}}

/* touch: 16px fields (iOS zooms the page on anything smaller), 44px targets, the whole menu row tappable, no grey tap flash */
@media (pointer:coarse){
  .btn{min-height:50px}
  .contact .field input,.contact .field textarea,.contact .field label{font-size:16px}
  .contact .field:has(:is(input,textarea):is(:focus,:not(:placeholder-shown))) label{transform:translateY(-19px) scale(.78)}
  .contact .field-submit .btn{min-height:48px}
  .contact .way{min-height:44px}
  .foot-links{gap:0 6px;margin-left:-8px}
  .foot-links a{min-height:44px;min-width:44px;padding:0 8px;display:inline-flex;align-items:center}
  .foot-brand{display:inline-flex;align-items:center;min-height:44px}
  .menu-link{display:flex;width:100%}
  .reel-range::-webkit-slider-thumb{opacity:1}
  .reel-range::-moz-range-thumb{opacity:1}
  .q summary,.stage-card article,.reel-box,.reel-box button,.mark,.wwd-launch,.btn,.way,.menu-link,.foot-links a{-webkit-tap-highlight-color:transparent}
}
/* touch has no hover: the orange copies are never fetched, a press lights the mark, and nothing stays lit after a tap */
@media (hover:none){
  .mark-img .ink-hot{display:none}
  .mark.is-hot .mark-img .ink-light,.mark.is-hot .mark-img .ink-dark,.mark:focus-visible .mark-img .ink-light,.mark:focus-visible .mark-img .ink-dark{opacity:.7}
  .mark:active{color:var(--accent-ink);opacity:1}
  .mark:active .mark-img .ink-light,.mark:active .mark-img .ink-dark{opacity:1}
  .way:active{border-color:var(--accent);color:var(--accent)}
  .nav-right > button:hover,.home-link:hover{transform:none}
  .home-link:hover{color:var(--text-primary)}
  .btn:hover::before{opacity:0}
  .btn:focus-visible::before{opacity:1}
  .btn:hover .arrow{transform:none}
  .stage-card:not(.is-active) article:hover,.stage-card:not(.is-active) article:focus-within{transform:none}
  .stage-card:not(.is-active) article:hover::after,.stage-card:not(.is-active) article:focus-within::after{opacity:0}
  .reel-btn:hover,.reel-mi:hover{background:transparent}
  .reel-btn:active,.reel-mi:active{background:rgba(238,241,246,.12)}
  .foot-links a:active{color:var(--accent)}
  .nav-right > *:active,.brand:active{opacity:.7}
}

/* the menu: opaque (page text showed through), still while open, reachable on a short screen */
@media (max-width:820px),(pointer:coarse){.menu{background:var(--canvas);overscroll-behavior:contain}.menu-close{background:var(--canvas)}}
@media (max-width:820px),(pointer:coarse){body.menu-open .fog,body.menu-open .aurora i{animation-play-state:paused}}

/* a phone on its side (the same gate as the still hero): everything fits a 360 to 430 px tall screen */
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px){
  :root{--section-pad:56px}
  .static-copy{padding:calc(var(--nav-h) + 4px) max(var(--gutter),env(safe-area-inset-right,0px)) 18px max(var(--gutter),env(safe-area-inset-left,0px));gap:10px}
  .static-brand{width:min(40vw,360px);margin:0 0 auto}
  .static-title{font-size:clamp(1.5rem,7.4vh,2.1rem)}
  .static-sub{font-size:1rem;max-width:44ch}
  .menu{padding-top:calc(var(--nav-h) + 8px);padding-bottom:16px;overflow-y:auto}
  .menu-list{gap:2px}
  .menu-link{font-size:clamp(1.6rem,min(6.4vw,11.5vh),3.4rem)}
  .menu-astro{position:fixed;width:auto;height:84vh;right:0;bottom:-6vh}
  .marks{--mark-h:30px;gap:0 8px;margin-top:28px}
  .mark{height:68px;padding:0 14px}
  .mark-svg,.mark-img{max-width:150px}
  .page-head{padding-top:calc(var(--nav-h) + 28px);padding-bottom:32px}
  .reel-box{width:min(100%,calc((100svh - var(--nav-h) - 32px) * 16 / 9));margin-inline:auto}
}
/* the wordmark over the bright helmet on the still hero */
@media (max-width: 720px), (orientation: portrait) and (max-width: 1024px), (orientation: portrait) and (pointer: coarse), (orientation: landscape) and (pointer: coarse) and (max-height: 560px){.static-banner{filter:drop-shadow(0 1px 2px rgba(5,5,10,.7)) drop-shadow(0 6px 18px rgba(5,5,10,.45))}}

/* what we do: a swipe that starts on the ring scrolls the page (it was a scroll trap); the glow is not cut */
@media (any-pointer:coarse){.wwd-launch{touch-action:pan-y;-webkit-touch-callout:none}}
@media (max-width:820px),(pointer:coarse){.wwd-ring{overflow:visible}.wwd-launch-alt,.wwd-launch-done{white-space:nowrap}}

/* how we work: on a phone the orbit is hidden, so the section no longer pins for a screen and a half */
@media (max-width:900px){
  .stages{min-height:0}
  .stages > .wrap{position:static;min-height:0;display:block;padding-top:0;padding-bottom:0}
  .orbit-wrap{margin-top:clamp(28px,5vh,48px);margin-bottom:0}
}

/* the showreel player on a phone: 44px controls, the scrub line on its own row, the quality menu inside the box, the bar steps away while it plays */
@media (max-width:820px),(pointer:coarse){
  .reel-btn{flex:0 0 auto}
  .reel-scrub{min-width:0}
  .reel-bar{flex-wrap:wrap;gap:0 2px;padding:16px 6px 4px}
  .reel-scrub{order:-1;flex:0 0 calc(100% - 20px);margin:0 10px;height:32px}
  .reel-range{height:32px}
  .reel-btn{width:44px;height:44px}
  .reel-time{margin:0 6px 0 2px}
  .reel-q{margin-left:auto;position:static}
  .reel-qbtn{width:auto;min-width:44px}
  .reel-q-auto{display:none}
  .reel-menu{left:8px;right:8px;bottom:calc(100% - 10px);min-width:0;display:flex;gap:4px}
  .reel-menu[hidden]{display:none}
  .reel-menu li{flex:1 1 0}
  .reel-mi{min-height:44px;justify-content:center;gap:6px;padding:0 6px}
  .reel-head .lede{justify-self:start}
}
.reel-box.is-touch.is-playing:not(.ui-on):not(.menu-open) .reel-bar{opacity:0;transform:translateY(6px);pointer-events:none}

/* services on a phone, upright or on its side: a two-column index of 44px links that never reflows, no weight changes that move lines */
@media (max-width:820px),(orientation:landscape) and (pointer:coarse) and (max-height:560px){
  .svp-grid{grid-template-columns:1fr}
  .svp-index{position:static}
  .svp-index ul{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 14px}
  .svp-index a{display:flex;align-items:center;min-height:44px;line-height:1.2;opacity:.75}
  .svp-index a.is-active{font-weight:300;opacity:.75}
  .svp-lines li.is-read{font-weight:inherit}
  .svp-item{scroll-margin-top:12px}
  .svp{padding-top:clamp(28px,5vh,48px)}
  .about-mind h2 + .lede{margin-top:clamp(16px,2.4vh,26px)}
  body:not(:has(#hero)) :is(.brand,.nav-right > *){background:color-mix(in oklab,var(--canvas) 96%,transparent)}
  :root{--t-label:400 0.75rem/1.4 var(--font-mono)}
}
@media (orientation:landscape) and (pointer:coarse) and (max-height:560px){
  .svp-index ul{grid-template-columns:repeat(4,minmax(0,1fr))}
  .svp-item{grid-template-columns:minmax(0,1fr) minmax(0,1.1fr)}
  .svp-item:nth-child(even) .svp-still{order:2}
}

/* the bar on a phone: once the page has moved, a soft ground under it, so text never runs through the logo (menu.js sets html.is-moved) */
@media (max-width:820px),(orientation:landscape) and (pointer:coarse) and (max-height:560px){
  .nav::before{content:"";position:absolute;inset:0 0 -26px 0;z-index:-1;pointer-events:none;opacity:0;transition:opacity .35s var(--ease-out);
    background:linear-gradient(to bottom,color-mix(in oklab,var(--canvas) 94%,transparent) 0%,color-mix(in oklab,var(--canvas) 78%,transparent) 52%,transparent 100%)}
  html.is-moved .nav::before{opacity:1}
  html.is-moved body.menu-open .nav::before{opacity:0;transition-delay:.3s}
  html.is-moved body:has(#hero.on-screen) :is(.brand,.nav-right > *){background:rgba(11,13,18,.94)}
  html.is-moved body:has(#hero.on-screen) .nav::before{background:linear-gradient(to bottom,rgba(11,13,18,.94) 0%,rgba(11,13,18,.78) 52%,transparent 100%)}
  body.deck-first .nav::before{opacity:0}
}

/* second pass (16v): what the independent re-check of the phone build confirmed (review/spec/briefs/2026-10-01-phone-verify.json) */
@media (pointer:coarse) and (max-width:1100px){.brand svg{height:22px}}
@media (max-width:359px){.wwd-launch{width:min(192px,58vw)}}
@media (max-width:480px){.foot-copy{letter-spacing:.08em}}
@media (max-width:359px){.foot-copy{letter-spacing:.02em}}
@media (max-width:900px){.contact .foot-grid{gap:12px}}
@media (max-width:820px),(pointer:coarse){.menu-close{right:max(clamp(14px,1.8vw,26px),env(safe-area-inset-right,0px));top:clamp(10px,1.2vw,16px);transition:opacity .4s var(--ease-out) .15s,border-color var(--t-fast)}}
@media (max-width:720px){.menu-close{top:12px}}
/* the showreel on touch: the bar follows the player's own state, and a stalled film shows that it is loading */
.reel-box.is-touch.has-started.ui-on .reel-bar{opacity:1;transform:none;pointer-events:auto}
.reel-box.is-touch.is-waiting::after{content:"";position:absolute;left:50%;top:50%;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;border:2px solid rgba(238,241,246,.25);border-top-color:var(--accent);animation:reel-wait .9s linear infinite;pointer-events:none}
@keyframes reel-wait{to{transform:rotate(360deg)}}

/* --------------------------------------------------------------------------
   27 The film on phones (16x)
   Suryam: the phone gets the same film as the laptop, one swipe a slide. hero.js pages the deck by touch; these rules
   lay the slides out for a tall screen. A mouse on a wide screen matches none of them.
   -------------------------------------------------------------------------- */
@media (pointer:coarse){
  .stage{touch-action:none}
}
@media (max-width:720px) and (orientation:portrait){
  /* the slice of the frame an upright phone shows: around the tower, the astronaut and the helmet */
  .rest,.film{object-position:76% 50%}
  .clip{object-position:50% 50%}
  /* every slide's lines sit low on the picture, the full width of the screen, over a soft ground */
  .band-2,.band-3,.band-4,.band-settle{left:var(--gutter);right:var(--gutter);width:auto;top:auto;bottom:clamp(108px,15svh,150px);transform:none}
  .band-banner{width:min(84vw,520px);top:40%}
  .band h1,.band h2,.band p.split{font-size:clamp(32px,9vw,40px);line-height:1.08;max-width:none}
  .band-2 h1,.band p.split,.band-settle h2{max-width:none}
  .band .sub{margin-top:14px;font-size:16px;line-height:1.45;max-width:32ch}
  .band::before,.band-2::before,.band-4::before,.band-settle::before{inset:-110px calc(-1 * var(--gutter)) -150px;background:linear-gradient(to bottom,rgba(5,5,10,0) 0%,rgba(5,5,10,.5) 34%,rgba(5,5,10,.66) 100%)}
  .band-settle .cta-row{flex-direction:row;flex-wrap:wrap;gap:8px;margin-top:16px}
  .band-settle .cta-row .btn{width:auto;min-height:44px;padding:0 15px;font-size:.84rem;justify-content:center}
  .hud{bottom:max(18px,env(safe-area-inset-bottom,0px))}
}

/* How we work on a narrow screen (16x): the four steps are one row swiped sideways, and the swipe draws the line above
   them and moves the dot along it (sections.js seeks the laptop's own line by the row's travel) */
@media (max-width:900px){
  svg.orbit{display:block;position:relative;inset:auto;width:100%;height:auto;aspect-ratio:1200 / 420;margin:2px 0 10px}
  .orbit-path{stroke-width:3;stroke-dasharray:10 28}
  .orbit-draw{stroke-width:5.5}
  .orbit-core,.orbit-halo{transform-box:fill-box;transform-origin:center}
  .orbit-core{transform:scale(3.3)}
  .orbit-halo,.stages.in.on-screen .orbit-halo{animation:none;transform:scale(2.6);opacity:.28}
  .stage-list{display:flex;gap:12px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;margin:0 calc(-1 * var(--gutter));padding:4px var(--gutter) 8px;scroll-padding-inline:var(--gutter)}
  .stage-list::-webkit-scrollbar{display:none}
  .stage-card{flex:0 0 min(78vw,330px);scroll-snap-align:start}
  .stage-card article{height:100%;align-content:start}
  .stage-card.is-active article,.stage-card article:hover,.stage-card article:focus-within{transform:none}
  .stage-promise{max-width:none}
}

/* --------------------------------------------------------------------------
   28 Phone type, rhythm and weight (16x)
   Suryam: on the phone the text read like a book. Everything is a little smaller, the measure is shorter, the bands
   between sections are tighter and fixed (no viewport-height maths that shifts when the browser bar moves), the eight
   services are tiles in two columns, and the drifting background layers hold still so a swipe has the frame to itself.
   -------------------------------------------------------------------------- */
@media (max-width:720px){
  html{font-size:92%}
  :root{
    --section-pad:68px;
    --t-h1:300 2.05rem/1.06 var(--font-display);
    --t-h2:300 1.85rem/1.08 var(--font-display);
    --t-h3:700 1.1rem/1.25 var(--font-sub);
    --t-sub:400 1.02rem/1.45 var(--font-sub);
    --t-body:400 1rem/1.58 var(--font-body);
    --t-small:400 .86rem/1.5 var(--font-body);
    --t-label:400 .74rem/1.4 var(--font-mono);
  }
  /* a shorter measure: no paragraph runs the full width of the screen */
  .lede,.page-head .lede,.reel-head .lede,.services-close,.contact .contact-head p,.memo p,.about p{max-width:34ch}
  .q p{max-width:36ch}
  .stage-promise{font-size:.95rem}
  /* What we do: eight tiles in two columns, not eight full-width lines */
  .wwd-titles{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:22px}
  .wwd-title,.wwd-title.is-lit{padding:40px 12px 14px 14px}
  .wwd-title{min-height:98px;border:1px solid var(--line);border-radius:14px;background:rgba(238,241,246,.03);font-size:.98rem;line-height:1.22;text-wrap:balance;transition:color .25s,border-color .25s}
  .wwd-title::before{left:14px;top:14px}
  .wwd-title .wwd-ico{position:absolute;right:12px;top:11px;width:19px;height:19px;margin:0}
  .wwd-title.is-lit{border-color:color-mix(in oklab,var(--accent) 60%,transparent)}
  .wwd-right{margin-top:28px}
  /* the open cards: one row swiped sideways instead of a tall stack */
  .wwd-cards{display:flex;gap:12px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;scrollbar-width:none;margin:0 calc(-1 * var(--gutter));padding:26px var(--gutter) 6px;scroll-padding-inline:var(--gutter)}
  .wwd-cards::-webkit-scrollbar{display:none}
  .wwd-card{flex:0 0 min(74vw,300px);scroll-snap-align:start}
  .wwd .services-close{margin-top:44px}
  /* the fixed background layers hold still on a phone */
  .aurora i,.fog{animation:none}
}
@media (max-width:720px) and (pointer:coarse){
  .aurora i,.fog,.grain::before{will-change:auto}
}
@media (max-width:720px){
  .about-copy{gap:14px}
  .about-copy p{font-size:1.02rem;line-height:1.6;max-width:38ch}
  .memo-body{gap:14px}
  .memo-body p{font-size:1.08rem;line-height:1.55;max-width:36ch}
  .svp-item p,.svp-lines li{max-width:40ch}
}
/* on a touch screen both clips stay on the glass at all times, one above the other, and a move only changes which is
   on top: a clip that is switched from hidden to visible paints nothing for a frame, and that frame showed the canvas
   beneath (the earth of the first slide popping up mid-move on a phone). The text and the readout sit above both. */
@media (pointer:coarse){
  .stage .ring{display:none}   /* the cover carries the loading on a touch screen; the ring has no job there (Suryam: remove the circle) */
  .stage.film-ready .clip{opacity:1;visibility:visible;z-index:1}
  .stage.film-ready .clip.on{z-index:2}
  .stage .rest{z-index:0}
  .stage .bands{z-index:5}
  .stage .hud{z-index:6}
}
/* on a phone the sky stays under the film (the film is one screen and opaque, so it costs nothing), and shows in the
   strip the browser's bar uncovers below the stage and all the way down the page */
@media (pointer:coarse){
  html[data-film="1"] .sky{opacity:1;visibility:visible;transition:none}
}

/* --------------------------------------------------------------------------
   29 Phone tidy (16x, Suryam's second list)
   -------------------------------------------------------------------------- */
@media (max-width:720px){
  .clients-explore{display:none}
  /* the three ways to reach us: one tidy column, full width */
  .ways{display:grid;grid-template-columns:1fr;gap:8px;margin-top:22px}
  .way{width:100%;justify-content:flex-start;min-height:46px}
  /* the lead's glow is still on a phone (it restarted on every scroll past) */
  .contact.in.on-screen .lead::before{animation:none}
  /* the footer, centred in one column */
  .foot{padding-top:28px}
  .foot-grid,.contact .foot-grid{grid-template-columns:1fr;grid-template-areas:"brand" "nav" "line" "copy";justify-items:center;gap:14px;text-align:center}
  .foot-brand{width:132px}
  .foot-links{display:flex;flex-wrap:wrap;justify-content:center;gap:4px 18px;margin:0}
  .foot-links a{min-height:44px;min-width:0;padding:0 6px}
  .foot-line{margin-top:6px;text-align:center}
  .foot-copy{text-align:center;letter-spacing:.06em}
}
/* the top bar on a phone: the logo, the home pill and the menu pill a little smaller, and clear of the corners */
@media (max-width:720px){
  :root{--nav-h:70px}
  .nav{padding:18px 18px 10px}
  .brand{min-height:40px;padding:7px 11px;border-radius:12px}
  .brand svg{height:19px}
  .nav-right{gap:6px}
  .nav-right > *{min-height:40px;min-width:40px;padding:0 10px;font-size:11px}
  .home-link{padding:0 10px}
  .menu-close{top:18px;right:18px;width:40px;height:40px;min-height:40px}
}

/* 16x: a quiet bold line under the Kickstart Media wordmark on the first slide, phone and laptop alike (Suryam). It lives
   inside the banner band, so it fades with the wordmark; it waits for the film (film-ready), so it never shows over the
   loading ring or the still hero. */
.swipe-hint{display:block;position:absolute;left:50%;top:calc(100% + 28px);margin:0;transform:translateX(-50%);font-size:13px;font-weight:700;line-height:1;letter-spacing:.24em;text-transform:uppercase;white-space:nowrap;color:var(--hero-ink-2);opacity:0;text-shadow:var(--tshadow);transition:opacity .4s var(--ease-inout);pointer-events:none}
.stage.film-ready .band-banner .swipe-hint{opacity:.72}
.hero.in.on-screen .stage.film-ready .band-banner.is-on .swipe-hint{animation:hint-bob 2.8s var(--ease-inout) infinite;animation-delay:-1.4s}
html[data-motion="reduced"] .swipe-hint{animation:none}
@media (max-height:560px){.swipe-hint{display:none}}
@keyframes hint-bob{0%,100%{transform:translate(-50%,0)}50%{transform:translate(-50%,5px)}}
