/* Self-hosted, latin + latin-ext only. Same faces Google served, fetched
   once at build time so the page contacts no third-party origin and the
   files can be cached by the site's own CDN with the site's own headers. */
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Archivo';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Archivo';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Archivo';font-style:normal;font-weight:700;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:700;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Archivo';font-style:normal;font-weight:800;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:800;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Archivo';font-style:normal;font-weight:900;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:900;font-stretch:100%;font-display:swap;src:url('../fonts/archivo-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/ibm-plex-mono-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/ibm-plex-mono-500-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:600;font-stretch:100%;font-display:swap;src:url('../fonts/instrument-sans-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/* ============================================================
   SPACING + TYPE SYSTEM
   every gap on this page comes from this scale. nothing is eyeballed.
   ============================================================ */
:root{
  --s1:8px;  --s2:16px; --s3:24px; --s4:40px;
  --s5:64px; --s6:96px; --s7:140px; --s8:200px;

  --r1:14px; --r2:24px; --r3:34px;

  --void:#000000;
  --surface:#0B0B0D;
  --surface2:#141417;
  --hair:rgba(255,255,255,.075);
  --hair2:rgba(255,255,255,.14);

  --bone:#EFECE7;
  --steel:#94979D;
  --dim:#6E7278;
  --blue:#1E8FFF;
  --glow:#7FD0FF;
  --warn:#FF6B4A;

  --maxw:1080px;
  --narrow:760px;

  /* ============================================================
     SONIC INTERACTION LANGUAGE — motion tokens
     Sonique is continuous, reactive, light. Every transition on the
     page is one of these four curves and one of these five durations.
     Nothing is eyeballed here either.
     ============================================================ */
  --e-conduct:cubic-bezier(.22,1,.36,1);   /* entrances: fast out, long settle */
  --e-settle:cubic-bezier(.33,1,.68,1);    /* state changes */
  --e-press:cubic-bezier(.3,1.5,.5,1);     /* physical: overshoots once */
  --e-linear:linear;                        /* only for scrubbed values */

  --t-tap:120ms;    /* the eye reads this as instant */
  --t-quick:240ms;
  --t-move:420ms;
  --t-settle:720ms;
  --t-arrive:1100ms;

  /* live signals, written by sonic.js, readable by any rule on the page.
     they are the reason motion here is one system and not twelve. */
  --px:0;        /* pointer x, smoothed, -1 .. 1 */
  --py:0;        /* pointer y, smoothed, -1 .. 1 */
  --pin:0;       /* 1 while a fine pointer is over the document */
  --vel:0;       /* scroll velocity, smoothed, -1 .. 1 */
  --avel:0;      /* |velocity| */
  --prog:0;      /* document scroll progress, 0 .. 1 */
  --near:1;      /* pointer proximity to the hero module, 0 .. 1 (1 when unknown) */
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;background:var(--void);-webkit-text-size-adjust:100%;
  scroll-padding-top:86px}
[id]{scroll-margin-top:86px}
body{
  background:var(--void);color:var(--bone);
  font-family:"Instrument Sans",system-ui,-apple-system,sans-serif;
  font-size:17px;line-height:1.6;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;display:block;height:auto}
a{color:inherit}
button{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--blue);outline-offset:4px;border-radius:6px}
/* anchor navigation focuses the target section so keyboard users land inside
   it. that focus is programmatic, and Safari draws the ring for it anyway: a
   2px blue box around a whole section, which read as a stray line cutting the
   page. the scroll is the indicator there; the ring is for real controls. */
[tabindex="-1"]:focus,[tabindex="-1"]:focus-visible{outline:none}
::selection{background:var(--blue);color:#000}

.wrap{max-width:var(--maxw);margin:0 auto;
  padding-left:max(var(--s3),env(safe-area-inset-left));
  padding-right:max(var(--s3),env(safe-area-inset-right))}
.narrow{max-width:var(--narrow);margin-left:auto;margin-right:auto}
.center{text-align:center}

/* ---- type roles ---- */
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);font-weight:400}
.d1{font-family:"Archivo",system-ui,sans-serif;font-weight:800;letter-spacing:-.042em;line-height:1.0;font-size:clamp(42px,7.4vw,96px)}
.d2{font-family:"Archivo",system-ui,sans-serif;font-weight:800;letter-spacing:-.038em;line-height:1.04;font-size:clamp(32px,5.2vw,62px)}
.d3{font-family:"Archivo",system-ui,sans-serif;font-weight:700;letter-spacing:-.03em;line-height:1.12;font-size:clamp(21px,2.6vw,30px)}
.d4{font-family:"Archivo",system-ui,sans-serif;font-weight:700;letter-spacing:-.01em;line-height:1.25;font-size:17px}
.lead{font-size:clamp(17px,1.85vw,21px);line-height:1.55;color:var(--steel);letter-spacing:-.012em}
.body{color:var(--steel)}
.blue{color:var(--blue)}
.tnum{font-variant-numeric:tabular-nums}

/* ---- rhythm ---- */
.sec{padding:var(--s7) 0}
.sec-tight{padding:var(--s6) 0}
.stack-1 > * + *{margin-top:var(--s1)}
.stack-2 > * + *{margin-top:var(--s2)}
.stack-3 > * + *{margin-top:var(--s3)}
.stack-4 > * + *{margin-top:var(--s4)}
.stack-5 > * + *{margin-top:var(--s5)}

/* ============================================================
   NAV
   ============================================================ */
nav{position:sticky;top:0;z-index:90;
  background:rgba(0,0,0,calc(.34 + var(--prog,0) * .0 + var(--navsolid,0) * .48));
  backdrop-filter:saturate(160%) blur(calc(6px + var(--navsolid,0) * 16px));
  -webkit-backdrop-filter:saturate(160%) blur(calc(6px + var(--navsolid,0) * 16px));
  border-bottom:1px solid rgba(255,255,255,calc(var(--navsolid,0) * .07));
  transition:background var(--t-move) var(--e-settle),border-color var(--t-move) var(--e-settle)}
.navrow{max-width:1240px;margin:0 auto;
  padding-left:max(var(--s3),env(safe-area-inset-left));
  padding-right:max(var(--s3),env(safe-area-inset-right));
  display:flex;align-items:center;gap:var(--s3);
  height:calc(64px - var(--navsolid,0) * 10px);
  transition:height var(--t-move) var(--e-settle)}
.navbrand{display:flex;align-items:center;gap:10px;text-decoration:none;opacity:.9;
  transition:opacity var(--t-quick) var(--e-settle);flex:none}
.navbrand:hover{opacity:1}
.navbrand img{width:20px;height:auto}
.navbrand span{font-family:"Archivo";font-weight:600;letter-spacing:.4em;font-size:11px;text-transform:uppercase;padding-left:.4em}

.navlinks{display:flex;align-items:center;gap:2px;margin-left:auto}
.navlink{position:relative;text-decoration:none;padding:8px 14px;border-radius:100px;
  font-size:13.5px;color:var(--steel);letter-spacing:-.005em;
  transition:color var(--t-quick) var(--e-settle)}
.navlink:hover,.navlink[aria-current="true"]{color:var(--bone)}
.navcta{flex:none;margin-left:var(--s2)}
#prog{position:absolute;left:0;bottom:0;height:1px;background:var(--blue);
  width:100%;transform-origin:0 50%;transform:scaleX(var(--prog,0))}

