/* ══════════════════════════════════════════════════════════════
   Anuansh Tiwari — portfolio
   Near-monochrome, heavy grain, square edges, display-scale
   grotesque. Motion-heavy and scroll-driven.
   ══════════════════════════════════════════════════════════════ */

@font-face{
  font-family:"Federant";
  src:url("../fonts/federant.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}

:root{
  /* the Lycoris palette: ink, bone type (khaki, deliberately not white)
     and one crimson — the colour of the chrome spider lily in the hero */
  --bg:#050505;
  --bg-2:#0b0a09;
  --surface:rgba(255,255,255,.028);
  --surface-2:rgba(255,255,255,.055);
  --line:rgba(255,255,255,.11);
  --line-2:rgba(255,255,255,.22);

  --text:#b6b095;      /* headlines — the specimen's bone, 9.2:1 on --bg */
  --hi:#e7e1c6;        /* brightest ink: hovers, selection, strong — was pure white */
  --ink:#050505;       /* text set on a --hi or --accent ground */
  --body:#8f8a78;      /* body copy — low contrast on purpose, 5.8:1 */
  --muted:#84806f;     /* 5.0:1 on the page background — passes AA */
  --dim:#7c7868;       /* 4.6:1 — dimmest text tier. Was #6b6b6b at 3.8:1, which the
                          comment here called decorative-only, but four pieces of real
                          text used it: .nav__role, .nav__pct, .edge and .hero__cue-text,
                          all 9–10.5px, where AA needs 4.5:1. */

  /* the one signal colour, used sparingly: bullets, active marks, counters.
     The lily itself is #e3131b; this is lifted a touch so small crimson
     text still clears AA (4.7:1 on --bg, and --ink on it the same) */
  --crimson:#e3131b;
  --accent:#ea2a31;
  --accent-ink:#050505;
  --accent-soft:rgba(234,42,49,.12);
  --accent-line:rgba(234,42,49,.4);

  --font:"Inter Tight","Inter",ui-sans-serif,system-ui,-apple-system,"Helvetica Neue",sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  /* Federant, a free Art Nouveau uncial (SIL OFL), self-hosted; the
     component's own fallback chain behind it */
  --font-display:"Federant","Uncial Antiqua","Cinzel Decorative","Iowan Old Style","Palatino Linotype",Georgia,serif;

  --shell:1320px;
  --gutter:clamp(18px,4vw,56px);

  --ease:cubic-bezier(.22,.9,.24,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  --sp:0;
  --nav-h:60px;
}

*,*::before,*::after{box-sizing:border-box}

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

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font);
  font-size:clamp(15px,.3vw + 14px,16px);
  font-weight:500;
  line-height:1.5;
  letter-spacing:-.012em;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}

/* Scroll-driven wash — near-monochrome, only a breath of hue.
   The hue used to travel by computing it inside the colour itself:
     hsl(calc(70 + var(--sp) * 180) 18% 11% / calc(.42 - var(--sp) * .12))
   which stacks a unitless calc() hue, a calc() alpha after the slash and a
   custom property in both, inside modern space-separated hsl(). Browsers do
   not all parse that the same way, and this is the backmost layer covering
   the whole viewport — so when one gets it wrong the entire page goes with
   it, in exactly this hue. Two static washes cross-faded on --sp reach the
   same place using only plain-number calc() in opacity, which is safe
   everywhere. The old base ramp (#060606 to #090909) is dropped: three
   units of grey over the full height was never visible, and body already
   paints --bg underneath. */
body::before,
body::after{
  content:"";position:fixed;inset:-20vh -10vw;z-index:-4;pointer-events:none;
}
body::before{
  opacity:calc(1 - var(--sp,0));
  background:
    radial-gradient(62vw 56vh at calc(16% + var(--sp) * 66%) calc(4% + var(--sp) * 28%),
      hsla(70,18%,11%,.42), transparent 66%),
    radial-gradient(72vw 62vh at calc(88% - var(--sp) * 72%) calc(86% - var(--sp) * 36%),
      hsla(356,48%,9%,.24), transparent 70%);
}
body::after{
  opacity:var(--sp,0);
  background:
    radial-gradient(62vw 56vh at calc(16% + var(--sp) * 66%) calc(4% + var(--sp) * 28%),
      hsla(356,44%,10%,.3), transparent 66%),
    radial-gradient(72vw 62vh at calc(88% - var(--sp) * 72%) calc(86% - var(--sp) * 36%),
      hsla(52,16%,10%,.34), transparent 70%);
}

/* ---------- ambient ---------- */
.aurora{position:fixed;inset:0;z-index:-3;pointer-events:none;overflow:hidden}
.orb{position:absolute;display:block;will-change:transform}
.orb > i{display:block;width:100%;height:100%;border-radius:50%;will-change:transform}
/* softness from gradient stops, never filter:blur() — a 90px blur on
   elements this size costs tens of frames per second on its own */
.orb--1{width:60vw;height:60vw;left:-14vw;top:-4vh}
.orb--1 > i{
  background:radial-gradient(circle closest-side,
    rgba(255,255,255,.075),rgba(255,255,255,.035) 34%,
    rgba(255,255,255,.012) 58%,rgba(255,255,255,0) 76%);
  animation:drift1 26s var(--ease) infinite alternate;
}
.orb--2{width:54vw;height:54vw;right:-12vw;top:32vh}
.orb--2 > i{
  background:radial-gradient(circle closest-side,
    rgba(234,42,49,.05),rgba(234,42,49,.022) 34%,
    rgba(234,42,49,.007) 58%,rgba(234,42,49,0) 76%);
  animation:drift2 32s var(--ease) infinite alternate;
}
.orb--3{width:52vw;height:52vw;left:24vw;bottom:-16vh}
.orb--3 > i{
  background:radial-gradient(circle closest-side,
    rgba(210,215,255,.055),rgba(210,215,255,.024) 34%,
    rgba(210,215,255,.008) 58%,rgba(210,215,255,0) 76%);
  animation:drift3 38s var(--ease) infinite alternate;
}
@keyframes drift1{to{transform:translate3d(8vw,6vh,0)}}
@keyframes drift2{to{transform:translate3d(-7vw,-8vh,0)}}
@keyframes drift3{to{transform:translate3d(6vw,-5vh,0)}}

.field{position:fixed;inset:0;z-index:-2;pointer-events:none}
.field canvas{width:100%;height:100%;display:block;opacity:.7}

/* heavy film grain — a defining texture here, not a whisper */
.grain{
  position:fixed;inset:-120px;z-index:-1;pointer-events:none;opacity:.16;
  background-image: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='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1s steps(5) infinite;
  will-change:transform;
}
@keyframes grain{
  0%{transform:translate3d(0,0,0)}      20%{transform:translate3d(-6%,4%,0)}
  40%{transform:translate3d(5%,-5%,0)}  60%{transform:translate3d(-4%,-3%,0)}
  80%{transform:translate3d(6%,5%,0)}   100%{transform:translate3d(0,0,0)}
}

/* ---------- cursor ---------- */
.cursor{position:fixed;inset:0;z-index:1;pointer-events:none;display:none;opacity:0;transition:opacity .4s var(--ease)}
.has-cursor .cursor{display:block}
.has-cursor .cursor.is-on{opacity:1}
.cursor__glow{
  position:absolute;top:0;left:0;width:520px;height:520px;margin:-260px 0 0 -260px;
  border-radius:50%;opacity:.8;
  background:radial-gradient(circle,rgba(255,255,255,.075),rgba(255,255,255,.025) 42%,transparent 68%);
  mix-blend-mode:screen;
  transition:transform .35s var(--ease),opacity .35s var(--ease);
  will-change:transform;
}
.cursor.is-hot .cursor__glow{--cs:1.4;opacity:1}

/* ---------- type ---------- */
h1,h2,h3{font-weight:700;letter-spacing:-.035em;line-height:1.02;margin:0}
p{margin:0 0 1em}
strong{color:var(--hi);font-weight:700}
em{font-style:normal;color:var(--accent)}
a{color:inherit;text-decoration:none}
::selection{background:var(--accent);color:var(--ink)}

.skip-link{
  position:fixed;top:10px;left:10px;z-index:400;padding:10px 16px;
  background:var(--hi);color:var(--ink);font-weight:700;
  transform:translateY(-200%);transition:transform .2s var(--ease);
}
.skip-link:focus-visible{transform:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

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

/* small caps label with a signal dot: ●RESEARCH 02 */
.bul{
  display:inline-block;width:7px;height:7px;background:var(--accent);
  border-radius:50%;margin-right:8px;vertical-align:1px;
}
.sec-head__idx{
  display:block;font-family:var(--font);font-weight:700;font-size:13px;
  letter-spacing:-.01em;color:var(--text);margin:0 0 22px;
}


/* ---------- progress ---------- */
.progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:120;background:rgba(255,255,255,.06)}
.progress__bar{
  display:block;height:100%;width:100%;
  transform:scaleX(var(--sp));transform-origin:0 50%;
  background:var(--accent);
}

/* ---------- nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:110;
  transition:background .4s var(--ease),backdrop-filter .4s var(--ease),border-color .4s var(--ease);
  border-bottom:1px solid transparent;
}
.nav__inner{
  width:100%;max-width:var(--shell);margin-inline:auto;
  padding:16px var(--gutter);display:flex;align-items:center;gap:24px;
  transition:padding .45s var(--ease);
}
.nav.is-condensed{
  background:rgba(6,6,6,.78);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom-color:var(--line);
}
.nav.is-condensed .nav__inner{padding-block:9px}
.nav.is-condensed .nav__role{opacity:0;max-width:0;margin-left:0}

.nav__brand{display:flex;align-items:center;gap:9px;min-width:0}
.nav__mark{
  display:grid;place-items:center;width:26px;height:26px;flex:none;
  border:1px solid var(--line-2);color:var(--text);
  transition:transform .55s var(--ease),background .3s,color .3s;
}
.nav__brand:hover .nav__mark{background:var(--hi);color:var(--ink)}
.nav__name{font-weight:700;font-size:14px;letter-spacing:-.02em;white-space:nowrap}
.nav__name::after{content:"®";font-size:9px;vertical-align:super;color:var(--dim);margin-left:1px}
.nav__role{
  font-family:var(--font-mono);font-size:10.5px;color:var(--dim);white-space:nowrap;
  overflow:hidden;max-width:180px;margin-left:6px;text-transform:uppercase;letter-spacing:.08em;
  transition:opacity .35s var(--ease),max-width .45s var(--ease);
}

.nav__links{display:flex;gap:2px;margin-left:auto;position:relative}
.nav__pill{
  position:absolute;top:50%;left:0;height:28px;margin-top:-14px;width:var(--pw,0px);
  background:rgba(255,255,255,.08);border:1px solid var(--line);
  transform:translate3d(var(--px,0px),0,0);opacity:0;pointer-events:none;
  transition:transform .5s var(--ease),width .5s var(--ease),opacity .3s var(--ease);
}
.nav__links.has-pill .nav__pill{opacity:1}
.nav__links a{
  position:relative;z-index:1;padding:6px 12px;
  font-size:13px;font-weight:600;color:var(--muted);
  transition:color .3s var(--ease);
}
.nav__links a:hover{color:var(--text)}
.nav__links a.is-active{color:var(--hi)}

.nav__meta{display:flex;align-items:center;gap:10px}
.nav__pct{
  font-family:var(--font-mono);font-size:10.5px;color:var(--dim);
  padding:4px 6px;border:1px solid var(--line);font-variant-numeric:tabular-nums;
}
.nav__pct::after{content:"%";opacity:.45}

.nav__toggle{display:none;width:38px;height:32px;padding:0;background:none;border:1px solid var(--line);cursor:pointer}
.nav__toggle span{display:block;width:15px;height:1.5px;margin:3.5px auto;background:var(--text);transition:transform .3s var(--ease)}
.nav__toggle[aria-expanded="true"] span:first-child{transform:translateY(2.5px) rotate(45deg)}
.nav__toggle[aria-expanded="true"] span:last-child{transform:translateY(-2.5px) rotate(-45deg)}

.nav__drawer{
  display:none;flex-direction:column;padding:6px var(--gutter) 18px;
  background:rgba(6,6,6,.97);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid var(--line);
}
.nav__drawer a{
  padding:12px 2px;border-bottom:1px solid var(--line);
  font-size:20px;font-weight:700;color:var(--body);
  opacity:0;transform:translateY(-8px);animation:drawerIn .4s var(--ease-out) forwards;
}
.nav__drawer a:nth-child(1){animation-delay:.02s} .nav__drawer a:nth-child(2){animation-delay:.06s}
.nav__drawer a:nth-child(3){animation-delay:.1s}  .nav__drawer a:nth-child(4){animation-delay:.14s}
.nav__drawer a:nth-child(5){animation-delay:.18s} .nav__drawer a:nth-child(6){animation-delay:.22s}
.nav__drawer a:nth-child(7){animation-delay:.26s}
@keyframes drawerIn{to{opacity:1;transform:none}}

/* ---------- rail ---------- */
.rail{position:fixed;right:16px;top:50%;margin-top:-120px;z-index:100;display:none;flex-direction:column;gap:13px;align-items:flex-end}
@media (min-width:1240px){
  .rail{display:flex}
  /* keep every section's content clear of the rail rather than letting
     long lines run underneath it */
  .shell{padding-right:calc(var(--gutter) + 52px)}
  .edge--r{display:none}          /* the rail already occupies this edge */
}
.rail a{display:flex;flex-direction:row-reverse;align-items:center;gap:10px;padding:3px 0}
.rail__bar{display:block;width:16px;height:2px;flex:none;background:rgba(255,255,255,.22);transition:width .45s var(--ease),background .35s}
.rail a:hover .rail__bar{width:28px;background:rgba(255,255,255,.6)}
.rail a.is-active .rail__bar{width:34px;background:var(--accent)}
.rail__label{
  font-family:var(--font-mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);white-space:nowrap;opacity:0;transform:translateX(8px);
  transition:opacity .35s var(--ease),transform .35s var(--ease),color .35s;
}
.rail a:hover .rail__label{opacity:1;transform:none;color:var(--text)}
.rail a.is-active .rail__label{opacity:.8;transform:none;color:var(--text)}

/* ---------- hero ---------- */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:calc(var(--nav-h) + 9vh) 0 12vh;overflow:hidden}
.hero__grid{
  position:absolute;inset:-25% -10%;z-index:-1;
  background-image:
    linear-gradient(to right,rgba(255,255,255,.04) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:72px 72px;
  mask-image:radial-gradient(60% 50% at 50% 45%,#000,transparent);
  -webkit-mask-image:radial-gradient(60% 50% at 50% 45%,#000,transparent);
  will-change:transform;
}
.hero__shell{
  position:relative;display:block;
  /* --hp is the scroll exit, --px/--py the pointer drift; composed in one
     transform so neither clobbers the other */
  transform:translate3d(var(--px,0px),calc(var(--hp,0) * -46px + var(--py,0px)),0)
            scale(calc(1 - var(--hp,0) * .06));
  opacity:calc(1 - var(--hp,0) * 1.25);
  transition:transform .5s cubic-bezier(.22,.9,.24,1);
}
.hero__grid-l{position:relative}
@media (min-width:1000px){.hero__title{padding-top:clamp(70px,11vh,130px)}}

/* rotated marks on the edges */
.edge{
  position:absolute;top:50%;font-family:var(--font-mono);font-size:10px;
  letter-spacing:.3em;text-transform:uppercase;color:var(--dim);white-space:nowrap;
  pointer-events:none;
}
.edge--l{left:14px;transform:translateY(-50%) rotate(180deg);writing-mode:vertical-rl}
.edge--r{right:14px;transform:translateY(-50%);writing-mode:vertical-rl}
@media (max-width:1000px){.edge{display:none}}

[data-hero]{opacity:0;transform:translateY(24px);filter:blur(6px)}
.is-ready [data-hero]{animation:heroIn 1s var(--ease-out) forwards;animation-delay:calc(var(--hd,0) * 1ms)}
@keyframes heroIn{to{opacity:1;transform:none;filter:none}}

.hero__title{
  font-size:clamp(2.1rem,11.5vw,10rem);
  font-weight:800;letter-spacing:-.055em;line-height:.85;
  margin-bottom:clamp(20px,3vw,34px);text-transform:uppercase;
}

/* the credentials stack, mirroring the reference's release metadata */
.meta{display:flex;flex-direction:column;gap:18px;text-align:left;max-width:380px;margin-bottom:34px}
@media (min-width:1000px){
  .meta{
    position:absolute;top:0;right:var(--gutter);z-index:2;
    text-align:right;margin:0;max-width:340px;
  }
}
@media (min-width:1240px){
  .meta{right:calc(var(--gutter) + 76px)}
}
.meta__block{
  font-size:clamp(14px,1.2vw,17px);font-weight:700;line-height:1.28;
  letter-spacing:-.02em;color:var(--body);margin:0;
}

.hero__lede{
  font-size:clamp(1.3rem,3.4vw,2.6rem);font-weight:700;
  line-height:1.05;letter-spacing:-.035em;color:var(--text);
  max-width:17ch;margin-bottom:clamp(26px,4vw,40px);
}
@media (min-width:700px){.hero__lede{max-width:22ch}}

.hero__links{display:flex;flex-wrap:wrap;gap:8px}

.btn{
  position:relative;display:inline-flex;align-items:center;gap:8px;overflow:hidden;
  padding:11px 17px;border:1px solid var(--line-2);background:transparent;
  font-size:13px;font-weight:600;color:var(--text);
  transition:transform .3s var(--ease),border-color .3s,background .3s,color .3s;
  will-change:transform;
}
.btn::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 36%,rgba(255,255,255,.22) 50%,transparent 64%);
  transform:translateX(-130%);transition:transform .8s var(--ease);
}
.btn:hover::after{transform:translateX(130%)}
.btn > *{position:relative;z-index:1}
.btn:hover{background:var(--hi);color:var(--ink);border-color:var(--hi)}
.btn--primary{background:var(--hi);color:var(--ink);border-color:var(--hi);font-weight:700}
.btn--primary:hover{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn--lg{padding:15px 24px;font-size:15px}
.btn__mono{font-family:var(--font-mono);font-size:11px;opacity:.65}

.hero__cue{position:absolute;bottom:22px;left:50%;translate:-50% 0;display:flex;flex-direction:column;align-items:center;gap:8px}
.hero__cue-line{width:1px;height:42px;background:linear-gradient(180deg,transparent,var(--text));transform-origin:50% 0;animation:cue 2.4s var(--ease) infinite}
@keyframes cue{0%{transform:scaleY(.2);opacity:0}40%{transform:scaleY(1);opacity:1}100%{transform:scaleY(1) translateY(42px);opacity:0}}
.hero__cue-text{font-family:var(--font-mono);font-size:9px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim)}

.dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;animation:pulse 2.6s var(--ease) infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(234,42,49,.5)}70%{box-shadow:0 0 0 9px rgba(234,42,49,0)}100%{box-shadow:0 0 0 0 rgba(234,42,49,0)}}

