/* ---- site.css ---- */
/* ============================================================================
   Self hosted fonts. No CDN request of any kind: the woff2 files sit beside
   this stylesheet in assets/fonts/. Latin and latin-ext only. Archivo ships
   as one variable file, so 400 and 500 name the same woff2 and the weight
   axis does the work.
   ========================================================================== */
/* Archivo 400 normal · latin-ext */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:400;
  font-stretch:100%;
  font-display:swap;
  src:url(fonts/archivo-var-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;
}
/* Archivo 400 normal · latin */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:400;
  font-stretch:100%;
  font-display:swap;
  src:url(fonts/archivo-var-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;
}
/* Archivo 500 normal · latin-ext */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:500;
  font-stretch:100%;
  font-display:swap;
  src:url(fonts/archivo-var-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;
}
/* Archivo 500 normal · latin */
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:500;
  font-stretch:100%;
  font-display:swap;
  src:url(fonts/archivo-var-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;
}
/* Space Mono 400 italic · latin-ext */
@font-face{
  font-family:'Space Mono';
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url(fonts/spacemono-400-italic-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;
}
/* Space Mono 400 italic · latin */
@font-face{
  font-family:'Space Mono';
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url(fonts/spacemono-400-italic-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;
}
/* Space Mono 400 normal · latin-ext */
@font-face{
  font-family:'Space Mono';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url(fonts/spacemono-400-normal-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;
}
/* Space Mono 400 normal · latin */
@font-face{
  font-family:'Space Mono';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url(fonts/spacemono-400-normal-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;
}

/* ============================================================================
   Mindshake · home · Fable prototype, round 2 · 2026-09-03
   Round 2 applies the owner's seven notes: one dark world (no cream blocks),
   no accent dots on labels, the brain object as a scroll driven world with
   clickable service regions, device frames for the footage, pointer light on
   every plate, the v4 essay diagrams. Motion decisions are tagged M1..M16.
   No long dash of any kind appears in this file.
   ========================================================================== */
:root{
  --ground:#040A19; --raised:#0A1530; --ground-veil:rgba(4,10,25,.86);
  --ink:#F4F1E6; --ink-muted:rgba(244,241,230,.62); --ink-quiet:rgba(244,241,230,.55);
  --hairline:rgba(244,241,230,.16); --border:rgba(244,241,230,.29);
  /* the plate: one world, one material. A raised navy object with a lit edge,
     never a second colour. Replaces the cream RELIEF of round 1 by owner note. */
  --plate:#0B1631; --plate-2:#101D3E; --plate-hi:rgba(255,252,244,.10); --plate-hair:rgba(244,241,230,.12);
  --tile:#0E1A38; --tile-hair:rgba(244,241,230,.11);
  --screen:#1E2331; --screen-ink:#CBDBE1;
  --accent:#FF6B4A; --machine:#37C8DB;
  --mark:var(--accent); --machine-mark:var(--machine);
  --lx:34%;
  --catch-hi:rgba(255,252,244,.32); --catch-mid:rgba(255,252,244,.12); --catch-lo:rgba(255,252,244,.045);
  --sh-c:rgba(0,2,8,.62); --sh-a:rgba(0,3,14,.55);
  --el-block:0 1px 2px -1px var(--sh-c),0 34px 70px -30px var(--sh-a);
  --el-raise:0 1px 2px -1px var(--sh-c),0 16px 30px -16px var(--sh-a);
  --el-chrome:0 1px 2px -1px var(--sh-c),0 22px 46px -18px var(--sh-a);
  --el-press:0 1px 1px -1px var(--sh-c),0 4px 9px -7px var(--sh-a);
  --rec:inset 0 2px 4px -2px rgba(0,0,0,.6),inset 0 1px 1px -1px rgba(0,0,0,.7),inset 0 -1px 0 var(--catch-lo),inset 0 0 0 1px var(--hairline);
  --font-a:'Archivo',system-ui,-apple-system,sans-serif;
  --font-b:'Space Mono',ui-monospace,SFMono-Regular,monospace;
  --t-label:12px; --t-micro:14px; --t-body:16px; --t-lede:19px; --t-name:44px; --t-h1:64px; --t-display:120px;
  /* Round-five display stays legible at the same authored step on phones. */
  --t-fixed-display:44px;
  --t-track-label:.11em;
  --wrap:1240px; --gutter:72px; --block:44px; --radius:28px; --sec:116px; --measure:66ch; --nav-clear:100px;
  --ease:cubic-bezier(.2,.7,.25,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-entrance:700ms; --dur-crossfade:420ms; --stagger:90ms; --dur-hover:260ms;
  --au-warm:rgba(255,107,74,.16); --au-cool:rgba(55,200,219,.12); --au-deep:rgba(15,30,66,.9);
  --grain-a:.07;
  color-scheme:dark;
}
:root[data-theme="light"]{
  --ground:#F4F1E6; --raised:#E9E3D2; --ground-veil:rgba(244,241,230,.86);
  --ink:#040A19; --ink-muted:rgba(4,10,25,.62); --ink-quiet:rgba(4,10,25,.55);
  --hairline:rgba(4,10,25,.16); --border:rgba(4,10,25,.29);
  --plate:#ECE6D6; --plate-2:#E6DFCC; --plate-hi:rgba(255,255,250,.9); --plate-hair:rgba(4,10,25,.10);
  --tile:#E9E3D2; --tile-hair:rgba(4,10,25,.10);
  --mark:#D1401F; --machine-mark:#0E7C8C;
  --catch-hi:rgba(255,255,250,.92); --catch-mid:rgba(255,255,250,.42); --catch-lo:rgba(255,255,250,.10);
  --sh-c:rgba(46,36,18,.26); --sh-a:rgba(46,36,18,.20);
  --au-warm:rgba(255,107,74,.14); --au-cool:rgba(55,200,219,.12); --au-deep:rgba(233,227,210,.9);
  --grain-a:.06;
  color-scheme:light;
}

*{box-sizing:border-box}
html{scroll-behavior:auto;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ground);color:var(--ink);font:400 var(--t-body)/1.62 var(--font-a);-webkit-font-smoothing:antialiased;overflow-x:hidden}
img,video{max-width:100%;display:block}
a{color:inherit}
h1,h2,h3,p{margin:0}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
input,textarea{font:inherit;color:inherit}
:focus{outline:none}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px}
::selection{background:var(--machine-mark);color:var(--ground)}
.skip{position:absolute;left:12px;top:-60px;z-index:100;padding:10px 16px;background:var(--ink);color:var(--ground);border-radius:999px;font-size:var(--t-micro)}
.skip:focus{top:12px}
.wrap{width:min(var(--wrap),100% - 2*var(--gutter));margin-inline:auto}
.mono{font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;line-height:1.5}
.eyebrow{font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);margin-bottom:22px}
.h2{font-size:var(--t-name);line-height:1.08;letter-spacing:-.022em;font-weight:500;text-wrap:balance;max-width:20ch}
/* Headings already balance. Running copy asks for the other one: pretty keeps a
   paragraph from ending on a single orphaned word, which was happening in the
   two column rows on every page ("waiting to be filled." / "check." / "on.").
   Browsers without it fall back to normal wrapping, so nothing depends on it. */
.lede{font-size:var(--t-lede);line-height:1.55;color:var(--ink-muted);max-width:var(--measure);text-wrap:pretty}
.body{max-width:var(--measure);color:var(--ink-muted);text-wrap:pretty}
.prose p,.demo-step p,.sy-say,.sr-attrib,.sb-proof,.partner .quote,.contact .when li,footer .blurb{text-wrap:pretty}
.body + .body{margin-top:1em}
.sec{padding-block:var(--sec)}
/* Where two plates follow one another with no field section between them (the
   systems page: the limit, then the contact), their rounded edges landed 5px
   apart and read as one slab with a seam through it. The interval is the block
   step, so the second plate reads as the next object rather than a mistake. */
section.plate + section.plate{margin-top:var(--block)}
.field{position:relative}
.num{font-variant-numeric:tabular-nums}

/* ── M2 ground: aurora, grain, dust ──────────────────────────────────────── */
#ground{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;background:var(--ground)}
#aurora{position:absolute;left:-10vw;top:-15vh;width:120vw;height:150vh;will-change:transform;transform-origin:50% 40%;
  background:
    radial-gradient(60vw 48vh at var(--lx) 24%, var(--au-warm), transparent 68%),
    radial-gradient(48vw 52vh at 82% 30%, var(--au-cool), transparent 70%),
    radial-gradient(70vw 40vh at 30% 78%, var(--au-cool), transparent 72%),
    radial-gradient(90vw 70vh at 60% 55%, var(--au-deep), transparent 75%),
    linear-gradient(180deg,var(--ground),var(--raised));
  opacity:0;transition:opacity 1400ms var(--ease) 200ms}
html.entered #aurora{opacity:1}
#aurora-lean{position:absolute;inset:0;will-change:transform}
@supports (animation-timeline: scroll()){ #aurora{animation:au-drift linear both;animation-timeline:scroll(root block)} }
@keyframes au-drift{to{transform:translateY(-13vh) scale(1.04)}}
#dust{position:absolute;inset:0}
#dust i{position:absolute;width:3px;height:3px;border-radius:50%;background:var(--ink);opacity:.14;animation:dust var(--d,40s) linear infinite var(--o,0s);left:var(--x);top:var(--y)}
@keyframes dust{0%{transform:translate3d(0,0,0)}50%{transform:translate3d(18px,-60px,0)}100%{transform:translate3d(-8px,-120px,0);opacity:0}}

/* ── M15 the world: the Nightworld (three.js), a camera on the scroll ───────
   Mounted from world-nightworld.js. The canvas is wider than the viewport and
   shifted so the world's centre (the tower) lands in the hero's right column. */
#nw{position:fixed;left:-8vw;top:0;width:152vw;height:100vh;z-index:1;pointer-events:none;display:block;opacity:0;transition:opacity 1400ms var(--ease) 300ms}
html.entered #nw{opacity:1}
/* the veil: the world stays vivid in the hero and calms behind the copy. A pure function of scroll on the compositor. */
#veil{position:fixed;inset:0;z-index:1;pointer-events:none;background:var(--ground);opacity:0}
@supports (animation-timeline: scroll()){ #veil{animation:veil linear both;animation-timeline:scroll(root block);animation-range:0 100vh} }
@keyframes veil{from{opacity:0}to{opacity:.68}}
@supports not (animation-timeline: scroll()){ #veil{opacity:.45} }
main{position:relative;z-index:2}

/* ── M4 masthead ─────────────────────────────────────────────────────────── */
.mast{position:fixed;top:14px;left:0;right:0;z-index:20;display:flex;justify-content:center;pointer-events:none;opacity:0;transform:translateY(-8px);transition:opacity 420ms var(--ease),transform 420ms var(--ease)}
.mast::before{content:"";position:absolute;left:0;right:0;top:-14px;height:112px;pointer-events:none;background:linear-gradient(180deg,var(--ground) 0%,color-mix(in srgb,var(--ground) 92%,transparent) 55%,transparent 100%);opacity:0;transition:opacity 400ms var(--ease)}
html.scrolled .mast::before{opacity:1}
html.entered .mast{opacity:1;transform:none}
.mast .pill-bar{pointer-events:auto;width:min(var(--wrap),100% - 2*var(--gutter));height:58px;border-radius:999px;display:flex;align-items:center;gap:6px;padding:0 10px 0 22px;
  background:var(--ground-veil);backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4);
  box-shadow:inset 0 0 0 1px var(--hairline),inset 0 1px 0 var(--catch-mid),var(--el-chrome)}
.brand{font-weight:500;letter-spacing:-.01em;text-decoration:none;margin-right:auto;display:flex;align-items:center;gap:10px}
.brand svg{width:18px;height:18px;color:var(--ink)}
.nav{display:flex;gap:2px}
.nav a{font-size:var(--t-micro);text-decoration:none;color:var(--ink-muted);padding:8px 12px;border-radius:999px;position:relative;transition:color var(--dur-hover) var(--ease)}
.nav a::after{content:"";position:absolute;left:12px;right:12px;bottom:5px;height:1px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform 320ms var(--ease-out)}
.nav a:hover,.nav a:focus-visible{color:var(--ink)}
.nav a:hover::after,.nav a:focus-visible::after{transform:scaleX(1)}
/* Two values, one mark. A service page names its own nav link with
   aria-current="page"; an essay has no nav link of its own, so it names the
   section it sits under with aria-current="true" rather than claiming a link
   that navigates away is this page. Both read as the held state. */
.nav a[aria-current]{color:var(--ink)}
.nav a[aria-current]::after{transform:scaleX(1)}
/* 44px of hit area around a 16px mark. The button carries no background of its
   own, so the box can grow to the touch floor without the mark changing size. */
.theme{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;color:var(--ink-muted);transition:color var(--dur-hover) var(--ease),transform var(--dur-hover) var(--ease-out)}
.theme:hover{color:var(--ink);transform:rotate(25deg)}
.theme svg{width:16px;height:16px}
.burger{display:none}
/* The burger sheet is a phone and tablet control. Above 900 the burger itself
   is not rendered, so the sheet must not be rendered either: left in flow it
   sat as a 26px row of links under the hero, invisible to the eye and a real
   Tab stop. It is display:none at every width until it is opened, and it also
   carries `inert` while closed, so neither the Tab key nor a screen reader can
   reach it before a person has asked for it. */
.menu{display:none}

/* ── M11 pills, links, rows ──────────────────────────────────────────────── */
.pill{--lift:0px;display:inline-flex;align-items:center;gap:10px;height:44px;max-width:fit-content;padding:0 22px;border-radius:999px;font-size:var(--t-micro);font-weight:500;text-decoration:none;white-space:nowrap;position:relative;isolation:isolate;
  transform:translate3d(var(--mx,0),calc(var(--my,0) + var(--lift)),0);
  transition:transform var(--dur-hover) var(--ease-out),box-shadow var(--dur-hover) var(--ease-out),background var(--dur-hover) var(--ease),color var(--dur-hover) var(--ease)}
.pill.primary{background:var(--ink);color:var(--ground);box-shadow:inset 0 1px 0 var(--catch-hi),var(--el-raise)}
.pill.primary:hover{--lift:-2px;box-shadow:inset 0 1px 0 var(--catch-hi),0 2px 5px -2px var(--sh-c),0 22px 40px -18px var(--sh-a)}
.pill.primary:active{--lift:1px;box-shadow:inset 0 1px 0 var(--catch-hi),var(--el-press);transition-duration:80ms}
.pill.ghost{color:var(--ink);box-shadow:inset 0 0 0 1px var(--border),inset 0 1px 0 var(--catch-lo)}
.pill.ghost:hover{--lift:-2px;box-shadow:inset 0 0 0 1px var(--ink),inset 0 1px 0 var(--catch-mid),var(--el-press)}
.pill.ghost:active{--lift:1px;transition-duration:80ms}
.pill .ar{width:14px;height:14px;transition:transform 320ms var(--ease-out)}
.pill:hover .ar{transform:translateX(4px)}
.pill.small{height:38px;padding:0 18px}
/* max-width, not width: as a stretch item in a column flex container (the demo
   stage, the demo steps, the systems rows) an inline-flex link was taking the
   whole column, so "See the desk" measured 357px wide at 1440 and a click 300px
   to the right of the words still navigated. The cap shrink-wraps it without
   touching the cross axis alignment a row flex parent sets. */
.link{display:inline-flex;align-items:center;gap:8px;max-width:fit-content;text-decoration:none;font-weight:500;font-size:var(--t-micro);background:linear-gradient(currentColor,currentColor) no-repeat 0 100%/0 1px;transition:background-size 360ms var(--ease-out);padding-bottom:2px}
.link:hover,.link:focus-visible{background-size:100% 1px}
.link .ar{width:14px;height:14px;transition:transform 320ms var(--ease-out)}
.link:hover .ar{transform:translateX(4px)}
.ar{flex:none}

/* ── M13 reveals ─────────────────────────────────────────────────────────── */
.rv{opacity:1;translate:0 0}
.rv.done{will-change:auto}
/* M17 · the word stream (the house reveal from v4): words arrive in reading order, 13ms apart, on a 700ms tail */
.ws .w{display:inline-block;opacity:0;translate:0 .35em;transition:opacity 700ms var(--ease-out),translate 700ms var(--ease-out)}
.ws.in .w{opacity:1;translate:0 0}
html.still .ws .w{opacity:1;translate:0 0;transition:none}

/* ── M1 hero ─────────────────────────────────────────────────────────────── */
.hero{min-height:100svh;display:grid;align-items:center;padding-top:calc(var(--nav-clear) + 20px);padding-bottom:40px}
.hero .wrap{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:40px;align-items:center}
.h1{font-size:var(--t-h1);line-height:1.04;letter-spacing:-.026em;font-weight:500;text-wrap:balance;max-width:14ch}
.h1 .w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.h1 .w b{display:inline-block;font-weight:inherit;transform:translateY(110%);transition:transform 900ms var(--ease-out);transition-delay:calc(140ms + var(--i) * 45ms)}
html.entered .h1 .w b{transform:none}
.hero .lede{margin-top:28px;opacity:0;translate:0 8px;transition:opacity 700ms var(--ease) 620ms,translate 700ms var(--ease) 620ms}
html.entered .hero .lede{opacity:1;translate:0 0}
/* The three hero doors share ONE set of columns: the name, the mono tag, the
   arrow. The tag used to sit inline right after the name, so SEARCH, FLUENCY
   and SYSTEMS each started wherever their own name ended and the three staggered
   down the block. The list owns the tracks and each row subgrids onto them, so
   the tag column has one left edge for all three rows and the gap between name
   and tag is the width the longest name leaves. */
.routes{margin:34px 0 0;padding:0;list-style:none;display:grid;grid-template-columns:minmax(0,1fr) auto 16px;
  column-gap:28px;border-top:1px solid var(--hairline)}
.routes li{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;column-gap:28px;
  opacity:0;translate:0 8px;transition:opacity 600ms var(--ease),translate 600ms var(--ease);transition-delay:calc(760ms + var(--i) * 90ms)}
.routes .route{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;column-gap:28px;align-items:center}
.routes .route small{margin:0;justify-self:start}
.routes .route .rt{min-width:0}
html.entered .routes li{opacity:1;translate:0 0}
.route{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 4px;border-bottom:1px solid var(--hairline);text-decoration:none;font-size:var(--t-lede);line-height:1.3;position:relative;transition:color var(--dur-hover) var(--ease)}
.route > *{transition:transform 320ms var(--ease-out)}
.route::before{content:"";position:absolute;left:0;top:50%;width:12px;height:1px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform 320ms var(--ease-out)}
.route:hover > :first-child,.route.hot > :first-child{transform:translateX(18px)}
.route:hover::before,.route.hot::before{transform:scaleX(1)}
.route .ar{width:16px;height:16px;color:var(--ink-muted);transition:transform 320ms var(--ease-out),color var(--dur-hover) var(--ease)}
.route:hover .ar,.route.hot .ar{transform:translateX(6px);color:var(--ink)}
.route small{font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);margin-right:auto;margin-left:14px}
.hero .cta{margin-top:30px;display:flex;align-items:center;gap:18px;flex-wrap:wrap;opacity:0;translate:0 8px;transition:opacity 600ms var(--ease) 1100ms,translate 600ms var(--ease) 1100ms}
html.entered .hero .cta{opacity:1;translate:0 0}
.hero .cta .note{font-size:var(--t-micro);color:var(--ink-muted);max-width:32ch}
.stage{position:relative;aspect-ratio:1;max-width:560px;width:100%;justify-self:end}

/* ── hero brain ──────────────────────────────────────────────────────────────
   The stage is one instrument: a canvas filling it, and a legend of six chips
   in the bottom band. The canvas covers the legend's box as well, so a leader
   line can be drawn from a chip's top edge up to its region in the anatomy.
   The stage sits SECOND in the hero's DOM, after the headline and the routes,
   so a screen reader meets the H1 first and Tab reaches the three routes and
   the CTA before the six chips. Source order already places it in the right
   hand column here; the tablet band lifts it over the headline with order:-1,
   which is the only place order is used. */
.stage:has(> .legend){display:flex;flex-direction:column;justify-content:flex-end;opacity:0;transition:opacity 900ms var(--ease) 520ms;
  /* a little taller than square: the brain is the hero object, and the column
     is 500px wide, so the height is what buys it size. It stays shorter than
     the copy column beside it, so the hero's height does not change. */
  aspect-ratio:1 / 1.06;
}
/* the scrim: the Nightworld runs its tower straight through this box and the
   plexus needs something to sit on, so a field of the page's own ground sits
   behind it, nearly solid where the brain is and gone before its own edge. It
   lives on a pseudo element LARGER than the stage, because a background is
   clipped to its box and in the light polarity that clip reads as a pale
   rectangle. It never changes, so the compositor holds it and the canvas is
   not repainting it 60 times a second. */
.stage:has(> .legend)::before{content:"";position:absolute;inset:-16% -12%;pointer-events:none;
  background:radial-gradient(ellipse 50% 43% at 50% 43%,
    color-mix(in srgb,var(--ground) 92%,transparent) 0%,
    color-mix(in srgb,var(--ground) 86%,transparent) 55%,
    color-mix(in srgb,var(--ground) 48%,transparent) 78%,
    color-mix(in srgb,var(--ground) 14%,transparent) 92%,
    transparent 100%)}
html.entered .stage:has(> .legend){opacity:1}
html.still .stage:has(> .legend){opacity:1;transition:none}
#brainmap{position:absolute;inset:0;width:100%;height:100%;display:block}
.legend{position:relative;z-index:1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
/* a legend chip is a readout, not a button: a hairline box, lit along its top
   edge, a 6px region dot that fills when the region lights. Never a glow.
   Scoped to .legend, because .chip is already the status badge on the built
   section and the two must not collide. */
.legend .chip{display:flex;align-items:center;gap:9px;min-height:36px;padding:0 12px;border-radius:8px;
  font-family:var(--font-a);font-size:14px;font-weight:400;letter-spacing:-.006em;line-height:1.2;text-transform:none;text-align:left;white-space:nowrap;color:var(--ink-muted);
  background:color-mix(in srgb,var(--plate) 58%,transparent);
  box-shadow:inset 0 0 0 1px var(--plate-hair),inset 0 1px 0 var(--catch-mid);
  transition:color var(--dur-hover) var(--ease),box-shadow var(--dur-hover) var(--ease),background var(--dur-hover) var(--ease)}
.legend .chip::before{content:"";width:6px;height:6px;border-radius:50%;flex:none;background:transparent;
  box-shadow:inset 0 0 0 1px var(--machine-mark);transition:background var(--dur-hover) var(--ease)}
.legend .chip:hover,.legend .chip.hot{color:var(--ink);background:color-mix(in srgb,var(--plate) 84%,transparent);
  box-shadow:inset 0 0 0 1px var(--border),inset 0 1px 0 var(--catch-hi)}
.legend .chip:hover::before,.legend .chip.hot::before{background:var(--machine-mark)}
.legend .chip:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
/* the chip's preview of where it goes: the target row is bracketed by two lit
   hairlines it already owns, a section heading takes a lit underline. */
.prow{transition:border-color 360ms var(--ease)}
.prow .sub{transition:color 360ms var(--ease)}
.prow.preview,.prow.preview + .prow{border-top-color:color-mix(in srgb,var(--machine-mark) 62%,transparent)}
.prow.preview:last-child{border-bottom-color:color-mix(in srgb,var(--machine-mark) 62%,transparent)}
.prow.preview .sub{color:var(--ink)}
.h2.preview{text-decoration:underline;text-decoration-color:var(--machine-mark);text-decoration-thickness:1px;text-underline-offset:12px}

/* ── M5 proof strip ──────────────────────────────────────────────────────── */
.proof{padding-block:0 calc(var(--sec) - 40px)}
.proof .strip{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline)}
.proof .cell{padding:38px 28px 34px 0;border-right:1px solid var(--hairline);min-width:0;display:flex;flex-direction:column;justify-content:flex-end}
.proof .cell:last-child{border-right:0;padding-left:28px;gap:14px}
.proof .cell + .cell{padding-left:28px}
.display{font-size:var(--t-display);line-height:.92;letter-spacing:-.04em;font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums;display:block}
.display sup{font-size:.42em;vertical-align:top;line-height:1;margin-left:.04em;top:.18em;position:relative}
.proof .cap.pre{margin:0 0 14px}
.proof .cap{margin-top:16px;color:var(--ink-muted);font-size:var(--t-micro);max-width:22ch;line-height:1.45}
.proof .cell:last-child p{font-size:var(--t-lede);line-height:1.4;max-width:20ch}
/* Three rows shared by all four cells, so the figures sit on one baseline and
   the captions under them start on one line however many lines each runs to.
   Row 1 holds the one caption that sits above its figure, row 2 the figures,
   row 3 the captions. The fourth cell is a sentence and a link, not a stat, so
   it keeps the whole span and bottom aligns with the captions. Only the four
   across layout needs this; below 1180 the strip is two by two and each cell is
   read on its own. */
@media (min-width:1181px){
  .proof .strip{grid-template-rows:auto auto auto}
  .proof .cell{grid-row:1 / span 3;display:grid;grid-template-rows:subgrid;row-gap:0}
  .proof .cell > .cap.pre{grid-row:1;align-self:end}
  .proof .cell > .display{grid-row:2;align-self:end}
  .proof .cell > .cap:not(.pre){grid-row:3;align-self:start}
  .proof .cell:last-child{display:flex;flex-direction:column;justify-content:flex-end}
}

/* ── stakes ──────────────────────────────────────────────────────────────── */
.stakes .wrap{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:64px;align-items:start}
.instr{border-top:1px solid var(--hairline)}
.instr .row{display:grid;grid-template-columns:24px minmax(0,1fr) auto;gap:18px;align-items:center;padding:22px 0;border-bottom:1px solid var(--hairline);font-size:var(--t-lede);line-height:1.35}
.instr .row > *{transition:transform var(--dur-hover) var(--ease-out)}
.instr .row:hover > *{transform:translateX(8px)}
.instr .dot{width:10px;height:10px;border-radius:50%;background:var(--ink-quiet);justify-self:center;transition:background 400ms var(--ease),box-shadow 400ms var(--ease)}
.instr .row.lit .dot{background:var(--mark);box-shadow:0 0 0 4px color-mix(in srgb,var(--mark) 18%,transparent)}
.instr .verdict{font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted)}
.instr .row.lit .verdict{color:var(--ink)}
.instr .row.lit{font-weight:500}

/* ── M6 seam ─────────────────────────────────────────────────────────────── */
.seam{overflow:hidden;border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);padding:18px 0;margin-top:-24px;mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.seam .track{display:flex;width:max-content;animation:seam 46s linear infinite}
.seam:hover .track{animation-play-state:paused}
.seam ul{display:flex;margin:0;padding:0;list-style:none}
.seam li{font-family:var(--font-b);font-size:var(--t-micro);letter-spacing:.02em;color:var(--ink-muted);padding:0 28px;display:flex;align-items:center;gap:28px;white-space:nowrap}
.seam li::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--ink-quiet)}
@keyframes seam{to{transform:translateX(-50%)}}