@media(max-width:860px){
  .navlinks{display:none}
  /* the links carried margin-left:auto; without them the CTA has to push itself */
  .navcta{margin-left:auto}
  .navrow{height:58px}
}

/* ============================================================
   BUTTONS — one component, three weights.
   Press is a real press: the surface gives, then returns past centre.
   ============================================================ */
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;text-decoration:none;white-space:nowrap;
  border-radius:100px;padding:15px 26px;cursor:pointer;border:1px solid transparent;
  transform:translate3d(var(--mx,0),var(--my,0),0);
  transition:background var(--t-quick) var(--e-settle),color var(--t-quick) var(--e-settle),
             border-color var(--t-quick) var(--e-settle),transform var(--t-move) var(--e-conduct),
             box-shadow var(--t-move) var(--e-settle);
  overflow:hidden;isolation:isolate;-webkit-tap-highlight-color:transparent}
.btn:active{transform:translate3d(var(--mx,0),var(--my,0),0) scale(.975);transition-duration:var(--t-tap)}
.btn-sm{padding:11px 18px;font-size:10.5px}
.btn-primary{background:var(--bone);color:#000;font-weight:500}
.btn-primary:hover{background:#fff;box-shadow:0 0 0 1px rgba(255,255,255,.25),0 10px 40px rgba(30,143,255,.22)}
.btn-blue{background:var(--blue);color:#fff}
.btn-blue:hover{background:#3AA0FF;box-shadow:0 10px 44px rgba(30,143,255,.34)}
.btn-ghost{background:transparent;border-color:var(--hair2);color:var(--steel)}
.btn-ghost:hover{color:var(--bone);border-color:var(--steel)}
.btn .arw{display:inline-block;transition:transform var(--t-move) var(--e-conduct)}
.btn:hover .arw{transform:translateX(3px)}
.btn[disabled]{opacity:.45;cursor:default;pointer-events:none}

/* the contact ripple. every deliberate action on this page emits one, because
   that is literally what the device does: a vibration that propagates outward
   from the point it is applied. */
/* the contact ripple: it opens from where the finger landed and is gone in
   half a second. small on purpose. you should feel it answered, not watch it. */
.ring{position:absolute;border-radius:50%;pointer-events:none;z-index:0;
  border:1px solid currentColor;opacity:.4;
  transform:scale(.32);
  animation:ringout 520ms var(--e-conduct) forwards}
@keyframes ringout{60%{opacity:.22}to{transform:scale(1);opacity:0}}
/* the pills clip it, so it can never draw outside the control it belongs to */
.tab,.pillbtn{position:relative;overflow:hidden}
/* :not(.ring) matters. This rule and .ring have the same specificity, and this
   one comes later, so without the exclusion it turned the ripple into a
   position:relative in-flow child and the button grew to contain it. That was
   the button "getting huge" on tap. */
.btn > *:not(.ring){position:relative;z-index:1}

/* ============================================================
   HERO
   ============================================================ */
.hero{padding:var(--s6) 0 var(--s5)}
.hero h1{margin-top:var(--s3)}
.hero .lead{margin:var(--s4) auto 0;max-width:52ch}
/* mobile-first the hero is centred; the desktop query below unpicks all of it */
.herolede,.hero .herolede{margin-left:auto;margin-right:auto}
.herocta{justify-content:center}

/* isolate so the wide wash below can sit behind the portrait and nowhere else */
.headstage{margin-top:var(--s6);position:relative;will-change:transform;isolation:isolate}

/* tight, bright: the transducer itself */
.headstage::before{
  content:"";position:absolute;left:57%;top:49%;width:min(680px,88%);aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(closest-side,rgba(30,143,255,.30),rgba(30,143,255,.07) 46%,transparent 72%);
  pointer-events:none;
}

/* wide, faint: an ambient wash behind the whole figure. deliberately weak,
   so it separates the silhouette from the black without ever being noticed
   as a shape of its own. */
.headstage::after{
  content:"";position:absolute;left:50%;top:36%;width:132%;aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;z-index:-1;
  background:radial-gradient(closest-side,
    rgba(30,143,255,.11),
    rgba(30,143,255,.045) 40%,
    rgba(30,143,255,.015) 62%,
    transparent 78%);
  pointer-events:none;
}
/* the portrait reads the smoothed pointer and the scroll position straight
   off :root. no per-frame style writes, no layout thrash — the browser
   composites it. this is what "reactive, never delayed" costs: nothing. */
.headwrap{position:relative;max-width:600px;margin:0 auto;
  transform:translate3d(calc(var(--px) * -14px), calc(var(--py) * -10px + var(--herodepth,0px)), 0);
  transition:transform 60ms linear}
.headwrap img{width:100%;
  filter:saturate(.38) contrast(1.06) brightness(.88);
  -webkit-mask-image:linear-gradient(to bottom,#000 58%,rgba(0,0,0,.35) 88%,transparent 99%);
  mask-image:linear-gradient(to bottom,#000 58%,rgba(0,0,0,.35) 88%,transparent 99%)}
.hero h1 span{display:block}
/* the third line is the reversal, and the reversal is the product.
   blue only there — it is the one clause a reader has to finish. */
.hero h1 em{font-style:normal;color:var(--blue)}

.herolede{font-size:clamp(16.5px,1.7vw,20px);line-height:1.55;color:var(--steel);
  letter-spacing:-.012em;max-width:46ch;margin-top:var(--s3)}
.herolede b{color:var(--bone);font-weight:600}

.herocta{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;margin-top:var(--s4)}
.herocta .sub{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim)}

/* the conduction graphic brightens as the pointer approaches the device.
   it has to sit on the <svg>, not on .arcg: the keyframes there animate
   opacity themselves and would win. --near defaults to 1, so a touch device
   -- which never reports proximity -- gets the graphic at full strength. */
.headwrap svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none;
  opacity:calc(.5 + var(--near,1) * .5);transition:opacity 220ms var(--e-settle)}
.arc{fill:none;stroke:var(--blue);stroke-width:2.5;stroke-linecap:round}
@keyframes conduct{0%{opacity:0;transform:scale(.35)}18%{opacity:.85}100%{opacity:0;transform:scale(2.1)}}
.arcg{transform-origin:687px 568px;animation:conduct 3.6s cubic-bezier(.2,.6,.4,1) infinite}
.a2{animation-delay:1.2s} .a3{animation-delay:2.4s}
@keyframes travel{0%{offset-distance:0%;opacity:0}14%{opacity:1}86%{opacity:1}100%{offset-distance:100%;opacity:0}}
.pip{fill:var(--glow);offset-path:path("M 687 568 C 640 596 580 590 534 560");animation:travel 2.2s linear infinite}
@keyframes throb{0%,100%{opacity:.4;r:7}50%{opacity:1;r:10}}
.core{fill:var(--glow);animation:throb 2.2s ease-in-out infinite}

/* ---- stat line (no boxes) ---- */
.statline{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4);margin-top:var(--s7)}
.stat{text-align:center}
.statnum{font-family:"Archivo";font-weight:700;font-size:clamp(20px,2.7vw,32px);letter-spacing:-.035em;line-height:1;font-variant-numeric:tabular-nums}
.stat .mono{display:block;margin-top:var(--s2);font-size:10px}

/* ============================================================
   AIRY COLUMNS (replaces bordered grids)
   ============================================================ */
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5) var(--s4)}
.cols4{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s5) var(--s4)}
.col .d4{margin-bottom:var(--s2)}
.col p{color:var(--steel);font-size:16px;line-height:1.55}
.tick{width:5px;height:5px;border-radius:50%;background:var(--blue);margin-bottom:var(--s3)}

/* ============================================================
   SURFACES — the only boxes left on the page
   ============================================================ */
.surface{background:var(--surface);border-radius:var(--r3);padding:clamp(24px,4vw,56px)}
.surface-h{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s5)}

