/* ═══════════════════════════════════════════════════════════
   Shashwat Sharma - personal profile
   Black / white ground, violet accent.
   Type: Geist (display) + Geist Mono (labels), self-hosted.
   ═══════════════════════════════════════════════════════════ */

@font-face{font-family:"Geist";src:url("assets/fonts/geist-var-latin.woff2") format("woff2-variations");font-weight:100 900;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Geist";src:url("assets/fonts/geist-var-latin-ext.woff2") format("woff2-variations");font-weight:100 900;font-display:swap;unicode-range:U+0100-02BA,U+02BD-02C5,U+1E00-1E9F,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Geist Mono";src:url("assets/fonts/geistmono-var-latin.woff2") format("woff2-variations");font-weight:100 900;font-display:swap}

/* ── theme tokens ────────────────────────────────────────
   :root is the dark theme - the one the site loads in. The light theme is a
   token swap on [data-theme="light"], nothing more, so every rule below is
   written once. Two things do NOT swap: type that sits ON a violet fill
   (--violet-mist, #fff) stays pale in both themes. */
:root{
  /* brand constants - same in both themes */
  --cream:#F4F1EE;
  --violet-deep:#3B1080;   /* brand core, large fills */
  --violet-band:#7C3AED;   /* full-bleed floods - white type needs the deeper tone */
  --violet-mist:#E9C0FA;   /* pale violet - only ever sits ON a violet fill */

  /* ground + figure */
  --ink:#000; --paper:#fff;
  --void:#030303;          /* deepest ground - origin */
  --sunken:#0A0A0B;        /* recessed plate - the framed painting */

  /* accent */
  --violet:#8B4AFF;        /* the accent - replaces Honey's #F44849 */
  --violet-soft:#E9C0FA;  /* violet at small sizes, ON the page ground */

  /* type, brightest to dimmest */
  --tx-hi:#EDEDED;
  --tx-1:#D6D6D6;
  --tx-2:#B4B4B4;
  --tx-3:#8E8E8E;
  --g1:#3D3D3D; --g2:#757575; --g3:#979797;
  --off:#242424;           /* unlit type - the reveal's "before" state */
  --off-hi:#3E3E3E;        /* unlit type where the ground is busier */

  /* lines */
  --line:#191919;          /* hairline rules */
  --line-2:#2A2A2A;        /* drawn borders - buttons, ghost, rails */
  --line-3:#1C1C1C;        /* image and plate borders */

  /* the inversion block (08 · izna foundation, and the footer signoff) */
  --inv-bg:var(--cream); --inv-fg:#000; --inv-dim:#8A8A8A;
  --inv-lede:#2A2A2A; --inv-tag:#3B1080; --inv-line:#DFD9D2;
  --inv-tex:rgba(0,0,0,.055); --inv-tex-2:rgba(0,0,0,.035);

  /* decorative overlays - grain, mesh and scanlines are drawn in this tint */
  color-scheme:dark;
  --tex-fine:rgba(255,255,255,.028);
  --tex-mid:rgba(255,255,255,.035);
  --tex-mesh:rgba(255,255,255,.05);
  --tex-mesh-2:rgba(255,255,255,.032);
  --tex-scan:rgba(255,255,255,.022);
  --tex-bloom:rgba(255,255,255,.055);
  --tex-scan-2:rgba(255,255,255,.045);
  --flip-bloom:
    radial-gradient(closest-side,rgba(139,74,255,.55),rgba(139,74,255,.22) 42%,
      rgba(59,16,128,.10) 68%,transparent 100%);
  --origin-wash:
    radial-gradient(ellipse 78% 62% at 28% 18%,
      rgba(59,16,128,.60) 0%,rgba(59,16,128,.34) 34%,rgba(59,16,128,.12) 62%,transparent 88%),
    radial-gradient(ellipse 70% 78% at 84% 78%,
      rgba(139,74,255,.26) 0%,rgba(139,74,255,.11) 42%,transparent 84%),
    var(--void);

  --gut:clamp(16px,4.2vw,56px);
  --label:clamp(9.5px,0.72vw,11px);
  --lede:clamp(15px,1.15vw,18px);
  --ease:cubic-bezier(.16,1,.3,1);
  --chapters:11;
}

/* ── light theme ────────────────────────────────────────
   A warm paper ground rather than pure white - the palette already runs warm
   (--cream), and #fff under a violet accent goes cold and clinical. The accent
   drops from #8B4AFF to #6D28D9: the bright violet is tuned for glowing off
   black and fails contrast as small type on paper. */