/* ── the plate: one material, a lit edge, the pointer's light (M14) ──────── */
.plate{position:relative;background:linear-gradient(180deg,var(--plate-2),var(--plate));border-radius:var(--radius);margin-inline:var(--block);padding-block:calc(var(--sec) - 20px);
  box-shadow:inset 0 0 0 1px var(--plate-hair),inset 0 1px 0 var(--plate-hi),var(--el-block);isolation:isolate}
.plate::before,.plate::after{border-radius:var(--radius)}
.plate::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(60% 45% at 100% 0%,color-mix(in srgb,var(--machine) 14%,transparent),transparent 62%),radial-gradient(50% 40% at 0% 100%,color-mix(in srgb,var(--accent) 9%,transparent),transparent 60%)}
.plate::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:0;transition:opacity 500ms var(--ease);
  background:radial-gradient(520px circle at var(--px,50%) var(--py,50%),rgba(255,252,244,.035),transparent 60%)}
.plate.lit::after{opacity:1}
.plate > *{position:relative;z-index:1}
.plate.rv{translate:0 0;opacity:0;transform:translateY(24px) scale(.992);transition:transform 900ms var(--ease-out),opacity 900ms var(--ease-out)}
.plate.rv.in{opacity:1;transform:none}
.tile{position:relative;background:var(--tile);border-radius:calc(var(--radius) - 8px);padding:28px;isolation:isolate;overflow:hidden;
  box-shadow:inset 0 0 0 1px var(--tile-hair),inset 0 1px 0 var(--plate-hi),var(--el-raise);transition:transform 400ms var(--ease-out),box-shadow 400ms var(--ease-out)}
.tile::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:0;transition:opacity 400ms var(--ease);
  background:radial-gradient(260px circle at var(--px,50%) var(--py,50%),rgba(255,252,244,.07),transparent 60%)}
.tile.lit::after{opacity:1}
.tile > *{position:relative;z-index:1}
.tile:hover{transform:translateY(-3px);box-shadow:inset 0 0 0 1px var(--border),inset 0 1px 0 var(--plate-hi),0 2px 5px -2px var(--sh-c),0 28px 50px -22px var(--sh-a)}

/* ── M7 practices rail ───────────────────────────────────────────────────── */
.practices .wrap{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:64px;align-items:start}
.practices .rail{position:sticky;top:calc(var(--nav-clear) + 8px)}
.practices .rail .h2{font-size:28px;max-width:22ch}
.practices .rail .idx{margin:34px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:2px}
.practices .rail .idx li{display:flex;align-items:center;gap:14px;font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-quiet);padding:8px 0;transition:color 400ms var(--ease)}
.practices .rail .idx li i{width:28px;height:1px;background:var(--hairline);transform:scaleX(.6);transform-origin:left;transition:background 400ms var(--ease),transform 400ms var(--ease-out)}
.practices .rail .idx li.on{color:var(--ink)}
.practices .rail .idx li.on i{background:var(--ink);transform:scaleX(1)}
.prow{padding:44px 0 40px;border-top:1px solid var(--hairline);display:grid;grid-template-columns:minmax(0,1fr);gap:18px;position:relative}
.prow:last-child{border-bottom:1px solid var(--hairline)}
.prow .k{color:var(--ink-muted)}
.prow h3{font-size:var(--t-name);line-height:1.06;letter-spacing:-.022em;font-weight:500;max-width:24ch;text-wrap:balance}
.prow .sub{color:var(--ink-muted);max-width:var(--measure)}
.prow .foot{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;margin-top:8px}
.prow .pf{display:flex;align-items:center;gap:12px;font-size:var(--t-micro);color:var(--ink-muted)}
.prow .pf b{font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums}

/* ── the firm ────────────────────────────────────────────────────────────── */
.firm .wrap{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:64px;align-items:center}
.fly{position:relative;aspect-ratio:1;max-width:520px;margin-inline:auto;width:100%}
.fly svg{width:100%;height:100%;overflow:visible}
.fly .ring{fill:none;stroke:var(--hairline);stroke-width:1}
.fly .arc{fill:none;stroke:var(--ink);stroke-width:1.2;stroke-dasharray:1000;stroke-dashoffset:1000;transition:stroke-dashoffset 1800ms var(--ease-out)}
.fly.in .arc{stroke-dashoffset:0}
.fly .arc.a2{transition-delay:300ms}.fly .arc.a3{transition-delay:600ms}
.fly .node{fill:var(--ground);stroke:var(--border);stroke-width:1}
.fly .core{fill:var(--mark)}
.fly text{font-family:var(--font-a);font-size:15px;fill:var(--ink);font-weight:500}
.fly text.m{font-family:var(--font-b);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;fill:var(--ink-muted);font-weight:400}
.fly .spin{transform-origin:260px 260px;animation:spin 60s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.firm .flow{margin-top:26px;display:flex;flex-direction:column;border-top:1px solid var(--hairline)}
.firm .flow div{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:20px;align-items:baseline;padding:14px 0;border-bottom:1px solid var(--hairline);font-size:var(--t-micro)}
.firm .flow b{font-weight:500;color:var(--ink)}
.firm .flow span{color:var(--ink-muted)}
/* the flow clause runs to 33 characters, which is a sentence rather than a
   label: it keeps the mono voice and the tracking, and loses the uppercase,
   because word shape is what carries a phrase this long. */
.firm .flow em{font-style:normal;font-family:var(--font-b);font-size:13px;letter-spacing:normal;text-transform:none;color:var(--ink-muted)}

/* ── the network ─────────────────────────────────────────────────────────── */
.network .h2{max-width:24ch}
.network .h2 b{font-weight:500;color:var(--ink)}
.network .bridge{margin-top:22px;max-width:var(--measure);color:var(--ink-muted)}
.network .placed{margin-top:22px;font-size:var(--t-lede);max-width:var(--measure);line-height:1.5}
.wall{margin-top:48px;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:0 48px}
.wall .col h3{margin:0 0 4px;font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);font-weight:400;padding:12px 0;border-bottom:1px solid var(--hairline)}
.wall ul{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr}
.wall li{padding:13px 0;border-bottom:1px solid var(--hairline);font-size:var(--t-micro);color:var(--ink-muted);transition:color 300ms var(--ease),transform 300ms var(--ease-out)}
.wall li:hover{color:var(--ink);transform:translateX(6px)}
.wall li:nth-child(odd){padding-right:24px}

/* ── M8 the device: footage as a lit instrument ──────────────────────────── */
.device{position:relative;margin-top:44px;perspective:1400px;max-width:1040px;margin-inline:auto}
.device .halo{position:absolute;inset:-6% -4%;pointer-events:none;z-index:0;filter:blur(30px);opacity:.9;
  background:radial-gradient(50% 60% at 20% 30%,color-mix(in srgb,var(--accent) 22%,transparent),transparent 70%),radial-gradient(55% 60% at 85% 70%,color-mix(in srgb,var(--machine) 22%,transparent),transparent 70%)}
.device .shell{position:relative;z-index:1;border-radius:18px;background:var(--screen);box-shadow:inset 0 0 0 1px rgba(203,219,225,.14),inset 0 1px 0 rgba(255,255,255,.14),0 2px 5px -2px var(--sh-c),0 40px 80px -30px rgba(0,3,14,.7);overflow:hidden;
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));will-change:transform;
  opacity:0;translate:0 10px;transition:opacity var(--dur-crossfade) var(--ease) 200ms,translate var(--dur-crossfade) var(--ease) 200ms,transform 600ms var(--ease-out)}