/* ---- noise lab ---- */
.sliderwrap{margin-bottom:var(--s5)}
.sliderwrap input{-webkit-appearance:none;appearance:none;width:100%;height:3px;border-radius:2px;background:var(--hair2);outline:none;margin:var(--s3) 0 var(--s2)}
.sliderwrap input::-webkit-slider-thumb{-webkit-appearance:none;width:28px;height:28px;border-radius:50%;background:var(--bone);cursor:grab;box-shadow:0 2px 12px rgba(0,0,0,.6)}
.sliderwrap input::-webkit-slider-thumb:active{cursor:grabbing}
.sliderwrap input::-moz-range-thumb{width:28px;height:28px;border:none;border-radius:50%;background:var(--bone);cursor:grab}
.slabels{display:flex;justify-content:space-between}
.readout{font-family:"Archivo";font-weight:700;font-size:clamp(22px,2.6vw,30px);letter-spacing:-.035em;font-variant-numeric:tabular-nums}

.chans{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4)}
.chan{background:var(--surface2);border-radius:var(--r2);padding:var(--s4) var(--s3) var(--s3)}
.chantop{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);margin-bottom:var(--s1)}
.pill{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:4px 10px;border-radius:100px;background:rgba(30,143,255,.14);color:var(--blue);white-space:nowrap}
.pill.bad{background:rgba(255,107,74,.14);color:var(--warn)}
.chan canvas{width:100%;height:110px;display:block;margin:var(--s3) 0}
.script{font-family:"IBM Plex Mono",monospace;font-size:13px;line-height:1.7;min-height:3.4em;word-break:break-word;color:var(--bone)}
.script.bad{color:var(--warn)}

/* ============================================================
   THE GATE
   ============================================================ */
.gate{display:grid;grid-template-columns:1fr 1fr;gap:var(--s6);align-items:center}
.busbox svg{width:100%;height:auto;overflow:visible}
.bus{fill:none;stroke-width:2.5;stroke-linecap:round;transition:stroke .5s}
.bus-live{stroke:var(--blue)}
.bus-dead{stroke:rgba(255,255,255,.13)}
@keyframes flow{to{stroke-dashoffset:-36}}
.flowline{stroke-dasharray:3 15;animation:flow 1.1s linear infinite}
.nodelbl{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;fill:var(--dim)}
.nodelbl.on{fill:var(--blue)}

.switchrow{display:flex;align-items:center;gap:var(--s3);margin:var(--s4) 0 var(--s3)}
.switch{width:76px;height:42px;border-radius:100px;background:var(--surface2);border:1px solid var(--hair2);position:relative;cursor:pointer;transition:background .35s,border-color .35s;flex:none;padding:0}
.switch::after{content:"";position:absolute;top:4px;left:4px;width:32px;height:32px;border-radius:50%;background:var(--steel);transition:transform .35s cubic-bezier(.3,1.4,.5,1),background .35s}
.switch[aria-checked="true"]{background:rgba(30,143,255,.22);border-color:var(--blue)}
.switch[aria-checked="true"]::after{transform:translateX(34px);background:var(--blue);box-shadow:0 0 18px var(--blue)}
.switchstate{font-family:"Archivo";font-weight:700;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);transition:color .35s}
.switchstate.on{color:var(--blue)}

.log{margin-top:var(--s4);min-height:190px;border-top:1px solid var(--hair);padding-top:var(--s3)}
.logline{font-family:"IBM Plex Mono",monospace;font-size:12.5px;line-height:1.9;color:var(--steel);opacity:0;transform:translateY(6px);transition:opacity .4s,transform .4s}
.logline.in{opacity:1;transform:none}
.logline b{color:var(--bone);font-weight:400}
.logline.off{color:var(--dim)}

/* ============================================================
   3D VIEWER
   ============================================================ */
.tabs{display:flex;gap:6px;justify-content:center;margin-bottom:var(--s4);flex-wrap:wrap}
.tab{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  background:transparent;border:1px solid var(--hair2);border-radius:100px;padding:11px 20px;cursor:pointer;
  color:var(--steel);transition:color .25s,background .25s,border-color .25s}
.tab:hover{color:var(--bone);border-color:var(--steel)}
.tab[aria-selected="true"]{color:#000;background:var(--bone);border-color:var(--bone)}

.pillbtn{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;background:transparent;border:1px solid var(--hair2);border-radius:100px;
  padding:11px 20px;cursor:pointer;color:var(--steel);transition:color .25s,border-color .25s,background .25s}
.pillbtn:hover{color:var(--bone);border-color:var(--steel)}
.pillbtn[aria-pressed="true"]{color:var(--blue);border-color:var(--blue)}
.pillbtn[hidden]{display:none}

.viewer{position:relative;border-radius:var(--r3);overflow:hidden;
  background:radial-gradient(ellipse at 50% 40%,#2B2E34 0%,#101115 72%)}
#vcanvas{display:block;width:100%;height:clamp(320px,50vw,540px);touch-action:pan-y}
.vfallback{display:none;padding:var(--s5) var(--s4)}
.viewer.failed #vcanvas{display:none}
.viewer.failed .vfallback{display:block}

.vload{position:absolute;inset:0;display:grid;place-items:center;gap:var(--s3);
  align-content:center;background:rgba(10,10,12,.72);transition:opacity .5s}
.vload.gone{opacity:0;pointer-events:none}
.vbar{width:160px;height:2px;border-radius:2px;background:var(--hair2);overflow:hidden}
.vbar i{display:block;height:100%;width:0;background:var(--blue);transition:width .25s}

.vhint{position:absolute;left:var(--s3);bottom:var(--s3);pointer-events:none;opacity:.55}
.vplay{position:absolute;right:var(--s3);bottom:var(--s3)}

.vcopy{margin-top:var(--s5);display:grid;grid-template-columns:1fr 1fr;gap:var(--s5)}
.vcopy p{color:var(--steel)}
.vfacts{display:block}
.vfact{position:relative;padding-left:20px;margin-bottom:var(--s3);overflow-wrap:anywhere}
.vfact:last-child{margin-bottom:0}
.vfact::before{content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:50%;background:var(--blue)}
.vfact b{display:block;font-family:"Archivo",system-ui,sans-serif;font-weight:700;font-size:14px;
  letter-spacing:.01em;line-height:1.35;color:var(--bone);margin-bottom:4px}
.vfact span{display:block;font-size:15px;color:var(--steel);line-height:1.55}

.scalebar{margin-top:var(--s4)}
.scalerule{position:relative;width:51mm;max-width:100%;height:1px;background:var(--blue)}
.scalerule::before,.scalerule::after{content:"";position:absolute;top:-4px;width:1px;height:9px;background:var(--blue)}
.scalerule::before{left:0} .scalerule::after{right:0}
.scalebar .mono{display:block;margin-top:var(--s2)}

.viewer.failed .vload{display:none}
.vload.gone{opacity:0;pointer-events:none}
@media(max-width:640px){
  .vcopy{grid-template-columns:1fr;gap:var(--s4)}
  #vcanvas{height:clamp(380px,112vw,460px)}
}

/* ============================================================
   MORNING
   ============================================================ */
.mgrid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4);margin-bottom:var(--s5)}
.mcard{background:var(--surface2);border-radius:var(--r2);padding:var(--s4) var(--s3);text-align:center}
.mcard.win{background:rgba(30,143,255,.07)}
.mbig{font-family:"Archivo";font-weight:800;font-size:clamp(40px,7vw,76px);letter-spacing:-.05em;line-height:1;font-variant-numeric:tabular-nums}
.mcard.win .mbig{color:var(--blue)}
.msub{margin-top:var(--s2);font-size:14px;color:var(--steel)}
.mtime{margin-top:var(--s1);font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--dim);font-variant-numeric:tabular-nums}