/* ---------- sections ---------- */
.section{position:relative;padding:clamp(90px,14vw,190px) 0}
.section--contact{padding-bottom:0}
.sec-head{max-width:none;margin-bottom:clamp(40px,6vw,74px)}
.sec-head__title{font-size:clamp(1.35rem,7.6vw,7rem);letter-spacing:-.05em;text-transform:uppercase;font-weight:800}
.sec-head__rule{display:block;height:1px;width:100%;background:var(--line);margin:26px 0 20px}
.sec-head__sub{
  color:var(--body);font-size:clamp(1.05rem,1.7vw,1.4rem);
  font-weight:500;line-height:1.4;letter-spacing:-.01em;max-width:44ch;margin:0;
}

/* ---------- reveal ---------- */
[data-reveal]{
  opacity:0;transform:translateY(28px);filter:blur(5px);
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out),filter .8s var(--ease-out);
  transition-delay:calc(var(--rd,0) * 1ms);
  will-change:opacity,transform;
}
[data-reveal].is-in{opacity:1;transform:none;filter:none}
[data-reveal="left"]{transform:translateX(-16px);filter:none}
[data-reveal="scale"]{transform:translateY(24px) scale(.94)}
[data-reveal="title"]{opacity:1;transform:none;filter:none;transition:opacity .5s var(--ease-out)}
[data-reveal="rule"]{opacity:1;filter:none;transform:scaleX(0);transform-origin:0 50%;transition:transform .9s var(--ease-out);transition-delay:calc(var(--rd,0) * 1ms)}
[data-reveal="rule"].is-in{transform:scaleX(1)}