.device.in .shell{opacity:1;translate:0 0}
.device .bar{height:38px;display:flex;align-items:center;gap:8px;padding:0 14px;background:linear-gradient(180deg,#262C3D,#20263A);box-shadow:inset 0 -1px 0 rgba(0,0,0,.4);color:var(--screen-ink)}
.device .bar i{width:9px;height:9px;border-radius:50%;background:rgba(203,219,225,.22);box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
.device .bar .t{margin-left:8px;font-family:var(--font-b);font-size:11px;letter-spacing:var(--t-track-label);text-transform:uppercase;color:rgba(203,219,225,.7);display:flex;align-items:center;gap:8px}
.device .bar .t b{font-weight:400;color:var(--screen-ink)}
.device .bar .live{margin-left:auto;display:flex;align-items:center;gap:8px;font-family:var(--font-b);font-size:11px;letter-spacing:var(--t-track-label);text-transform:uppercase;color:rgba(203,219,225,.7)}
.device .bar .live i{width:6px;height:6px;background:var(--accent)}
@keyframes live{0%,100%{opacity:1}50%{opacity:.35}}
.device .win{position:relative;aspect-ratio:1280/670;overflow:hidden;background:#1E2331}
.device .win video,.device .win img{position:absolute;left:0;top:0;width:100%;height:auto}
.device .win .sheen{position:absolute;inset:0;pointer-events:none;background:linear-gradient(180deg,rgba(255,255,255,.04),transparent 26%,transparent 72%,rgba(11,22,49,.85))}
.device .win .ctl{position:absolute;right:12px;bottom:10px;font-family:var(--font-b);font-size:11px;letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--screen-ink);opacity:.75;padding:6px 10px;border-radius:999px;background:rgba(30,35,49,.75);backdrop-filter:blur(6px)}
.device .cap{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:start;margin-top:22px;position:relative;z-index:1}
.device .cap p{max-width:var(--measure)}
.device .cap small{display:block;color:var(--ink-muted);font-size:var(--t-micro);margin-top:6px}
.built .h2{max-width:16ch}
.built .top{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:64px;align-items:start}
.built .lab{margin-top:64px;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px}
.built .lab .intro{grid-column:1/-1;font-size:var(--t-lede);color:var(--ink-muted);margin-bottom:6px}
.lab .item{padding:26px 0 8px;border-top:1px solid var(--hairline)}
.lab .item .head,.tile .head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.lab .item h3,.tile h3{font-size:var(--t-lede);font-weight:500;letter-spacing:-.01em}
.lab .item p{color:var(--ink-muted)}
.chip{display:inline-flex;align-items:center;gap:8px;padding:5px 10px;border-radius:999px;font-family:var(--font-b);font-size:11px;letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);box-shadow:inset 0 0 0 1px var(--hairline)}
.chip i{width:6px;height:6px;border-radius:50%;background:var(--machine-mark)}
.chip.warm i{background:var(--mark)}
.tile p{color:var(--ink-muted)}

/* ── M16 writing: the v4 argument diagrams, drawn on entrance ────────────── */
.writing .cards{margin-top:44px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px}
.card{display:flex;flex-direction:column;text-decoration:none;padding:0;min-width:0}
.card .viz{aspect-ratio:260/130;display:grid;place-items:center;padding:14px 18px 6px;color:var(--ink)}
.card .viz svg{width:100%;height:100%;overflow:visible;fill:none;stroke-linecap:round;stroke-linejoin:round}
.card .v-faint{stroke:var(--ink);stroke-opacity:.22;stroke-width:1}
.card .v-faint.dash{stroke-dasharray:3 4}
.card .v-dot{fill:var(--ink)}
.card .v-dot.faint{fill-opacity:.35}
.card .v-live{stroke:var(--machine-mark);stroke-width:1.6;stroke-dasharray:400;stroke-dashoffset:400;transition:stroke-dashoffset 1400ms var(--ease-out) 200ms}
.card .v-live.dash{stroke-dasharray:3 4;stroke-dashoffset:0;stroke-opacity:.6}
.card.in .v-live{stroke-dashoffset:0}
.card .v-ring{stroke:var(--machine-mark);stroke-width:1.2;transform-box:fill-box;transform-origin:center;transition:transform 600ms var(--ease-out),stroke-opacity 600ms var(--ease)}
.card:hover .v-ring{transform:scale(1.5);stroke-opacity:.5}
.card .v-rule{stroke:var(--ink);stroke-width:2;stroke-opacity:.22}
.card .v-rule.live{stroke:var(--machine-mark);stroke-opacity:1}
.card .v-dot.hot{fill:var(--machine-mark)}
.card .txt{padding:18px 20px 22px;display:flex;flex-direction:column;gap:14px;flex:1;border-top:1px solid var(--tile-hair)}
.card h3{font-size:var(--t-body);font-weight:500;line-height:1.4;letter-spacing:-.005em;text-wrap:balance}
.card p{font-size:var(--t-micro);color:var(--ink-muted);line-height:1.5}
.card .link{margin-top:auto}
.writing .tile{padding:0}
.writing .pledge{margin-top:28px;color:var(--ink-muted);font-size:var(--t-micro)}

/* ── contact ─────────────────────────────────────────────────────────────── */
.contact .wrap{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:64px;align-items:start}
.form{margin-top:36px;display:grid;gap:18px;max-width:560px}
.fld{display:grid;gap:8px}
.fld label{font-size:var(--t-micro);font-weight:500}
.fld input,.fld textarea{width:100%;background:color-mix(in srgb,#000 22%,transparent);border:0;border-radius:14px;padding:14px 16px;box-shadow:var(--rec);transition:box-shadow var(--dur-hover) var(--ease)}
:root[data-theme="light"] .fld input,:root[data-theme="light"] .fld textarea{background:color-mix(in srgb,#000 5%,transparent)}
.fld input:focus-visible,.fld textarea:focus-visible{outline:none;box-shadow:var(--rec),0 0 0 2px var(--ink)}
.fld textarea{min-height:120px;resize:vertical}
.fld small{color:var(--ink-muted);font-size:13px;min-height:1em}
.fld.err input,.fld.err textarea{box-shadow:var(--rec),0 0 0 2px var(--mark)}
/* the field's own error line: a distinct node, never the hint recoloured, so
   a reader can tell "why this failed" from "what this field wants" at a
   glance. Empty and hidden until the field is marked .err. */
.fld-err{display:none;margin:0;color:var(--mark);font-size:13px;line-height:1.5}
.fld.err .fld-err{display:block}
.form .send{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.form .send small{color:var(--ink-muted);font-size:var(--t-micro)}
/* the confirmation used to be a bordered, rounded box sitting inside the
   contact plate: a card inside a card. It is a single sentence, so it reads as
   a rule and a line, and the plate stays the only surface in this column. */
.form .sent{display:none;padding:16px 0 0;border-radius:0;box-shadow:none;
  border-top:1px solid var(--tile-hair);font-size:var(--t-micro)}
.form.is-sent .sent{display:block}
/* the recap: what was sent stays legible beside the confirmation, read only,
   so a successful send is closure rather than a hole where the form was. */
.form .recap{margin-top:14px;padding-top:14px;border-top:1px solid var(--tile-hair);display:grid;gap:8px;color:var(--ink-muted);font-size:var(--t-micro);line-height:1.6}
.form .recap b{color:var(--ink);font-weight:500}
/* the submit error, spoken not shown: the field messages already carry it on
   screen, so this region only exists to say the same thing out loud. */
.form .ferr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.form.is-sent .send,.form.is-sent .fld{display:none}
.contact .alt{margin-top:22px;font-size:var(--t-micro);color:var(--ink-muted)}
.partner{display:grid;gap:22px;padding-top:6px}
.partner .who{display:grid;grid-template-columns:96px minmax(0,1fr);gap:20px;align-items:center}
.partner img{width:96px;height:96px;border-radius:20px;object-fit:cover;box-shadow:inset 0 1px 0 var(--catch-hi),var(--el-raise)}
.partner .name{font-size:var(--t-lede);font-weight:500}
.partner .role{color:var(--ink-muted);font-size:var(--t-micro);margin-top:2px}
.partner .direct{margin-top:8px}
.partner .quote{font-size:var(--t-lede);line-height:1.45}
/* This was `.when.tile`: a filled, rounded tile inside the contact plate, which
   is the nested card the floor bans. Its content was already hairline rows, so
   the tile is gone and the rows sit straight on the plate, aligned with the
   partner note above them instead of inset 28px from it. */
.contact .when{margin-top:34px;padding:26px 0 10px;border-top:1px solid var(--hairline)}
.contact .when h3{font-size:var(--t-micro);font-weight:500;color:var(--ink);padding-bottom:14px;border-bottom:1px solid var(--hairline)}
.contact .when ul{list-style:none;margin:0;padding:0}
.contact .when li{display:grid;grid-template-columns:20px minmax(0,1fr);gap:14px;padding:13px 0;border-bottom:1px solid var(--hairline);font-size:var(--t-micro);color:var(--ink-muted);line-height:1.5}
.contact .when li::before{content:"";width:10px;height:1px;background:var(--ink-quiet);margin-top:10px}

/* ── M12 expanders ───────────────────────────────────────────────────────── */
.faq .h2{margin-bottom:34px}
.qa{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:0 48px;align-items:start}
.qa .col{border-top:1px solid var(--hairline)}
/* The open question still lifts into a tile, but the tile is a layer behind the
   row rather than padding and margin on the row itself. Animating padding and
   margin relaid out the whole column on every frame of the 420ms ease and moved
   the open row 8px under the reader's cursor as it opened; the layer eases
   opacity and a transform the compositor owns, and the row never moves. The
   inset carries the same geometry the padding used to: 6px above, 22px each
   side, 4px below. */
.qa details{position:relative;border-bottom:1px solid var(--hairline);border-radius:0;padding:0;
  transition:border-bottom-color 420ms var(--ease)}
/* The open row's plate bleeds down, up and to the right, never past the column's
   own left edge: a 22px bleed on that side put the open answer 22px out of the
   margin every closed row below it holds, which reads as a jog in the spine. */
.qa details::before{content:"";position:absolute;inset:-6px -22px -4px 0;z-index:0;pointer-events:none;
  border-radius:calc(var(--radius) - 8px);background:var(--tile);
  box-shadow:inset 0 0 0 1px var(--tile-hair),inset 0 1px 0 var(--plate-hi),var(--el-raise);
  opacity:0;transform:scaleY(.97);transform-origin:50% 0;
  transition:opacity 420ms var(--ease),transform 420ms var(--ease-out)}
.qa details[open]::before{opacity:1;transform:none}
.qa details[open]{border-bottom-color:transparent}
.qa summary,.qa .a{position:relative;z-index:1}
.qa summary{list-style:none;display:grid;grid-template-columns:minmax(0,1fr) 30px;gap:16px;align-items:center;padding:20px 0;cursor:pointer;font-size:var(--t-lede);font-weight:500;line-height:1.35}
.qa summary::-webkit-details-marker{display:none}
.qa summary > span:first-child{transition:transform var(--dur-hover) var(--ease-out)}
.qa summary:hover > span:first-child{transform:translateX(6px)}
.qa summary .pl{width:30px;height:30px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--hairline);position:relative;transition:transform 420ms var(--ease-out),box-shadow var(--dur-hover) var(--ease)}
.qa summary .pl::before{content:"";position:absolute;left:50%;top:50%;width:7px;height:7px;border-right:1px solid var(--ink);border-bottom:1px solid var(--ink);transform:translate(-50%,-65%) rotate(45deg)}
.qa details[open] summary .pl{transform:rotate(180deg)}
.qa summary:hover .pl{box-shadow:inset 0 0 0 1px var(--ink)}
.qa .a{display:grid;grid-template-rows:0fr;transition:grid-template-rows 480ms var(--ease-out)}
.qa details[open] .a{grid-template-rows:1fr}
.qa .a > div{overflow:hidden;min-height:0}
.qa .a p{padding:0 0 22px 0;max-width:62ch;color:var(--ink-muted);opacity:0;translate:0 -4px;transition:opacity 420ms var(--ease) 80ms,translate 420ms var(--ease) 80ms}
.qa details[open] .a p{opacity:1;translate:0 0}

/* ── footer ──────────────────────────────────────────────────────────────── */
footer{padding:0 0 28px}
footer .plate{padding:64px 0 34px;margin-bottom:0}
footer .grid{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:48px;align-items:start}
footer .cols{display:grid;grid-template-columns:auto auto;gap:36px;margin-top:34px}
footer .where{color:var(--ink-muted);font-size:var(--t-micro);margin-top:6px}
footer .blurb{color:var(--ink-muted);max-width:52ch;margin-top:28px;padding-top:24px;border-top:1px solid var(--hairline);font-size:var(--t-micro)}
footer .talk{padding:34px 34px 30px;position:relative;overflow:hidden}
footer .talk .h2{font-size:38px;max-width:8ch;margin-bottom:26px}
footer .talk > svg{position:absolute;right:-10px;top:-10px;width:56%;height:auto;opacity:.9;pointer-events:none}
footer .talk > svg line,footer .talk > svg circle{stroke:var(--ink);stroke-opacity:.28;stroke-width:1;fill:none}
footer .talk > svg circle.d{fill:var(--ink);fill-opacity:.5;stroke:none}
footer .talk > svg circle.acc{fill:var(--mark);stroke:none;fill-opacity:1}
footer h3{margin:0 0 12px;font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);font-weight:400}
footer ul{list-style:none;margin:0;padding:0;display:grid;gap:8px}
footer ul a{text-decoration:none;color:var(--ink-muted);font-size:var(--t-micro);transition:color var(--dur-hover) var(--ease)}
footer ul a:hover{color:var(--ink)}
footer .meta{margin-top:44px;padding-top:22px;border-top:1px solid var(--hairline);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;font-size:var(--t-micro);color:var(--ink-muted)}
footer .meta .live{display:inline-flex;align-items:center;gap:8px}
footer .meta .live i{width:6px;height:6px;border-radius:50%;background:var(--machine-mark)}

/* ── M9 cursor ───────────────────────────────────────────────────────────── */
html.has-cursor{cursor:none}
html.has-cursor a,html.has-cursor button,html.has-cursor summary,html.has-cursor input,html.has-cursor textarea,html.has-cursor label{cursor:none}
/* Native dialogs are in the top layer, above the page's custom cursor. */
html.has-cursor dialog[open]{cursor:auto}
html.has-cursor dialog[open] :is(a,button,summary,label){cursor:pointer}
html.has-cursor dialog[open] :is(input,textarea){cursor:text}
body:has(dialog[open]) :is(#cur-dot,#cur-ring){visibility:hidden}
#cur-dot,#cur-ring{position:fixed;left:0;top:0;z-index:60;pointer-events:none;border-radius:50%;will-change:transform,scale}
#cur-dot{width:6px;height:6px;margin:-3px 0 0 -3px;background:var(--ink);mix-blend-mode:difference;transition:opacity 200ms var(--ease)}
/* One 34px box that never resizes. The states scale it, so the ring's growth is
   a compositor transform instead of a width, height and margin ease on a layer
   that follows the pointer every frame. The stroke and the label divide by the
   same --cs, so a 1px hairline stays 1px and the 10px word stays 10px at every
   size. --cs also feeds the press state, which multiplies rather than replaces. */
#cur-ring{--cs:1;--cd:1;width:34px;height:34px;margin:-17px 0 0 -17px;
  box-shadow:inset 0 0 0 calc(1px / var(--cs)) var(--ink);opacity:.55;display:grid;place-items:center;
  font-family:var(--font-b);font-size:calc(10px / var(--cs));letter-spacing:.11em;text-transform:uppercase;color:transparent;
  scale:calc(var(--cs) * var(--cd));
  transition:scale 320ms var(--ease-out),opacity 320ms var(--ease),background 320ms var(--ease),box-shadow 320ms var(--ease),color 320ms var(--ease),font-size 320ms var(--ease-out)}
html[data-cur="off"] #cur-dot,html[data-cur="off"] #cur-ring{opacity:0}
html[data-cur="act"] #cur-ring{--cs:1.529;opacity:.9}
html[data-cur="media"] #cur-dot{opacity:0}
html[data-cur="media"] #cur-ring{--cs:2.235;opacity:1;background:var(--ink);box-shadow:inset 0 1px 0 rgba(255,255,255,.5),var(--el-raise);color:var(--ground)}
html[data-cur="world"] #cur-dot{opacity:0}
html[data-cur="world"] #cur-ring{--cs:1.882;opacity:1;box-shadow:inset 0 0 0 calc(1px / var(--cs)) var(--machine-mark);color:var(--ink)}
html[data-cur-down] #cur-ring{--cd:.9}

@media (prefers-reduced-motion: reduce){
  :root{--dur-entrance:1ms;--dur-crossfade:1ms;--stagger:0ms;--dur-hover:1ms}
  .ws .w{opacity:1;translate:0 0;transition:none}
  .rv,.plate.rv{opacity:1;translate:0 0;transform:none;transition:none}
  .h1 .w b,.hero .lede,.routes li,.hero .cta,.mast,#aurora,#nw{opacity:1;transform:none;translate:0 0;transition:none}
  #aurora{animation:none}
  .seam .track{animation:none}
  #dust i{animation:none}
  .fly .arc{stroke-dashoffset:0;transition:none}
  .fly .spin{animation:none}
  .card .v-live{stroke-dashoffset:0;transition:none}
  .device .shell{opacity:1;translate:0 0;transition:none}
  .device .bar .live i,footer .meta .live i{animation:none}
  .qa .a,.qa .a p,.qa summary .pl,.qa summary .pl::after,.qa details::before{transition:none}
  .pill,.link,.route,.tile,.nav a::after{transition:none}
  #cur-ring{transition:none}
}
html.still .rv,html.still .plate.rv{opacity:1;translate:0 0;transform:none;transition:none}
html.still .h1 .w b,html.still .hero .lede,html.still .routes li,html.still .hero .cta,html.still .mast,html.still #aurora,html.still #nw{opacity:1;transform:none;translate:0 0;transition:none}
html.still .seam .track,html.still #dust i,html.still .fly .spin{animation:none}
html.still .device .shell{opacity:1;translate:0 0}
html.still .card .v-live{stroke-dashoffset:0}

@media (max-width:1180px){
  :root{--gutter:44px;--block:20px;--sec:88px}
  #nw{left:0;width:100vw}
  @keyframes veil{from{opacity:.42}to{opacity:.62}}
  .hero .wrap{grid-template-columns:minmax(0,1fr);gap:24px}
  .stage{max-width:440px;justify-self:center;order:-1;margin-top:-20px}
  .proof .strip{grid-template-columns:repeat(2,minmax(0,1fr))}
  .proof .cell:nth-child(2){border-right:0}
  .proof .cell:nth-child(3){border-top:1px solid var(--hairline);padding-left:0}
  .proof .cell:last-child{border-top:1px solid var(--hairline)}
  .stakes .wrap,.firm .wrap,.contact .wrap,.built .top{grid-template-columns:minmax(0,1fr);gap:44px}
  .practices .wrap,.faq .wrap{grid-template-columns:minmax(0,1fr);gap:32px}
  .practices .rail,.faq .side{position:static}
  .practices .rail .idx{display:none}
  .writing .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
  footer .grid{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:900px){
  :root{--gutter:clamp(22px,5.2vw,40px);--block:14px;--sec:84px;--radius:22px;--t-display:64px;--nav-clear:92px;--t-name:34px}
  .nav,.mast .pill.primary{display:none}
  .burger{display:inline-flex;align-items:center;gap:8px;height:44px;padding:0 16px;border-radius:999px;font-size:var(--t-micro);box-shadow:inset 0 0 0 1px var(--border)}
  .mast .pill-bar{padding-left:18px}
  /* The sheet is an opaque plate, not a blur. Translucent, the hero copy and
     the tower read straight through its lower edge and the door rows underneath
     competed with the links for the tap. */
  .menu{position:fixed;inset:80px 14px auto;z-index:19;background:var(--plate);border-radius:22px;box-shadow:inset 0 0 0 1px var(--hairline),var(--el-chrome);padding:14px;display:none;flex-direction:column;gap:2px}
  .menu.open{display:flex}
  .menu a{padding:12px 14px;border-radius:12px;text-decoration:none;font-size:var(--t-lede)}
  .hero{padding-top:calc(var(--nav-clear) + 8px)}
  .h1{max-width:none}
  .stage{max-width:300px;margin-top:-10px}
  .proof .cell{padding:26px 16px 24px 0}
  .proof .cell + .cell{padding-left:16px}
  .proof .cell:last-child p{font-size:var(--t-body)}
  .wall{grid-template-columns:minmax(0,1fr)}
  .wall ul{grid-template-columns:1fr}
  .wall li:nth-child(odd){padding-right:0}
  /* stacked, the second list's heading landed on the same pitch as a name and
     read as one more row of the first list. A heading takes more space above
     it than below it. */
  .wall .col + .col{margin-top:38px}
  .built .lab{grid-template-columns:minmax(0,1fr)}
  .device .win{aspect-ratio:343/352}
  .device .win video,.device .win img{max-width:none;width:calc(100% * 1280 / 560);left:calc(-190 / 560 * 100%);top:calc(-150 / 560 * 100%)}
  .device .cap{grid-template-columns:minmax(0,1fr)}
  .writing .cards{grid-template-columns:minmax(0,1fr)}
  .qa summary{grid-template-columns:minmax(0,1fr) 30px;font-size:var(--t-body);padding:18px 0}
  /* the tile layer bleeds 12px each side here, not 22: at 375 the gutter is
     22px and a 22px bleed on top of the old 12px margin put 13px of the page
     past the viewport. The row itself keeps the wrap's own edges. */
  .qa details[open]{margin:0;padding:0}
  .qa details::before{inset:-4px -12px -2px 0}
  .qa .a p{padding-left:0}
  .proof .cell:nth-child(3){padding-left:0}
  .firm .flow div{grid-template-columns:minmax(0,1fr);gap:4px;padding:14px 0}
  .firm .flow em{font-size:13px}
  .fly text{display:none}
  .fly{max-width:300px}
  .device .bar .t{display:none}
  .plate{padding-block:56px 36px}
  .prow{padding:34px 0 30px}
  .card .viz{aspect-ratio:260/104}
  .mast .pill-bar{background:color-mix(in srgb,var(--ground) 94%,transparent)}
  @keyframes veil{from{opacity:.56}to{opacity:.9}}
  @supports not (animation-timeline: scroll()){ #veil{opacity:.78} }
  .partner .who{grid-template-columns:72px minmax(0,1fr)}
  .partner img{width:72px;height:72px}
  .qa{grid-template-columns:minmax(0,1fr)}
  footer .cols{grid-template-columns:1fr}
  /* the footer links were a 15px line on a 23px pitch: two adjacent targets
     inside one thumb. The pitch opens to 45px so each one is its own. */
  footer ul{gap:0}
  footer ul a{display:block;padding-block:15px}
  footer ul li + li a{border-top:1px solid var(--hairline)}
  .instr .row{grid-template-columns:20px minmax(0,1fr);font-size:var(--t-body)}
  .instr .verdict{grid-column:2}
  .prow .foot{flex-direction:column;align-items:flex-start}
}
@media (max-width:560px){
  :root{--t-h1:44px;--t-display:44px;--t-name:30px}
  .display sup{font-size:.5em}
}

/* ── hero brain, by width ────────────────────────────────────────────────────
   Below 720 the brain is not drawn and the chips are not rendered: the routes
   list carries the navigation. The module script empties the stage there, so
   there is no canvas and nothing focusable, not merely something hidden.
   Between 720 and 1180 the stage sits above the headline and the legend is one
   wrapped row. */
/* :empty catches the home stage after the module has emptied it, and any hero
   stage that has no brain in it yet; :has(> .legend) catches it before that.
   The fluency page's stage keeps its mark brain and its locator line here. */
@media (max-width:719px){ .stage:empty,.stage:has(> .legend){display:none} }
/* And with the stage gone, the copy is the only thing left inside a box still
   holding a whole screen open. align-items:center split the slack, so about
   200px of it landed under the last link on search, fluency and systems and
   read as the page having ended. Below 720 the hero sizes to its own copy and
   keeps a section's foot under it. The home hero's copy is taller than the
   screen at this width, so it is unchanged. */
@media (max-width:719px){ .hero{min-height:0;padding-bottom:64px} }
@media (min-width:720px) and (max-width:1180px){
  /* order:-1 is restated here because the shared .stage rule that sets it in
     the 1180 band is less specific than the :has() scoping above, and without
     it the brain drops below the headline instead of sitting over it. */
  .stage:has(> .legend){max-width:480px;aspect-ratio:1;margin-top:-8px;order:-1;justify-self:center}
  .legend{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}
  .legend .chip{min-height:32px;font-size:13px;padding:0 11px}
}
@media (prefers-reduced-motion: reduce){ .stage:has(> .legend){opacity:1;transition:none} .prow{transition:none} }

/* ── light polarity, every page ──────────────────────────────────────────────
   The Nightworld always renders its dark palette (groundTokens pins the theme
   to dark), so in the light polarity the veil has to be most of the way up
   from scroll 0 or the dark ink sits on a dark world. At .82 the world's tower
   and ribbons still move visibly through the cream, and the lede measures
   4.87:1 there; by 100vh it is at .92.

   This used to be scoped away from body.reading, so the essay pages kept the
   dark polarity's reading ramp (.52 to .8) in both polarities. Measured on
   connection-by-design at 1440, light, scroll 0, that left the cream ground
   reading as grey and the muted ink under the floor: standfirst 3.15:1 and
   byline 2.66:1 against the world showing through. The exclusion is gone, so
   the light polarity now has ONE veil law for every page, hero or reading, and
   the same measurements come back at 11.68:1 for the title, 10.62:1 for the
   prose, 4.69:1 for the standfirst and 4.70:1 for the byline. The rules set
   animation-name only, so the timeline, range and fill still come from the
   shorthand on #veil (hero pages) or on body.reading #veil (essays), and there
   is still one compositor driven veil on the page.

   The phone retune stays its own pair, because the retune below 900 changes
   @keyframes veil, which the light polarity does not use. */
@keyframes veil-light{from{opacity:.82}to{opacity:.92}}
@keyframes veil-light-sm{from{opacity:.86}to{opacity:.95}}
:root[data-theme="light"] body #veil{opacity:.82}
@supports (animation-timeline: scroll()){ :root[data-theme="light"] body #veil{animation-name:veil-light} }
@supports not (animation-timeline: scroll()){ :root[data-theme="light"] body #veil{opacity:.86} }
@media (max-width:900px){
  :root[data-theme="light"] body #veil{opacity:.86}
  @supports (animation-timeline: scroll()){ :root[data-theme="light"] body #veil{animation-name:veil-light-sm} }
  @supports not (animation-timeline: scroll()){ :root[data-theme="light"] body #veil{opacity:.9} }
}

/* search page */
.proof .strip.three{grid-template-columns:repeat(3,minmax(0,1fr))}
.proof .strip.three .cell.last{padding-left:28px}
.lede.big{font-size:var(--t-lede);max-width:56ch;color:var(--ink)}
.argument .wrap{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:64px;align-items:start}
.perf .h2{max-width:22ch;font-size:28px}
.pstrip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);margin-top:28px}
.pstrip .cell{padding:30px 24px 26px 0;border-right:1px solid var(--hairline);min-width:0}
.pstrip .cell + .cell{padding-left:24px}
.pstrip .cell:last-child{border-right:0}
.pstrip .display{font-size:88px}
.pstrip .cap{margin-top:12px;color:var(--ink);font-size:var(--t-micro);max-width:20ch;line-height:1.4}
/* one of the three reads to 39 characters. All three drop the uppercase
   together, so the row stays one voice rather than two. */
.pstrip .sub{margin-top:10px;color:var(--ink-muted);text-transform:none;letter-spacing:normal}
.runs .wrap{align-items:start}
.prow.mech{gap:14px}
.prow.mech .device{margin:6px 0 4px}
.device.small{width:440px;max-width:100%}
.device.portrait{width:440px;max-width:100%}
.device .win.still{aspect-ratio:auto}
.device .win.still img{position:static;width:100%;height:auto}
.runs .wrap.phases{display:block}
.phases{margin-top:64px}
.tickrule{height:14px;margin:22px 0 0;background:repeating-linear-gradient(90deg,var(--hairline) 0 1px,transparent 1px 10px) bottom/100% 8px no-repeat,linear-gradient(var(--hairline),var(--hairline)) bottom/100% 1px no-repeat}
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:32px;margin-top:22px}
.step h4{margin:8px 0 8px;font-size:var(--t-lede);font-weight:500}
.step p{color:var(--ink-muted);font-size:var(--t-micro);line-height:1.55}
.step .mono{color:var(--ink-muted)}
.functions{margin-top:56px}
.fhead{display:flex;align-items:baseline;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:14px}
.fhead h3{font-size:var(--t-lede);font-weight:500}
.levels{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap}
.functions .qa summary{font-size:var(--t-body)}
.functions .qa .a p{font-size:var(--t-micro)}
/* Sectors as a readable list, not a ticker. A moving strip is unreadable
   at a glance and adds motion the page does not need. */
.sr-sectors{margin-top:64px;padding-top:24px;border-top:1px solid var(--hairline)}
.sr-sectors h3{font:400 var(--t-label)/1.5 var(--font-b);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);margin:0 0 16px}
.sr-sectors ul{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px 32px;margin:0;padding:0;list-style:none}
.sr-sectors li{font-size:var(--t-body);color:var(--ink)}
@media(max-width:900px){.sr-sectors ul{grid-template-columns:repeat(2,minmax(0,1fr))}}
.companies{margin-top:64px}
.companies .wall{grid-template-columns:repeat(3,minmax(0,1fr));gap:0 40px}
.companies .wall ul{grid-template-columns:1fr}
.companies .wall li:nth-child(odd){padding-right:0}
.settle{margin-top:64px;max-width:var(--measure)}
.checks{list-style:none;margin:22px 0 0;padding:0;border-top:1px solid var(--hairline)}
.checks li{display:grid;grid-template-columns:20px minmax(0,1fr);gap:14px;padding:14px 0;border-bottom:1px solid var(--hairline);color:var(--ink-muted);line-height:1.55}
.checks li::before{content:"";width:10px;height:1px;background:var(--ink-quiet);margin-top:11px}
.qa.one{grid-template-columns:minmax(0,1fr)}
.others{list-style:none;margin:0;padding:0}
.contact .when .others li{display:block;padding:0;border:0}
.contact .when .others li::before{display:none}
.others .route{font-size:var(--t-body);line-height:1.45;padding:16px 4px}
.others .route b{font-weight:500}
html.entered [data-entry]{opacity:1 !important}
@media (max-width:1180px){
  .argument .wrap{grid-template-columns:minmax(0,1fr);gap:44px}
  .proof .strip.three{grid-template-columns:minmax(0,1fr)}
  .proof .strip.three .cell{border-right:0;border-bottom:1px solid var(--hairline);padding-left:0}
  .proof .strip.three .cell.last{padding-left:0;border-bottom:0}
  .steps{grid-template-columns:repeat(2,minmax(0,1fr))}
  .companies .wall{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:900px){
  .pstrip{grid-template-columns:minmax(0,1fr)}
  .pstrip .cell{border-right:0;border-bottom:1px solid var(--hairline);padding-left:0}
  .pstrip .cell:last-child{border-bottom:0}
  .pstrip .display{font-size:var(--t-display)}
  .steps{grid-template-columns:minmax(0,1fr)}
  .device .win.still img{position:static;width:100%}
}

/* essay page */
/* One reading column, held on the wrap's left edge, on the same dark world as
   every other page. The wrap is centred in the page; the column inside it is
   not, so the title, the prose and the foot all hang off one margin.
   The measure is the shared --measure token; the opening paragraph is set at
   --t-lede and everything after it at --t-body, per the essay spec. Light on
   dark is compensated the way the typeset playbook asks: a little more leading
   and a hair of tracking, and the prose sits one step off pure --ink so a
   three thousand word read does not glare. */
.essay{padding-top:calc(var(--nav-clear) + 52px);padding-bottom:var(--sec)}
.essay .wrap{width:min(var(--wrap),100% - 2*var(--gutter))}
/* One reading column, CENTRED in the wrap. Held on the wrap's left edge it left
   the right 47% of a 1440 viewport carrying nothing for the whole article. The
   title, the standfirst, the byline, the prose and the fact pledge all take the
   same measure and the same centre line, so the article reads as a column on a
   ground rather than as text pushed into a corner. */
.essay-head,.essay-foot{max-width:var(--measure);margin-inline:auto}
/* An essay has no hero, so the world is calm from the first line rather than
   from the first scroll: the shared veil starts already raised on a reading
   page and finishes a little higher. Same law as the other pages, different
   starting point, and the page still has one compositor driven veil. This is
   the DARK polarity's ramp; the light polarity block above outranks it and
   gives every page, reading or not, the one light ramp. */
body.reading #veil{opacity:.78}
@supports (animation-timeline: scroll()){
  body.reading #veil{animation:veil-reading linear both;animation-timeline:scroll(root block);animation-range:0 100vh}
}
@keyframes veil-reading{from{opacity:.78}to{opacity:.92}}
.essay-title{margin:0;font-size:clamp(31px,4.2vw,50px);line-height:1.07;letter-spacing:-.024em;font-weight:500;text-wrap:balance}
.standfirst{margin:24px 0 0;max-width:50ch;font-size:var(--t-lede);line-height:1.5;color:var(--ink-muted)}
.byline{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:34px 0 0;padding:15px 0 14px;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline);
  font-family:var(--font-b);font-size:13px;letter-spacing:.015em;color:var(--ink-muted)}
.byline b{font-weight:400;color:var(--ink)}
.byline time{font-variant-numeric:tabular-nums}

.prose{max-width:var(--measure);margin-top:52px;margin-inline:auto;color:color-mix(in srgb,var(--ink) 92%,var(--ground))}
.prose p{margin:0 0 1.16em;font-size:var(--t-body);line-height:1.78;letter-spacing:.004em}
.prose p.opening{margin-bottom:1.3em;font-size:var(--t-lede);line-height:1.6;letter-spacing:0;color:var(--ink)}
.prose h2{margin:66px 0 18px;max-width:26ch;font-size:26px;line-height:1.2;letter-spacing:-.016em;font-weight:500;color:var(--ink);text-wrap:balance}
.prose h3{margin:38px 0 8px;font-size:var(--t-body);line-height:1.45;font-weight:500;color:var(--ink)}
.prose h3 + p{margin-bottom:0}
.prose ul,.prose ol{margin:0 0 1.16em;padding-left:1.25em}
.prose li{margin-bottom:.45em;line-height:1.72}
.prose blockquote{margin:38px 0;padding-left:26px;border-left:1px solid var(--hairline);color:var(--ink-muted)}
.prose blockquote p{font-size:var(--t-lede);line-height:1.55}
.prose a:not(.link){color:var(--ink);text-decoration:none;
  background:linear-gradient(currentColor,currentColor) no-repeat 0 100%/100% 1px;
  transition:opacity var(--dur-hover) var(--ease)}
.prose a:not(.link):hover{opacity:.72}
.prose .signoff{margin:52px 0 0;padding-top:26px;border-top:1px solid var(--hairline);color:var(--ink-muted)}
.prose .signoff em{display:block;font-style:italic}
.prose .signoff .link{margin-top:14px;color:var(--ink)}
.prose h2 + .sources{margin-top:22px}
.prose .sources{list-style:none;margin:0;padding:0;border-top:1px solid var(--hairline)}
.prose .sources li{margin:0;padding:12px 2px;border-bottom:1px solid var(--hairline);
  font-family:var(--font-b);font-size:12.5px;line-height:1.62;color:var(--ink-muted)}

.essay-foot{display:flex;align-items:flex-start;justify-content:space-between;gap:26px;flex-wrap:wrap;
  margin-top:72px;padding-top:28px;border-top:1px solid var(--hairline)}
.essay-foot .pledge{margin:0;max-width:44ch;font-size:var(--t-micro);line-height:1.55;color:var(--ink-muted)}
.essay-foot .link{flex:none;color:var(--ink)}

@media (max-width:900px){
  .essay{padding-top:calc(var(--nav-clear) + 26px)}
  .prose{margin-top:40px}
  .prose h2{margin-top:52px;font-size:23px}
  .essay-foot{margin-top:56px;gap:18px}
}
/* end essay page */

/* scroll demo */
/* ── the scroll demo: a pinned stage beside steps that light in turn ──────────
   Geometry note. The home crops differ in aspect (a wide portal strip, a
   mandate list, a near square approval card), so the window keeps its width
   and its pinned position and eases its HEIGHT across the crossfade to the
   live crop's own aspect. The frame fills the window edge to edge and is never
   stretched out of shape. The stage never moves; only how much of the screen
   it shows changes. Nothing is ever drawn over the frame: no sheen, no scrim,
   no tint. The only mark on the window is a one pixel inside edge.
   ------------------------------------------------------------------------- */
.demo{position:relative}
.demo.is-pinned{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,360px);gap:72px;
  min-height:calc(var(--demo-states,3) * 90vh);margin-top:56px}
/* the stage column is a fixed grid area, so containment keeps the window's
   height ease from reaching the rest of the page on every crossfade frame */
.demo-col{position:relative;contain:layout style}
/* Both columns start at the TOP of the pinned box, not in its middle. A wide
   crop such as the mandate strip draws 180px tall; centring it in a viewport
   tall box put ~300px of dead ground above and below the only thing in the
   column, while the steps beside it started at the top. One shared start edge,
   so the stage and its first step arrive on the same line. */
.demo.is-pinned .demo-stage,.demo.is-pinned .demo-steps{position:sticky;top:calc(var(--nav-clear) + 16px);
  height:calc(100svh - var(--nav-clear) - 48px);display:flex;flex-direction:column;justify-content:flex-start}
.demo .device{margin:0;max-width:none}

/* The window's height still eases between states of different aspect, because
   the states genuinely are different shapes and the stage has to make room for
   the live one. What changed is the property carrying the ease: a single grid
   row track rather than `height`, so the value the engine writes lands on a
   track the container already owns and the ease stays inside this element's
   `contain: layout paint` box. The engine writes --win-h; nothing else reads it. */
.demo-win{position:relative;width:100%;min-height:150px;overflow:hidden;background:var(--screen);contain:layout paint;
  display:grid;grid-template-rows:var(--win-h,150px);
  transition:grid-template-rows var(--dur-crossfade) var(--ease-out),background-color var(--dur-crossfade) var(--ease)}
.demo-layer{position:absolute;left:50%;top:50%;translate:-50% -50%;width:100%;height:auto;display:block;
  opacity:0;transition:opacity var(--dur-crossfade) var(--ease)}
.demo-layer.on{opacity:1}
/* the first state's own crop, written to disk once, so the reader has a real
   frame the instant the HTML paints rather than the flat --screen colour
   while the burst decodes. The engine's canvas is appended after this in the
   DOM and paints over it as soon as it has a frame; nothing here is removed,
   it is just never visible again once that happens. */
.demo-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}
.demo-poster[hidden]{display:none}
.demo-kind{aspect-ratio:var(--demo-aspect,1280/684)}
.demo-win::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(203,219,225,.10),inset 0 1px 0 rgba(255,255,255,.07)}

/* the shell chrome, borrowed from the prototype device, one title per state.
   The title names the state, so unlike the video device it stays on tablets. */
.demo .bar .t{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:559.98px){ .demo .bar .t{display:none} }
.demo-full{margin-top:20px;color:var(--ink)}
.demo-full:hover,.demo-full:focus-visible{color:var(--ink)}
.demo-full .ar{width:13px;height:13px}
.demo-full:hover .ar{transform:none;scale:1.14}

/* the scrub rail: built by demo.js, one dot per state, so the reader who has
   not read a single word yet still sees that this block has more than one
   picture and that scrolling is what turns the page. Lit from the same
   lastState write as the step and its hairline, engine.js setState(). */
.demo-rail{display:flex;gap:9px;margin-top:22px}
.demo-rail i{width:5px;height:5px;border-radius:50%;background:var(--ink-quiet);opacity:.5;
  transition:background var(--dur-crossfade) var(--ease),opacity var(--dur-crossfade) var(--ease),scale var(--dur-crossfade) var(--ease)}
.demo-rail i.on{background:var(--mark);opacity:1;scale:1.5}
.demo-rail + .demo-full{margin-top:14px}
@media (prefers-reduced-motion: reduce){ .demo-rail i{transition:none} }

/* the steps. Each one owns its share of the scroll span, so the reader is
   always reading the step the stage is playing. */
.demo-steps{list-style:none;margin:0;padding:0;gap:30px}
.demo-step{display:flex;flex-direction:column;gap:10px}
.demo-step h3{position:relative;margin:0;padding-top:20px;border-top:1px solid var(--hairline);
  font-size:var(--t-lede);font-weight:500;letter-spacing:-.012em;color:var(--ink-quiet);
  transition:color 420ms var(--ease)}
/* the hairline over the live step fills as its state plays. It is a real
   element so the tick writes a transform the compositor can take, rather than
   a custom property that would invalidate style on every frame. */
.demo-step-bar{position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--mark);
  transform:scaleX(0);transform-origin:left;opacity:0;transition:opacity 300ms var(--ease)}
.demo-step.on .demo-step-bar{opacity:1;will-change:transform}
.demo-step p{margin:0;color:var(--ink-quiet);max-width:40ch;transition:color 420ms var(--ease)}
.demo-step.on h3{color:var(--ink)}
.demo-step.on p{color:color-mix(in srgb,var(--ink) 86%,transparent)}

/* the whole screen overlay */
.demo-dialog{border:0;padding:0;background:transparent;color:var(--ink);
  width:min(96vw,1440px);max-width:96vw;max-height:92vh;overflow:visible}
.demo-dialog::backdrop{background:rgba(4,10,25,.88);backdrop-filter:blur(8px)}
:root[data-theme="light"] .demo-dialog::backdrop{background:rgba(244,241,230,.9)}
.demo-dialog-head{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:14px}
.demo-dialog-cap{margin:0;font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);
  text-transform:uppercase;color:var(--ink-muted)}
.demo-dialog-pane{overflow:auto;display:flex;justify-content:flex-start;max-height:74vh;border-radius:14px;background:var(--screen);
  box-shadow:inset 0 0 0 1px rgba(203,219,225,.14),0 2px 5px -2px var(--sh-c),0 40px 80px -30px rgba(0,3,14,.7);
  cursor:grab;overscroll-behavior:contain}
.demo-dialog-pane.is-dragging{cursor:grabbing}
.demo-dialog-frame{position:relative;overflow:hidden;flex:none}
.demo-dialog-pane img{display:block;width:1280px;max-width:none;user-select:none}
.demo-dialog-note{margin:14px 0 0;font-size:var(--t-micro);color:var(--ink-muted)}

/* the stacked layout: phones, and every reduced motion reader on any width.
   The stage stops being pinned and each state plays under its own step. */
.demo.is-stacked{display:block;min-height:0;margin-top:40px}
.demo.is-stacked .demo-col{display:none}
.demo.is-stacked .demo-steps{padding-left:0;display:block;height:auto;position:static}
.demo.is-stacked .demo-step{display:block;margin-bottom:44px}
.demo.is-stacked .demo-step-bar{display:none}
.demo.is-stacked .demo-step h3,.demo.is-stacked .demo-step.on h3{color:var(--ink)}
.demo.is-stacked .demo-step p{color:var(--ink-muted);max-width:var(--measure);margin-top:10px}
.demo.is-stacked .demo-inline{margin-top:20px;max-width:1000px}
.demo.is-stacked .demo-inline .demo-win{transition:none}
.demo.is-stacked .demo-inline .demo-layer{opacity:1}
.demo.is-stacked .demo-full{margin-top:24px}

@media (max-width:1080px){
  .demo.is-pinned{grid-template-columns:minmax(0,1fr) minmax(260px,320px);gap:48px}
  .demo-step p{max-width:36ch}
}
@media (max-width:719.98px){
  .demo.is-stacked .demo-inline{margin-inline:0}
  .demo-dialog{width:96vw}
  .demo-dialog-pane{max-height:68vh}
}
@media (prefers-reduced-motion: reduce){
  .demo-win,.demo-layer,.demo-step h3,.demo-step p{transition:none}
}
html.still .demo-win,html.still .demo-layer,html.still .qa details::before{transition:none}

/* the what we built plate, rewired around the demo */
.built .made{margin-top:76px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 24px;
  border-top:1px solid var(--hairline)}
.built .made div{padding:22px 0 0}
.built .made h3{margin:0 0 6px;font-family:var(--font-b);font-size:var(--t-label);
  letter-spacing:var(--t-track-label);text-transform:uppercase;font-weight:400;color:var(--ink-muted)}
.built .made p{margin:0;color:var(--ink)}
.built .disclosure{margin-top:34px;padding-top:22px;border-top:1px solid var(--hairline);
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:end}
.built .disclosure p{margin:0;max-width:60ch;color:var(--ink-muted);font-size:var(--t-micro)}
@media (max-width:900px){
  .built .top{grid-template-columns:minmax(0,1fr);gap:26px}
  .built .made{grid-template-columns:minmax(0,1fr);gap:0}
  .built .made div{border-top:1px solid var(--hairline);padding-top:18px}
  .built .made div:first-child{border-top:0}
  .built .disclosure{grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}
}
/* end scroll demo */

/* fluency page */
/* Everything below belongs to /fluency/ only. It is appended as one delimited
   block so the four pages keep one stylesheet and no page rewrites another
   page's rules. Where a component already exists on the shared layer
   (.plate, .tile, .chip, .mono, .steps, .tickrule, .qa, .contact, footer) the
   page uses it and adds nothing. */

/* the hero: the one locator brain the three service pages share, at 360, with
   the locator line under it. The size, the flex column and the 720 cut off are
   written the same way in each page's block, so the three heroes cannot drift
   apart again. Below 720 the brain is not drawn at all, per spec 4.1, so the
   phone gets the headline at full width and no empty square. */
.fl-hero .stage{max-width:360px;display:flex;flex-direction:column;justify-content:flex-end}
@media (max-width:719px){ .fl-hero .stage{display:none} }
#brain{position:absolute;inset:0;width:100%;height:100%;display:block}
/* "You are here · Executive search" is 31 characters. The three pages carry the
   same locator, so all three lose the uppercase rather than only the long one. */
.stage .here{position:relative;z-index:1;text-align:center;color:var(--ink-muted);padding-top:12px;border-top:1px solid var(--hairline);text-transform:none;letter-spacing:normal}

/* the argument: the five word heading holds its column while the diagnosis
   scrolls past it, so the left half is never an abandoned rectangle. */
.fl-arg .wrap > div:first-child{position:sticky;top:calc(var(--nav-clear) + 20px)}

/* questions: the heading holds the left column, the three answers stack in one
   readable column on the right. Two short columns left a dead quadrant. */
.fl-faq .wrap{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:0 64px;align-items:start}
.fl-faq .fq-head{position:sticky;top:calc(var(--nav-clear) + 20px)}
.fl-faq .h2{margin-bottom:0}

/* the plate head: the H2 against the one line format statement. Everything
   this block used to carry above the areas (the figure, the tick rule, the
   four steps) now sits in .how-proof, after them. */
.fl-head{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:56px;align-items:start}
.fl-head .lede{max-width:54ch}
.case-top .chip,.inst-top .chip{white-space:nowrap}

/* the demoted strip: the honest figure and the four steps, after the areas
   rather than before them. One hairline marks it off from the device above. */
.how-proof{margin-top:64px;padding-top:28px;border-top:1px solid var(--plate-hair)}
.fl-facts{display:flex;align-items:baseline;justify-content:space-between;gap:24px;flex-wrap:wrap}
.ff-fig{font-size:var(--t-lede);line-height:1.4;color:var(--ink);flex:1 1 auto}
.ff-note{color:var(--ink-muted);font-size:var(--t-micro)}
.how .steps{margin-top:26px}
.how .step h3{margin:8px 0;font-size:var(--t-lede);font-weight:500}
/* the one honest line on this page's unconfirmed formats, stated once at the
   foot rather than shared as a chip on the hero figure's own baseline. */
.how-foot{margin-top:26px;color:var(--ink-muted);font-size:var(--t-micro)}

/* ── the marking device ──────────────────────────────────────────────────────
   No script. Eleven native radios in one group, each inside the row it marks,
   and the readout is a later sibling switched by :has(). Nothing is counted,
   stored or sent: the state chip says so and the caption says so in a
   sentence, and there is no code here that could contradict either. */
.aimed{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:0 56px;margin-top:56px}

.fa + .fa{margin-top:58px}
.fa-name{font-size:26px;line-height:1.15;letter-spacing:-.02em;font-weight:500}
.fa-intro{margin-top:10px;color:var(--ink-muted);max-width:52ch}
/* the cue and the honesty note sit on the first list only, as a small inline
   row rather than a second block repeated over all three areas. */
.rec-cue{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 18px;margin-top:22px}
.rec-cue .mono{color:var(--ink)}
.rec-cue-note{color:var(--ink-muted);font-size:var(--t-micro)}
.rec-cue + .recog{margin-top:10px}

/* the three empty case cards collapse into one light strip until a client
   clears the first one for showing; see .case/.case-top etc. on the systems
   page for the full card this restores to. */
.case-strip{margin-top:40px;padding-top:16px;border-top:1px solid var(--plate-hair);color:var(--ink-muted);font-size:var(--t-micro);line-height:1.6}
.case-strip .mono{color:var(--ink-muted);margin-right:6px}

.recog{list-style:none;margin:24px 0 0;padding:0;border-top:1px solid var(--plate-hair)}
.rec{position:relative;border-bottom:1px solid var(--plate-hair)}
/* the control stays in its row, so arrowing down the group scrolls to the row
   and not to a hidden input parked somewhere above the list */
.rec .y{position:absolute;left:0;top:15px;width:18px;height:18px;margin:0;padding:0;border:0;opacity:0;appearance:none;-webkit-appearance:none;pointer-events:none}
.pick{display:grid;grid-template-columns:18px minmax(0,1fr) 40px;gap:14px;align-items:start;padding:14px 4px;cursor:pointer}
.rt{min-width:0;color:var(--ink-muted);line-height:1.55;transition:color var(--dur-hover) var(--ease)}
/* the radio idiom the rail's own "pick none" ring already uses: a ring, and a
   small centred dot when marked, never a flat fill. See .pick-none below. */
.bx{width:18px;height:18px;margin-top:3px;border-radius:50%;position:relative;flex:none;
  box-shadow:inset 0 0 0 1px var(--border);transition:box-shadow var(--dur-hover) var(--ease)}
.bx::after{content:"";position:absolute;left:50%;top:50%;width:8px;height:8px;border-radius:50%;background:var(--ink);
  transform:translate(-50%,-50%) scale(0);opacity:0;transition:opacity 180ms var(--ease),transform 260ms var(--ease-out)}
.rg-obj{width:40px;display:block}
.rg-obj svg{width:100%;height:auto;display:block;fill:none;stroke:var(--ink-quiet);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:stroke var(--dur-hover) var(--ease)}
.rg-obj .ix-f{fill:var(--ink-quiet);stroke:none;transition:fill var(--dur-hover) var(--ease)}
.rec:hover .rt{color:var(--ink)}
.rec:hover .bx{box-shadow:inset 0 0 0 1px var(--ink)}
.rec:hover .rg-obj svg{stroke:var(--ink)}
.rec:hover .rg-obj .ix-f{fill:var(--ink)}
.rec:has(.y:checked) .rt{color:var(--ink)}
.rec:has(.y:checked) .rg-obj svg{stroke:var(--ink)}
.rec:has(.y:checked) .rg-obj .ix-f{fill:var(--ink)}
.rec:has(.y:checked) .bx{box-shadow:inset 0 0 0 1px var(--ink)}
.rec:has(.y:checked) .bx::after{opacity:1;transform:translate(-50%,-50%) scale(1)}
.rec:has(.y:focus-visible){outline:2px solid var(--ink);outline-offset:2px;border-radius:10px}

/* the business case slot: the klartext shape, named part by part, TO FOLLOW */
.case{margin-top:30px;padding:22px 24px 20px;border-radius:calc(var(--radius) - 12px);
  background:color-mix(in srgb,var(--plate-2) 72%,transparent);box-shadow:inset 0 0 0 1px var(--plate-hair)}
.case-top{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.case-top .mono{color:var(--ink-muted)}
.case-title{margin-top:16px;font-size:var(--t-lede);line-height:1.35;font-weight:500;color:var(--ink);max-width:34ch}
.case-desc{margin-top:8px;color:var(--ink-muted);font-size:var(--t-micro);line-height:1.6;max-width:58ch}
.case-out{list-style:none;margin:16px 0 0;padding:0}
.case-out li{display:grid;grid-template-columns:18px minmax(0,1fr);gap:12px;padding:11px 0;border-top:1px solid var(--plate-hair);color:var(--ink-muted);font-size:var(--t-micro);line-height:1.55}
.case-out li::before{content:"";width:12px;height:1px;background:var(--ink-muted);margin-top:11px}
.case-note{margin-top:14px;padding-top:13px;border-top:1px solid var(--plate-hair);color:var(--ink-muted);font-size:13px;line-height:1.55}

/* the readout. It holds a state, never a quantity. */
.aimed-rail{align-self:start;position:sticky;top:calc(var(--nav-clear) + 20px)}
.inst{padding:26px 28px 28px}
.inst:hover{transform:none}
.inst-top{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-bottom:16px;border-bottom:1px solid var(--tile-hair)}
.inst-top .mono{color:var(--ink-muted)}
.inst-lab{margin-top:20px;color:var(--ink-muted)}
/* the slot is a receptacle, so it is drawn as one: the same recessed
   material the form fields use, which is this layer's "something lands here"
   surface. Empty, it reads as a waiting well rather than as a gap. */
.inst-slot{margin-top:12px;min-height:108px;padding:16px 18px;border-radius:14px;background:color-mix(in srgb,#000 20%,transparent);box-shadow:var(--rec)}
:root[data-theme="light"] .inst-slot{background:color-mix(in srgb,#000 5%,transparent)}
.echo{display:none}
.echo p{color:var(--ink);line-height:1.5}
.echo-none{color:var(--ink-muted);line-height:1.55}
.aimed:has(#y1:checked) .e1,
.aimed:has(#y2:checked) .e2,
.aimed:has(#y3:checked) .e3,
.aimed:has(#y4:checked) .e4,
.aimed:has(#y5:checked) .e5,
.aimed:has(#y6:checked) .e6,
.aimed:has(#y7:checked) .e7,
.aimed:has(#y8:checked) .e8,
.aimed:has(#y9:checked) .e9,
.aimed:has(#y10:checked) .e10{display:grid;grid-template-columns:44px minmax(0,1fr);gap:16px;align-items:start}
.aimed:has(#y0:checked) .e0{display:block;color:var(--ink);font-size:var(--t-lede);font-weight:500}
.aimed:has(.y:checked) .echo-none{display:none}
.rg-lg{width:44px}
.rg-lg svg{stroke:var(--ink)}
.rg-lg .ix{stroke:var(--machine-mark)}
.rg-lg .ix-f{fill:var(--machine-mark)}
.inst .y{display:inline-block;vertical-align:middle;width:1px;height:1px;margin:0;padding:0;border:0;opacity:0;appearance:none;-webkit-appearance:none;pointer-events:none}
.pick-none{display:inline-flex;align-items:center;height:38px;padding:0 18px;margin-top:22px;border-radius:999px;font-size:var(--t-micro);font-weight:500;cursor:pointer;color:var(--ink-muted);
  box-shadow:inset 0 0 0 1px var(--border);transition:color var(--dur-hover) var(--ease),box-shadow var(--dur-hover) var(--ease)}
.pick-none:hover{color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.aimed:has(#y0:checked) .pick-none{color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink),inset 0 1px 0 var(--catch-mid)}
.inst:has(.y:focus-visible) .pick-none{outline:2px solid var(--ink);outline-offset:3px}
.inst-note{margin-top:22px;padding-top:18px;border-top:1px solid var(--tile-hair);color:var(--ink-muted);font-size:var(--t-micro);line-height:1.6}
.inst-do{margin-top:22px}
.inst-cap{margin-top:16px;color:var(--ink-muted);font-size:13px;line-height:1.55;max-width:46ch}

/* ── what this runs on ────────────────────────────────────────────────────── */
.noscreen .wrap{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:64px;align-items:start}
.noscreen .body{max-width:60ch}
.await{padding:26px 28px 24px}
.await-line{margin-top:14px;color:var(--ink-muted);line-height:1.6}
.ilink{color:var(--ink);text-decoration:underline;text-decoration-color:var(--border);text-underline-offset:4px;text-decoration-thickness:1px;transition:text-decoration-color var(--dur-hover) var(--ease)}
.ilink:hover,.ilink:focus-visible{text-decoration-color:var(--ink)}

@media (max-width:1180px){
  .fl-head{grid-template-columns:minmax(0,1fr);gap:26px}
  .aimed{grid-template-columns:minmax(0,1fr);margin-top:64px}
  .aimed-rail{position:static;margin-top:52px}
  .noscreen .wrap{grid-template-columns:minmax(0,1fr);gap:40px}
  .fl-hero .stage{max-width:320px}
  .fl-arg .wrap > div:first-child{position:static}
  .fl-faq .wrap{grid-template-columns:minmax(0,1fr);gap:32px}
  .fl-faq .fq-head{position:static}
  .fl-faq .h2{margin-bottom:0}
}
/* the tablet band keeps the four steps in two columns: one column of four
   full width rows leaves half the plate empty. */
@media (min-width:621px) and (max-width:900px){
  .how .steps{grid-template-columns:repeat(2,minmax(0,1fr));gap:28px 32px}
}
@media (max-width:900px){
  .fl-facts{flex-direction:column;align-items:flex-start;gap:16px}
  .aimed{margin-top:52px}
  .inst-slot{min-height:84px}
  .fa + .fa{margin-top:46px}
}
@media (max-width:620px){
  .inst-top{flex-direction:column;align-items:flex-start;gap:10px}
  .pick{grid-template-columns:18px minmax(0,1fr);gap:12px}
  .rec .rg-obj{display:none}
  .inst{padding:22px 20px 24px}
  .case{padding:20px 18px 18px}
  .fa-name{font-size:23px}
}
/* F6 fix, see the "fluency r2" block near the end of this file: the phone
   readout used to be a docked, position:fixed bar here (which also needed
   #how{translate:none} to escape the section's own containing block). That
   bar pinned a third of the viewport over the scrolling copy for the rest of
   the page once any line was marked, colliding with #runs-on and the FAQ
   heading below. The rail is desktop-only from 719px down now; .pr in the
   fluency r2 block is the in-flow reading it was replaced with, one instance
   under each area. */
@media (max-width:719px){
  .aimed-rail{display:none}
}
@media (prefers-reduced-motion: reduce){
  .rt,.bx,.bx::after,.rg-obj svg,.rg-obj .ix-f,.pick-none,.ilink,.aimed-rail{transition:none}
}
/* end fluency page */

/* search page, finished */
/* Everything below belongs to /search/ only, appended as one delimited block so
   the four pages keep one stylesheet and no page rewrites another page's rules.
   Where a component already exists on the shared layer (.plate, .tile, .chip,
   .qa, .wall, .steps, .tickrule, .demo, .contact, footer) the page uses it and
   this block only adds what the finished copy needs. */

/* the hero: the one locator brain the three service pages share, at 360, with
   the practice's region held lit and the locator line under it rather than over
   it. Below 720 the stage is not rendered at all (spec 4.1: the brain is not
   drawn on phones), so the page opens on the headline instead of an empty
   square. */
.sr-hero .stage{max-width:360px;display:flex;flex-direction:column;justify-content:flex-end}
@media (max-width:719px){ .sr-hero .stage{display:none} }

/* the proof cells: each one keyed, so the reader learns what kind of fact it is
   before they read the fact. The key holds the top of the cell and the figure
   keeps the baseline it already had. */
.proof .key,.proof .cell:last-child .key{margin:0 0 auto;padding-bottom:22px;color:var(--ink-muted);
  font-size:var(--t-label);line-height:1.5}
.proof .cap b{font-weight:500;color:var(--ink)}
.proof .strip.three .cap{max-width:27ch}

/* the argument: the line that says whose record the three figures are. It is
   the page's disclosure, so it sits under the strip in the reader's own voice
   size rather than as a footnote nobody is meant to reach. */
.sr-attrib{margin-top:24px;font-size:var(--t-micro)}

/* the plate head, shared by "how a mandate runs": the H2 against the sentence
   that says what the reader is about to watch. */
.sr-head{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:64px;align-items:end}
.sr-head .body{max-width:54ch}
.sr-phases-h{font-size:28px}

/* the function directory. The seat line is visible with the expander closed,
   because it is the reason to open one; the role titles are what opens.
   Card layout (the grid itself, the baseline row, the plus mark) is specced
   in the search r2 block at the end of this file; .fline stays the shared
   colour/transition rule since the plate under it is the same in both. */
.functions .fline{display:block;margin-top:5px;font-size:var(--t-micro);font-weight:400;
  line-height:1.45;color:var(--ink-muted);max-width:54ch;transition:color 420ms var(--ease)}
.functions .qa details[open] .fline{color:var(--ink-quiet)}
/* the level legend: a plain reference, never a control. One hairline rule,
   a fixed width mono label, and the levels as quiet running text. No pill,
   no lit state, no hover or focus treatment: nothing here is clickable and
   nothing should look like it is. */
.levels{border-top:1px solid var(--hairline);padding-top:10px}
.levels-lbl{flex:0 0 auto;min-width:9ch;font-family:var(--font-b);font-size:var(--t-label);
  letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-quiet)}
.levels ul{list-style:none;margin:0;padding:0;display:flex;gap:18px;flex-wrap:wrap}
.levels li{font-family:var(--font-a);font-size:var(--t-micro);color:var(--ink-muted);cursor:default}
.sr-cap{margin-top:18px;font-size:var(--t-micro)}

/* the wall: the teams in one column, the investors beside them split by the two
   kinds of capital. Two strips rather than three peer columns, because the
   record has two kinds of entry and not three. */
.sr-wall-h{font-size:28px;max-width:30ch}
.sr-wall-h b{font-weight:500;color:var(--ink)}
.sr-wall-sub{margin-top:14px;font-size:var(--t-micro)}
/* the specificity here is deliberate: the older search page block above sets
   .companies .wall to three equal columns for the three column wall this
   section used to be, and that selector would otherwise outrank .sr-wall. */
.companies .wall.sr-wall{grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:0 56px;margin-top:34px}
.sr-wall .col > h4{margin:0 0 4px;font-family:var(--font-b);font-size:var(--t-label);
  letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);
  font-weight:400;padding:12px 0;border-bottom:1px solid var(--hairline)}
.sr-wall .col > ul{grid-template-columns:1fr}
/* The investors column carries a second level of label (Venture capital,
   Private equity) that the companies column does not, so its names started
   42px lower than the names beside them and the three lists read as three
   unrelated tables. The companies list takes the same offset: 16px of margin,
   an 11px line, and 10px of padding, the h5's own box. */
.sr-wall .col:not(.sr-inv) > ul{margin-top:calc(16px + 10px + 1.5 * 11px)}
.sr-wall li{padding-right:0}
.sr-inv-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 40px}
.sr-inv-cols > div > h5{margin:16px 0 0;padding-bottom:10px;font-family:var(--font-b);font-size:11px;
  letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-quiet);font-weight:400}
.sr-inv-cols ul{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr}
.sr-settle-h{font-size:28px}

/* the limit: the one block that costs the firm a fee, so it gets plate material
   and the reader's full width rather than a paragraph inside the record. */
.limit .h2{max-width:16ch}
.sr-limit{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:56px;align-items:start}
.sr-limit .lede{max-width:58ch}

/* the cross links in the contact tile: each route names where it goes. */
.sr-go{display:block;width:fit-content;margin-top:10px;font-size:var(--t-micro);color:var(--ink-muted);
  padding-bottom:2px;background:linear-gradient(currentColor,currentColor) no-repeat 0 100%/0 1px;
  transition:background-size 360ms var(--ease-out),color var(--dur-hover) var(--ease)}
.route:hover .sr-go,.route:focus-visible .sr-go{color:var(--ink);background-size:100% 1px}

@media (max-width:1180px){
  .sr-hero .stage{max-width:320px}
  .sr-head{grid-template-columns:minmax(0,1fr);gap:24px;align-items:start}
  .sr-limit{grid-template-columns:minmax(0,1fr);gap:22px}
  .companies .wall.sr-wall{grid-template-columns:minmax(0,1fr);gap:0}
  .sr-wall .col:not(.sr-inv) > ul{margin-top:0}
  .sr-inv{margin-top:26px}
}
@media (max-width:900px){
  .sr-inv-cols{grid-template-columns:minmax(0,1fr);gap:0}
  .sr-inv-cols > div + div > h5{margin-top:38px}
  .sr-wall-h,.sr-settle-h,.sr-phases-h{font-size:26px}
  .proof .key{padding-bottom:16px}
  /* the stacked figures line up on the left margin. The older block's
     .pstrip .cell + .cell outranks its own single class reset here, so the
     second and third figures were indented 24px on a phone. */
  .pstrip .cell + .cell{padding-left:0}
}
/* end search page, finished */

/* systems page */
/* Everything below belongs to /systems/ only. It is appended as one delimited
   block so the four pages keep one stylesheet and no page rewrites another
   page's rules. Where a component already exists on the shared layer (.plate,
   .tile, .chip, .case, .mono, .device, the scroll demo, .contact, footer) the
   page uses it and adds nothing. */

/* the hero: the same locator brain the other two service pages carry, held on
   this practice's region. Below 720 it is not drawn at all, per spec 4.1, so
   the phone gets the headline at full width and no empty square. */
.sy-hero .stage{max-width:360px;display:flex;flex-direction:column;justify-content:flex-end}
@media (max-width:719px){ .sy-hero .stage{display:none} }

/* the argument. The hook is COPY-v8 section 6's first sentence and it is the
   page's most quotable line, so it holds the left column while the diagnosis
   scrolls past it. It is set below .h2's 44px because it is a 15 word sentence
   rather than a title: at 44px in this column it breaks to nine lines. */
.sy-arg .wrap > div:first-child{position:sticky;top:calc(var(--nav-clear) + 20px)}
.sy-hook{font-size:clamp(27px,2.5vw,35px);line-height:1.14;letter-spacing:-.02em;max-width:18ch}
.sy-coda{margin:26px 0 0;color:var(--ink);max-width:44ch}

/* the model swap answer, lifted out of the body so the clause is rendered once
   on the page. The label sits BESIDE the sentence and never above it: spec
   section 3 bans a kicker over a heading, and this sentence is the block's
   whole content. */
.sy-swap{margin-top:40px;padding-top:24px;border-top:1px solid var(--hairline);
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:16px 44px;align-items:baseline}
.sy-swap .mono{margin:0;color:var(--ink-muted);white-space:nowrap}
.sy-swap p + p{margin:0;font-size:var(--t-lede);line-height:1.5;color:var(--ink);max-width:42ch}

/* the head both plates share: the heading against the sentence that frames it */
.sy-head{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:56px;align-items:start}
.sy-head .body{max-width:52ch}

/* the demo plate's footer: the substitution disclosure and the bridge down to
   the register, on one hairline */
.sy-disclosure{margin-top:48px;padding-top:26px;border-top:1px solid var(--plate-hair);
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:end}
.sy-disclosure p{margin:0;max-width:62ch;color:var(--ink-muted);font-size:var(--t-micro)}

/* ── the register ────────────────────────────────────────────────────────────
   Three kinds, each a head and then its rows. A row is a real register line
   and not a card: name and state on the left, what it is in the middle, what a
   stranger can do about it on the right, all on one hairline. The three
   columns are what makes the block auditable, because the check column can be
   read down on its own. */
.sy-kind + .sy-kind{margin-top:66px}
.register .sy-kind:first-of-type{margin-top:62px}
.sy-kind-head{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:20px 56px;align-items:baseline;
  padding-bottom:20px;border-bottom:1px solid var(--hairline)}
.sy-kind-head h3{margin:0;font-size:26px;line-height:1.15;letter-spacing:-.02em;font-weight:500;color:var(--ink)}
.sy-kind-head p{margin:0;color:var(--ink-muted);max-width:56ch}

.sy-row{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,5fr) minmax(0,4fr);gap:18px 44px;
  padding:26px 0 24px;border-bottom:1px solid var(--hairline)}
.sy-id{display:flex;flex-direction:column;align-items:flex-start;gap:11px;min-width:0}
.sy-id h4{margin:0;font-size:var(--t-lede);line-height:1.25;font-weight:500;letter-spacing:-.012em;color:var(--ink)}
.sy-say{margin:0;color:var(--ink-muted);line-height:1.6}
.sy-check{min-width:0}
.sy-check .mono{margin:0 0 9px;color:var(--ink-muted)}
.sy-check p + p{margin:0;color:var(--ink-muted);font-size:var(--t-micro);line-height:1.6}
.sy-check .link{color:var(--ink)}
.sy-kind .case{margin-top:30px}

/* ── the reader's own arithmetic ─────────────────────────────────────────────
   Subordinate to the register above by FOUNDATION 3.6, and set at a smaller
   weight because a calculator shows nothing this firm made. The result is a
   sentence rather than two labelled figures: a labelled figure invites the
   reader to read it as ours, and a sentence carrying "you entered" cannot be
   misread that way. */
.sy-fig{margin-top:84px;padding-top:34px;border-top:1px solid var(--hairline)}
.sy-fig-head{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:56px;align-items:baseline}
.sy-fig-h{margin:0;font-size:30px;line-height:1.14;letter-spacing:-.02em;font-weight:500;color:var(--ink)}
.sy-fig-head .body{margin:0;max-width:46ch}
.sy-calc{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-top:38px}
.sy-out{margin-top:34px;min-height:132px;display:grid;align-content:center;gap:14px;
  padding-bottom:28px;border-bottom:1px solid var(--hairline)}
.sy-rest{margin:0;font-size:var(--t-lede);line-height:1.5;color:var(--ink-muted);max-width:40ch}
.sy-res{margin:0;font-size:32px;line-height:1.32;letter-spacing:-.018em;color:var(--ink-muted);max-width:26ch}
.sy-res.long{font-size:28px}
.sy-res.vlong{font-size:23px;line-height:1.35}
.sy-res .num{color:var(--ink);font-weight:500}
.sy-const{margin:0;color:var(--ink-muted);font-size:var(--t-micro)}
.sy-disclose{margin:20px 0 0;color:var(--ink-muted);font-size:13px;line-height:1.55;max-width:58ch}

/* the limit: the concession holds the right column against its heading */
.sy-limit .wrap{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:64px;align-items:start}
.sy-limit .wrap > div:first-child{position:sticky;top:calc(var(--nav-clear) + 20px)}
.sy-limit .lede.big{max-width:52ch}
.sy-land{display:block;margin-top:.8em;color:var(--ink);font-weight:500}

/* contact: the named reply line sits over the partner note, so the promise and
   the face that keeps it are read together */
.sy-reply{margin:0 0 26px;padding-bottom:20px;border-bottom:1px solid var(--plate-hair);
  font-size:var(--t-lede);line-height:1.45;color:var(--ink)}

/* the cross links name where they go */
.sy-go{display:block;width:fit-content;margin-top:10px;font-size:var(--t-micro);color:var(--ink-muted);
  padding-bottom:2px;background:linear-gradient(currentColor,currentColor) no-repeat 0 100%/0 1px;
  transition:background-size 360ms var(--ease-out),color var(--dur-hover) var(--ease)}
.others .route:hover .sy-go,.others .route:focus-visible .sy-go{color:var(--ink);background-size:100% 1px}

/* ── the five step column ────────────────────────────────────────────────────
   Five states is two more than the home and search demos carry, and five open
   bodies do not fit a pinned column: measured at 798px against a 752px box on
   a 900px viewport, so the last step was cut by the fold. In the pinned layout
   each body is therefore held closed and the live one opens, which fits at any
   height and makes the step the stage is playing unmistakable rather than one
   of five paragraphs of the same weight. The stacked layout, the phone and
   every reduced motion reader still get all five bodies as a plain list, so
   nothing is hidden from a reader who cannot drive the demo. */
/* The shared window carries min-height:150px so a state cannot collapse before
   its frames decode. The health strip state draws 93px tall at this width, so
   that floor would letterbox it and print the sampled edge colours as a two
   tone mat with a seam down the middle. The engine writes an explicit height
   on every state here, so the floor is not needed on this page. */
.how-built .demo-win{min-height:0}
.how-built .demo.is-pinned .demo-steps{gap:22px}
.how-built .demo.is-pinned .demo-step{gap:0}
/* --ink-quiet measures 4.27:1 on the light plate, under the 4.5:1 floor, and a
   step title a reader has not reached yet is still a heading they have to read.
   The live step is separated by --ink at 14:1 and by the accent hairline, so
   the differentiation survives the lift. */
.how-built .demo.is-pinned .demo-step:not(.on) h3{color:var(--ink-muted)}
.how-built .demo.is-pinned .demo-step p{display:grid;grid-template-rows:0fr;opacity:0;
  transition:grid-template-rows 460ms var(--ease-out),opacity 260ms var(--ease)}
.how-built .demo.is-pinned .demo-step p > span{display:block;overflow:hidden;min-height:0}
.how-built .demo.is-pinned .demo-step.on p{grid-template-rows:1fr;opacity:1}
.how-built .demo.is-pinned .demo-step.on p > span{padding-top:10px}
@media (prefers-reduced-motion: reduce){
  .how-built .demo.is-pinned .demo-step p{transition:none}
}
html.still .how-built .demo.is-pinned .demo-step p{transition:none}

/* The stacked layout gives every state a full width device. State 2's crop is
   179 x 684, a natively portrait region, so the engine caps its drawn width by
   height and the rest of a full width shell is mat. The second step's stage is
   therefore narrowed to the portrait it holds, and the shell reads as a mount
   rather than as a screen with a strip lost in the middle of it. */
.how-built .demo.is-stacked .demo-step:nth-child(2) .demo-inline{max-width:264px}

@media (max-width:1180px){
  .sy-arg .wrap > div:first-child{position:static}
  .sy-hook{max-width:26ch}
  .sy-head,.sy-fig-head{grid-template-columns:minmax(0,1fr);gap:24px}
  .sy-kind-head{grid-template-columns:minmax(0,1fr);gap:12px}
  .sy-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px 40px}
  .sy-id{grid-column:1 / -1;flex-direction:row;align-items:center;gap:16px}
  .sy-limit .wrap{grid-template-columns:minmax(0,1fr);gap:32px}
  .sy-limit .wrap > div:first-child{position:static}
  .sy-hero .stage{max-width:320px}
}
@media (max-width:900px){
  .sy-swap{grid-template-columns:minmax(0,1fr);gap:12px}
  .sy-row{grid-template-columns:minmax(0,1fr);gap:14px;padding:24px 0 22px}
  .sy-id{flex-wrap:wrap;gap:12px}
  .sy-calc{grid-template-columns:minmax(0,1fr);gap:18px}
  .sy-fig{margin-top:62px}
  .sy-kind + .sy-kind{margin-top:52px}
  .register .sy-kind:first-of-type{margin-top:46px}
  .sy-disclosure{grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}
  .sy-out{min-height:0;margin-top:28px}
  .sy-res{font-size:26px}
  .sy-res.long{font-size:23px}
  .sy-res.vlong{font-size:20px}
}
/* end systems page */

/* second brain */
/* ── the second brain: a product section whose first proof is the instrument
   the reader has already used at the top of the page. Everything below belongs
   to the home page's #brain section only, appended as one delimited block so no
   page rewrites another page's rules.

   The brain here is the same engine as the hero, in its own 'product' mode,
   drawn straight onto the plate: no fake window chrome, no screen that holds
   its own fixed colours, so it reads the page's own tokens like the hero does
   and repaints on a theme switch. A click opens .sb-panel beside whichever
   region was clicked; its content is never new copy, only the .sb-item rows
   below and the two example readouts kept in the template above, cloned in. */

/* The section id is also the canvas id in the service page heroes, whose rule
   (position:absolute;inset:0) would lift this whole section out of the flow.
   Same stylesheet, later, one tag more specific: put it back. */
section#brain{position:relative;inset:auto;width:auto;height:auto;display:block}

.brain .sb-head{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:64px;align-items:end}
.brain .h2{max-width:18ch}
.sb-proof{margin-top:20px;font-size:var(--t-micro);line-height:1.6;color:var(--ink-muted);max-width:48ch}
.sb-note{margin-top:60px;padding-top:18px;border-top:1px solid var(--hairline);
  font-size:var(--t-micro);color:var(--ink-muted)}

/* ── the stage: the brain, its legend, its reveal panel ───────────────────── */
.sb-block{margin-top:40px;display:flex;justify-content:center}
/* 660px, the middle of the 620-680 range: the brain is the hero of its own
   section, bigger than the page hero's own 560px column, and the same
   aspect a touch taller than square that its sizing maths (REACH_X/Y) is
   tuned for. */
.sb-stage{position:relative;width:100%;max-width:660px;aspect-ratio:1/1.06}
#sbcanvas{position:absolute;inset:0;width:100%;height:100%;display:block;cursor:default}
.sb-legend{position:absolute;left:0;right:0;bottom:0;z-index:1;
  grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:640px){.sb-legend{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ── the reveal panel: a small card beside the region that was clicked,
   never centred over the canvas. .left/.right choose the corner so it never
   sits on top of the region it is explaining. --sb-legend-h is written by the
   wiring script from the legend's own measured height, so the panel clears
   the chip row instead of sitting on top of it at every width; 84px is a
   plain fallback if that write has not landed yet. */
.sb-panel{position:absolute;z-index:2;bottom:calc(var(--sb-legend-h,84px) + 16px);width:min(46%,336px);max-width:calc(100% - 32px);
  padding:17px 20px 16px;border-radius:16px;background:var(--tile);
  box-shadow:inset 0 0 0 1px var(--tile-hair),var(--el-raise);
  opacity:0;translate:0 10px;pointer-events:none;
  transition:opacity var(--dur-crossfade) var(--ease),translate 420ms var(--ease-out)}
.sb-panel.left{left:16px}
.sb-panel.right{right:16px}
.sb-panel.on{opacity:1;translate:0 0;pointer-events:auto}
.sb-panel:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.sb-panel-close{position:absolute;top:10px;right:10px;width:28px;height:28px;border-radius:50%;
  display:grid;place-items:center;padding:0;border:0;background:transparent;color:var(--ink-quiet);cursor:pointer;
  transition:color var(--dur-hover) var(--ease),background var(--dur-hover) var(--ease)}
.sb-panel-close svg{width:14px;height:14px}
.sb-panel-close:hover,.sb-panel-close:focus-visible{color:var(--ink);background:var(--tile-hair)}
.sb-panel-row + .sb-panel-row{margin-top:12px;padding-top:12px;border-top:1px solid var(--tile-hair)}
.sb-panel-row h4{margin:0 0 8px;font-size:var(--t-lede);line-height:1.3;font-weight:500;letter-spacing:-.012em;color:var(--ink)}
.sb-panel-row p{margin:0;font-size:var(--t-micro);line-height:1.6;color:var(--ink-muted)}

/* ── the illustrated answer, and the week's digest: cloned into the panel as
   is, plain (no ".over" variant here, the panel above already is the frame) */
.sb-answer{margin:0;max-width:none}
.sb-q{font-size:var(--t-micro);line-height:1.5;font-weight:500;color:var(--ink)}
.sb-a{margin-top:12px;padding-top:12px;border-top:1px solid var(--tile-hair);
  font-size:var(--t-micro);line-height:1.62;color:var(--ink-muted)}
.sb-src{margin-top:14px;padding-top:11px;border-top:1px solid var(--tile-hair)}
.sb-src-h{display:flex;align-items:center;justify-content:space-between;gap:14px;
  font-family:var(--font-b);font-size:11px;letter-spacing:var(--t-track-label);
  text-transform:uppercase;color:var(--ink-quiet)}
.sb-src-h .chip{color:var(--ink-quiet)}
.sb-source{display:flex;align-items:center;gap:11px;margin-top:9px;font-size:13px;line-height:1.4;color:var(--ink-muted)}
.sb-source::before{content:"";width:24px;height:1px;flex:none;background:var(--border)}

/* the three cells are sized to the length of their own clause, so the last one
   does not wrap alone against two single line neighbours. Cloned into the
   panel with data-at="2" always set, so every line shows lit: there is no
   beat left to page through, only the three lines at once. */
.sb-digest{margin:0;display:grid;grid-template-columns:minmax(0,1fr);gap:12px}
.sb-cell{position:relative;margin:0;padding:11px 0 0;border-top:1px solid var(--tile-hair);
  font-size:13px;line-height:1.45;color:var(--ink)}

/* ── what you get, and the one action ────────────────────────────────────── */
.sb-h3{margin-top:96px;font-size:28px;line-height:1.16;letter-spacing:-.02em;font-weight:500;max-width:34ch;text-wrap:balance}
.sb-rows{margin-top:28px;border-top:1px solid var(--hairline)}
.sb-item{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:10px 56px;
  padding:20px 0;border-bottom:1px solid var(--hairline)}
.sb-item h4{margin:0;font-size:var(--t-lede);line-height:1.35;font-weight:500;letter-spacing:-.012em;color:var(--ink)}
/* 44ch, not 58. At 58 all five rows broke with two or three words on the
   second line and the block read as five stacked widows; measured across the
   set, 44 is the widest measure where every row's second line still carries
   five words or more. The copy is untouched, only where it turns. */
.sb-item p{margin:0;color:var(--ink-muted);max-width:44ch}
.sb-foot{margin-top:46px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:32px;align-items:center}
.sb-who{margin:0;font-size:var(--t-lede);line-height:1.5;color:var(--ink);max-width:54ch}

@media (max-width:1180px){
  .brain .sb-head{grid-template-columns:minmax(0,1fr);gap:24px;align-items:start}
  .sb-h3{margin-top:76px}
}
@media (max-width:900px){
  .sb-item{grid-template-columns:minmax(0,1fr);gap:8px}
  .sb-item p{max-width:var(--measure)}
  .sb-foot{grid-template-columns:minmax(0,1fr);gap:24px;align-items:start}
  .sb-note{margin-top:48px}
  .sb-h3{margin-top:64px}
}
@media (max-width:620px){
  .sb-panel{width:calc(100% - 32px)}
  .sb-src-h{gap:10px}
}
@media (prefers-reduced-motion: reduce){
  .sb-panel{transition:none}
}
html.still .sb-panel{transition:none}
/* end second brain */

/* offer menu
   The cxo.dev mechanism: one plate that names the units of work a cheque buys,
   built entirely out of the systems register's own row component. Three rules
   only, and every value is a token already in the contract. The row title is an
   h3 rather than the register's h4 so the heading order under the section h2
   stays clean, which is the one thing .sy-id does not already style. */
.offer .sy-rows{margin-top:40px;border-top:1px solid var(--hairline)}
.offer .sy-id h3{margin:0;font-size:var(--t-lede);line-height:1.25;font-weight:500;letter-spacing:-.012em;color:var(--ink)}
.offer .sy-id .mono{color:var(--ink-muted)}
/* end offer menu */

/* search r2 */
/* S-R2: the function directory, ported from the reference FunctionsDirectory
   (ref-functions.md) rather than left as a second FAQ accordion. Layout only
   changes here: a three column card grid on hairlines, a baseline row for the
   category name and a mono "+" mark, the seat line under it. The site keeps
   its own <details>/<summary> mechanism (native keyboard support, the M12
   height-animated close already in site.js scoped to ".qa details", so no
   new JS) and its own richer per-card seat line instead of the reference's
   bare role list; the seat line is clamped to one line here so a card never
   grows taller than its neighbours before anyone opens it. Selectors carry
   ".functions .qa.fgrid" (three classes) throughout on purpose: enough
   specificity to beat the shared two-column ".qa"/".qa details" rules above
   regardless of where in the cascade this block sits. */
.functions .qa.fgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  column-gap:48px;row-gap:0;align-items:start}
.functions .qa.fgrid details{position:relative;border-top:1px solid var(--hairline);border-bottom:0;
  border-radius:0;padding:14px 0 20px;transition:border-top-color 420ms var(--ease)}
.functions .qa.fgrid details[open]{border-top-color:transparent}
/* S-R3: the reference's own hover treatment ("no background, no shadow, no
   scale") stays true for hover here, but an OPEN card still sits on the same
   stage as the Nightworld tower behind this section; with no ground of its
   own the tower rendered at full strength straight through the open panel,
   competing with the role list for attention. Opening a card now lifts the
   same flat tile ground the rest of the site uses for a raised surface,
   opacity only (no scale, no shadow), so the card holds on its own once open
   and stays a plain hairline row the rest of the time. */
.functions .qa.fgrid details::before{content:"";position:absolute;inset:-10px -16px -14px -16px;z-index:0;
  pointer-events:none;border-radius:calc(var(--radius) - 10px);background:var(--tile);
  box-shadow:inset 0 0 0 1px var(--tile-hair),inset 0 1px 0 var(--plate-hi);
  opacity:0;transition:opacity 320ms var(--ease)}
.functions .qa.fgrid details[open]::before{opacity:1}
.functions .qa.fgrid summary{display:block;padding:0;cursor:pointer;line-height:1.3}
.functions .qa.fgrid summary b{font-family:var(--font-a);font-size:var(--t-body);font-weight:500;color:var(--ink)}
.functions .qa.fgrid .fn-mark{float:right;font-family:var(--font-b);font-size:var(--t-micro);
  line-height:1.6;color:var(--ink-quiet);
  transition:transform var(--dur-hover) var(--ease-out),color var(--dur-hover) var(--ease)}
.functions .qa.fgrid details[open] .fn-mark{transform:rotate(45deg)}
/* colour only, never on touch: the hover shift is the mark brightening to
   ink, matching the site's own convention (.nav a, .route .sr-go) rather
   than the reference's teal, and the guard keeps a tap from leaving it lit. */
@media (hover:hover) and (pointer:fine){
  .functions .qa.fgrid summary:hover .fn-mark{color:var(--ink)}
}
.functions .qa.fgrid .fline{clear:both;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
@media (max-width:900px){
  .functions .qa.fgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .functions .qa.fgrid{grid-template-columns:minmax(0,1fr)}
}
@media (prefers-reduced-motion: reduce){
  .functions .qa.fgrid details::before,.functions .qa.fgrid .fn-mark{transition:none}
}
html.still .functions .qa.fgrid details::before,html.still .functions .qa.fgrid .fn-mark{transition:none}

/* S-L1: the plate's shared ambient corner wash (.plate::before, above) mixes
   in --accent at the bottom-left corner; against this plate's own light,
   warm ground that reads as an orange smear rather than a lit edge. The
   systems page also has a section named ".limit.plate" (its own "sy-limit"),
   so this is scoped to search's own marker class rather than ".limit" alone,
   and drops the wash for the "some seats shouldn't go to a search firm"
   concession card only, leaving it the flat two-stop ground the token
   contract calls for. */
.sr-limit-plate.plate::before{background:none}
/* /search r2 */

/* nightworld premium */

/* A6: below 719px (this site's own phone cutoff, the same width the hero
   brain unmounts at) the hero's text column and every later section run
   full width over the Nightworld instead of sharing it with a right hand
   stage, so the tower's window grid and the ribbons sit directly behind
   the H1, the CTA row and every later paragraph with no relation to the
   copy they're behind (measured: the dark theme phone hero showed the
   tower's lit grid squarely behind "your building" and "has to genuinely").
   The shared #veil already does exactly this job for the rest of the site
   (a scroll-linked fade to --ground); the phone dark theme just needed it
   doing harder, and doing it all the way down the page instead of
   plateauing after the first screen. Equal specificity to every other
   #veil rule in this file (a bare ID selector), appended last, so it wins
   at the 1180px and 900px tablet steps above without editing them. The
   light theme's own veil law already reaches .82 to .95 from scroll 0
   (see "light polarity, every page" above) and does not need this. */
@media (max-width:719px){
  #veil{opacity:.83}
  @supports (animation-timeline: scroll()){
    #veil{animation-name:veil-nw-phone;animation-range:0 240vh}
  }
  @supports not (animation-timeline: scroll()){ #veil{opacity:.90} }
}
@keyframes veil-nw-phone{from{opacity:.83}to{opacity:.96}}

/* S-R3: the nine function cards (.functions, the search page's own
   accordion, ported from ref-functions.md) are copy the reader opened on
   purpose, not a window onto the tower behind them. While one is open,
   anywhere on the site, dim the world a step further than the scroll
   position alone would, without the search page's own CSS having to know
   the world exists behind it. Scoped to .functions rather than to any
   <details> so the FAQ's one default-open item (every page ships with one)
   does not itself hold the hero dark from first paint.

   !important is load bearing here, not a specificity shortcut: #veil carries
   a running CSS animation (the scroll driven fade above), and the Animation
   origin outranks a plain Normal-Author declaration regardless of selector
   specificity or source order, so a bare override is silently ignored while
   the animation runs (measured: opacity stayed at the scroll value with the
   card open until this was added). Important-Author is the one origin that
   still outranks Animation, so it is the only way to top the veil up for a
   boolean state without retargeting the animation itself. */
@supports selector(:has(*)) {
  body:has(.functions details[open]) #veil{opacity:.86 !important}
}

/* A5 round 2: light theme, the Nightworld's own hero, 900px and up (the
   same breakpoint the page-wide light veil law already treats as its own
   step - see "light polarity, every page" above). The page-wide veil opens
   at .82 opacity from scroll 0 so body copy lower down the page reads over
   the world; but that same .82 sits over the hero too, where the tower,
   the water reflection and the far city are the point, not something to
   be read past. At .82, 82% of every composited pixel is the flat cream
   var(--ground) regardless of what the canvas drew there, so the shader's
   own tower-vs-sky contrast (see the "A5 round 2" comment on CUBE_FRAG in
   world-nightworld.js) only ever reached the screen at 18 cents on the
   sRGB unit: measured, the critic's capture showed the composited tower
   within 8-20 sRGB units of the sky it stands against, short of the 35 the
   brief calls for, no matter how much darker the material got.

   .72, not lower: the hero's own lede is 62%-alpha ink over this same
   canvas, and that alpha blend does not get monotonically safer as the
   world gets darker underneath it the way a solid-colour background would
   - measured across the full range, a black world under a .60-.68 veil
   still lands the lede in the high 3s to low 4s, because a dark bg pulls
   the blended (already-translucent) text down toward it at the same time.
   .72 was the value where a full-frame, sub-pixel sweep of the rendered
   hero (text hidden, every background pixel checked, not just a sample
   grid) held the lede at 4.62:1 worst-case while the tower still cleared
   the sky by 39.5 sRGB units - both with a real margin over their floors
   (4.5:1, 35 units).

   min-width:900px, not every width: below that step the hero's copy runs
   full width over the world (the stage that shares the row above 900 is
   gone, see the hero-brain-by-width rules above), so the tower sits
   directly behind the lede rather than beside it - measured, the same
   sub-pixel sweep at 375 put part of the lede's own line box over the
   tower's silhouette at 4.15:1 under this same .72, a regression the
   1440 capture never has to face. Below 900 this rule does not match, so
   the page-wide small-screen step (.86 opening to .95) is the only law on
   #veil and the phone hero keeps the coverage its own body copy needs;
   raising the tower's contrast there is left to the shader-only changes
   in world-nightworld.js, which hold at every width.

   This does not touch the page-wide law: it retargets the SAME #veil
   element's animation to its own curve, .72 at scroll 0 opening to .90 by
   100vh, the same point the page-wide curve reaches .92, so any body copy
   that has scrolled into view by then is back on the contrast the base
   rule was measured for (11.68:1 title, 10.62:1 prose there). Scoped to
   html[data-world="night"] so the brain hero variant, which never mounts
   this canvas, is untouched. Equal specificity to the base light-theme
   #veil rule (:root[data-theme] is one pseudo-class, [data-world] is one
   attribute selector, so this trades one selector kind for the other
   rather than adding weight) and appended after it in source order, so it
   wins above 900px without editing that rule. */
@media (min-width:900px){
  @supports (animation-timeline: scroll()){
    html[data-world="night"][data-theme="light"] #veil{animation-name:veil-light-nw}
  }
  @supports not (animation-timeline: scroll()){
    html[data-world="night"][data-theme="light"] #veil{opacity:.76}
  }
}
/* The hero has its own reading scrim; let daylight materials show outside it. */
@keyframes veil-light-nw{from{opacity:.28}to{opacity:.90}}

/* /nightworld premium */

/* systems r2 */
/* Titles keep a common left edge; metadata follows rather than becoming a
   kicker or pushing short headings towards the right. The product register
   has its own name/chip arrangement and is not affected. */
.offer .sy-id{flex-direction:row;align-items:baseline;gap:14px;flex-wrap:wrap}
.offer .sy-id h3{order:-1}
.offer .sy-id .mono{flex:none}
@media (max-width:900px){.offer .sy-id{gap:10px 14px}}

/* Y6/A8: systems only (search via :has() so home's identical #offer, which
   is followed by a short .firm section and was never the complaint, is
   untouched). Below the offer rows the next section is the pinned demo
   track; its .rv reveal only fires once 8% of its own (very tall) box has
   scrolled into view, so the offer's own trailing padding was stacking a
   plain, contentless wait on top of that lag. This does not own the demo
   section's height or its reveal threshold (DEMOS builder, shared site.js),
   so it only trims what this row owns: less dead scroll before the plate.
   Measured before: offer's padding-bottom var(--sec)=116px stacked with the
   plate's own 96px top pad and the reveal lag read as most of a viewport of
   black. After: 48px closes 68px of that on its own side of the seam. */
#offer:has(+ .how-built){padding-bottom:48px}
@media (max-width:900px){
  #offer:has(+ .how-built){padding-bottom:28px}
}

/* Y6/A8 cont.: the plate's own top padding (.plate's shared 96px) was the
   other half of the same dead stretch, stacked under the reveal lag site.js
   now fixes with data-rv-eager on this section (see M13 in site.js: a tall
   .rv no longer waits for 8% of its own height to clear the fold before
   revealing, only for its first edge to cross in). Trimmed on this section
   only, not .plate itself, so the register plate below and every other
   .plate on the site keep their 96px. Measured before, scrolling at 1440:
   the eager fix alone moved the reveal trigger from the section's top at
   ~410px down the viewport to ~792px, i.e. from ~260px of scroll runway
   before "Build, then leave" fully leaves the top to ~640px, so the 900ms
   fade has finished (opacity 1) well before the reader arrives instead of
   still being ~35-65% faded in on a brisk scroll. On top of that, plain
   plate padding between the two sections was still 96px settled (hbTop to
   h2 top at the row-just-left scroll position). After: 48px halves that on
   this side of the seam, matching the offer's own trimmed 48px above it, for
   a settled total of 96px of plate between the two sections, under the
   160px target. */
.how-built{padding-top:48px}

/* Y15/Y16: the calculator result and inputs. The euro sign is static markup,
   not part of fmt()'s output, so the "no currency" build-ban comment inside
   the inline script (now stale) is corrected alongside this rather than left
   to contradict the shipped markup. Hints are plain input placeholders. */
.sy-calc .fld input::placeholder{color:var(--ink-quiet)}

/* Y14: the second brain row on the register gets the same instrument the
   hero already carries, in mark mode (one core region lit, non interactive,
   the page is the destination). 84px, so it reads as a proof thumbnail next
   to the row's own check column and never competes with the real demo above
   it. mountBrain auto pauses off screen through its own IntersectionObserver
   and shares the page's one rAF via SITE.onFrame, so a second instance here
   costs nothing while it is not on screen. */
.sy-brain-mini{width:84px;aspect-ratio:1;margin:0 0 14px;border-radius:14px;overflow:hidden;isolation:isolate;
  background:radial-gradient(60% 60% at 50% 38%,color-mix(in srgb,var(--machine) 16%,transparent),transparent 72%),
    var(--tile);box-shadow:inset 0 0 0 1px var(--tile-hair)}
.sy-brain-mini canvas{width:100%;height:100%;display:block}

/* H5: the practices rail's sticky index stays pinned through the whole
   height of the taller "rows" grid cell (the spec this pattern relies on to
   work at all); with the last row's own paragraph as short as the rail's
   heading is tall, the two ran out of runway at the same moment the plate's
   own bottom padding closed in, so the outgoing sentence and the rail's idx
   list occupied the same few rows of pixels right as the rounded corner
   arrived. This does not change the sticky mechanism (shared, every page
   that uses .rail); it only gives the last row more room to finish and
   scroll fully clear of the fixed header before the plate's edge shows, so
   the two events no longer land in the same frame. Measured before: corner
   and the tail of "so you can see what leaving it alone costs." both
   readable at once at scroll 2700 (1440x900). After: padding-bottom 220px
   moves the corner about 170px later, past where that sentence has already
   cleared the header. */
.practices .rows{padding-bottom:220px}
@media (max-width:1180px){ .practices .rows{padding-bottom:120px} }
@media (max-width:900px){ .practices .rows{padding-bottom:0} }

/* A4/Y3: the systems hero's own CTA row, scoped to .sy-hero so this does not
   touch the shared .hero .cta rule the other three heroes still use. That
   rule stages the CTA row in on a fixed 1100ms delay plus a 600ms fade (the
   M1 entry choreography, not the word stream), so "Scope the work" was
   simply absent for the first 1.7s of every load. A CTA is not a headline;
   it must be a hit target from first paint. */
.sy-hero .cta{opacity:1;translate:0 0;transition:none}
/* /systems r2 */

/* Direction B: the Nightworld remains the background; hub.css composes the
   separate home brain portal. Service pages leave the world unobstructed. */
html[data-world] .sr-hero .stage,html[data-world] .fl-hero .stage,html[data-world] .sy-hero .stage{display:none !important}
.sr-hero .wrap,.fl-hero .wrap,.sy-hero .wrap{grid-template-columns:minmax(0,1fr)}
/* The home portal occupies its own row rather than covering the tower. */
html[data-world="night"] .hero .stage::before{display:none} /* the halo was for the canvas; at full width it ran 12% past the wrap */
html[data-world="night"] .hero .stage{grid-column:1 / -1;grid-row:2;aspect-ratio:auto;max-width:none;justify-self:stretch;margin-top:10px;order:0}
html[data-world="night"] .hero .legend{display:flex;flex-wrap:wrap;gap:4px 24px;border-top:1px solid var(--hairline);padding-top:12px}
html[data-world="night"] .hero .legend .chip{box-shadow:none;padding:0;min-height:30px;border-radius:0;background:none}
html[data-world="night"] .hero .routes{margin-top:26px}
html[data-world="night"] .hero .cta{margin-top:24px}
/* A4: the hero CTA row paints at once on every page */
.hero .cta{transition-delay:0ms,0ms}
/* a jump target lands under the header, not behind it */
main section[id],main .sec[id],main [id][data-beat]{scroll-margin-top:calc(var(--nav-clear) - 12px)}
/* chip states ease instead of snapping */
.legend .chip{transition:color 200ms var(--ease),background-color 200ms var(--ease),box-shadow 200ms var(--ease)}
/* /Nightworld layout */

/* fluency r2 */
/* F6: .pr is the phone's in-flow readout, one instance under each of the
   three areas' own <ul class="recog"> (see fluency/index.html), reusing that
   area's own .echo e1..e10 markup rather than new copy. The show/hide logic
   is the existing ".aimed:has(#yN:checked) .eN" rule above (.pr sits inside
   .aimed, so it already applies, no new selector needed per line); only the
   idle placeholder needs a rule here, scoped to the area's OWN radios via
   :has() on .fa so ticking one area never blanks or lights up another area's
   readout. Hidden above 719px: the sticky desktop rail is untouched. */
.pr{display:none}
.fa:not(:has(.y:checked)) .pr,.teaching-unlisted[hidden]{display:none!important}
@media (max-width:719px){
  .pr{display:block;margin-top:16px;padding:14px 16px;border-radius:14px;
    background:color-mix(in srgb,#000 20%,transparent);box-shadow:var(--rec)}
  :root[data-theme="light"] .pr{background:color-mix(in srgb,#000 5%,transparent)}
  .pr .rg-lg{width:34px}
  .pr .echo p{font-size:var(--t-micro);line-height:1.5}
  .pr .echo{grid-template-columns:minmax(0,1fr)!important}
  .pr-idle{color:var(--ink-muted);font-size:var(--t-micro);line-height:1.55}
  .fa:has(.y:checked) .pr-idle{display:none}
}
/* /fluency r2 */

/* Keep the search record readable while the Nightworld remains at its edges. */
.record > .wrap{position:relative;isolation:isolate}
.record > .wrap::before{content:"";position:absolute;inset:-24px 0;z-index:-1;pointer-events:none;background:linear-gradient(90deg,transparent,var(--ground-veil) 5%,var(--ground-veil) 95%,transparent)}

/* FAQ cards keep real inner gutters, including the first open answer.
   The function directory has its own geometry and is intentionally excluded. */
.faq .qa details{padding-inline:20px}
.faq .qa details::before{inset:0}
@media(max-width:700px){.faq .qa details{padding-inline:16px}}

/* The two products the home page no longer features. A deliberate second read
   rather than a proof band, so it opens on the reader's request. */
.other-builds{margin-top:32px;border-top:1px solid var(--hairline)}
.other-builds>summary{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:44px;padding-block:16px;cursor:pointer;list-style:none;font-size:var(--t-body)}
.other-builds>summary::-webkit-details-marker{display:none}
.other-builds>summary::after{content:"+";font-family:var(--font-b);color:var(--ink-muted)}
.other-builds[open]>summary::after{content:"\2212"}
.other-builds p{max-width:64ch;margin:0 0 16px;color:var(--ink-muted)}
.other-builds>summary:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
/* ---- footer.css ---- */
/* The closing page, not a compressed sitemap. Identity and the partner
   invitation share an upper tier; description and legal lines close below. */
footer.field{padding-top:24px;padding-bottom:32px}
footer .plate{padding:72px 0 32px}
footer .grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);grid-template-areas:'identity talk' 'where talk' 'email talk' 'navigation talk' 'description description';column-gap:96px;row-gap:8px;align-items:start}
footer .grid>div:first-child{display:contents}
footer .grid>div:first-child>.brand{grid-area:identity;width:fit-content;font-size:28px;line-height:1.25;margin-bottom:12px}
footer .brand>svg{width:24px;height:24px}
footer .where{grid-area:where;margin:0;max-width:34ch;font-size:16px;line-height:1.6}
footer .grid>div:first-child>p:not(.where):not(.blurb){grid-area:email;margin-top:8px !important}
footer .cols{grid-area:navigation;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px;margin:40px 0 0}
footer h3{margin-bottom:16px}
footer ul{gap:0}
footer ul a{display:inline-flex;align-items:center;min-height:40px;font-size:16px;line-height:1.45;padding:7px 0}
footer ul a:focus-visible{outline:2px solid var(--ink);outline-offset:4px}
footer .talk{grid-area:talk;min-height:360px;padding:44px;display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-start;border-radius:16px}
footer .talk .h2{font-size:48px;line-height:1.04;letter-spacing:-.025em;max-width:9ch;margin:0 0 28px;position:relative}
footer .talk>svg{width:68%;top:0;right:0;opacity:.65}
footer .talk>.pill{position:relative;max-width:100%}
footer .footer-prompt{font-size:16px;line-height:1.6;margin:0 0 24px;color:var(--ink-muted)}
footer .footer-partner{display:flex;align-items:center;gap:16px;margin-bottom:24px}
footer .footer-partner img{width:72px;height:72px;object-fit:cover;border-radius:16px}
footer .footer-partner p{font-size:16px;line-height:1.6;margin:0}
footer .footer-partner span{font-size:14px;color:var(--ink-muted)}
footer .footer-partner a{text-decoration:underline;text-underline-offset:3px}
footer .footer-actions{display:flex;flex-wrap:wrap;gap:12px}
footer .footer-actions .pill{font-size:14px}
footer .blurb{grid-area:description;margin:48px 0 0;padding:28px 0 0;max-width:74ch;font-size:16px;line-height:1.6;border:0}
footer .meta{margin-top:28px;padding-top:24px;gap:16px 32px;font-size:12px;line-height:1.6;align-items:baseline}
footer .meta span:nth-child(2){max-width:48ch}
@media(max-width:1050px){footer .grid{column-gap:48px}footer .talk{padding:32px;min-height:340px}footer .talk .h2{font-size:44px}}
@media(max-width:700px){
 footer.field{padding-top:8px;padding-bottom:20px}
 footer .plate{padding:40px 0 24px}
 footer .grid{grid-template-columns:minmax(0,1fr);grid-template-areas:'identity' 'where' 'email' 'navigation' 'talk' 'description';gap:8px}
 footer .grid>div:first-child>.brand{font-size:26px;margin-bottom:12px}
 footer .where{font-size:16px;max-width:28ch}
 footer .cols{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;margin-top:32px;margin-bottom:32px}
 footer h3{font-size:11px;letter-spacing:.08em;margin-bottom:12px}
 footer ul li+li a{border:0}
 footer ul a{min-height:44px;font-size:14px;line-height:1.4;padding:8px 0}
 footer .talk{min-height:300px;padding:28px}
 footer .talk .h2{font-size:44px;max-width:8ch}
 footer .talk>svg{width:72%;opacity:.7}
 footer .talk>.pill{font-size:14px}
 footer .blurb{margin-top:28px;padding-top:0;font-size:14px}
 footer .meta{margin-top:28px;display:grid;grid-template-columns:minmax(0,1fr);gap:12px;font-size:12px}
}

/* P10: the two smallest tap targets on the site. Everything else is 44px;
   these measured 39x14 and 66x15 at 375. */
footer .meta a,footer .footer-partner a{display:inline-flex;align-items:center;min-height:32px;padding-block:8px}
/* ---- contact.css ---- */
/* Ada: one quiet launcher, one bounded working surface. Component spacing tokens
   extend the site's 4/8 rhythm; colour, type, elevation and easing are inherited. */
.assistant,.assistant-inline-launch{--ada-u:4px;--ada-s:8px;--ada-m:16px;--ada-l:24px;--ada-avatar:56px;--ada-width:420px;--ada-height:560px;--ada-hit:44px;--ada-edge:24px;--ada-radius:16px;font:400 var(--t-body)/1.5 var(--font-a);color:var(--ink)}
.contact{--contact-gap:16px;--contact-action-space:24px}
.contact .convo{display:flex;flex-wrap:wrap;gap:var(--contact-gap);margin-top:var(--contact-action-space)}
.assistant{position:relative;z-index:70}
.assistant *, .assistant-inline-launch{box-sizing:border-box}
.assistant [hidden]{display:none!important}
.assistant :is(button,a,input,textarea,summary):focus-visible,.assistant-inline-launch:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.assistant :is(button,a,summary),.assistant-inline-launch{touch-action:manipulation}
.assistant button,.assistant-inline-launch{font:inherit;color:inherit;cursor:pointer;border:1px solid var(--border);border-radius:var(--ada-s);padding:var(--ada-s) calc(var(--ada-s) + var(--ada-u));min-height:var(--ada-hit);background:transparent;line-height:1.4;transition:border-color var(--dur-hover) var(--ease),background var(--dur-hover) var(--ease)}
.assistant button:disabled{cursor:wait;opacity:.6}
.assistant a{color:var(--ink);text-decoration:underline;text-underline-offset:var(--ada-u);overflow-wrap:anywhere}
.assistant p{margin:0}.assistant h2,.assistant h3{font:500 var(--t-body)/1.4 var(--font-a);letter-spacing:0;margin:0;text-transform:none}
.assistant .assistant-launcher{position:fixed;right:max(var(--ada-edge),env(safe-area-inset-right));bottom:max(var(--ada-edge),env(safe-area-inset-bottom));display:flex;gap:var(--ada-s);align-items:center;padding:0;border:0;max-width:calc(100vw - 2 * var(--ada-edge));background:none}
.assistant-avatar{display:block;width:var(--ada-avatar);height:var(--ada-avatar);flex:none;border-radius:50%;background:var(--ground);box-shadow:var(--el-raise)}
.assistant-avatar img{display:block;width:100%;height:100%;border-radius:50%}
.assistant-invitation{background:var(--ground);border:1px solid var(--border);box-shadow:var(--el-raise);border-radius:var(--ada-radius);padding:var(--ada-s) calc(var(--ada-m) + var(--ada-hit)) var(--ada-s) var(--ada-m);text-align:left}
.assistant .assistant-dismiss{position:fixed;right:calc(max(var(--ada-edge),env(safe-area-inset-right)) + var(--ada-avatar) + var(--ada-s));bottom:calc(max(var(--ada-edge),env(safe-area-inset-bottom)) + (var(--ada-avatar) - var(--ada-hit))/2);width:var(--ada-hit);height:var(--ada-hit);background:transparent;border:0;font-size:var(--t-lede);padding:0}
.assistant[data-invitation="dismissed"] :is(.assistant-invitation,.assistant-dismiss){display:none}
.assistant[data-obstructed="true"] :is(.assistant-launcher,.assistant-dismiss){visibility:hidden;pointer-events:none}
@media(max-width:600px){html{scroll-padding-bottom:96px}}
.assistant-invitation span{display:block;font-size:var(--t-micro)}
.assistant-invitation span:first-child{font-weight:500}.assistant-invitation span:last-child{color:var(--ink-muted);font-size:var(--t-label)}
.assistant-panel{position:fixed;right:max(var(--ada-edge),env(safe-area-inset-right));top:calc(var(--assistant-vtop,0px) + var(--assistant-vh,100dvh) - min(var(--ada-height),var(--assistant-vh,100dvh) - 2 * var(--ada-edge)) - var(--ada-edge));width:min(var(--ada-width),calc(100vw - 2 * var(--ada-edge)));height:min(var(--ada-height),calc(var(--assistant-vh,100dvh) - 2 * var(--ada-edge)));display:flex;flex-direction:column;min-width:0;overflow:hidden;background:var(--ground);border:1px solid var(--border);border-radius:var(--ada-radius);box-shadow:var(--el-block);isolation:isolate;animation:ada-open var(--dur-crossfade) var(--ease-out) both}
.assistant-head{display:flex;align-items:center;gap:var(--ada-s);padding:var(--ada-m);border-bottom:1px solid var(--hairline);flex:none;background:var(--raised)}
.assistant-head .assistant-avatar{--ada-avatar:40px;box-shadow:none;margin-right:var(--ada-u)}
.assistant-head>div{flex:1;min-width:0}.assistant-head #ada-identity{font-size:var(--t-label);color:var(--ink-muted)}
.assistant-head button{font-size:var(--t-label);border:0;padding:var(--ada-s)}
.assistant-head .assistant-close{font-size:var(--t-lede);min-width:var(--ada-hit)}
.assistant-scroll{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;padding:var(--ada-m);overflow-wrap:anywhere}
.assistant .assistant-note{font-size:var(--t-label);line-height:1.6;color:var(--ink-muted)}
.assistant-nav{display:flex;flex-wrap:wrap;gap:0 var(--ada-m);padding:var(--ada-s) 0 var(--ada-m);border-bottom:1px solid var(--hairline);margin-bottom:var(--ada-l)}
.assistant-nav a{font-size:var(--t-micro);min-height:var(--ada-hit);display:inline-flex;align-items:center}
.assistant-log{display:flex;flex-direction:column;gap:var(--ada-l)}
.assistant-message{flex:none;max-width:100%;font-size:var(--t-body);line-height:1.6;overflow-wrap:anywhere}
.assistant-message .assistant-speaker{font-family:var(--font-b);font-size:var(--t-label);letter-spacing:var(--t-track-label);text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--ada-s)}
.assistant-message p+p{margin-top:var(--ada-s)}
.assistant-user{margin-left:var(--ada-l);padding:var(--ada-m);background:var(--raised);border-radius:var(--ada-radius) var(--ada-radius) var(--ada-u) var(--ada-radius)}
.assistant-source{display:block;font-size:var(--t-micro);padding:var(--ada-s) 0;min-height:var(--ada-hit);margin-top:var(--ada-s)}
.assistant-message blockquote{margin:var(--ada-s) 0;padding:var(--ada-s) var(--ada-m);border-left:2px solid var(--border);white-space:pre-wrap}
.assistant-choices{display:flex;flex-wrap:wrap;gap:var(--ada-s);margin:var(--ada-m) 0}
.assistant-choices button{text-align:left;font-size:var(--t-micro);position:relative;padding-right:var(--ada-l)}
/* M6: these chips ask Ada another question on this surface. The north-east
   arrow says "you are leaving", which inverted the one affordance that matters. */
.assistant-choices button::after{content:'';position:absolute;right:var(--ada-s);top:50%;translate:0 -50%;width:6px;height:6px;border:1px solid var(--ink-muted);border-left:0;border-bottom:0;rotate:45deg}
.assistant-status{font-size:var(--t-micro);white-space:pre-wrap;line-height:1.5;margin:var(--ada-s) 0!important}.assistant-status:empty{display:none}
.assistant details{border-top:1px solid var(--hairline)}
.assistant summary{font-size:var(--t-micro);padding:var(--ada-m) 0;cursor:pointer;min-height:var(--ada-hit)}
.assistant label{display:block;font-size:var(--t-micro);line-height:1.5}
.assistant label:has(input[type=checkbox]){display:flex;align-items:flex-start;gap:var(--ada-s);padding:var(--ada-s) 0}
.assistant input[type=checkbox]{flex:none;width:18px;height:18px;accent-color:var(--ink);margin:2px 0}
.assistant :is(textarea,input[type=email]){font:400 var(--t-body)/1.5 var(--font-a);color:var(--ink);background:var(--raised);border:1px solid var(--ink-muted);border-radius:var(--ada-s);padding:var(--ada-s);width:100%;min-width:0;display:block;margin-top:var(--ada-s)}
.assistant textarea{resize:vertical;max-height:240px}.assistant textarea::placeholder{color:var(--ink-muted)}
.assistant input[type=file]{display:block;max-width:100%;font:inherit;color:var(--ink);margin:var(--ada-s) 0}
.assistant input::file-selector-button{font:inherit;color:var(--ink);background:var(--raised);border:1px solid var(--ink-muted);border-radius:var(--ada-s);min-height:var(--ada-hit);padding:var(--ada-s);margin-right:var(--ada-s);cursor:pointer}
.assistant-file pre{font:400 var(--t-micro)/1.6 var(--font-a);white-space:pre-wrap;overflow-wrap:anywhere;max-height:200px;overflow:auto;overscroll-behavior:contain;border:1px solid var(--border);padding:var(--ada-s);border-radius:var(--ada-s)}
.assistant-file button{font-size:var(--t-micro);margin:var(--ada-s) 0}
.assistant-handoff{display:flex;flex-wrap:wrap;gap:var(--ada-m);border-top:1px solid var(--hairline);margin-top:var(--ada-s);padding-top:var(--ada-s)}
.assistant-handoff button{padding:var(--ada-s) 0;border:0;text-decoration:underline;text-underline-offset:var(--ada-u);font-size:var(--t-micro)}
.assistant-draft{margin-top:var(--ada-l);padding-top:var(--ada-m);border-top:1px solid var(--border);display:grid;gap:var(--ada-m)}
.assistant-draft button{font-size:var(--t-micro)}.assistant-draft a{font-size:var(--t-micro)}
.assistant-send{display:grid;gap:var(--ada-m)}
.assistant-foot{padding:var(--ada-m);background:var(--raised);border-top:1px solid var(--hairline);flex:none}
.assistant-composer{position:relative;display:flex;align-items:end;gap:var(--ada-s);margin:0!important}
.assistant-composer label{flex:1;min-width:0;font-size:var(--t-label)}
.assistant-composer textarea{resize:none;max-height:none;background:var(--ground);padding-left:calc(var(--ada-hit) + var(--ada-s))}
.assistant-composer .assistant-attach{position:absolute;left:var(--ada-u);bottom:var(--ada-u);width:var(--ada-hit);padding:var(--ada-s);background:transparent;color:var(--ink);border:0}
.assistant-attach svg,.assistant-more svg{display:block;width:24px;height:24px}
.assistant-attach-hint{margin:var(--ada-s) 0 0;font-size:var(--t-micro);line-height:1.5;color:var(--ink-muted)}
.assistant-composer button[type="submit"]{min-width:var(--ada-hit)}
.assistant .assistant-more{font-size:var(--t-lede);min-width:var(--ada-hit)}
.assistant-options{padding-top:var(--ada-s);border-top:1px solid var(--hairline)}
.assistant-composer button{background:var(--ink);color:var(--ground);min-height:var(--ada-hit);font-size:var(--t-micro);flex:none}
.assistant-foot>.assistant-note{margin-top:var(--ada-s)}
.assistant-foot .assistant-handoff{margin:0 0 var(--ada-s);padding:0;border:0;gap:var(--ada-m)}
.assistant[data-compact="true"] .assistant-foot>.assistant-note{display:none}
.assistant-inline-launch{border-radius:999px}
@keyframes ada-open{from{opacity:0;translate:0 var(--ada-s)}to{opacity:1;translate:0 0}}
@media(hover:hover){.assistant button:not(:disabled):hover,.assistant-inline-launch:hover{border-color:var(--ink)}.assistant a:hover{text-decoration-thickness:2px}.assistant-choices button:hover{background:var(--raised)}}
@media(max-width:600px){.assistant{--ada-edge:8px}.assistant-nav{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 var(--ada-s)}.assistant-panel{top:calc(var(--assistant-vtop,0px) + var(--ada-edge));height:calc(var(--assistant-vh,100dvh) - 2 * var(--ada-edge));width:calc(100vw - 2 * var(--ada-edge));max-height:none}.assistant-head{padding:var(--ada-s) var(--ada-m)}.assistant-launcher{--ada-edge:16px}.assistant-foot{padding-bottom:max(var(--ada-m),env(safe-area-inset-bottom))}}
@media(prefers-reduced-motion:reduce){.assistant *{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

/* Compact before the first exchange; the composer stays reachable as history grows. */
.assistant[data-stage="intro"]{--ada-height:320px}
.assistant[data-stage="intro"] .assistant-choices button{font-size:var(--t-label);border-radius:999px;padding:var(--ada-s);min-height:var(--ada-hit)}
.assistant[data-stage="intro"] .assistant-choices button::after{display:none}
@media(max-width:600px){
 .assistant[data-stage="intro"] .assistant-panel{height:min(320px,calc(var(--assistant-vh,100dvh) / 2));top:calc(var(--assistant-vtop,0px) + var(--assistant-vh,100dvh) - min(320px,calc(var(--assistant-vh,100dvh) / 2)) - var(--ada-edge))}
}

/* Booking window. Same surface language as the Ada panel: one ground, one
   hairline, the site's radius and elevation. The calendar itself only appears
   after Load calendar, so nothing here implies availability of its own. */
.assistant-booking{--ada-u:4px;--ada-s:8px;--ada-m:16px;--ada-l:24px;--ada-hit:44px;--ada-edge:24px;--ada-radius:16px;
  position:fixed;inset:0;margin:auto;width:min(760px,calc(100vw - 2 * var(--ada-edge)));max-width:100%;
  max-height:min(860px,calc(100dvh - 2 * var(--ada-edge)));padding:0;overflow:auto;overscroll-behavior:contain;
  display:none;flex-direction:column;gap:var(--ada-m);
  background:var(--ground);color:var(--ink);border:1px solid var(--border);border-radius:var(--ada-radius);
  box-shadow:var(--el-block);font:400 var(--t-body)/1.6 var(--font-a)}
.assistant-booking[open]{display:flex;animation:ada-open var(--dur-crossfade) var(--ease-out) both}
.assistant-booking::backdrop{background:rgba(4,10,25,.5);backdrop-filter:blur(3px)}
.assistant-booking *{box-sizing:border-box}
.assistant-booking>*{margin-inline:var(--ada-l)}
.assistant-booking header{display:flex;align-items:center;gap:var(--ada-m);margin:0;padding:var(--ada-m) var(--ada-l);
  background:var(--raised);border-bottom:1px solid var(--hairline)}
.assistant-booking h2{flex:1;min-width:0;margin:0;font:500 var(--t-lede)/1.3 var(--font-a);letter-spacing:0;text-transform:none}
.assistant-booking p{margin:0 var(--ada-l);max-width:64ch}
.assistant-booking .assistant-note{max-width:none}
.assistant-booking button,.assistant-booking a{font:inherit;color:var(--ink);min-height:var(--ada-hit);cursor:pointer}
.assistant-booking button{appearance:none;background:transparent;border:1px solid var(--border);border-radius:var(--ada-s);
  padding:var(--ada-s) calc(var(--ada-s) + var(--ada-u));line-height:1.4;align-self:flex-start;
  transition:border-color var(--dur-hover) var(--ease),background var(--dur-hover) var(--ease)}
.assistant-booking button:hover:not(:disabled){border-color:var(--ink)}
.assistant-booking button:disabled{cursor:wait;opacity:.6}
.assistant-booking header button{flex:none;min-width:var(--ada-hit);border:0;font-size:var(--t-label);color:var(--ink-muted)}
.assistant-booking header button:hover{color:var(--ink)}
.assistant-booking a{display:inline-flex;align-items:center;text-decoration:underline;text-underline-offset:var(--ada-u);
  font-size:var(--t-micro);align-self:flex-start}
.assistant-booking [role=status]{font-size:var(--t-micro);color:var(--ink-muted)}
.assistant-booking [role=status]:empty{display:none}
.assistant-booking .assistant-cal-host{min-height:0;border-radius:var(--ada-s);overflow:hidden}
.assistant-booking .assistant-cal-host:not(:empty){min-height:520px;border:1px solid var(--hairline)}
.assistant-booking .assistant-note{font-size:var(--t-label);line-height:1.6;color:var(--ink-muted);
  padding-bottom:var(--ada-l);border-top:1px solid var(--hairline);padding-top:var(--ada-m)}
.assistant-booking :is(button,a):focus-visible{outline:2px solid var(--ink);outline-offset:3px}
@media (max-width:620px){
  .assistant-booking{--ada-edge:12px;--ada-l:16px}
  .assistant-booking .assistant-cal-host:not(:empty){min-height:440px}
}
@media (prefers-reduced-motion:reduce){.assistant-booking[open]{animation:none}}

/* B2 · the booking window before the calendar is connected. Same surface, one
   real action. Nothing here apologises for the firm; it names the route that
   works today and says the calendar is arriving. */
.assistant-booking[data-state="connecting"]{max-width:min(520px,calc(100vw - 2 * var(--ada-edge)))}
.assistant-booking[data-state="connecting"] p:not(.assistant-note){padding-top:var(--ada-s)}
.assistant-booking .assistant-booking-primary{align-self:flex-start;margin-block:var(--ada-s) var(--ada-l);
  padding:var(--ada-s) var(--ada-l);min-height:var(--ada-hit);border-radius:999px;
  background:var(--ink);color:var(--ground);text-decoration:none;font-size:var(--t-body);font-weight:500}
.assistant-booking .assistant-booking-primary:hover{opacity:.88}

/* B6 · the source, opened inside the answer. */
.assistant-source{border-top:1px solid var(--hairline);margin-top:var(--ada-m)}
.assistant-source>summary{font-size:var(--t-micro);color:var(--ink-muted)}
.assistant-source>summary:hover{color:var(--ink)}
.assistant-source-body{padding-bottom:var(--ada-m);display:grid;gap:var(--ada-s)}
.assistant-source-body blockquote{margin:0;padding:var(--ada-s) var(--ada-m);border-left:2px solid var(--border);
  font-size:var(--t-micro);line-height:1.6}
.assistant-source-away{display:inline-flex;align-items:center;min-height:var(--ada-hit);font-size:var(--t-micro)}

/* M5 · the firm's main intake route had 9% of a 1440x900 screen, and 46% of a
   two-turn conversation was out of sight with no cue that anything was above.
   Once a conversation exists the panel takes the height it needs, the top edge
   fades when there is history above it, and the scrollbar is visible. */
.assistant[data-stage="active"]{--ada-height:min(760px,calc(var(--assistant-vh,100dvh) - 2 * var(--ada-edge)))}
@media(min-width:900px){.assistant{--ada-width:480px}}
.assistant-scroll{scrollbar-color:var(--ink-muted) transparent}
.assistant[data-scrolled="true"] .assistant-scroll{mask-image:linear-gradient(to bottom,transparent 0,#000 28px)}