.mtl{position:relative;padding-left:var(--s4)}
.mtl::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--hair)}
.mfill{position:absolute;left:5px;top:6px;width:1px;height:0;background:var(--blue);transition:height .5s linear}
.mev{position:relative;padding:var(--s2) 0;opacity:.28;transition:opacity .5s}
.mev.on{opacity:1}
.mev::before{content:"";position:absolute;left:calc(-1 * var(--s4) + 1px);top:calc(var(--s2) + 9px);width:9px;height:9px;border-radius:50%;
  background:var(--surface);border:1px solid var(--hair2);transition:background .4s,border-color .4s}
.mev.on::before{background:var(--blue);border-color:var(--blue)}
.mevtop{display:flex;gap:var(--s2);align-items:baseline;flex-wrap:wrap}
.mevt{font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--blue);font-variant-numeric:tabular-nums}
.mevn{font-family:"Archivo";font-weight:700;font-size:12px;letter-spacing:.09em;text-transform:uppercase}
.mev p{font-size:15px;color:var(--steel);margin-top:2px}

.mfoot{margin-top:var(--s5);padding-top:var(--s4);border-top:1px solid var(--hair)}
.yearline{font-family:"Archivo";font-weight:700;letter-spacing:-.03em;font-size:clamp(19px,2.4vw,27px);line-height:1.35}
.yearline b{color:var(--blue);font-weight:700;font-variant-numeric:tabular-nums}
.mctl{display:flex;align-items:center;gap:var(--s3);margin-top:var(--s4);padding-bottom:var(--s1);flex-wrap:wrap}
.mctl input{-webkit-appearance:none;appearance:none;flex:1;min-width:180px;height:3px;border-radius:2px;background:var(--hair2);outline:none}
.mctl input::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;border-radius:50%;background:var(--bone);cursor:grab}
.mctl input::-moz-range-thumb{width:22px;height:22px;border:none;border-radius:50%;background:var(--bone);cursor:grab}

/* ============================================================
   NOTHING + BAND
   ============================================================ */
.nothing{font-family:"Archivo";font-weight:900;letter-spacing:-.06em;font-size:clamp(70px,17.5vw,208px);line-height:.82;
  color:transparent;-webkit-text-stroke:1.5px var(--blue);margin:var(--s3) 0}

.closer{padding:var(--s7) 0 var(--s8);text-align:center}
.closer img{width:56px;margin:0 auto var(--s5);opacity:.9}
#early{padding-bottom:var(--s6)}

/* ---- reveal ----
   the arrival is a settle, not a fade: the element is already travelling in
   the direction the page is travelling and simply comes to rest. --i staggers
   siblings so a group arrives as one movement instead of eight separate ones. */
.rv{opacity:0;transform:translate3d(0,var(--rv-y,22px),0);
  transition:opacity var(--t-settle) var(--e-conduct) var(--rv-d,0ms),
             transform var(--t-arrive) var(--e-conduct) var(--rv-d,0ms);
  will-change:opacity,transform}
.rv.in{opacity:1;transform:none;will-change:auto}
.rv[data-stagger] > *{opacity:0;transform:translate3d(0,var(--rv-y,18px),0);
  transition:opacity var(--t-settle) var(--e-conduct),transform var(--t-arrive) var(--e-conduct)}
.rv[data-stagger].in > *{opacity:1;transform:none;
  transition-delay:calc(var(--i,0) * var(--stagger,70ms))}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .arcg,.pip,.core,.hot u,.flowline,.ring,.beam{animation:none}
  .arcg{opacity:.3}
  .rv,.rv[data-stagger] > *{opacity:1;transform:none;transition:none}
  .parallax,.depth{transform:none !important}
  *{scroll-behavior:auto}
}

/* ============================================================
   EARLY ACCESS
   ============================================================ */
.getgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s5) var(--s6);
  max-width:var(--narrow);margin:0 auto;text-align:left}
.get{position:relative;padding-left:var(--s4)}
.get b{display:block;font-family:"Archivo",system-ui,sans-serif;font-weight:700;font-size:16px;
  letter-spacing:-.01em;color:var(--bone);margin-bottom:6px}
.get span{display:block;font-size:15px;line-height:1.55;color:var(--steel)}
.getnum{position:absolute;left:0;top:1px;font-family:"IBM Plex Mono",monospace;font-size:11px;
  letter-spacing:.1em;color:var(--blue)}

.signup{max-width:520px;margin:var(--s6) auto 0}
.signrow{display:flex;gap:var(--s2);align-items:stretch}
.signup input[type=email]{
  flex:1;min-width:0;background:var(--surface2);border:1px solid var(--hair2);border-radius:100px;
  padding:15px 22px;color:var(--bone);font-family:inherit;font-size:16px;outline:none;transition:border-color .25s}