:root[data-theme="light"]{
  /* A warm paper rather than #fff, and every grey sits well clear of it. The
     first pass carried the dark theme's *ratios* straight across, which is
     wrong: an off-white ground swallows a light grey where black makes a dark
     grey read fine. The marquee's outlined type and the hairlines were the
     tell - both had all but disappeared. */
  --ink:#F4F1EB; --paper:#0C0C0E;
  --void:#EDE8DF;
  --sunken:#E9E3D9;

  --violet:#6D28D9;
  --violet-soft:#4C1D95;

  --tx-hi:#111114;
  --tx-1:#23232A;
  --tx-2:#303038;
  --tx-3:#4A4640;
  --g1:#8C857A; --g2:#575349; --g3:#443F38;
  --off:#C9C1B2;
  --off-hi:#B7AE9C;

  --line:#D5CDC0;
  --line-2:#BEB5A6;
  --line-3:#CBC3B5;

  /* the inversion flips too, or section 08 stops being an inversion */
  --inv-bg:#0C0C0E; --inv-fg:#F4F1EE; --inv-dim:#7C776F;
  --inv-lede:#CFCAC3; --inv-tag:#C9A9FF; --inv-line:#232326;
  --inv-tex:rgba(255,255,255,.06); --inv-tex-2:rgba(255,255,255,.04);

  color-scheme:light;
  /* black-on-paper needs more alpha than white-on-black to read at all */
  --tex-fine:rgba(0,0,0,.055);
  --tex-mid:rgba(0,0,0,.065);
  --tex-mesh:rgba(0,0,0,.085);
  --tex-mesh-2:rgba(0,0,0,.06);
  --tex-scan:rgba(0,0,0,.045);
  --tex-bloom:rgba(0,0,0,.07);
  --tex-scan-2:rgba(0,0,0,.06);
  --flip-bloom:
    radial-gradient(closest-side,rgba(59,16,128,.30),rgba(109,40,217,.15) 46%,
      rgba(109,40,217,.05) 72%,transparent 100%);
  /* the same two washes, pulled right back - at dark-theme strength they turn
     the whole origin section opaque purple and swallow the copy */
  --origin-wash:
    radial-gradient(ellipse 78% 62% at 28% 18%,
      rgba(59,16,128,.22) 0%,rgba(59,16,128,.12) 34%,rgba(59,16,128,.05) 62%,transparent 88%),
    radial-gradient(ellipse 70% 78% at 84% 78%,
      rgba(109,40,217,.16) 0%,rgba(109,40,217,.08) 42%,transparent 84%),
    var(--void);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html,body{margin:0;padding:0}
html{background:var(--ink)}
body{
  background:var(--ink);color:var(--paper);
  font-family:"Geist",-apple-system,"Helvetica Neue",Arial,sans-serif;
  font-weight:400;overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
body.is-loading{overflow:hidden;height:100vh}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
ol,ul{margin:0;padding:0;list-style:none}
h1,h2,h3,p{margin:0}
::selection{background:var(--violet);color:#fff}

/* Only while a theme switch is in flight - a permanent transition on * would
   fight every hover and every GSAP-driven colour on the page. The reveal
   characters are excluded: their colour is scrubbed by ScrollTrigger, and a
   transition on top of a scrub reads as lag. */
html.is-theming *,html.is-theming *::before,html.is-theming *::after{
  transition:background-color .35s ease,color .35s ease,border-color .35s ease,
             fill .35s ease,stroke .35s ease!important;
}
html.is-theming .ch{transition:none!important}

/* ── primitives ─────────────────────────────────────────── */
.mono{
  font-family:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:var(--label);font-weight:400;
  text-transform:uppercase;letter-spacing:.13em;line-height:1.5;
}
.dim{color:var(--g2)}
.display{
  font-weight:400;letter-spacing:-.028em;line-height:.94;
  font-size:clamp(2.1rem,6.4vw,5.5rem);
  text-wrap:balance;
}
.lede{font-size:var(--lede);line-height:1.55;color:var(--tx-1);max-width:62ch}
.eyebrow{color:var(--violet-soft)}
.eyebrow--float{
  display:block;color:var(--violet);
  margin-top:clamp(28px,4vw,56px);
}

/* ── preloader ──────────────────────────────────────────── */
.loader{
  position:fixed;inset:0;z-index:200;background:var(--ink);
  display:flex;align-items:flex-end;justify-content:space-between;
  padding:var(--gut);transition:transform 1s var(--ease);
}
.loader.is-done{transform:translateY(-101%)}
.loader__inner{display:flex;align-items:flex-end;gap:.6em}
.loader__label{color:var(--paper)}
.loader__count{color:var(--violet);font-size:clamp(2.5rem,14vw,9rem);letter-spacing:-.04em;line-height:.8;text-transform:none}
.loader__bar{position:absolute;left:var(--gut);right:var(--gut);bottom:calc(var(--gut) - 1px);height:1px;background:var(--line)}
.loader__bar i{display:block;height:100%;width:0;background:var(--violet)}

/* ── cursor ─────────────────────────────────────────────── */
.cursor{
  position:fixed;top:0;left:0;z-index:190;pointer-events:none;
  width:12px;height:12px;border-radius:50%;background:var(--violet);
  mix-blend-mode:normal;translate:-50% -50%;
  transition:width .3s var(--ease),height .3s var(--ease),background .3s;
  display:grid;place-items:center;
}
.cursor.is-big{width:74px;height:74px;background:var(--violet)}
.cursor__label{color:#fff;opacity:0;transition:opacity .2s;font-size:9px;letter-spacing:.1em}
.cursor.is-big .cursor__label{opacity:1}
@media (hover:none),(max-width:900px){.cursor{display:none}}

/* ── nav ────────────────────────────────────────────────── */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:120;
  /* baseline, not flex-start: the brand is two lines and the pill has vertical
     padding, so only baseline alignment puts every label on one optical line */
  display:flex;align-items:baseline;justify-content:space-between;
  gap:clamp(12px,2.4vw,36px);
  padding:var(--gut) var(--gut) clamp(12px,1.5vw,20px);
  transition:transform .5s var(--ease),opacity .4s;
  /* The bar was transparent on desktop, which left it unreadable wherever it
     passed over a photograph, a violet flood or the cream block. It now carries
     a veil of whatever ground is under it, blurred, so the labels always have
     something to sit on. Bottom padding exists so the veil reads as a bar
     rather than stopping at the baseline. */
  background:var(--nav-veil);
  -webkit-backdrop-filter:saturate(140%) blur(14px);
  backdrop-filter:saturate(140%) blur(14px);
}
.nav.is-hidden{transform:translateY(-140%);opacity:0}
/* The nav used to carry mix-blend-mode:difference to stay legible over the
   cream block in §07. It never worked: .nav is position:fixed with a z-index,
   which makes it a stacking context, and that isolates its descendants'
   blending - there is nothing behind them to blend with, so they always
   rendered plain white (invisible on cream, and invisible on the light theme's
   paper). The colour is a pair of nav-scoped tokens now, and navInverse() in
   script.js flips them when an inverted section is actually under the bar. */
.nav{--nav-fg:var(--paper);--nav-dim:var(--g2);--nav-faint:var(--g1);
  --nav-bg:var(--ink);--nav-line:var(--line);--nav-veil:rgba(0,0,0,.62)}
.nav.is-inverse{--nav-fg:var(--inv-fg);--nav-dim:var(--inv-dim);--nav-faint:var(--inv-dim);
  --nav-bg:var(--inv-bg);--nav-line:var(--inv-line);--nav-veil:rgba(244,241,238,.66)}
/* The veil is a tint of the ground it sits on, so it has to flip with the theme
   and again over an inverted block. Written out rather than mixed from
   --nav-bg so the alpha can differ per case. */
:root[data-theme="light"] .nav{--nav-veil:rgba(244,241,235,.70)}
:root[data-theme="light"] .nav.is-inverse{--nav-veil:rgba(12,12,14,.58)}
.nav .dim{color:var(--nav-dim)}
.nav__brand{display:flex;flex-direction:column;line-height:1.5;color:var(--nav-fg)}
/* spread across the middle instead of bunching in the centre, with room held
   back from the brand and the pill so nothing collides */
.nav__links{
  display:flex;flex:1;justify-content:space-between;
  gap:clamp(14px,2.4vw,40px);
  padding-inline:clamp(20px,5vw,96px);
}
/* Never let a label break internally - the index and its word are one unit, and
   wrapping split them onto separate lines. Items still wrap between each other
   on a phone, where .nav__links carries flex-wrap. */
.nav__links a{position:relative;color:var(--nav-fg);transition:color .3s;white-space:nowrap}
.nav__links a:hover{color:var(--violet-soft)}
/* Over an inverted block the accent is the wrong lightness by definition, so
   the affordance there is a rule rather than a hue. */
.nav.is-inverse .nav__links a:hover{
  color:var(--nav-fg);text-decoration:underline;
  text-underline-offset:.35em;text-decoration-thickness:1px;
}
.nav__links i{font-style:normal;color:var(--nav-dim);margin-right:.55em}
.nav__short{display:none}

.pill{
  display:inline-block;background:var(--violet);color:#fff;
  padding:.55em 1.05em;border-radius:2px;white-space:nowrap;
  transition:background .3s,color .3s,transform .35s var(--ease);
  will-change:transform;
}
.pill:hover{background:var(--violet-soft);color:var(--ink)}
.pill--dark{background:var(--violet-deep);color:#fff;margin-top:2.2em}
.pill--dark:hover{background:var(--inv-fg);color:var(--inv-bg)}

/* theme toggle - both options always visible with the live one lit, the same
   one-at-a-time device the skills reel and the bands use. It is inside the
   nav, so it inherits the nav's own colour tokens. */
.themetog{
  align-self:baseline;flex:0 0 auto;
  background:none;border:0;padding:0;margin:0;
  font:inherit;letter-spacing:.13em;text-transform:uppercase;
  cursor:pointer;display:inline-flex;align-items:baseline;gap:.45em;
  white-space:nowrap;-webkit-tap-highlight-color:transparent;
}
.themetog__o{color:var(--nav-dim);transition:color .35s var(--ease)}
.themetog__sep{color:var(--nav-faint)}
:root:not([data-theme="light"]) .themetog__o[data-mode="dark"],
:root[data-theme="light"] .themetog__o[data-mode="light"]{color:var(--nav-fg)}
.themetog:hover .themetog__o{color:var(--nav-fg)}
.themetog:focus-visible{outline:1px solid var(--nav-fg);outline-offset:5px}

/* The theme change is a circular reveal that starts at the switch. The
   snapshots are stacked rather than cross-faded, and script.js animates the
   new one's clip-path outwards from the switch's centre; the old theme simply
   sits underneath until it is covered. Browsers without view transitions fall
   back to the .is-theming crossfade. */
::view-transition-old(root),
::view-transition-new(root){animation:none;mix-blend-mode:normal}
::view-transition-old(root){z-index:1}
::view-transition-new(root){z-index:2}

/* ── hero ───────────────────────────────────────────────── */
.hero{
  position:relative;min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:0 var(--gut) var(--gut);overflow:hidden;
}
.hero__canvas{
  position:absolute;inset:0;width:100%;height:100%;
  z-index:0;pointer-events:none;
}
.hero__inner{position:relative;z-index:2;margin-bottom:clamp(24px,4vw,54px)}
/* On the light theme the funnel's stem is a near-black object crossing
   near-black type, and the letters behind it disappear. White type in
   difference blend inverts against whatever is actually behind each glyph:
   over the paper it comes back as near-black, over the stem as near-white.
   The blend has to sit on .hero__inner, not on the h1 - .hero__inner is
   position+z-index, so it is a stacking context, and a blend applied inside it
   would be isolated from the canvas and blend with nothing (the same trap the
   nav was in). It also depends on html carrying the page background: if body's
   background propagated to the canvas instead, there would be no backdrop here
   to difference against. Dark keeps plain white type - the funnel is dark on
   black there, so nothing is lost, and difference would turn the rings' violet
   highlights green where they cross a letter. */
:root[data-theme="light"] .hero__inner{mix-blend-mode:difference;color:#fff}
.hero__line{font-size:clamp(2.5rem,8.4vw,6.2rem);max-width:16ch}
.hero__foot{
  position:relative;z-index:2;display:flex;justify-content:space-between;
  align-items:flex-end;gap:20px;border-top:1px solid var(--line);padding-top:14px;
}
.scrollcue{animation:cue 2.6s ease-in-out infinite}
@keyframes cue{0%,100%{opacity:.35}50%{opacity:1}}

/* ── chapter shell ──────────────────────────────────────── */
.chapter{position:relative;padding:clamp(64px,11vh,148px) var(--gut);overflow:clip}
.idx{
  position:absolute;top:clamp(20px,3vh,40px);left:var(--gut);
  color:var(--g2);z-index:5;
}
.chapter__tag{
  display:block;color:var(--violet);margin-bottom:clamp(28px,5vw,72px);
  padding-top:clamp(18px,3vh,34px);
}
.chapter__body{position:relative;z-index:2}

/* oversized parallax plate */
.plate{
  position:absolute;left:0;right:0;top:-18%;height:136%;
  z-index:0;pointer-events:none;will-change:transform;
}
.plate__grain{
  position:absolute;inset:0;
  background:
    radial-gradient(ellipse 70% 50% at 78% 22%,rgba(139,74,255,.20),transparent 62%),
    radial-gradient(ellipse 60% 45% at 12% 78%,rgba(59,16,128,.30),transparent 60%),
    repeating-linear-gradient(115deg,var(--tex-fine) 0 1px,transparent 1px 7px);
  filter:blur(.2px);
}
.plate--how .plate__grain{
  background:
    radial-gradient(ellipse 55% 60% at 20% 30%,rgba(139,74,255,.16),transparent 60%),
    repeating-linear-gradient(-72deg,var(--tex-mid) 0 1px,transparent 1px 11px);
}

/* 01 · about - per-character reveal */
/* The paragraph is only ~0.4vh tall, so an unpinned reveal finished inside two
   thirds of a screen of scrolling - much too fast to read along with. It is held
   sticky over a runway instead: the text does not move while the characters
   light, so the reveal can take as long as it likes and every line stays
   readable to the end. Starting later without this would only make it faster. */
.about-run{position:relative;height:215vh}
#about .chapter__body{position:sticky;top:22vh}
.reveal-copy{
  font-size:clamp(1.35rem,3.5vw,3rem);line-height:1.22;
  letter-spacing:-.02em;max-width:26ch;font-weight:400;
}
.reveal-copy .w{display:inline-block}
.reveal-copy .ch{display:inline-block;color:var(--off)}

/* 02 · what i do - the skills reel.
   The whole row is held sticky over a scroll runway while the word list travels
   UP through a masked window: words enter from the bottom, exit the top, and
   exactly one - whichever is nearest the middle of the window - is lit. */
.chapter--services{overflow:visible}
.mesh{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    repeating-linear-gradient(60deg,var(--tex-mesh) 0 1px,transparent 1px 68px),
    repeating-linear-gradient(-60deg,var(--tex-mesh) 0 1px,transparent 1px 68px),
    repeating-linear-gradient(0deg,var(--tex-mesh-2) 0 1px,transparent 1px 59px);
  -webkit-mask-image:radial-gradient(ellipse 62% 68% at 76% 52%,#000 0%,rgba(0,0,0,.55) 46%,transparent 82%);
  mask-image:radial-gradient(ellipse 62% 68% at 76% 52%,#000 0%,rgba(0,0,0,.55) 46%,transparent 82%);
}
/* The floor has to leave room for the whole reel to travel while the block is
   still pinned. On a short viewport 215vh fell under that, so the reel had to
   run faster than the scroll to finish in time. */
.serv-run{position:relative;z-index:2;height:clamp(1550px,215vh,2200px)}
.serv{
  position:sticky;top:clamp(74px,12vh,132px);
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.8fr);
  gap:clamp(28px,5vw,100px);align-items:start;
}
.serv__say .lede{margin-top:clamp(22px,3vw,40px)}
.ghost{
  display:inline-flex;align-items:center;gap:clamp(28px,4vw,64px);
  border:1px solid var(--line-2);border-radius:2px;
  padding:.9em 1.15em;margin-top:clamp(26px,4vw,52px);
  color:var(--g3);transition:border-color .4s,color .4s,gap .4s var(--ease);
}
.ghost i{font-style:normal}
.ghost:hover{border-color:var(--violet);color:var(--violet-soft);gap:clamp(36px,5vw,84px)}

/* the window the words travel through - faded at both ends so they arrive and
   leave rather than popping */
/* Height is five words, not a slice of the viewport. Tying it to vh made the
   window as tall as the entire list - nine of ten words on screen at once, so
   nothing read as travelling. Deriving it from the word metrics keeps exactly
   five in frame at every width, and keeps the two from drifting apart. */
.skills__win{
  --skill-size:clamp(1.55rem,3.5vw,3rem);--skill-line:1.16;--skill-rows:5;
  position:relative;overflow:hidden;
  height:calc(var(--skill-size) * var(--skill-line) * var(--skill-rows));
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 17%,#000 83%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 17%,#000 83%,transparent 100%);
}
.skills{display:flex;flex-direction:column;will-change:transform}
.skills li{
  font-size:var(--skill-size);letter-spacing:-.032em;line-height:var(--skill-line);
  color:var(--off);font-weight:400;
  transition:color .45s var(--ease),transform .45s var(--ease),opacity .45s var(--ease);
}
.skills li.is-on{color:var(--tx-hi);transform:translateX(.1em)}
.skills li:hover{color:var(--violet-soft)}

@media(max-width:900px){
  /* No reel on a phone - the row can't be held still and read at the same time.
     It becomes a ruled list instead of a floating block of grey words, and the
     highlight is driven by scroll position so the one-at-a-time idea survives. */
  .serv-run{height:auto}
  .serv{position:static;grid-template-columns:1fr}
  .skills__win{height:auto;overflow:visible;
    -webkit-mask-image:none;mask-image:none;
    margin-top:clamp(26px,5vw,44px);border-top:1px solid var(--line-3)}
  .skills{transform:none!important}
  .skills li{
    color:var(--off-hi);border-bottom:1px solid var(--line-3);
    padding:.5em .1em;font-size:clamp(1.4rem,7vw,2rem);
  }
  .skills li.is-on{color:var(--tx-hi);transform:translateX(.14em)}
}

/* 03 · how i work - the light system.
   Full-bleed bands. Whichever one is nearest the middle of the viewport is
   lit: a solid violet fill, with the light spilling out of the top and bottom
   edges into the black. Everything else sits grey and unlit. */
.chapter--how{padding-bottom:clamp(60px,9vh,120px)}
.how__head{max-width:20ch}
.how__sub{margin-top:1.4em}

.lit{
  position:relative;z-index:2;
  margin:clamp(34px,5vw,72px) calc(-1 * var(--gut)) 0;
}
/* All three bands are meant to sit on ONE screen - each is roughly a third of
   the viewport, and the light sweeps down them as you scroll. Earlier versions
   made each band 64vh, so only one was ever visible and the whole comparison
   was lost. Keep them compact. */
.band{
  position:relative;isolation:isolate;cursor:default;
  min-height:clamp(224px,29vh,330px);
  display:grid;place-items:center;
  padding:clamp(18px,2.6vh,34px) var(--gut);text-align:center;
}
/* the fill IS the band - hard top and bottom edge, bright lip, tight glow */
.band__wash{
  position:absolute;inset:0;
  z-index:-1;background:var(--violet-band);opacity:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.55),inset 0 -1px 0 rgba(255,255,255,.3);
  transition:opacity .5s var(--ease);
}
/* tight falloff - a neon tube throws a short, dense glow, not a soft blur */
.band__wash::before,.band__wash::after{
  content:"";position:absolute;left:0;right:0;height:clamp(52px,9vh,110px);
  pointer-events:none;
}
.band__wash::before{
  bottom:100%;
  background:linear-gradient(to top,rgba(124,58,237,.80),rgba(124,58,237,.20) 46%,rgba(124,58,237,0));
}
.band__wash::after{
  top:100%;
  background:linear-gradient(to bottom,rgba(124,58,237,.80),rgba(124,58,237,.20) 46%,rgba(124,58,237,0));
}
.band.is-lit .band__wash{opacity:1}
/* A neon tube reads as light because the room is dark. On paper the same
   spill has nothing to light up - it just bleeds a violet haze over the
   background and fights the type next to it. So on the light theme the tube
   becomes an ink block instead: same hard edges, same flood, no falloff. */
:root[data-theme="light"] .band__wash::before,
:root[data-theme="light"] .band__wash::after{display:none}
:root[data-theme="light"] .band__wash{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28),inset 0 -1px 0 rgba(0,0,0,.16);
}
/* a hint that the band responds to the pointer, before it is the lit one */
.band:not(.is-lit):hover h3{color:var(--tx-1)}

.band__in{max-width:60ch}
.band__head{display:flex;align-items:flex-start;justify-content:center;gap:.55em}
.band__n{
  color:var(--violet);padding-top:.55em;
  transition:color .6s var(--ease);
}
.band h3{
  font-size:clamp(1.7rem,4.2vw,3.4rem);color:var(--tx-2);
  transition:color .6s var(--ease);
}
.band__rule{
  display:block;height:1px;background:var(--line-2);
  margin:clamp(11px,1.5vw,20px) auto;width:100%;
  transition:background .6s var(--ease);
}
.band p{
  color:var(--g2);max-width:50ch;margin:0 auto;
  line-height:1.65;letter-spacing:.055em;
  font-size:calc(var(--label) * 1.28);
  transition:color .6s var(--ease);
}
.band.is-lit .band__n{color:rgba(255,255,255,.62)}
.band.is-lit h3{color:#fff}
.band.is-lit .band__rule{background:rgba(0,0,0,.28)}
.band.is-lit p{color:rgba(255,255,255,.85)}

/* 04 · the chariot - the reference's mirrored-headline device: the same line
   said twice with the roles swapped, the second one dimmed to grey. */
.chapter--chariot{overflow:clip}
.mirror{max-width:22ch}
.mirror__a,.mirror__b{
  display:block;font-size:clamp(1.7rem,4vw,3rem);
  letter-spacing:-.028em;line-height:1.06;
}
.mirror__a{color:var(--paper)}
.mirror__b{color:var(--tx-3)}
.chariot__grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.72fr);
  gap:clamp(30px,5vw,90px);margin-top:clamp(30px,4vw,60px);align-items:start;
}
.chariot__cols{display:grid;gap:clamp(18px,2.4vw,32px)}
@media(max-width:940px){.chariot__grid{grid-template-columns:1fr}}

/* the visual sits in a masked block that opens on scroll - the reference frames
   its section image the same way, clipped with a caption underneath */
.frame{margin:0}
.frame__in{
  position:relative;overflow:hidden;border:1px solid var(--line-3);border-radius:3px;
  aspect-ratio:4/5;background:var(--sunken);
  clip-path:inset(0 0 100% 0);
}
.frame__in img{
  width:100%;height:100%;object-fit:cover;display:block;
  /* an 1830 painting is warmer and busier than the rest of the page; pull the
     saturation back a touch so it sits in the palette without being recoloured */
  filter:saturate(.9) contrast(1.02);
}
/* faint violet wash + scanlines so the plate belongs to the same surface as the
   rest of the site, without tinting the artwork itself */
.frame__in::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(ellipse 78% 64% at 50% 50%,transparent 38%,rgba(59,16,128,.22) 100%),
    repeating-linear-gradient(0deg,var(--tex-scan) 0 1px,transparent 1px 4px);
  mix-blend-mode:soft-light;
}
.frame figcaption{
  display:grid;gap:.5em;color:var(--g2);margin-top:1.1em;max-width:40ch;
}
.frame__credit{color:var(--g1)}
.chariot__kicker{
  margin-top:clamp(38px,6vw,84px);max-width:26ch;
  font-size:clamp(1.5rem,3.4vw,2.7rem);line-height:1.12;
}
.chariot__kicker span{color:var(--violet)}

/* 05 · track record */
.record__cols{margin-top:clamp(30px,4vw,58px)}
.record__cols .lede{max-width:70ch}
.roles{margin-top:clamp(34px,5vw,74px);border-top:1px solid var(--line)}
.roles li{
  display:grid;grid-template-columns:minmax(180px,1.1fr) 2fr auto;
  gap:clamp(10px,2vw,30px);align-items:baseline;
  border-bottom:1px solid var(--line);padding:1.15em 0;
  position:relative;transition:padding-left .4s var(--ease);
}
.roles li::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:0;
  background:var(--violet);opacity:.09;transition:width .45s var(--ease);
}
.roles li:hover{padding-left:.9em}
.roles li:hover::before{width:100%}
.roles__co{font-size:clamp(1rem,1.5vw,1.35rem)}
.roles__ttl{color:var(--g3)}
.roles__yr{color:var(--violet);text-align:right;white-space:nowrap}
.record__edu{margin-top:clamp(22px,3vw,40px)}

/* ── 05 · BEFORE // AFTER - the pinned set piece ─────────── */
.flip{position:relative;height:600vh}
.flip__pin{
  position:sticky;top:0;height:100svh;overflow:hidden;
  display:flex;flex-direction:column;
  padding:var(--gut);
}
/* backdrop: a grain/streak texture so the pinned stage isn't a flat black
   rectangle, plus a violet bloom that grows as the scroll crosses into AFTER */
.flip__bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.flip__grain{
  position:absolute;inset:-10%;
  background:
    radial-gradient(ellipse 60% 45% at 18% 12%,var(--tex-bloom),transparent 62%),
    radial-gradient(ellipse 50% 60% at 88% 82%,var(--tex-mid),transparent 66%),
    repeating-linear-gradient(97deg,var(--tex-fine) 0 1px,transparent 1px 13px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E");
  background-size:auto,auto,auto,190px 190px;
  opacity:.72;
}
.flip__bloom{
  position:absolute;left:34%;top:70%;width:165vmax;height:120vmax;
  translate:-50% -50%;opacity:0;
  background:var(--flip-bloom);
  filter:blur(10px);
}
/* Spread this wide and pale over paper and it is fog, not a bloom - it washes
   the whole stage lavender and the copy sits in the middle of it. Tighter,
   deeper and barely blurred reads as a deliberate field of colour instead. */
:root[data-theme="light"] .flip__bloom{
  width:104vmax;height:76vmax;left:38%;top:66%;filter:blur(3px);
}
.flip__head{position:relative;z-index:2;flex:0 0 auto;padding-top:clamp(28px,5vh,54px)}
.flip__head .idx{top:0}
.flip__title{
  position:relative;display:flex;flex-wrap:wrap;align-items:baseline;
  gap:.3em;font-weight:600;font-size:clamp(2rem,7vw,5.4rem);
}
.flip__word{position:relative;display:inline-block;transition:none}
.flip__word--after{position:absolute;left:0;top:0;color:var(--violet-soft);opacity:0}
.flip__mark{color:var(--g1);font-weight:400}
/* the mark's © belongs at the cap line, not on the baseline beside the word.
   -1.42em of the child works out to -0.48em of the parent, which puts the
   glyph's top on the parent's cap height. */
.flip__c{
  font-size:.34em;vertical-align:baseline;
  position:relative;top:-1.42em;margin-left:.08em;
}
.flip__panels{position:relative;z-index:2;flex:1 1 auto}
.panel{
  position:absolute;left:0;right:0;bottom:8%;max-width:64ch;
  opacity:0;will-change:transform,opacity;
}
.panel__n{color:var(--violet);display:block;margin-bottom:.9em}
.panel h3{font-size:clamp(1.7rem,4.6vw,3.4rem);margin-bottom:.55em}
.panel p{color:var(--tx-2);line-height:1.75;letter-spacing:.06em;max-width:56ch;
  font-size:calc(var(--label) * 1.28)}
.panel--after .panel__n{color:var(--violet-soft)}
.flip__rail{position:absolute;z-index:2;left:var(--gut);right:var(--gut);bottom:var(--gut);height:1px;background:var(--line-2)}
.flip__rail i{display:block;height:100%;width:0;background:var(--violet)}

/* ── 06 · the system ────────────────────────────────────── */
.system{position:relative;height:420vh}
.system__pin{
  position:sticky;top:0;height:100svh;overflow:hidden;
  padding:var(--gut);display:flex;flex-direction:column;
}
.system__pin .idx{top:var(--gut)}
.system__pin .chapter__tag{padding-top:clamp(28px,5vh,54px)}
.system__pin h2{max-width:22ch}
.system__stage{flex:1;display:flex;flex-direction:column;justify-content:center;gap:1.4em}
.system__word{
  font-size:clamp(2.6rem,11vw,9rem);color:var(--violet);
  letter-spacing:-.04em;line-height:.9;
}
.system__copy{
  color:var(--g3);max-width:52ch;line-height:1.7;letter-spacing:.05em;
  text-transform:none;font-size:calc(var(--label) * 1.22);
}
.system__rail{
  display:grid;grid-template-columns:repeat(5,1fr);gap:2px;
  border-top:1px solid var(--line);padding-top:14px;
}
.system__rail li{
  color:var(--g1);transition:color .4s;position:relative;padding-top:12px;
}
.system__rail li::before{
  content:"";position:absolute;top:-15px;left:0;right:2px;height:1px;
  background:var(--violet);transform:scaleX(0);transform-origin:left;
  transition:transform .5s var(--ease);
}
.system__rail li.is-on{color:var(--paper)}
.system__rail li.is-on::before{transform:scaleX(1)}
.system__rail i{font-style:normal;color:var(--violet);margin-right:.6em}

/* ── 08 · izna foundation - cream inversion ─────────────── */
.invert{background:var(--inv-bg);color:var(--inv-fg)}
.invert .idx{color:var(--inv-dim)}
.invert .chapter__tag{color:var(--inv-tag)}
.invert .lede{color:var(--inv-lede)}
/* The cross-hatch on the inversion. Same idea as .mesh in §02 - hairlines and
   a radial mask so it fades rather than stopping - but finer, and drawn from
   inversion-aware tokens: the block is cream on the dark theme and near-black
   on the light one, so the --tex-* tokens are the wrong polarity here. */
.weave{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    repeating-linear-gradient(45deg,var(--inv-tex) 0 1px,transparent 1px 14px),
    repeating-linear-gradient(-45deg,var(--inv-tex-2) 0 1px,transparent 1px 14px);
  -webkit-mask-image:radial-gradient(ellipse 74% 78% at 80% 42%,#000 0%,rgba(0,0,0,.5) 48%,transparent 84%);
  mask-image:radial-gradient(ellipse 74% 78% at 80% 42%,#000 0%,rgba(0,0,0,.5) 48%,transparent 84%);
}
/* .chapter__tag and the heading are static, so a positioned .weave would paint
   over them - same reason .chapter__body carries a z-index. */
#izna .chapter__tag,#izna h2,#izna .izna{position:relative;z-index:2}

/* Words left, photographs right. The copy comes first in the markup, so the
   stacked order under 820px is copy then picture without any reordering. */
.izna{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(26px,4.5vw,72px);align-items:start;
  margin-top:clamp(32px,5vw,68px);
}
@media(max-width:820px){.izna{grid-template-columns:1fr;gap:clamp(24px,5vw,36px)}}
.izna__copy{max-width:62ch}
.izna__copy .lede+.lede{margin-top:1.2em}
.izna__meta{
  display:block;margin-top:clamp(20px,2.6vw,32px);
  color:var(--inv-dim);letter-spacing:.13em;
}
/* One photograph at a time with an arrow either side, and the whole thing to
   the left of the copy. A rotation, not a scroller: the frames are stacked in
   one box and cross-faded, which is what lets a set of mixed aspect ratios sit
   in a single frame without the box resizing between them. */
.izna__shots{margin:0}
.izna__stage{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:clamp(8px,1.4vw,18px);
}
.izna__stage:focus-visible{outline:1px solid var(--inv-tag);outline-offset:6px}
.izna__btn{
  width:clamp(34px,3.2vw,46px);height:clamp(34px,3.2vw,46px);
  display:grid;place-items:center;
  background:none;border:1px solid var(--inv-line);border-radius:2px;
  color:var(--inv-dim);font-size:15px;cursor:pointer;
  transition:border-color .3s,color .3s;
}
.izna__btn:hover{border-color:var(--inv-tag);color:var(--inv-fg)}
.izna__frame{
  position:relative;aspect-ratio:3/2;overflow:hidden;
  border:1px solid var(--inv-line);background:var(--inv-line);
}
.izna__shot{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:1;
}
/* Until the script takes the deck over - and under reduced motion, where it
   never does - there is no dealing to be done, so one frame stands on its own
   rather than four stacking on top of each other. */
.izna__frame:not(.is-live) .izna__shot:nth-child(n+2){display:none}
/* Parked off the frame, ready to be dealt. Order matters below: is-rev flips
   which side they wait on, and is-under / is-on come after so the two cards
   actually in the frame are not dragged out to a side by it. */
.izna__frame.is-live .izna__shot{transform:translate3d(104%,0,0) rotate(2.5deg)}
.izna__frame.is-live.is-rev .izna__shot{transform:translate3d(-104%,0,0) rotate(-2.5deg)}
.izna__frame.is-live .izna__shot.is-under{transform:none;z-index:2}
.izna__frame.is-live .izna__shot.is-on{
  transform:none;z-index:3;
  transition:transform .62s var(--ease);
}
.izna__shots figcaption{
  display:flex;justify-content:space-between;gap:16px;
  margin-top:clamp(12px,1.6vw,20px);color:var(--inv-dim);
}

/* ── 08 · house rules ───────────────────────────────────── */
.rules{padding-bottom:clamp(62px,9vh,120px);overflow:clip}
.marquee{
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  overflow:hidden;padding:clamp(14px,2vw,26px) 0;margin-bottom:clamp(50px,8vh,110px);
}
.marquee__track{
  display:flex;gap:.6em;width:max-content;will-change:transform;
  font-size:clamp(2.2rem,7.2vw,6rem);letter-spacing:-.03em;line-height:1;
  font-weight:500;
}
.marquee__track span{color:transparent;-webkit-text-stroke:1px var(--g1);white-space:nowrap}
.marquee__track span:nth-child(even){color:var(--violet);-webkit-text-stroke:0}
.rules__head{padding:clamp(26px,4vh,44px) var(--gut) 0;position:relative}
.rules__head .idx{top:0}
.rules__list{margin-top:clamp(40px,6vw,84px);padding:0 var(--gut);border-top:1px solid var(--line)}
.rules__list li{
  display:grid;grid-template-columns:5.5em 1fr;gap:clamp(10px,2vw,28px);
  align-items:baseline;border-bottom:1px solid var(--line);
  padding:clamp(.85em,1.5vw,1.25em) 0;position:relative;
  transition:padding-left .45s var(--ease);
}
.rules__list li>span{color:var(--violet)}
.rules__list li>b{
  font-weight:400;font-size:clamp(1rem,2.1vw,1.65rem);
  letter-spacing:-.01em;color:var(--tx-hi);
}
.rules__list li::after{
  content:"";position:absolute;left:0;bottom:-1px;height:1px;width:0;
  background:var(--violet);transition:width .55s var(--ease);
}
.rules__list li:hover{padding-left:1em}
.rules__list li:hover::after{width:100%}
.rules__list li:hover>b{color:var(--violet-soft)}

/* ── 09 · loud in public ────────────────────────────────── */
.loud{padding:clamp(62px,10vh,132px) 0;overflow:clip}
.loud__head{padding:clamp(26px,4vh,44px) var(--gut) 0;position:relative}
.loud__head .idx{top:0}
/* stat row - the only hard numbers on the page, so they get display size */
.stats{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(14px,2vw,32px);padding:clamp(44px,6vw,90px) var(--gut) 0;
  border-top:1px solid var(--line);margin-top:clamp(40px,6vw,80px);
}
.stats li{display:flex;flex-direction:column;gap:.5em}
.stats b{
  font-family:"Geist",sans-serif;font-weight:400;color:var(--violet);
  font-size:clamp(2.1rem,5vw,4.2rem);letter-spacing:-.04em;line-height:.9;
}
.stats span{color:var(--g2);max-width:18ch}
@media(max-width:820px){.stats{grid-template-columns:repeat(2,1fr);row-gap:clamp(24px,4vw,40px)}}

/* episode list */
.eps{margin-top:clamp(22px,3vw,40px);border-top:1px solid var(--line)}
.eps a{
  display:grid;grid-template-columns:4.6em 1fr auto 3em;
  gap:clamp(10px,1.6vw,26px);align-items:baseline;
  border-bottom:1px solid var(--line);padding:.95em 0;
  position:relative;transition:padding-left .4s var(--ease);
}
.eps a:hover{padding-left:.85em}
.eps a::after{
  content:"";position:absolute;left:0;bottom:-1px;height:1px;width:0;
  background:var(--violet);transition:width .5s var(--ease);
}
.eps a:hover::after{width:100%}
.eps__n{color:var(--violet)}
.eps b{font-weight:400;font-size:clamp(.95rem,1.35vw,1.2rem);letter-spacing:-.01em}
.eps a:hover b{color:var(--violet-soft)}
.eps__g{color:var(--g2);text-align:right}
.eps__t{color:var(--g1);text-align:right}
.pod__all{display:inline-block;margin-top:1.7em;color:var(--violet)}
.pod__all:hover{color:var(--violet-soft)}
@media(max-width:700px){
  .eps a{grid-template-columns:4.2em 1fr;row-gap:2px}
  .eps__g{grid-column:2;text-align:left}
  .eps__t{display:none}
}

.pod{
  display:grid;grid-template-columns:minmax(220px,340px) 1fr;
  gap:clamp(24px,4vw,64px);align-items:center;
  padding:clamp(44px,7vw,100px) var(--gut) clamp(40px,6vw,90px);
}
.pod__art img{border-radius:3px;border:1px solid var(--line-3)}
/* The cover is a circle of artwork on a square black backing. Against black
   the backing is invisible; against paper it is a hole punched in the page.
   So on the light theme the backing is clipped away and the disc sits on the
   paper directly - the artwork itself is untouched, and the circle is measured
   from the file (centre 49.6%/50.9%, radius 38.5% of the width). */
:root[data-theme="light"] .pod__art img{
  border:0;border-radius:0;
  clip-path:circle(38.5% at 49.6% 50.9%);
  /* clipping the backing costs the block about a quarter of its width, so put
     the visual weight back without overflowing the grid column */
  transform:scale(1.18);
}
.pod__copy h3{font-size:clamp(1.6rem,3.6vw,2.9rem);margin:.5em 0 .8em}
@media(max-width:760px){.pod{grid-template-columns:1fr}.pod__art{max-width:260px}}

/* The wall is a real horizontal scroller: the scroll-linked drift, the arrows and
   the keyboard all move the same `scrollLeft`, so nothing fights anything. */
.wall{
  overflow-x:auto;overflow-y:hidden;padding-left:var(--gut);
  scrollbar-width:none;-ms-overflow-style:none;
}
.wall::-webkit-scrollbar{display:none}
.wall:focus-visible{outline:1px solid var(--violet);outline-offset:4px}
.wall__track{display:flex;gap:clamp(12px,1.6vw,26px);width:max-content}
.wall__track::after{content:'';flex:0 0 var(--gut)}

.wall__bar{
  display:flex;align-items:center;gap:clamp(16px,3vw,40px);
  padding:0 var(--gut) clamp(16px,2.4vw,26px);
}
.wall__rail{flex:1;height:1px;background:var(--line-3);position:relative}
.wall__rail i{
  position:absolute;left:0;top:0;height:100%;width:12%;
  background:var(--violet);transition:width .2s linear,left .2s linear;
}
.wall__nav{display:flex;gap:8px}
.wall__btn{
  width:clamp(38px,3.4vw,46px);height:clamp(38px,3.4vw,46px);
  display:grid;place-items:center;
  background:none;border:1px solid var(--line-2);border-radius:2px;
  color:var(--g3);font-size:15px;cursor:pointer;
  transition:border-color .3s,color .3s,background .3s;
}
.wall__btn:hover:not(:disabled){border-color:var(--violet);color:var(--violet-soft)}
.wall__btn:disabled{opacity:.3;cursor:default}
@media(max-width:700px){
  .wall__bar{gap:14px;padding-bottom:14px}
  .wall__btn{width:42px;height:42px}
}
.wall__card{margin:0;width:clamp(220px,26vw,380px);flex:0 0 auto}
.wall__card img{
  width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;
  border:1px solid var(--line-3);border-radius:3px;
  /* monochrome at rest, full colour under the cursor - the dim is what makes the
     colour arriving read as a change; plain grayscale(1) was too subtle on
     creatives that are already mostly black, white and violet */
  filter:grayscale(1) brightness(.78) contrast(1.04);
  transition:filter .45s var(--ease),transform .45s var(--ease);
}
.wall__card:hover img,.wall__card:focus-within img{
  filter:grayscale(0) brightness(1) contrast(1);transform:translateY(-6px);
}
/* No cursor means no way to reveal the colour, so touch devices get it outright -
   on a phone these images are the content, not a hover reward. */
@media (hover:none){
  .wall__card img{filter:grayscale(0) brightness(1) contrast(1)}
}
.wall__card figcaption{color:var(--g2);margin-top:.9em}

/* ── 10 · origin ────────────────────────────────────────── */
.origin{position:relative;padding:clamp(72px,13vh,172px) var(--gut);overflow:clip}
.origin__bg{position:absolute;inset:0;z-index:0}
.origin__bg::before{
  content:"";position:absolute;inset:-20%;
  background:var(--origin-wash);
  animation:drift 26s ease-in-out infinite alternate;
}
.origin__scan{
  position:absolute;inset:0;
  background:repeating-linear-gradient(0deg,var(--tex-scan-2) 0 1px,transparent 1px 4px);
  mix-blend-mode:overlay;
}
@keyframes drift{from{transform:scale(1) translate(0,0)}to{transform:scale(1.14) translate(-3%,2%)}}
.origin__body{position:relative;z-index:2;max-width:66ch;margin-top:clamp(26px,4vw,54px)}
.origin__body h2{margin-bottom:clamp(28px,4vw,56px);max-width:20ch}
.origin__body p{font-size:clamp(15px,1.25vw,19px);line-height:1.75;color:var(--tx-1);margin-bottom:1.35em}
.origin__body p.origin__word{
  font-size:clamp(3rem,15vw,12rem);color:var(--violet);
  letter-spacing:-.05em;line-height:.85;margin-top:.15em;margin-bottom:0;
}

/* ── parked fixed CTA ───────────────────────────────────── */
.parked{
  position:fixed;right:var(--gut);bottom:var(--gut);z-index:110;
  background:var(--violet-deep);border:1px solid var(--violet);
  padding:14px 18px;border-radius:3px;max-width:250px;
  opacity:0;transform:translateY(20px);pointer-events:none;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.parked.is-on{opacity:1;transform:none;pointer-events:auto}
.parked__k{display:block;color:var(--violet-mist);margin-bottom:.6em}
.parked a{color:#fff}
.parked a:hover{color:var(--violet-mist)}
@media(max-width:700px){.parked{display:none}}

/* ── 11 · faq ───────────────────────────────────────────── */
.faq{position:relative;padding:clamp(64px,11vh,148px) var(--gut)}
.faq h2{max-width:22ch}
.faq__list{margin-top:clamp(40px,6vw,84px);border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  display:grid;grid-template-columns:5em 1fr auto;gap:clamp(10px,2vw,28px);
  align-items:baseline;padding:clamp(1em,2vw,1.5em) 0;cursor:pointer;
  list-style:none;transition:padding-left .4s var(--ease);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{padding-left:.8em}
.faq summary>.mono{color:var(--violet)}
.faq__q{font-size:clamp(1.05rem,2.2vw,1.7rem);letter-spacing:-.015em}
.faq summary i{
  width:12px;height:12px;position:relative;justify-self:end;align-self:center;
}
.faq summary i::before,.faq summary i::after{
  content:"";position:absolute;background:var(--violet);
  transition:transform .4s var(--ease),opacity .3s;
}
.faq summary i::before{left:0;right:0;top:50%;height:1px}
.faq summary i::after{top:0;bottom:0;left:50%;width:1px}
.faq details[open] summary i::after{transform:scaleY(0)}
.faq__a{overflow:hidden}
.faq__a p{color:var(--g3);line-height:1.7;max-width:64ch;padding:0 0 clamp(1.4em,2.4vw,2.2em) 5.9em}
@media(max-width:640px){
  .faq summary{grid-template-columns:3.4em 1fr auto}
  .faq__a p{padding-left:0}
}

/* ── footer ─────────────────────────────────────────────
   One full-bleed band, like the reference: the question in cream running to the
   left edge, the answer as a light block hard against the right. No gutter. */
.foot{padding:0;border-top:1px solid var(--line)}
.signoff{
  display:flex;align-items:stretch;justify-content:space-between;
  min-height:clamp(104px,16vh,176px);
}
.signoff__q,.signoff__a{
  display:flex;align-items:center;
  font-size:clamp(1.35rem,4.2vw,3.15rem);
  letter-spacing:-.03em;line-height:1;
}
.signoff__q{flex:1;padding:0 var(--gut);color:var(--tx-hi)}
.signoff__a{
  padding:0 clamp(26px,5vw,86px);background:var(--inv-bg);color:var(--inv-fg);
  transition:background .45s var(--ease),color .45s var(--ease),padding .45s var(--ease);
}
.signoff:hover .signoff__a{
  background:var(--violet-band);color:#fff;
  padding-inline:clamp(38px,7vw,124px);
}
.foot__meta{
  display:flex;flex-wrap:wrap;gap:clamp(12px,2.4vw,40px);
  color:var(--g2);border-top:1px solid var(--line);
  padding:16px var(--gut);
}
.foot__meta a:hover{color:var(--violet-soft)}

/* ── responsive collapse ────────────────────────────────── */
@media(max-width:1100px){.services{grid-template-columns:repeat(3,1fr)}}
@media(max-width:900px){
  /* The transparent bar works on desktop: it sits over one section at a time and
     hides on scroll-down. On a phone it wraps to two rows and the page scrolls
     *underneath* it, so the section index and tag ended up occupying the same
     pixels as the brand and the links - two unrelated texts on top of each other.
     Give the bar the page's own ground (and the inverted ground over §07) so
     content passes behind it. Desktop is untouched. */
  .nav{
    gap:10px;
    padding:11px var(--gut) 11px;
    border-bottom:1px solid var(--nav-line);
  }
  .nav__brand{line-height:1.3}
  /* Drop the inset and tighten the gaps, but keep the links on the same line as
     everything else - with MAIL / PODCAST / LINKEDIN the row only needs ~646px,
     so there is no reason to spend a second row on it here. */
  .nav__links{gap:22px;padding-inline:0 clamp(12px,2.4vw,26px)}
  /* an opaque bar would otherwise swallow the heading on an anchor jump */
  main > section{scroll-margin-top:72px}
  .band{min-height:clamp(250px,34vh,380px)}
  .band__wash::before,.band__wash::after{height:clamp(40px,7vh,80px)}
  .roles li{grid-template-columns:1fr auto;row-gap:2px}
  .roles__ttl{grid-column:1;grid-row:2}
  .flip{height:520vh}
  /* The active marker is a segment drawn 15px above the item, which lands on
     the rail's own top border and only reads while the rail is a single row.
     In two columns every row after the first drew its line straight through
     the text of the row above it. Underline the item itself instead. */
  .system__rail{grid-template-columns:repeat(2,1fr);gap:10px 18px}
  .system__rail li{padding-top:0;padding-bottom:10px}
  .system__rail li::before{top:auto;bottom:0}
}
@media(max-width:700px){
  /* the pill's full wording is the first thing to go when space runs out */
  .nav__long{display:none}
  .nav__short{display:inline}
  .nav__links{gap:8px 20px}
}
/* Below this the single row genuinely stops fitting - 601px of content against
   the available width - so the links move to their own row underneath. */
@media(max-width:640px){
  .nav{flex-wrap:wrap}
  .nav__links{order:3;flex-basis:100%;flex-wrap:wrap;justify-content:flex-start;padding-inline:0}
  main > section{scroll-margin-top:96px}
}
/* On a phone the old rhythm burned ~320px of black between the end of one
   section's content and the next section's heading - about 40% of the screen,
   twelve times over. Tighten the section padding and pull the chapter tag up so
   the index and the tag read as one unit instead of floating apart. */
@media(max-width:700px){
  .chapter{padding:clamp(50px,7vh,64px) var(--gut)}
  .idx{top:16px}
  .chapter__tag{padding-top:2px;margin-bottom:clamp(18px,4vw,26px)}
  .origin{padding:clamp(54px,8vh,72px) var(--gut)}
  .loud{padding:clamp(48px,7vh,64px) 0}
  .rules{padding-bottom:clamp(30px,4vh,40px)}
  .faq{padding:clamp(50px,7vh,64px) var(--gut)}
  .chapter--how{padding-bottom:clamp(18px,2.5vh,26px)}
  .eyebrow--float{margin-top:clamp(20px,4vw,32px)}
  .lit{margin-top:clamp(24px,4vw,40px)}
  .roles,.rules__list,.faq__list,.eps,.services{margin-top:clamp(24px,5vw,40px)}
}
@media(max-width:560px){
  /* three items share the top row with the brand and the pill; on a 320px
     screen the toggle is the one with slack to give */
  .themetog{gap:.3em;letter-spacing:.08em}
  .services{grid-template-columns:repeat(2,1fr)}
  .rules__list li{grid-template-columns:3.6em 1fr}
  .system__rail{grid-template-columns:1fr}
  .system__rail li:not(.is-on){display:none}
}

/* ── reduced motion ─────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .reveal-copy .ch{color:var(--tx-hi)!important;opacity:1!important;filter:none!important}
  .about-run{height:auto}
  #about .chapter__body{position:static}
  .flip{height:auto}
  .flip__pin{position:relative;height:auto;display:block}
  .flip__panels{position:static;display:grid;gap:clamp(30px,5vw,60px);margin-top:40px}
  .panel{position:static;opacity:1!important;transform:none!important}
  /* both halves are on screen at once now, so the title has to read as a pair
     and the two groups need a visible seam */
  .flip__word--after{position:static;opacity:1!important;transform:none!important}
  .flip__word--after::before{content:"/ ";color:var(--g1)}
  .flip__mark{transform:none!important}
  .panel--after:nth-child(4){border-top:1px solid var(--line);padding-top:clamp(30px,5vw,60px)}
  .system{height:auto}
  .system__pin{position:relative;height:auto}
  .system__stage{display:none}
  .band__wash{opacity:0!important;transition:none}
  .band{min-height:auto}
  .band h3{color:var(--paper)}
  .band p{color:var(--tx-2)}
  .band__rule{background:var(--violet)}
  .flip__bloom{opacity:.45!important}
  .skills li{color:var(--tx-2)}
  .skills{transform:none!important}
  .skills__win{height:auto;overflow:visible;-webkit-mask-image:none;mask-image:none}
  .serv-run{height:auto}
  .serv{position:static}
  .frame__in{clip-path:none!important}
  .frame__in img{transform:none!important}
  /* Same wrap, same collision: one column here means five rows, so the marker
     has to underline its own item rather than reach up to the rail's border. */
  .system__rail{grid-template-columns:1fr;gap:10px}
  .system__rail li{color:var(--paper);padding-top:0;padding-bottom:10px}
  .system__rail li::before{top:auto;bottom:0}
  .wall{overflow-x:auto}
  .marquee__track{transform:none!important}
  .cursor{display:none}
}