/* split text */
.split .w{display:inline-block}
.split--words .w{overflow:hidden;vertical-align:bottom;padding-bottom:.09em}
.split--words .w > i{display:inline-block;font-style:normal;transform:translateY(105%);transition:transform 1s var(--ease-out);transition-delay:calc(var(--wi,0) * 70ms)}
.split--words.is-in .w > i{transform:none}
.split--chars .w{perspective:520px;white-space:nowrap}
.split--chars .c{
  display:inline-block;opacity:0;transform:translateY(.4em) rotateX(-55deg);filter:blur(8px);
  transition:opacity .7s var(--ease-out),transform .95s var(--ease-out),filter .7s var(--ease-out);
  transition-delay:calc(var(--cd,0) * 26ms);
}
.split--chars.is-in .c{opacity:1;transform:none;filter:none}
@keyframes charSheen{0%,100%{color:inherit;text-shadow:none}45%{color:var(--hi);text-shadow:0 0 30px rgba(227,19,27,.55)}}
.split--chars.is-swept .c{animation:charSheen 900ms var(--ease) 1 both;animation-delay:calc(1100ms + var(--cd,0) * 34ms)}

/* pointer-lit hairline */
.glow{position:relative}
.glow::before{
  content:"";position:absolute;inset:0;padding:1px;
  background:radial-gradient(280px circle at var(--mx,50%) var(--my,50%),rgba(255,255,255,.55),rgba(255,255,255,0) 62%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:0;pointer-events:none;z-index:3;transition:opacity .45s var(--ease);
}
.glow:hover::before{opacity:1}

/* ---------- about ---------- */
.about{display:grid;gap:clamp(34px,5vw,70px);grid-template-columns:1fr}
@media (min-width:980px){.about{grid-template-columns:1.5fr .8fr;align-items:start}}
.about__prose p{color:var(--body);max-width:52ch;font-size:clamp(15px,1.3vw,17px);line-height:1.5}

/* the lede at display scale, filling word by word as it is read */
.about__prose .lede{
  font-size:clamp(1.5rem,4.4vw,3.4rem);font-weight:700;line-height:1.04;
  letter-spacing:-.04em;color:var(--text);max-width:22ch;margin-bottom:.7em;
}
.lit .lw{display:inline-block;opacity:clamp(.14, calc(var(--lit,0) - var(--i,0)), 1);transition:opacity .18s linear}

.about__pillars{display:grid;gap:0;border-top:1px solid var(--line)}
.pillar{
  position:relative;padding:22px 0;border-bottom:1px solid var(--line);
  transition:background .4s,padding-left .4s var(--ease);
}
.pillar:hover{background:rgba(255,255,255,.02);padding-left:14px}
.pillar__k{font-family:var(--font-mono);font-size:10px;color:var(--accent);letter-spacing:.18em}
.pillar h3{font-size:clamp(1.05rem,1.8vw,1.4rem);margin:8px 0 6px;letter-spacing:-.03em}
.pillar p{font-size:14px;color:var(--body);margin:0;line-height:1.45}

/* counters */
.counters{display:grid;gap:0;margin-top:clamp(50px,8vw,96px);border-top:1px solid var(--line);grid-template-columns:repeat(2,1fr)}
@media (min-width:860px){.counters{grid-template-columns:repeat(4,1fr)}}
.counter{
  position:relative;padding:clamp(22px,3vw,34px) clamp(14px,2vw,26px) clamp(22px,3vw,34px) 0;
  border-bottom:1px solid var(--line);transition:background .4s var(--ease);
}
@media (min-width:860px){.counter + .counter{border-left:1px solid var(--line);padding-left:clamp(18px,2vw,30px)}}
.counter:hover{background:rgba(255,255,255,.02)}
.counter__num{
  display:block;font-weight:800;font-size:clamp(2.8rem,7.5vw,5rem);
  letter-spacing:-.06em;line-height:.9;color:var(--accent);
  font-variant-numeric:tabular-nums;margin-bottom:14px;
}
.counter__num.is-counting{text-shadow:0 0 30px rgba(234,42,49,.5)}
.counter__label{font-size:12.5px;color:var(--body);line-height:1.4;display:block;font-weight:600}
.counter__label i{font-style:normal;color:var(--muted);font-family:var(--font-mono);font-size:10.5px;font-weight:400}

/* ---------- research: a tracklist, not cards ---------- */
.papers{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.paper{
  position:relative;display:grid;gap:8px 30px;grid-template-columns:1fr;
  padding:clamp(26px,3.4vw,42px) 0;border-bottom:1px solid var(--line);
  transition:background .45s var(--ease);
}
@media (min-width:900px){.paper{grid-template-columns:64px 1fr 300px;align-items:start}}
.paper:hover{background:rgba(255,255,255,.022)}
@media (min-width:900px){
  .paper__idx{grid-row:1;grid-column:1;padding-top:.45em}
  .paper__title{grid-row:1;grid-column:2}
  .paper__venue{grid-row:2;grid-column:2}
  .paper__body{grid-row:1 / span 2;grid-column:3;margin:0}
  .paper .chips{grid-row:3;grid-column:2}
  .paper .todo,.paper .paper__links{grid-row:3;grid-column:3;margin:0;justify-self:start}
}
.paper__idx{display:block;font-family:var(--font-mono);font-size:11px;letter-spacing:.1em;color:var(--muted);margin-bottom:10px}
.paper__title{
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.35rem,2.6vw,2.1rem);line-height:1.08;letter-spacing:-.005em;
  margin:0 0 10px;transition:transform .5s var(--ease),color .4s;
}
.paper:hover .paper__title{transform:translateX(6px)}
.paper__venue{
  font-family:var(--font-mono);font-size:11px;color:var(--muted);
  margin:0 0 14px;line-height:1.9;max-width:72ch;
}
.paper__venue .tag{margin-right:8px;transform:translateY(-1px)}
.paper__body{font-size:14px;color:var(--body);margin:0 0 16px;line-height:1.45}

.tag{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;
  padding:4px 9px;border:1px solid var(--line-2);color:var(--text);white-space:nowrap;
}
.tag__dot{width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none;animation:tagPulse 2.4s var(--ease) infinite}
@keyframes tagPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}
.tag--live{color:var(--accent);border-color:var(--accent-line)}
.tag--wip{color:#ffc46b;border-color:rgba(255,196,107,.4)}

.chips{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:0;margin:0 0 14px}
.chips li{
  font-family:var(--font-mono);font-size:10px;color:var(--muted);
  padding:4px 8px;border:1px solid var(--line);
  transition:color .25s,border-color .25s,background .25s,transform .3s var(--ease);
}
.chips li:hover{color:var(--ink);background:var(--hi);border-color:var(--hi);transform:translateY(-2px)}
.chips--lg li{font-size:11.5px;padding:7px 12px}
.chips[data-stagger] li{
  opacity:0;transform:translateY(12px);
  transition:opacity .55s var(--ease-out),transform .55s var(--ease-out),color .25s,border-color .25s,background .25s;
  transition-delay:calc(var(--ci,0) * 45ms);
}
.is-in .chips[data-stagger] li{opacity:1;transform:none}
.is-in .chips[data-stagger] li:hover{transform:translateY(-2px);transition-delay:0ms}

.todo{
  font-family:var(--font-mono);font-size:10px;letter-spacing:.03em;color:#ffb44d;
  margin:auto 0 0;padding:6px 10px;border:1px dashed rgba(255,180,77,.35);
  align-self:flex-start;
}
.todo--center{width:fit-content;margin:28px auto 0}

/* ---------- marquee ---------- */
.marquee{
  position:relative;overflow:hidden;border-block:1px solid var(--line);
  padding:20px 0;
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
.marquee__track{display:flex;width:max-content;animation:marquee 44s linear infinite}
.marquee:hover .marquee__track{animation-play-state:paused}
.marquee__row{display:flex;align-items:center;gap:30px;padding-right:30px;white-space:nowrap}
.marquee__row b{font-weight:800;font-size:clamp(1.3rem,3.4vw,2.6rem);letter-spacing:-.04em;color:var(--body);text-transform:uppercase}
.marquee__row i{font-style:normal;color:var(--accent);font-size:1rem}
@keyframes marquee{to{transform:translate3d(-50%,0,0)}}

/* ---------- projects ----------
   One project per row: the text on the left, the work on the right in a
   browser frame titled with its real address. The frame is the one moving
   part: --ft (set by framePass in main.js) is 1 while it is still below the
   middle of the screen, tilted back into the page, and 0 once it arrives. */
.projects{display:grid;gap:clamp(72px,10vw,150px)}
.project{display:grid;gap:clamp(26px,4vw,60px);align-items:center}
@media (min-width:900px){.project{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}}

.project__body{display:flex;flex-direction:column}
.project__title{
  font-family:var(--font-display);font-weight:400;letter-spacing:-.01em;line-height:.95;
  font-size:clamp(2rem,4.2vw,3.6rem);margin:0 0 18px;color:var(--text);
}
.project__desc{font-size:15px;color:var(--body);margin:0 0 20px;line-height:1.55;max-width:52ch}

.project__links,.paper__links{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:auto 0 0}
.project__links{gap:18px;margin-top:6px}
.project__links a,.paper__links a{
  position:relative;font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--text);padding-bottom:3px;
}
.project__links a{font-family:var(--font);font-size:14px;font-weight:600;letter-spacing:-.01em;text-transform:none;color:var(--hi)}
.project__links a::after{content:"";display:inline-block;width:.42em;height:.42em;margin-left:.4em;border-top:1.5px solid var(--accent);border-right:1.5px solid var(--accent);transform:translateY(-.1em) rotate(45deg)}
.project__links a::before,.paper__links a::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:100% 50%;transition:transform .45s var(--ease);
}
.project__links a:hover::before,.paper__links a:hover::before{transform:scaleX(1);transform-origin:0 50%}
.project__links .todo,.paper__links .todo{margin:0}