.signup input[type=email]::placeholder{color:var(--dim)}
.signup input[type=email]:focus{border-color:var(--blue)}
.signup button{
  flex:none;border:none;border-radius:100px;padding:15px 26px;cursor:pointer;
  background:var(--bone);color:#000;font-family:"IBM Plex Mono",monospace;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;transition:background .25s,color .25s}
.signup button:hover{background:var(--blue);color:#fff}
.signup button[disabled]{opacity:.5;cursor:default}
.signnote{margin-top:var(--s3);text-align:center}
.signerr{margin-top:var(--s3);text-align:center;color:var(--warn)}
.signup[data-error] .signnote{display:none}
.signup input[type=email]:user-invalid{border-color:var(--warn)}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.signdone{display:none;text-align:center;padding:var(--s4) 0}
.signdone b{display:block;font-family:"Archivo",system-ui,sans-serif;font-weight:700;font-size:19px;
  letter-spacing:-.02em;color:var(--blue);margin-bottom:var(--s2)}
.signup.done .signrow,.signup.done .signnote{display:none}
.signup.done .signdone{display:block}

@media(max-width:640px){
  .getgrid{grid-template-columns:1fr;gap:var(--s4)}
  .signrow{flex-direction:column}
  .signup button{padding:15px 20px}
}

/* ============================================================
   ORIGIN
   the letters that survive stay lit, the ones that drop go dim,
   so the portmanteau explains itself without a caption
   ============================================================ */
/* the connector is the transition. it is drawn by the reader's own scroll,
   travels the full run-up, and only then does the equation settle in behind
   it: one continuous movement instead of a line and a separate fade. */
.origin{padding-top:var(--s8);position:relative}
/* the run-up carries its own scrub, so the line finishes drawing exactly as
   the equation comes into reading position, not a screen and a half later */
.originline,.sdiv{--sp:0;width:1px;background:var(--hair);pointer-events:none}
.originline i,.sdiv i{position:absolute;left:0;top:0;width:1px;
  height:calc(var(--sp) * 100%);background:var(--blue);
  box-shadow:0 0 14px rgba(30,143,255,.55)}
.originline::after,.sdiv::after{content:"";position:absolute;left:-2px;
  top:calc(var(--sp) * 100%);width:5px;height:5px;margin-top:-2px;border-radius:50%;
  background:var(--blue);box-shadow:0 0 16px var(--blue);
  opacity:calc(var(--sp) * 4)}
.originline{position:absolute;left:50%;top:0;height:var(--s8);
  transform:translateX(-50%)}

/* the same thread, between every section. the negative margin means it sits
   inside whitespace the page already had, so no section moves to make room. */
.sdiv{position:relative;height:var(--s6);margin:calc(var(--s6) / -2) auto}
/* the three beats of the equation arrive in the order they are read */
[data-rv-late]{--rv-d:300ms}
[data-rv-later]{--rv-d:620ms}
[data-rv-later] + .lead{--rv-d:820ms}
/* 1fr auto 1fr forces the operator onto the exact horizontal centre; with
   flex it drifted by half the difference between the two word widths */
.originrow{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  column-gap:var(--s4);margin-top:var(--s4)}
.originrow > :nth-child(1){justify-self:end}
.originrow > :nth-child(3){justify-self:start}
.word{font-family:"Archivo",system-ui,sans-serif;font-weight:800;letter-spacing:-.03em;
  font-size:clamp(30px,4.6vw,58px);line-height:1}
.word b{font-weight:800;color:var(--bone)}
.word i{font-style:normal;font-weight:800;color:rgba(255,255,255,.19)}
.op{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:clamp(15px,1.8vw,22px);
  color:var(--blue);line-height:1}
.originres{display:flex;align-items:center;justify-content:center;gap:var(--s3);
  margin-top:var(--s4)}
/* all-caps sits high in its own box, so true centre is a touch above the
   geometric middle. the nudge scales with how big the word beside it is. */
.originrow .op{transform:translateY(calc(clamp(30px,4.6vw,58px) * -0.082))}
.originres .op{transform:translateY(calc(clamp(52px,10vw,140px) * -0.050))}
.resword{font-family:"Archivo",system-ui,sans-serif;font-weight:900;letter-spacing:-.045em;
  font-size:clamp(52px,10vw,140px);line-height:.92;color:var(--bone)}
.origin .lead{margin-top:var(--s5)}
.origin .originsecond{margin-top:var(--s3)}
@media(max-width:640px){
  .originrow{column-gap:var(--s3)}
  .originres{gap:var(--s2)}
}

/* ============================================================
   TYPOGRAPHIC RHYTHM
   one section-header pattern; the browser balances every rag.
   ============================================================ */
.shead{text-align:center;margin-bottom:var(--s6)}
.shead > .mono{display:block;margin-bottom:var(--s3)}
.shead h2{margin:0 auto}

/* balance stops a headline dropping a single orphan word onto its own line;
   pretty does the same for the last line of body copy. */
h1,h2,h3,h4,.d1,.d2,.d3,.d4,.statnum,.mbig,.yearline,.nothing{text-wrap:balance}
p,.lead,.chan .mono,.vfact span,.col p{text-wrap:pretty}

/* measure: centred copy reads short, never the full 760px slab */
.lead{margin:var(--s4) auto 0}
.lead.narrow{max-width:56ch}
h2.d2.narrow{max-width:22ch}
.d3.center.narrow{max-width:30ch;text-wrap:balance}

.tnum,.mono{font-variant-numeric:tabular-nums}
.script{overflow-wrap:anywhere}

/* every repeated gap below is a class, not a number typed inline */
.cols3,.cols4{margin-top:var(--s7);text-align:left}
.col p{margin-top:var(--s2)}
.note{margin-top:var(--s4)}
.pull{margin:var(--s6) auto 0}
.vbody{margin-top:var(--s3)}

/* ============================================================
   HERO — two columns on desktop only.
   Below 1000px none of this applies and the stacked mobile
   layout stays exactly as it was: copy, portrait, then stats.
   ============================================================ */
@media(min-width:1000px){
  /* Two explicit rows. The portrait is bound to row 1, so it can never reach
     down into the copy the way it did when it was measured against the
     full height of the block. */
  .hero{position:relative;min-height:min(calc(100vh - 64px),880px);
    display:flex;align-items:stretch;overflow:hidden;padding:0}
  .hero > .wrap{max-width:1240px;width:100%;position:relative;z-index:2;text-align:left;
    display:flex;flex-direction:column;justify-content:center;
    padding-top:var(--s4);padding-bottom:calc(var(--s4) + var(--lift))}

  /* copy and portrait are raised by the SAME amount, so their optical centres
     stay on one line instead of drifting apart */
  .hero{--lift:clamp(16px,4vh,52px)}
  .herotext{max-width:56%;position:relative;z-index:3}

  /* Optical left edge. Values are the measured left side bearing of each first
     glyph, taken from the font files themselves, not estimated:
       W  Archivo 800    0.0180em
       A  Archivo 400    0.0090em
       S  Plex Mono 400  0.0450em
     Expressed in em, each correction scales with its own type size, so the
     ink edges stay on one vertical line at any width. */
  .herotext > .mono{display:block;margin-left:-.045em}
  .herotext h1.d1{font-size:clamp(44px,5.0vw,70px);letter-spacing:-.045em;line-height:.98;
    margin-top:var(--s3);margin-left:-.018em}
  .hero h1 span{white-space:nowrap}
  .herolede,.hero .herolede{margin-top:var(--s3);max-width:44ch;margin-left:0;margin-right:0}
  /* scoped: .herocta is reused by the closer, which stays centred */
  .hero .herocta{justify-content:flex-start}
  .hero .herocta{margin-top:var(--s4)}

  /* height-driven: the portrait fills row 1 and derives its width from the
     image ratio, so it scales with the window and never overflows the row */
  .headstage{position:absolute;top:0;bottom:0;right:-10vw;left:auto;width:auto;
    display:flex;align-items:center;justify-content:flex-end;margin:0;z-index:1;
    padding-bottom:var(--lift)}
  /* capped: the portrait is presence, not subject. left unbounded it grows with
     the row and starts competing with the headline for the same eye. */
  .headwrap{height:min(100%,76vh);width:auto;aspect-ratio:1200 / 1153;max-width:none;margin:0}
  /* dark enough that the eye lands on the headline first, the lit module second
     and the portrait third. it is the stage, not the actor. */
  .headwrap img{filter:saturate(.26) contrast(1.1) brightness(.58)}
  /* the near edge dissolves into the page instead of ending on a hard silhouette,
     so the copy column and the portrait share one field rather than two panels */
  .headwrap::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
    background:linear-gradient(90deg,var(--void) 0%,rgba(0,0,0,.82) 14%,rgba(0,0,0,.28) 34%,transparent 52%)}
  .headstage::before{width:64%;left:59%;
    background:radial-gradient(closest-side,rgba(30,143,255,.40),rgba(30,143,255,.10) 44%,transparent 72%)}
  .headstage::after{width:118%;top:34%}
}

@media(min-width:1000px) and (max-height:760px){
  /* short laptop screens: the fold is the constraint, not the type scale */
  .hero{min-height:auto;padding:var(--s5) 0}
  .scrollcue{display:none}
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media(max-width:900px){
  :root{--s7:104px;--s8:132px;--s6:76px}
  .gate,.devgrid{grid-template-columns:1fr;gap:var(--s5)}
  .cols3,.cols4{grid-template-columns:1fr 1fr}
}
@media(max-width:999px){
  /* the wash was sized for the wide desktop crop. stacked and centred it reads
     as a blue smear behind the head rather than as separation, so it comes off. */
  .headstage::before,.headstage::after{display:none}
}

@media(max-width:640px){
  /* the rails were pushing every list a full step in from the left while the
     headings stayed centred, and the mismatch read as a page shifted sideways.
     on a phone the rail belongs in the gutter, so body text starts on exactly
     the same line as every heading above it. */
  .beat{padding-left:0}
  .flowline-v{left:-14px}
  .beatdot{left:-21px}
  .mtl{padding-left:0}
  .mtl::before,.mfill{left:-14px}
  .mev::before{left:-18px}
  .get,.reserve .get{padding-left:0}
  .getnum{position:static;display:block;margin-bottom:6px}

  /* five lines of headline is not a headline. the claim has to land in the
     first glance on a phone too, so the type is sized to the measure. */
  .hero h1.d1{font-size:clamp(30px,8.1vw,44px);line-height:1.02;letter-spacing:-.04em}
  .hero .herolede{font-size:16px;max-width:38ch}
  .hero .herocta{flex-direction:column;align-items:stretch;width:100%}
  .hero .herocta .btn{width:100%}

  body{font-size:16px}
  :root{--s7:84px;--s8:104px;--s6:60px;--s5:48px}
  .closer{padding-top:var(--s5)}
  .chans,.mgrid{grid-template-columns:1fr}
  .cols3,.cols4{grid-template-columns:1fr;gap:var(--s4)}
  .statline{grid-template-columns:1fr 1fr;gap:var(--s5) var(--s3)}
  .surface{border-radius:var(--r2)}
}

/* ============================================================
   ============================================================
   ADDED FOR PRODUCTION — everything below this line is new.
   It uses only the tokens declared at the top of this file:
   no new colours, no new type sizes, no new spacing values.
   ============================================================
   ============================================================ */

/* ------------------------------------------------------------
   SECTION RAIL — a continuous position indicator, right edge.
   Not a menu: a readout of where in the object you currently are.
   ------------------------------------------------------------ */
.rail{position:fixed;right:22px;top:50%;transform:translateY(-50%);z-index:80;
  display:flex;flex-direction:column;gap:14px;
  opacity:0;pointer-events:none;transition:opacity var(--t-move) var(--e-settle)}
.rail.on{opacity:1;pointer-events:auto}
.rail a{position:relative;display:block;width:22px;height:10px;text-decoration:none}
.rail a::after{content:"";position:absolute;right:0;top:4px;width:16px;height:1px;
  background:var(--hair2);
  transition:width var(--t-move) var(--e-conduct),background var(--t-move) var(--e-settle)}
.rail a:hover::after{background:var(--steel);width:22px}
.rail a[aria-current="true"]::after{background:var(--blue);width:22px}
.rail .raillbl{position:absolute;right:30px;top:-4px;white-space:nowrap;
  font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--steel);
  opacity:0;transform:translateX(6px);pointer-events:none;
  transition:opacity var(--t-quick) var(--e-settle),transform var(--t-quick) var(--e-conduct)}
.rail a:hover .raillbl,.rail a:focus-visible .raillbl{opacity:1;transform:none}
@media(max-width:1180px){.rail{display:none}}

/* ------------------------------------------------------------
   HOW IT WORKS — three beats, scrubbed by scroll.
   Nothing here autoplays. --sp is written by sonic.js: it is this
   section's own 0 → 1 progress through the viewport, so the user's
   scroll is the transport control and nothing else is.
   ------------------------------------------------------------ */
.flow{--sp:0;position:relative;margin-top:var(--s6)}
/* the schematic column. sticky, so one diagram stays in view for the whole beat
   and the reader never has to hold the previous picture in their head. */
.flowfigs{display:none}
.flowfig{grid-area:1 / 1;opacity:0;transform:translate3d(0,10px,0);
  transition:opacity var(--t-settle) var(--e-settle),transform var(--t-arrive) var(--e-conduct);
  pointer-events:none}
.flowfig svg{width:100%;height:auto;overflow:visible}
.flow:not(.flow-inline)[data-live="0"] .flowfig:nth-child(1),
.flow:not(.flow-inline)[data-live="1"] .flowfig:nth-child(2),
.flow:not(.flow-inline)[data-live="2"] .flowfig:nth-child(3){opacity:1;transform:none}

/* phone layout: the diagram sits inside its own step, in normal flow.
   nothing is sticky, so nothing can overlap anything. the beat's own
   dimming is what brings it up, which keeps the whole section on one
   behaviour instead of two. */
.flow-inline .flowfigs{display:none}
.flow-inline .flowfig{grid-area:auto;position:static;opacity:1;transform:none;
  background:var(--surface);border-radius:var(--r2);
  padding:var(--s3) var(--s3) var(--s2);margin:var(--s3) 0 var(--s3)}
.hairline{stroke:rgba(255,255,255,.09);stroke-width:1}
.noisewave{stroke:rgba(255,255,255,.15);stroke-width:1.5;fill:none;stroke-linejoin:round}
.stopwall{stroke:var(--warn);stroke-width:1.5;stroke-dasharray:3 5;opacity:.7}
.figarcs .arc{stroke-width:2;opacity:.85;fill:none}
.figarcs .arc.a2{opacity:.5}
.figarcs .arc.a3{opacity:.26}

@media(min-width:1000px){
  .flow{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,.82fr);
    column-gap:var(--s6);align-items:start}
  .flow > .flowline-v,.flow > .beat{grid-column:1}
  .flowfigs{display:grid;grid-column:2;grid-row:1 / -1;
    position:sticky;top:calc(50vh - 130px);align-self:start;
    padding:var(--s4) 0}
}
.flowline-v{position:absolute;left:19px;top:12px;bottom:12px;width:1px;background:var(--hair)}
.flowline-v::after{content:"";position:absolute;left:0;top:0;width:1px;
  height:calc(var(--sp) * 100%);background:var(--blue);
  box-shadow:0 0 12px rgba(30,143,255,.5)}
.beat{position:relative;padding:var(--s4) 0 var(--s4) calc(var(--s5) + var(--s1));min-height:120px}
.beatdot{position:absolute;left:12px;top:calc(var(--s4) + 6px);width:15px;height:15px;border-radius:50%;
  background:var(--void);border:1px solid var(--hair2);display:grid;place-items:center;
  transition:border-color var(--t-move) var(--e-settle)}
.beatdot::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--hair2);
  transition:background var(--t-move) var(--e-settle),box-shadow var(--t-move) var(--e-settle)}
.beat.live .beatdot{border-color:var(--blue)}
.beat.live .beatdot::after{background:var(--blue);box-shadow:0 0 14px var(--blue)}
.beatn{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.2em;color:var(--dim);
  transition:color var(--t-move) var(--e-settle)}
.beat.live .beatn{color:var(--blue)}
.beat h3{margin-top:var(--s2)}
.beat p{color:var(--steel);margin-top:var(--s2);max-width:56ch;font-size:16px;line-height:1.6}
.beat .beatmeta{display:flex;gap:var(--s3);flex-wrap:wrap;margin-top:var(--s3)}
.beat .beatmeta span{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim)}
.beat .beatmeta span b{color:var(--steel);font-weight:400}
/* the copy itself lifts as its beat becomes the live one */
.beat{opacity:.34;transition:opacity var(--t-settle) var(--e-settle)}
.beat.live{opacity:1}
@media(max-width:999px){
  /* on a phone the diagram earns its place more than a fourth paragraph does:
     it sits above the beats and changes as each one becomes the live step. */
  /* relative + a solid ground, so the progress rail simply runs behind the
     card and emerges below it. no height arithmetic, nothing to keep in sync. */
  /* site.js moves each figure inside its own beat at this width; this block
     is the fallback for the moment before that runs, and for no-JS. */
  .flowfigs{display:grid;position:relative;margin-bottom:var(--s4);
    background:var(--surface);border-radius:var(--r2);
    padding:var(--s4) var(--s3);min-height:190px;align-content:center}
  .flowfig{grid-area:1 / 1}
}
@media(max-width:640px){
  .beat{padding-left:var(--s5)}
  .flowline-v{left:15px}
  .beatdot{left:8px}
  .beat{padding-top:var(--s3);padding-bottom:var(--s4)}
  .beat p{font-size:15px}
  .flow-inline .flowfig{padding:var(--s3) var(--s2) var(--s1);margin:var(--s3) 0}
}