.frame{
  --ft:0;
  position:relative;margin:0;border:1px solid var(--line-2);border-radius:10px;overflow:hidden;
  background:#0c0a09;
  box-shadow:0 50px 90px -40px rgba(227,19,27,.35),0 30px 60px -30px rgba(0,0,0,.9);
  transform:perspective(1500px) rotateX(calc(var(--ft) * 18deg)) scale(calc(1 - var(--ft) * .06));
  transform-origin:50% 100%;will-change:transform;
}
.frame__bar{
  display:flex;align-items:center;gap:7px;height:34px;padding:0 14px;
  border-bottom:1px solid var(--line);background:#12100e;
}
.frame__bar i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.14)}
.frame__bar span{
  flex:1;min-width:0;margin-left:10px;font-size:12px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.frame__view{position:relative;aspect-ratio:16/11;overflow:hidden;background:#0c0a09}
.frame__view img{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:cover;object-position:top center;
}

/* two real screens of one app, with a handle to slide between them */
.compare__top{clip-path:inset(0 0 0 var(--pos,50%))}
.compare__handle{
  position:absolute;top:0;bottom:0;left:var(--pos,50%);z-index:2;width:2px;margin-left:-1px;
  background:var(--hi);box-shadow:0 0 0 1px rgba(0,0,0,.25);pointer-events:none;
}
.compare__handle::after{
  content:"\2039\2002\203A";position:absolute;left:50%;top:50%;width:40px;height:40px;margin:-20px 0 0 -20px;
  display:grid;place-items:center;border-radius:50%;background:var(--accent);border:2px solid var(--hi);
  font-size:20px;font-weight:700;line-height:1;color:var(--hi);
  box-shadow:0 6px 18px rgba(0,0,0,.5);
}
.compare__range{
  position:absolute;inset:0;z-index:3;width:100%;height:100%;margin:0;
  opacity:0;cursor:ew-resize;touch-action:pan-y;
}
.compare:has(.compare__range:focus-visible) .compare__handle::after{outline:2px solid var(--hi);outline-offset:3px}
.compare__tag{
  position:absolute;bottom:12px;z-index:2;padding:5px 10px;border-radius:999px;
  font-size:12px;font-weight:600;color:var(--hi);background:rgba(5,5,5,.72);pointer-events:none;
}
.compare__tag--l{left:12px}
.compare__tag--r{right:12px}

/* BuildHub has no screenshot yet: the frame carries its loop instead */
.loop{display:grid;place-items:center;background:radial-gradient(60% 70% at 50% 50%,rgba(227,19,27,.12),transparent 70%),#0c0a09}
.loop__sq{position:relative;height:80%;aspect-ratio:1;container-type:size}
.loop__ring{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.loop__ring circle{fill:none;stroke:var(--line-2);stroke-width:1.5}
.loop__ring path{fill:none;stroke:var(--accent);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.loop__dot{
  position:absolute;left:50%;top:50%;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 18px 4px rgba(227,19,27,.6);
  transform:rotate(0deg) translateY(-32.5cqh);animation:loopOrbit 8s linear infinite;
}
@keyframes loopOrbit{to{transform:rotate(360deg) translateY(-32.5cqh)}}
.loop__w{
  position:absolute;font-family:var(--font-display);font-size:clamp(1.05rem,1.9vw,1.6rem);
  color:var(--muted);white-space:nowrap;animation:loopLit 8s linear infinite;
}
.loop__w--n{left:50%;top:-4%;transform:translate(-50%,-50%)}
.loop__w--e{left:85%;top:50%;transform:translate(0,-50%);animation-delay:-6s}
.loop__w--s{left:50%;top:104%;transform:translate(-50%,-50%);animation-delay:-4s}
.loop__w--w{right:85%;top:50%;transform:translate(0,-50%);animation-delay:-2s}
/* each word lights as the dot passes it */
@keyframes loopLit{0%,6%{color:var(--hi)}16%,94%{color:var(--muted)}100%{color:var(--hi)}}

/* ---------- skills orbit ----------
   From the orbiting-circles-02 component: three rings around a particle
   globe that sits on the stage's bottom edge, so only the upper half of
   everything shows. Each ring turns as a whole; each icon counter-turns by
   the same animation, so the logos stay upright. */
.orbit{
  --r1:min(62vw,460px);--r2:min(92vw,700px);--r3:min(124vw,960px);--g:min(46vw,380px);
  position:relative;height:calc(var(--r3) / 2 + 20px);margin:0 0 clamp(30px,5vw,60px);
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
}
.orbit::after{     /* the floor the globe rises from */
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line-2),transparent);
}
.orbit__globe{
  position:absolute;left:50%;bottom:0;width:var(--g);aspect-ratio:1;transform:translate(-50%,50%);
  background:radial-gradient(closest-side,rgba(227,19,27,.22),rgba(227,19,27,.05) 60%,transparent);
}
.orbit__globe canvas{display:block;width:100%;height:100%}
.orbit__ring{
  --size:var(--r1);
  position:absolute;left:50%;bottom:0;width:var(--size);height:var(--size);margin:0 0 calc(var(--size) / -2) calc(var(--size) / -2);
  border:1px solid var(--line);border-radius:50%;
  animation:orbitRing var(--d) linear infinite;
}
.orbit__ring--2{--size:var(--r2)}
.orbit__ring--3{--size:var(--r3)}
.orbit__ring--ccw{animation-direction:reverse}
.orbit__arm{
  position:absolute;left:50%;top:50%;width:0;height:0;
  transform:rotate(var(--a)) translateY(calc(var(--size) / -2)) rotate(calc(var(--a) * -1));
}
.orbit__icon{
  position:absolute;left:0;top:0;display:grid;place-items:center;
  width:clamp(40px,4.4vw,56px);height:clamp(40px,4.4vw,56px);transform:translate(-50%,-50%);
  border:1px solid var(--line-2);border-radius:50%;background:#0f0d0b;
  animation:orbitSpin var(--d) linear infinite reverse;
}
.orbit__ring--ccw .orbit__icon{animation-direction:normal}
.orbit__icon svg{width:46%;height:46%;fill:var(--text)}
@keyframes orbitSpin{from{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(360deg)}}
@keyframes orbitRing{to{transform:rotate(360deg)}}

/* ---------- experience ---------- */
/* The tracing beam, from the TracingBeam component. A faint rail runs down
   the left of the roles; on it, a crimson beam whose head follows the middle
   of the screen (--bh, px from the top, set by beamPass in main.js) and whose
   tail trails behind. Each role's dot lights as the head passes it. */
.beamed{--bh:0px;position:relative;padding-left:clamp(34px,5vw,64px)}
.beamed__rail{
  position:absolute;left:clamp(6px,1.4vw,18px);top:0;bottom:0;width:1px;
  background:var(--line);
}
.beamed__beam{
  position:absolute;left:-1px;width:3px;border-radius:3px;
  top:max(0px,calc(var(--bh) - 38vh));height:min(var(--bh),38vh);
  background:linear-gradient(180deg,rgba(227,19,27,0),var(--crimson) 70%,#ff8a7a);
  box-shadow:0 0 14px 1px rgba(227,19,27,.45);
}
.beamed__beam::after{    /* the head */
  content:"";position:absolute;left:50%;bottom:-5px;width:11px;height:11px;margin-left:-5.5px;
  border-radius:50%;background:#ffd9d3;box-shadow:0 0 16px 4px rgba(255,106,92,.7);
}
.beamed:not(.is-on) .beamed__beam{display:none}

.timeline{list-style:none;margin:0;padding:0;position:relative;border-top:1px solid var(--line)}
.tl{position:relative;display:grid;gap:6px;padding:clamp(24px,3vw,38px) 0;border-bottom:1px solid var(--line);transition:background .4s}
@media (min-width:760px){.tl{grid-template-columns:180px 1fr;gap:40px}}
.tl:hover{background:rgba(255,255,255,.022)}
/* the dot sits on the rail, level with the role's title */
.tl__dot{
  position:absolute;top:calc(clamp(24px,3vw,38px) + .55em);
  left:calc(clamp(6px,1.4vw,18px) - clamp(34px,5vw,64px) - 5px);
  width:11px;height:11px;border-radius:50%;
  border:1px solid var(--line-2);background:var(--bg);
  transition:background .4s,border-color .4s,box-shadow .4s;
}
.tl.is-lit .tl__dot{background:var(--crimson);border-color:#ff8a7a;box-shadow:0 0 12px 2px rgba(227,19,27,.5)}
.tl__when{font-size:13px;color:var(--muted);padding-top:6px}
.tl.is-lit .tl__when{color:var(--text)}
.tl__body h3{font-family:var(--font-display);font-weight:400;font-size:clamp(1.3rem,2.4vw,1.9rem);line-height:1.1;margin-bottom:10px;letter-spacing:-.005em}
/* Federant's uncial V reads as U; acronyms keep the body face */
.tl__body h3 .plain{font-family:var(--font);font-weight:700;font-size:.82em;letter-spacing:.02em}
.tl__body p{font-size:14.5px;color:var(--body);margin:0;max-width:68ch}

/* ---------- skills ---------- */
.skills{display:grid;gap:0;grid-template-columns:1fr;border-top:1px solid var(--line)}
@media (min-width:760px){.skills{grid-template-columns:repeat(2,1fr);column-gap:40px}}
.skillset{position:relative;padding:clamp(22px,2.8vw,32px) 0;border-bottom:1px solid var(--line)}
.skillset h3{
  font-family:var(--font-mono);font-weight:500;font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted);margin-bottom:16px;transition:color .4s var(--ease);
}
.skillset:hover h3{color:var(--accent)}
@media (min-width:760px){.skillset--wide{grid-column:1 / -1}}

/* ---------- leadership ---------- */
/* community: the three items that used to be the Leadership section */
.community{margin-top:clamp(64px,8vw,110px)}
.community__title{
  font-family:var(--font-display);font-weight:400;letter-spacing:-.01em;
  font-size:clamp(1.8rem,3.4vw,2.8rem);margin:0 0 clamp(18px,2.4vw,28px);color:var(--text);
}
.community__list{list-style:none;margin:0;padding:0;display:grid;gap:0;border-top:1px solid var(--line)}
@media (min-width:860px){.community__list{grid-template-columns:repeat(3,1fr);column-gap:40px}}
.community__list li{padding:clamp(20px,2.6vw,30px) 0;border-bottom:1px solid var(--line)}
.community__list h4{font-size:clamp(1.05rem,1.6vw,1.3rem);font-weight:700;letter-spacing:-.025em;margin:0 0 8px;line-height:1.2}
.community__list p{font-size:14.5px;color:var(--body);margin:0;line-height:1.5}

/* ---------- contact ---------- */
.cta{text-align:left;padding:clamp(30px,6vw,80px) 0 clamp(60px,9vw,120px);position:relative}
.cta__title{font-size:clamp(1.9rem,12vw,11rem);font-weight:800;letter-spacing:-.06em;line-height:.85;margin-bottom:28px;text-transform:uppercase}
.cta__sub{color:var(--body);max-width:32ch;margin:0 0 40px;font-size:clamp(1.1rem,2.4vw,1.8rem);font-weight:700;line-height:1.12;letter-spacing:-.03em}
.cta__actions{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:34px}
.copyfield{display:inline-flex;align-items:center;gap:6px;max-width:100%;min-width:0}
.copyfield .btn{min-width:0;overflow:hidden}
.copyfield .btn span,.copyfield .btn{text-overflow:ellipsis;white-space:nowrap}
@media (max-width:430px){
  /* the address is 26 characters — at this width it has to set its own scale */
  .cta__actions{flex-direction:column;align-items:stretch}
  .copyfield{width:100%}
  .copyfield .btn{flex:1}
  .btn--lg{padding:13px 16px;font-size:13.5px}
}
.copy{
  position:relative;display:grid;place-items:center;width:44px;height:44px;flex:none;padding:0;cursor:pointer;
  border:1px solid var(--line-2);background:transparent;color:var(--muted);
  transition:border-color .3s,color .3s,background .3s,transform .3s var(--ease);
}
.copy:hover{background:var(--hi);color:var(--ink);border-color:var(--hi);transform:translateY(-2px)}
.copy__i{position:absolute;transition:opacity .28s var(--ease),transform .28s var(--ease)}
.copy__i--ok{opacity:0;transform:scale(.4) rotate(-25deg)}
.copy.is-done{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.copy.is-done .copy__i--doc{opacity:0;transform:scale(.4) rotate(25deg)}
.copy.is-done .copy__i--ok{opacity:1;transform:none}

.cta__cv{margin:0 0 22px}
.cta__cv a{
  position:relative;display:inline-flex;align-items:center;gap:8px;
  font-size:clamp(1rem,2vw,1.35rem);font-weight:700;letter-spacing:-.03em;color:var(--text);
  padding-bottom:4px;
}
.cta__cv a::after{content:" \2193";font-size:.85em}
.cta__cv a::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--accent);
  transform:scaleX(1);transform-origin:0 50%;transition:transform .45s var(--ease);
}
.cta__cv a:hover::before{transform:scaleX(0);transform-origin:100% 50%}

.cta__links{display:flex;flex-wrap:wrap;gap:8px 30px;list-style:none;padding:0;margin:0}
.cta__links a{
  position:relative;font-family:var(--font-mono);font-size:12px;color:var(--muted);
  padding-bottom:3px;transition:color .3s var(--ease);
}
.cta__links a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--accent);transform:scaleX(0);transform-origin:100% 50%;transition:transform .45s var(--ease)}
.cta__links a:hover{color:var(--hi)}
.cta__links a:hover::after{transform:scaleX(1);transform-origin:0 50%}

.foot{border-top:1px solid var(--line);padding:26px 0}
.foot__inner{display:flex;flex-wrap:wrap;gap:10px 30px;justify-content:space-between;font-size:12px;color:var(--muted);font-family:var(--font-mono)}

/* ---------- fixed contact pill ---------- */
.pill{
  position:fixed;right:16px;bottom:16px;z-index:130;
  display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  font-family:inherit;
  padding:11px 18px;border-radius:99px;
  background:rgba(14,14,14,.9);border:1px solid var(--line-2);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  font-size:12.5px;font-weight:600;color:var(--text);
  transition:background .3s,border-color .3s,transform .35s var(--ease),gap .4s var(--ease);
}
/* collapsed to its mark by default — fixed to the corner, it would
   otherwise sit permanently on top of body copy */
.pill > span:last-child{
  max-width:0;opacity:0;overflow:hidden;white-space:nowrap;
  transition:max-width .45s var(--ease),opacity .3s var(--ease);
}
.pill{gap:0}
.pill:hover,.pill:focus-visible{background:var(--hi);color:var(--ink);border-color:var(--hi);transform:translateY(-2px);gap:10px}
.pill:hover > span:last-child,.pill:focus-visible > span:last-child{max-width:260px;opacity:1}
.pill__eq{display:flex;align-items:flex-end;gap:2px;height:12px}
/* the bars only move while something is actually playing */
.pill__eq i{display:block;width:2px;background:var(--accent);transform:scaleY(.35);transform-origin:50% 100%;transition:transform .3s var(--ease)}
.pill.is-playing .pill__eq i{animation:eq 1s ease-in-out infinite}
.pill:hover .pill__eq i,.pill:focus-visible .pill__eq i{background:var(--ink)}
.pill__eq i:nth-child(1){height:6px;animation-delay:0s}
.pill__eq i:nth-child(2){height:12px;animation-delay:.18s}
.pill__eq i:nth-child(3){height:8px;animation-delay:.36s}
@keyframes eq{0%,100%{transform:scaleY(.4)}50%{transform:scaleY(1)}}
@media (max-width:620px){.pill{display:none}}

/* ---------- enter gate ----------
   display:none by default so a page with no JS is never trapped behind a
   gate it has no way to dismiss. */
.gate{position:fixed;inset:0;z-index:300;display:none}
.gate.is-live{display:block}
.is-gate{overflow:hidden}

/* the black ground is two halves, so the exit can split them apart */
.gate__panel{
  position:absolute;left:0;right:0;background:var(--bg);
  will-change:transform;
  transition:transform 1.05s cubic-bezier(.76,0,.24,1);
}
.gate__panel--t{top:0;height:50.5%}
.gate__panel--b{bottom:0;height:50.5%}
.gate.is-out .gate__panel--t{transform:translateY(-100%)}
.gate.is-out .gate__panel--b{transform:translateY(100%)}

.gate__inner{
  position:absolute;inset:0;z-index:2;
  transition:opacity .45s var(--ease),transform .6s var(--ease);
}
.gate.is-out .gate__inner{opacity:0;transform:scale(.97)}

/* visually hidden — carries the identity the drawn stage cannot */
.sr-only{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* The living fluid fills the gate; the name sits on its dark heart. The
   component's bloom pass is this glow instead: one gradient, drawn once. */
.gate__field{position:absolute;inset:0;z-index:1}
.gate__field canvas{display:block;width:100%;height:100%;opacity:0;transition:opacity 1.2s var(--ease)}
.gate__field.is-on canvas{opacity:1}
.gate__glow{
  position:absolute;left:50%;top:50%;z-index:0;pointer-events:none;
  width:min(125vh,150vw);height:min(125vh,150vw);transform:translate(-50%,-50%);
  background:radial-gradient(closest-side,rgba(227,19,27,.2),rgba(227,19,27,.06) 48%,transparent 72%);
}

.gate__controls{
  position:absolute;inset:0;z-index:3;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 var(--gutter);text-align:center;pointer-events:none;
}
.gate__controls > *{pointer-events:auto}

/* the one bold thing: the name, rising letter by letter over the fluid */
.gate__title{
  margin:0 0 clamp(12px,2vh,22px);
  font-family:var(--font-display);font-weight:400;color:var(--hi);
  font-size:clamp(3.4rem,12.5vw,10rem);line-height:.86;letter-spacing:-.01em;
  text-shadow:0 2px 30px rgba(5,5,5,.55);
}
.gate__c{
  display:inline-block;opacity:0;transform:translateY(.45em);
  animation:gateRise 1.1s cubic-bezier(.2,.65,.3,.9) forwards;
  animation-delay:calc(.25s + var(--i) * .055s);
}
@keyframes gateRise{to{opacity:1;transform:none}}
.gate__sub{
  margin:0 0 clamp(22px,3.6vh,36px);font-size:clamp(.95rem,1.5vw,1.15rem);font-weight:500;
  letter-spacing:-.01em;color:var(--text);opacity:0;
  animation:gateIn .8s var(--ease-out) 1.1s forwards;
}

.gate__quote{
  margin:0;max-width:min(52ch,90vw);
  opacity:0;animation:gateIn .9s var(--ease-out) 1.35s forwards;
}
.gate__quote p{
  margin:0;font-family:var(--font-display);font-size:clamp(.95rem,1.4vw,1.15rem);
  line-height:1.4;color:var(--text);text-wrap:balance;
}
.gate__quote p::before{content:"\201C";color:var(--accent);margin-right:1px}
.gate__quote p::after{content:"\201D";color:var(--accent);margin-left:1px}
.gate__quote cite{
  display:block;margin-top:10px;font-style:normal;font-size:12.5px;
  letter-spacing:0;color:var(--muted);
}

/* loading and the way out, kept at the foot and out of the centre */
.gate__foot{
  position:absolute;left:0;right:0;bottom:clamp(22px,5vh,48px);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:0 var(--gutter);text-align:center;
  opacity:0;animation:gateIn .7s var(--ease-out) .5s forwards;
}
.gate__load{display:flex;align-items:center;gap:12px;margin:0}
.gate__bar{display:block;width:min(200px,46vw);height:1px;background:rgba(255,255,255,.14);overflow:hidden}
.gate__bar > i{display:block;height:100%;width:100%;background:var(--accent);transform:scaleX(0);transform-origin:0 50%}
.gate__pct{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;min-width:2.4em;text-align:left}
.gate__pct::after{content:"%";opacity:.5;margin-left:1px}
.gate__hint{margin:0;font-size:12.5px;color:var(--muted)}
@keyframes gateIn{to{opacity:1}}

/* ---------- toast ---------- */
.toast{
  position:fixed;left:50%;bottom:26px;z-index:160;padding:10px 18px;
  border:1px solid var(--line-2);background:rgba(10,10,10,.95);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  color:var(--text);font-family:var(--font-mono);font-size:11.5px;
  opacity:0;transform:translate(-50%,16px);pointer-events:none;
  transition:opacity .35s var(--ease),transform .35s var(--ease);
}
.toast.is-on{opacity:1;transform:translate(-50%,0)}

/* ---------- momentum scroll ---------- */
.smooth main{position:fixed;top:0;left:0;width:100%;will-change:transform}
.smooth{scroll-behavior:auto}

/* ---------- responsive nav ---------- */
@media (max-width:900px){
  .nav__links,.nav__pct{display:none}
  .nav__toggle{display:block;margin-left:auto}
  .nav__role{display:none}
  .nav.is-open .nav__drawer{display:flex}
  .nav.is-open{background:rgba(6,6,6,.94);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.15s!important;transition-delay:0ms!important;scroll-behavior:auto!important;
  }
  .field,.cursor{display:none!important}
  .gate__panel,.gate__inner{transition:none}
  .gate__quote,.gate__foot,.gate__sub,.gate__c{animation:none;opacity:1;transform:none}
  .gate__field canvas{transition:none}
  .grain{animation:none}
  .orb > i{animation:none}
  .marquee__track{animation:none}
  .lit .lw{opacity:1}
  .pill.is-playing .pill__eq i{animation:none}
  [data-hero]{opacity:1;transform:none;filter:none;animation:none}
  .hero__shell{transform:none;opacity:1}
  [data-reveal]{opacity:0;transform:none;filter:none;transition:opacity .25s linear}
  [data-reveal].is-in{opacity:1}
  [data-reveal="rule"],[data-reveal="rule"].is-in{transform:none;opacity:1}
  .split .w{overflow:visible}
  .split--words .w > i{transform:none!important;transition:none}
  .split--chars .c{opacity:1;transform:none!important;filter:none;animation:none!important}
  .chips[data-stagger] li{opacity:1;transform:none}
  .hero__cue-line{animation:none;opacity:.5}
  .dot,.tag__dot{animation:none}
  .orbit__ring,.orbit__icon{animation:none}
  .btn::after{display:none}
  .frame{transform:none}
  .loop__dot,.loop__w{animation:none}
  .btn:hover,.copy:hover,.chips li:hover,.pill:hover{transform:none}
  .paper:hover .paper__title{transform:none}
  .pillar:hover{padding-left:0}
}

/* ---------- portrait ---------- */
/* A cut-out, so he stands on the page instead of in a box. A soft pool of
   light sits behind the shoulders, and the bottom edge dissolves into the
   page so the crop at the chest never reads as a hard line. */
.portrait{margin:0 0 clamp(20px,2.6vw,30px);position:relative}
.portrait::before{
  content:"";position:absolute;left:8%;right:8%;top:14%;bottom:6%;z-index:0;
  background:radial-gradient(closest-side,rgba(255,255,255,.07),rgba(234,42,49,.035) 55%,transparent);
  pointer-events:none;
}
.portrait__img{
  position:relative;z-index:1;display:block;width:100%;height:auto;
  -webkit-mask-image:linear-gradient(180deg,#000 72%,transparent 99%);
  mask-image:linear-gradient(180deg,#000 72%,transparent 99%);
}
/* the ASCII reveal (asciiface.js) sits exactly over the photo while it runs */
.portrait__ascii{
  position:absolute;z-index:2;pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,#000 72%,transparent 99%);
  mask-image:linear-gradient(180deg,#000 72%,transparent 99%);
}
.portrait figcaption{
  margin-top:10px;font-family:var(--font-mono);font-size:10px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--muted);
}

/* ═══════════ EXAMINED — the Socrates interlude ═══════════
   Full-bleed, one viewport tall. --ex is this section's own scroll progress
   (0 entering, 1 leaving), set by examinedPass() in main.js. It is only ever
   used in transforms and opacity — never inside a colour function, which is
   the construct that washed the iPad out. */
/* Two layouts, chosen by whether the bust is actually on the page. Without
   it the section is compact and sized like its neighbours: one full
   viewport with the quote at the foot of it was a screen of empty black
   before any words appeared. With the bust it becomes the full-bleed
   stage, the picture filling the screen and the quote along its floor. */
.examined{
  --ex:0;
  position:relative;
  display:flex;align-items:center;overflow:hidden;isolation:isolate;
}
.examined:has(.examined__bust){min-height:100vh;min-height:100svh;align-items:flex-end}
/* no background of its own: the page's grain and field run straight through,
   and the stage fades in and out with a mask instead of painting black
   bands, which left a visible seam where the section met the next one */
.examined__stage{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 18%,#000 78%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 18%,#000 78%,transparent 100%);
}

/* the bust drifts up and settles from slightly too close as you pass it */
.examined__bust{
  position:absolute;left:0;top:-8%;width:100%;height:116%;
  object-fit:cover;object-position:68% 28%;
  filter:grayscale(1) contrast(1.14) brightness(.78);
  transform:translate3d(0,calc(var(--ex) * -7%),0) scale(calc(1.12 - var(--ex) * .09));
  transform-origin:65% 35%;
  will-change:transform;
  opacity:0;transition:opacity 1.2s var(--ease);
}
/* fade it in once decoded rather than letting it pop */
.examined__bust.is-loaded{opacity:1}
/* the honeycomb canvas grades its own greyscale and contrast, so it only
   needs pulling down a touch to sit in the page, not the photo's filter */
.examined__fx{filter:brightness(.88)}
.examined__bust[hidden]{display:none}

/* Wide screens: a bust photograph is portrait, so full-bleed it gets centred
   and the face lands directly behind the quote. Hold it to the right and
   feather its left edge into the page, and let the quote step down a size
   so the two sit side by side instead of on top of each other. */
@media (min-width:761px){
  .examined__bust{
    left:auto;right:0;width:60%;object-position:50% 4%;
    -webkit-mask-image:linear-gradient(90deg,transparent 0%,#000 34%);
    mask-image:linear-gradient(90deg,transparent 0%,#000 34%);
  }
  .examined:has(.examined__bust) .examined__q p{font-size:clamp(2.4rem,5.4vw,5.6rem);max-width:12ch}
}

/* a raking light that crosses the marble once as the section goes by */
.examined__sweep{
  position:absolute;inset:-20% -40%;
  background:linear-gradient(104deg,transparent 42%,rgba(255,255,255,.10) 49%,rgba(255,255,255,.16) 50%,rgba(255,255,255,.10) 51%,transparent 58%);
  transform:translate3d(calc(-45% + var(--ex) * 90%),0,0);
  opacity:calc(.25 + var(--ex) * .75);
}

/* darkness from the left and from the floor, so the type always has ground
   to stand on and the section bleeds into the page above and below */
.examined__shade{
  position:absolute;inset:0;
  background:
    linear-gradient(90deg,rgba(6,6,6,.92) 0%,rgba(6,6,6,.6) 38%,rgba(6,6,6,.08) 70%,transparent 100%),
    linear-gradient(0deg,rgba(6,6,6,.7) 0%,transparent 55%);
}

.examined__inner{position:relative;z-index:1;width:100%;padding-block:clamp(90px,14vw,190px)}
.examined:has(.examined__bust) .examined__inner{padding-block:clamp(110px,20vh,220px) clamp(70px,13vh,150px)}
.examined__k{
  display:flex;align-items:center;gap:10px;margin:0 0 clamp(18px,3vh,30px);
  font-family:var(--font-mono);font-size:11px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--accent);
}
.examined__q{margin:0}
.examined__q p{
  margin:0;max-width:13ch;
  font-size:clamp(2.6rem,7.6vw,7rem);font-weight:800;line-height:.96;
  letter-spacing:-.05em;color:var(--text);text-wrap:balance;
}
.examined__q cite{
  display:block;margin-top:clamp(20px,3.4vh,34px);font-style:normal;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted);
}
.examined__q cite em{font-style:italic;text-transform:none;letter-spacing:.06em}

/* phones: the bust moves to the top half and the words sit under his face */
@media (max-width:760px){
  .examined__bust{object-position:50% 4%}
  .examined__shade{
    background:
      linear-gradient(0deg,rgba(6,6,6,.9) 0%,rgba(6,6,6,.7) 40%,rgba(6,6,6,.12) 72%,transparent 100%);
  }
}

@media (prefers-reduced-motion:reduce){
  .examined__bust{transform:none}
  .examined__sweep{display:none}
}

/* ══════════ Lycoris ══════════
   The display face and the hero's spider lily, from the Lycoris Specimen
   component (components/ui/lycoris-specimen.tsx). Federant has one weight
   and is drawn for mixed case, so the display lines drop the grotesque's
   800 weight, tight tracking and uppercase. */
.hero__title,
.sec-head__title,
.cta__title,
.examined__q p,
.gate__quote p{
  font-family:var(--font-display);font-weight:400;text-transform:none;
}
.hero__title{letter-spacing:-.01em;line-height:.9}
.sec-head__title{letter-spacing:-.015em;line-height:.95}
.cta__title{letter-spacing:-.01em;line-height:.92}
.examined__q p{letter-spacing:-.01em;line-height:1}
.gate__quote p{letter-spacing:0}

/* the night sky, under the lily; it paints its own ground, so it fades
   out at the foot of the hero into the page's washes */
.hero__horizon{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,#000 76%,transparent);
  mask-image:linear-gradient(180deg,#000 76%,transparent);
}
.hero__horizon canvas{display:block;width:100%;height:100%;opacity:0;transition:opacity 1.4s var(--ease)}
.hero__horizon.is-on canvas{opacity:1}
@media (prefers-reduced-motion:reduce){.hero__horizon canvas{transition:none}}
.hero__horizon.is-lost{display:none}
.hero__lily{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
/* fade the scape out before the hero's bottom edge, so it never ends on a cut */
.hero__lily{
  -webkit-mask-image:linear-gradient(180deg,#000 70%,transparent 98%);
  mask-image:linear-gradient(180deg,#000 70%,transparent 98%);
}
/* the name always sets on two lines, clear of the flower */
.hero__title .w{display:block}
.hero__lily canvas{position:absolute;inset:0;display:block;width:100%;height:100%}
.lily__glow{
  position:absolute;left:0;top:0;border-radius:50%;pointer-events:none;will-change:transform;
  background:radial-gradient(closest-side,rgba(227,19,27,.24),rgba(227,19,27,.07) 45%,transparent 100%);
}
.hero__shell,.hero__cue,.edge{z-index:1}
/* the credentials sit over the flower's crown on wide screens */
.meta__block{text-shadow:0 0 18px var(--bg),0 0 3px var(--bg)}

/* ══════════ text ring funnel (contact) ══════════
   From the TextRingFunnel component (components/ui/hero-text-ring-funnel.tsx),
   drawn by funnel.js. The stage is a full-height band; the headline sits at
   the vanishing point and the rest of the contact block follows below. */
.section--contact{padding-top:clamp(40px,6vw,90px)}
.funnel{
  position:relative;isolation:isolate;overflow:hidden;
  height:min(100svh,940px);min-height:560px;
  display:grid;place-items:center;
  /* hold the backdrop's drifting lines back behind the rings, so the rings
     are the only motion here; the edges stay open onto the page */
  background:radial-gradient(closest-side,var(--bg) 62%,rgba(5,5,5,0));
}
.funnel__canvas{
  position:absolute;inset:0;z-index:0;display:block;width:100%;height:100%;
  font-family:var(--font-display);
  /* the near rings overflow the band; fade them out rather than cut them */
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 14%,#000 86%,transparent);
  mask-image:linear-gradient(180deg,transparent,#000 14%,#000 86%,transparent);
}
/* kept tight: rings inside this box's radius fade out, so every spare pixel costs a ring */
.funnel__core{position:relative;z-index:1;text-align:center;padding:0 16px;max-width:min(92vw,640px);width:fit-content}
.funnel__k{
  margin:0 0 14px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted);
}
.funnel .cta__title{font-size:clamp(2.1rem,5.4vw,4.6rem);margin:0 auto;line-height:.95;max-width:6.6em}
.funnel.is-bare{height:auto;min-height:0;padding:clamp(40px,8vw,120px) 0;background:none}

/* the rest of the contact block centres under the funnel */
.cta{text-align:center;padding-top:clamp(10px,2vw,30px)}
.cta__sub{margin-inline:auto}
.cta__actions,.cta__links{justify-content:center}
.cta__links{margin-bottom:28px}
@media (max-width:430px){.cta__actions{align-items:stretch}}