/* ------------------------------------------------------------
   COMPARISON — four columns, one of them ours.
   ------------------------------------------------------------ */
.cmpwrap{position:relative;overflow-x:auto;margin-top:var(--s6);
  -webkit-overflow-scrolling:touch;scrollbar-width:thin;
  /* the edges fade only while there is more table behind them; site.js sets
     .fade-l / .fade-r from the scroll position, so a reader who has arrived at
     the last column sees it whole */
  --mask-l:#000 0;
  --mask-r:#000 100%}
.cmpwrap.fade-l{--mask-l:transparent 0,#000 44px}
.cmpwrap.fade-r{--mask-r:#000 calc(100% - 44px),transparent 100%}
.cmpwrap.fade-l,.cmpwrap.fade-r{
  -webkit-mask-image:linear-gradient(90deg,var(--mask-l),var(--mask-r));
  mask-image:linear-gradient(90deg,var(--mask-l),var(--mask-r))}
/* the row label has to survive the horizontal scroll or the numbers stop
   meaning anything once you are two columns in */
.cmp tbody th,.cmp thead th:first-child{position:sticky;left:0;z-index:2;
  background:var(--void)}
@media(min-width:900px){
  .cmpwrap.fade-l,.cmpwrap.fade-r{-webkit-mask-image:none;mask-image:none}
  .cmp tbody th,.cmp thead th:first-child{position:static;background:none}
}

/* A phone cannot show five columns, and sideways scrolling through a
   comparison is not comparing. Below 760px each row becomes its own card:
   the question on top, the four answers under it, ours first and lit. */
@media(max-width:760px){
  .cmpwrap{overflow:visible;margin-top:var(--s5)}
  .cmpwrap.fade-l,.cmpwrap.fade-r{-webkit-mask-image:none;mask-image:none}
  .cmp,.cmp tbody,.cmp tr,.cmp th,.cmp td{display:block;width:auto}
  .cmp{min-width:0}
  .cmp thead{display:none}
  .cmp tbody tr{background:var(--surface);border-radius:var(--r2);
    padding:var(--s3);margin-bottom:var(--s2)}
  .cmp tbody th,.cmp tbody td{position:static;background:none;
    border-bottom:none;padding:0;width:auto}
  .cmp tbody th{text-align:left;font-size:10.5px;letter-spacing:.16em;
    color:var(--dim);margin-bottom:var(--s2)}
  /* the label is absolute, not a flex item: a cell whose text is part span and
     part bare text has to stay one flow, or the two halves break apart */
  .cmp tbody td{position:relative;padding:9px 0 9px 96px;
    border-top:1px solid var(--hair);font-size:14.5px}
  .cmp tbody td::before{content:attr(data-h);position:absolute;left:0;top:11px;
    width:88px;font-family:"IBM Plex Mono",monospace;font-size:10px;
    letter-spacing:.1em;text-transform:uppercase;color:var(--dim);line-height:1.5}
  .cmp tbody td.us{background:none;color:var(--bone);font-weight:500;
    border-top-color:var(--blue)}
  .cmp tbody td.us::before{color:var(--blue)}
}
  .cmp tbody th,.cmp thead th:first-child{position:static;background:none}
}
.cmp{width:100%;min-width:660px;border-collapse:collapse;text-align:left}
.cmp th,.cmp td{padding:var(--s3) var(--s3);vertical-align:top;
  border-bottom:1px solid var(--hair);font-size:15px}
.cmp thead th{padding-top:0;border-bottom:1px solid var(--hair2)}
.cmp tbody th{color:var(--steel);font-weight:400;font-size:14px;width:26%;
  font-family:"IBM Plex Mono",monospace;letter-spacing:.06em;text-transform:uppercase}
.cmp td{color:var(--steel)}
.cmphd{font-family:"Archivo",system-ui,sans-serif;font-weight:700;font-size:15px;
  letter-spacing:-.01em;color:var(--steel);display:block}
.cmphd small{display:block;font-family:"IBM Plex Mono",monospace;font-weight:400;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);margin-top:6px}
/* our column is lit, and the lift is a background, not a border, so the table
   grid stays unbroken */
.cmp .us{background:rgba(30,143,255,.055);color:var(--bone)}
.cmp thead .us .cmphd{color:var(--bone)}
.cmp thead .us .cmphd small{color:var(--blue)}
.cmp tbody tr:last-child th,.cmp tbody tr:last-child td{border-bottom:none}
.cmp .yes{color:var(--blue)}
.cmp .no{color:var(--dim)}
.cmpnote{margin-top:var(--s3)}

/* ------------------------------------------------------------
   SPEC SHEET — disclosure groups. Closed by default: the page is
   not obliged to shout its datasheet at someone who did not ask.
   ------------------------------------------------------------ */
.specs{margin-top:var(--s6);border-top:1px solid var(--hair)}
.spec{border-bottom:1px solid var(--hair)}
.spec > summary{list-style:none;cursor:pointer;padding:var(--s3) 0;
  display:flex;align-items:center;gap:var(--s3);
  font-family:"Archivo",system-ui,sans-serif;font-weight:700;font-size:17px;letter-spacing:-.01em;
  transition:color var(--t-quick) var(--e-settle)}
.spec > summary::-webkit-details-marker{display:none}
.spec > summary:hover{color:var(--blue)}
.spec > summary .sx{margin-left:auto;position:relative;width:12px;height:12px;flex:none}
.spec > summary .sx::before,.spec > summary .sx::after{content:"";position:absolute;
  background:var(--steel);transition:transform var(--t-move) var(--e-conduct),background var(--t-quick)}
.spec > summary .sx::before{left:0;top:5.5px;width:12px;height:1px}
.spec > summary .sx::after{left:5.5px;top:0;width:1px;height:12px}
.spec[open] > summary .sx::after{transform:rotate(90deg) scaleX(0)}
.spec[open] > summary .sx::before{background:var(--blue)}
.spec .specbody{padding:0 0 var(--s4);display:grid;grid-template-columns:1fr 1fr;
  gap:var(--s2) var(--s5)}
.srow{display:flex;justify-content:space-between;gap:var(--s3);align-items:baseline;
  padding:9px 0;border-top:1px solid var(--hair)}
.srow dt{font-size:14.5px;color:var(--steel)}
.srow dd{font-family:"IBM Plex Mono",monospace;font-size:12.5px;color:var(--bone);
  text-align:right;font-variant-numeric:tabular-nums}
.srow dd.soft{color:var(--dim)}
@media(max-width:760px){.spec .specbody{grid-template-columns:1fr;gap:0}}

/* ------------------------------------------------------------
   RESERVE — the commercial block. No card is taken here, and the
   layout says so before the button does.
   ------------------------------------------------------------ */
.reserve{margin-top:var(--s6);display:grid;grid-template-columns:1.05fr .95fr;
  gap:var(--s6);align-items:start}
.pricecard{background:var(--surface);border:1px solid var(--hair);border-radius:var(--r3);
  padding:clamp(24px,3.4vw,44px);position:relative;overflow:hidden}
.pricecard::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 90% -10%,rgba(30,143,255,.16),transparent 60%)}
.pricecard > *{position:relative}
.pricetag{display:flex;align-items:baseline;gap:12px;margin-top:var(--s3);flex-wrap:wrap}
.pricenow{font-family:"Archivo";font-weight:800;font-size:clamp(40px,5vw,60px);
  letter-spacing:-.05em;line-height:1;font-variant-numeric:tabular-nums}
.pricewas{font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--dim);
  text-decoration:line-through;text-decoration-color:var(--warn)}
.pricesub{font-size:14.5px;color:var(--steel);margin-top:var(--s2)}
.pricelist{margin-top:var(--s4);border-top:1px solid var(--hair);padding-top:var(--s3)}
.pricelist li{list-style:none;display:flex;gap:12px;align-items:flex-start;
  padding:8px 0;font-size:15px;color:var(--steel)}
.pricelist li::before{content:"";flex:none;width:5px;height:5px;border-radius:50%;
  background:var(--blue);margin-top:9px}
.reserve .signup{margin:var(--s4) 0 0;max-width:none}
.counter{display:flex;align-items:baseline;gap:10px;margin-top:var(--s4);
  padding-top:var(--s3);border-top:1px solid var(--hair)}
.counterbar{flex:1;height:2px;border-radius:2px;background:var(--hair2);overflow:hidden;min-width:80px}
.counterbar i{display:block;height:100%;width:0;background:var(--blue);
  transition:width var(--t-arrive) var(--e-conduct)}
/* beside the card there is half the width, so the four points stack instead of
   splitting into two columns barely wide enough for three words a line */
.reserve .getgrid{grid-template-columns:1fr;gap:var(--s4);max-width:none;margin:0}
.reserve .get{padding-left:var(--s5)}
/* the headline of this card is a promise, not a figure: it is set below the
   price scale so it never gets mistaken for one */
.pricecard .pricenow{font-size:clamp(32px,3.6vw,44px);letter-spacing:-.04em}
.counter[hidden]{display:none}
@media(max-width:900px){.reserve{grid-template-columns:1fr;gap:var(--s5)}}

/* ------------------------------------------------------------
   FAQ
   ------------------------------------------------------------ */
.faq{margin-top:var(--s6);max-width:var(--narrow);margin-left:auto;margin-right:auto;
  border-top:1px solid var(--hair)}
.faq .spec > summary{font-size:16.5px;font-weight:700}
.faq .ans{padding:0 0 var(--s4);color:var(--steel);font-size:15.5px;line-height:1.65;max-width:62ch}
.faq .ans + .ans{margin-top:var(--s2)}

/* ------------------------------------------------------------
   FOOTER
   ------------------------------------------------------------ */
footer{border-top:1px solid var(--hair);padding:var(--s5) 0 var(--s4);background:var(--void)}
.footrow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s5) var(--s4)}
.footcol h3{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--dim);font-weight:400;margin-bottom:var(--s2)}
.footcol a{display:block;padding:5px 0;font-size:14.5px;color:var(--steel);text-decoration:none;
  transition:color var(--t-quick) var(--e-settle)}
.footcol a:hover{color:var(--bone)}
.footbase{margin-top:var(--s5);padding-top:var(--s3);border-top:1px solid var(--hair);
  display:flex;justify-content:space-between;gap:var(--s3);flex-wrap:wrap}
.footbase .mono{font-size:10px;line-height:1.6}

@media(max-width:760px){
  /* Two groups of four sit side by side; the two-link group would leave a hole
     in a third column, so it takes the full width and lays its links out in a
     row. Everything starts on the same left edge as the rest of the page. */
  .footrow{grid-template-columns:1fr 1fr;gap:var(--s4) var(--s3)}
  .footcol:last-child{grid-column:1 / -1;display:flex;flex-wrap:wrap;
    align-items:baseline;column-gap:var(--s4);row-gap:0}
  .footcol:last-child h3{flex-basis:100%;margin-bottom:6px}
  .footbase{margin-top:var(--s4);flex-direction:column;gap:8px}
}

/* ------------------------------------------------------------
   THE LAST OF THE INLINE STYLES
   These four rules used to be style="" attributes in the markup. They live
   here so the page's Content-Security-Policy can refuse inline styles
   outright instead of having to allow them.
   ------------------------------------------------------------ */
[data-stagger-fast]{--stagger:60ms}
[data-stagger-slow]{--stagger:90ms}
.readout .env{font-weight:400}
.gatecopy{font-size:15px}
.vfallimg{max-width:460px;margin:0 auto}
.closercta{margin-top:var(--s5)}
.faq .faqbody{display:block}

/* ------------------------------------------------------------
   SHARED SMALL PARTS
   ------------------------------------------------------------ */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--bone);color:#000;
  padding:12px 18px;border-radius:0 0 10px 0;font-size:14px;text-decoration:none}
.skip:focus{left:0}
.sectag{display:inline-flex;align-items:center;gap:9px}
.sectag::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--blue)}
.quiet{color:var(--dim)}
.hidden{display:none !important}
/* used by sonic.tick so a counting number never reflows its neighbours */
.tnum{font-variant-numeric:tabular-nums}

/* a scrubbed horizontal rule: draws itself as its section is traversed */
.drawline{height:1px;background:var(--hair);position:relative;overflow:hidden}
.drawline::after{content:"";position:absolute;left:0;top:0;height:1px;
  width:calc(var(--sp,0) * 100%);background:var(--blue)}

@media (prefers-reduced-motion:reduce){
  .flowline-v::after{height:100%}
  .beat{opacity:1}
  .drawline::after{width:100%}
  .headwrap{transform:none !important}
  /* the cross-fade never runs, so the three schematics stack instead of one
     of them being the only one a reader ever sees */
  .originline i,.sdiv i{height:100%}
  .originline::after,.sdiv::after{opacity:1;top:100%}
  .flowfigs{position:static;gap:var(--s5)}
  .flowfig{grid-area:auto;opacity:1;transform:none}
  .flow-inline .flowfig{opacity:1}
}
