/* Forma DJR is licensed per-project from DJR (djr.com). No file is on this
   machine yet, so the stack below falls through to Helvetica Neue and the hero
   is set in the fallback. Drop FormaDJRBanner-Bold.woff2 and -Medium.woff2 into
   assets/fonts/, uncomment this block, and the real face takes over everywhere
   with no other change. Left commented so the console stays free of 404s.

@font-face{
  font-family:"Forma DJR Banner";
  src:url("fonts/FormaDJRBanner-Bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Forma DJR Banner";
  src:url("fonts/FormaDJRBanner-Medium.woff2") format("woff2");
  font-weight:500;font-style:normal;font-display:swap;
}
*/

:root{
  --beige:#EBE4D6;
  --beige-deep:#E2DACA;
  --bone:#F4EFE3;
  --panel:#F1EBDE;
  --black:#141210;
  --black-hover:#2A2520;
  --muted:#5C5449;
  --muted-inv:#A69C8C;
  --rule:#CBC2B0;
  --rule-inv:#2E2A25;
  --link-rule:#5C5449;
  --focus:#141210;

  --font-display:"Forma DJR Banner","Helvetica Neue","Inter","Arial Nova",Arial,sans-serif;
  --font-deck:"Forma DJR Deck","Helvetica Neue","Inter","Arial Nova",Arial,sans-serif;
  --font-text:"Forma DJR Text","Helvetica Neue","Inter","Arial Nova",Arial,sans-serif;

  --fs-hero:clamp(2.5rem,6.8vw,6.25rem);
  --fs-h2:clamp(2.125rem,5.2vw,4.5rem);
  --fs-h3:clamp(1.3125rem,2.1vw,1.875rem);
  --fs-lead:clamp(1.1875rem,2vw,1.6875rem);
  --fs-body:clamp(1rem,1.15vw,1.1875rem);
  --fs-meta:0.75rem;

  --gutter:clamp(1.5rem,5vw,4rem);
  --section:clamp(6rem,13vw,13rem);
  --sp-1:clamp(1rem,1.6vw,1.5rem);
  --sp-2:clamp(1.5rem,2.6vw,2.25rem);
  --sp-3:clamp(2.25rem,4vw,3.5rem);
  --sp-4:clamp(3rem,6vw,5.5rem);
  --maxw:1120px;
  --nav-h:72px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-padding-top:calc(var(--nav-h) + 1.5rem)}
body{
  margin:0;background:var(--beige);color:var(--black);
  font-family:var(--font-text);font-size:var(--fs-body);
  line-height:1.6;letter-spacing:-0.006em;font-weight:400;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;hyphens:none;
}
h1,h2,h3,p,ul,ol,figure,dl,dd,dt{margin:0}
ul{list-style:none;padding:0}
a{color:inherit}
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}

:focus-visible{outline:2px solid var(--focus);outline-offset:3px;border-radius:2px}
.band{--focus:var(--bone)}
.skip{--focus:var(--black)}
main:focus{outline:none}

.skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--black);color:var(--bone);
  padding:0.75rem 1.25rem;font-size:var(--fs-meta);
  letter-spacing:0.13em;text-transform:uppercase;
}
.skip:focus{left:var(--gutter);top:0.75rem}

/* ---------- shared type ---------- */
.meta{
  font-family:var(--font-text);font-size:var(--fs-meta);font-weight:500;
  letter-spacing:0.13em;text-transform:uppercase;line-height:1.2;color:var(--muted);
}
.h2{
  font-family:var(--font-deck);font-size:var(--fs-h2);font-weight:500;
  letter-spacing:-0.035em;line-height:0.94;text-wrap:balance;max-width:17ch;
}
.lead{
  font-family:var(--font-deck);font-size:var(--fs-lead);font-weight:400;
  letter-spacing:-0.014em;line-height:1.34;max-width:46ch;
}

/* ---------- nav ---------- */
.nav{
  position:sticky;top:0;z-index:50;background:var(--beige);
  border-bottom:1px solid transparent;transition:border-color .25s ease;
}
.nav.is-stuck{border-bottom-color:var(--rule)}
.nav__inner{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;min-height:var(--nav-h)}
.wordmark{
  font-family:var(--font-deck);font-size:clamp(1.0625rem,1.5vw,1.25rem);
  font-weight:500;letter-spacing:-0.03em;text-decoration:none;white-space:nowrap;
}
.nav__links{display:flex;align-items:center;gap:clamp(1rem,2.4vw,2rem)}
.nav__link{
  font-size:0.9375rem;letter-spacing:-0.006em;text-decoration:none;
  padding-block:0.25rem;border-bottom:1px solid transparent;
}
.nav__link:hover{border-bottom-color:var(--black)}
@media (max-width:430px){
  .nav .btn--sm{display:none}
  .nav__links{gap:1.25rem}
}

/* ---------- button ---------- */
.btn{
  display:inline-block;background:var(--black);color:var(--bone);
  font-family:var(--font-text);font-size:1.0625rem;font-weight:500;
  letter-spacing:-0.01em;line-height:1;padding:1.125rem 2.125rem;
  border-radius:999px;text-decoration:none;white-space:nowrap;
  transition:background-color .18s ease,transform .18s ease;
}
.btn:hover{background:var(--black-hover);transform:translateY(-1px)}
.btn--sm{font-size:0.9375rem;padding:0.6875rem 1.375rem}
.btn--inv{background:var(--bone);color:var(--black)}

/* Brushed-metal sheen on the primary button. The canvas sits under the label
   and is inert to the pointer, so the button behaves exactly as it did — with
   no WebGL, or under reduced motion, nothing mounts and it stays a flat
   black button. */
.btn{position:relative;isolation:isolate}
.btn > *{position:relative;z-index:1}
.metal{position:absolute;inset:0;width:100%;height:100%;display:block;
  border-radius:inherit;pointer-events:none;z-index:0}
/* The seal is a disc, so its sheen has to be clipped to a disc — a square
   canvas over a round mark shows its corners the moment the light reaches them. */
/* The sheen hangs on a wrapper that hugs the mark, not on .rail__seal — that
   one is a flex item the rail stretches to 540px tall, and a disc drawn into a
   tall box is an ellipse. */
.seal-metal{position:relative;isolation:isolate;display:block;aspect-ratio:1}
.seal-metal .metal{border-radius:50%;mix-blend-mode:screen}
.seal-metal > svg{position:relative;z-index:1;display:block;width:100%;height:auto}
.btn--inv:hover{background:#FBF7EE}
.textlink{
  font-size:1.0625rem;text-decoration:none;
  border-bottom:1px solid var(--link-rule);padding-bottom:5px;
  transition:border-color .18s ease;
}
.textlink:hover{border-bottom-color:var(--black)}

/* ---------- section frame ---------- */
.section{padding-block:var(--section)}
.section + .section{border-top:1px solid var(--rule)}
.section__head{margin-bottom:var(--sp-4)}
.section__head .meta{margin-bottom:var(--sp-1)}
.section__head .lead{margin-top:var(--sp-2);color:var(--muted)}
.section--deep{background:var(--beige-deep)}

/* Feature grid on ink. The cards carry the light ground instead of the page,
   so all the pale artwork already inside them keeps working untouched — only
   the surround inverts. Focus flips to bone for the same reason .band does. */
.section--ink{background:var(--black);color:var(--bone);--focus:var(--bone)}
.section--ink .meta{color:var(--muted-inv)}

/* ---------- feature cards ---------- */
/* Six columns so the row runs 2+2+2 then 3+3 — what stops a feature grid
   reading as five identical boxes. Cards are deliberately shallow: the copy
   is short enough that a tall card would just be padding. */
.bento--feat{display:grid;grid-template-columns:repeat(6,1fr);gap:clamp(0.75rem,1.1vw,1rem)}
.feat{
  background:var(--bone);color:var(--black);
  border-radius:22px;overflow:hidden;
  padding:clamp(1.25rem,1.8vw,1.625rem);
  display:flex;flex-direction:column;gap:0.625rem;
  transition:transform .45s cubic-bezier(.2,.7,.2,1);
}
.feat:hover{transform:translateY(-3px)}
.feat--span2{grid-column:span 2}
.feat--span3{grid-column:span 3}
.feat__role{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);margin-bottom:-0.25rem;
}
.feat__title{
  font-family:var(--font-deck);font-size:clamp(1.0625rem,1.35vw,1.25rem);font-weight:500;
  letter-spacing:-0.022em;line-height:1.15;text-wrap:balance;
}
.feat__body{color:var(--muted);font-size:clamp(0.875rem,0.95vw,0.9375rem);line-height:1.5;max-width:34ch}

/* ---------- the animated figures ---------- */
.fig{margin:0 0 0.25rem;height:76px;display:flex;align-items:center;justify-content:center}
.fig svg{width:auto;height:100%;overflow:visible}
.fig svg rect,.fig svg circle,.fig svg path{fill:none;stroke:var(--black);stroke-width:2}
.fig__core{fill:var(--black);stroke:none}
.fig__ring{stroke:var(--rule);opacity:.4}
.fig__lens{stroke-width:2.5}
.fig__stem{stroke-width:2.5;stroke-linecap:round}
.fig__track{stroke:var(--rule);stroke-width:2;stroke-linecap:round}
.fig__node{fill:var(--rule);stroke:none}
.fig__node--end{fill:var(--black)}
.fig__runner{fill:var(--black);stroke:none;opacity:1;
  /* parked on the path, so it is somewhere sensible even if nothing animates */
  offset-path:path("M22 54 C22 24 46 20 60 32 C74 44 98 40 98 22");offset-distance:62%}

/* Nothing moves until the card has actually arrived — .is-in comes from the
   same stagger that reveals the rest of the page. */
.is-in .fig__conv rect{animation:figConverge 3.4s cubic-bezier(.6,0,.2,1) infinite}
.is-in .fig__conv rect:nth-child(2){animation-delay:.08s}
.is-in .fig__conv rect:nth-child(3){animation-delay:.16s}
.is-in .fig__conv rect:nth-child(4){animation-delay:.24s}
@keyframes figConverge{
  0%,12%   {transform:translate(0,0);opacity:1}
  46%,62%  {transform:translate(var(--dx,0),var(--dy,0));opacity:0}
  92%,100% {transform:translate(0,0);opacity:1}
}
.fig__conv rect{transform-box:fill-box;transform-origin:center}
.fig__conv rect:nth-child(1){--dx:39px;--dy:15px}
.fig__conv rect:nth-child(2){--dx:-39px;--dy:15px}
.fig__conv rect:nth-child(3){--dx:39px;--dy:-15px}
.fig__conv rect:nth-child(4){--dx:-39px;--dy:-15px}
.is-in .fig__core{animation:figCore 3.4s cubic-bezier(.6,0,.2,1) infinite}
@keyframes figCore{0%,30%{transform:scale(.2);opacity:0}52%,64%{transform:scale(1);opacity:1}86%,100%{transform:scale(.2);opacity:0}}
.fig__core{transform-box:fill-box;transform-origin:center}

.is-in .fig__ring{animation:figPing 2.8s ease-out infinite}
.is-in .fig__ring--b{animation-delay:1.4s}
@keyframes figPing{0%{transform:scale(.55);opacity:.9}70%,100%{transform:scale(2.2);opacity:0}}
.fig__ring{transform-box:fill-box;transform-origin:center}
.is-in .fig__lens,.is-in .fig__stem{animation:figSweep 2.8s ease-in-out infinite}
@keyframes figSweep{0%,100%{transform:translate(-3px,2px)}50%{transform:translate(3px,-2px)}}

/* The runner is drawn along the path itself, so it follows the curve rather
   than a straight tween between two points. */
.is-in .fig__runner{animation:figRun 3s cubic-bezier(.45,0,.25,1) infinite}
@keyframes figRun{0%{offset-distance:0%;opacity:0}10%{opacity:1}90%{opacity:1}100%{offset-distance:100%;opacity:0}}
.is-in .fig__node--end{animation:figArrive 3s cubic-bezier(.45,0,.25,1) infinite}
@keyframes figArrive{0%,80%{r:3.5}90%{r:6}100%{r:3.5}}

/* the portal list: rows tick over one at a time, like something refreshing */
.fig--sm{height:44px;justify-content:flex-start;margin-bottom:.5rem}
.fig--sm svg{height:100%}
.fig__orbit-ring{stroke:var(--rule);stroke-width:2;stroke-dasharray:3 5}
.fig__sat{fill:var(--black);stroke:none}
.fig__refresh{stroke:var(--black);stroke-width:3;stroke-linecap:round}
.fig__tip{stroke:var(--black);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;fill:none}
.is-in .fig__orbit{animation:figOrbit 7s linear infinite;transform-origin:32px 32px}
@keyframes figOrbit{to{transform:rotate(360deg)}}
.is-in .fig__refresh,.is-in .fig__tip{animation:figSpin 7s cubic-bezier(.7,0,.3,1) infinite;
  transform-origin:32px 32px}
@keyframes figSpin{0%,55%{transform:rotate(0)}85%,100%{transform:rotate(360deg)}}

.fig--rows{display:flex;flex-direction:column;align-items:stretch;justify-content:center;gap:0;
  border-top:1px solid var(--rule)}
.fig__row{display:flex;align-items:baseline;justify-content:space-between;gap:.75rem;
  padding:.5rem .125rem;border-bottom:1px solid var(--rule)}
.fig__row b{font-family:var(--font-text);font-size:.8125rem;font-weight:500;letter-spacing:-0.01em}
.fig__row i{font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);font-style:normal;text-align:right}
/* No animation on these rows. They are a spec list; blinking text reads as a
   fault, not as motion. The card's movement lives in its icon instead. */

/* the four of us: each face lifts in turn */

/* The four of them ORBIT the ring rather than sitting inside it. Each portrait
   rides the same ellipse on offset-path, spaced a quarter of a lap apart, and
   scales down as it passes the far side so the ring reads as a plane in space
   rather than a flat circle. Fixed pixel size on purpose: offset-path takes
   absolute coordinates, so a fluid box would break the geometry. */
.orbit{position:relative;width:190px;height:120px;margin:0 auto;flex:none;
  transform:rotate(-13deg);transform-origin:center}
.orbit__ring{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
/* The ring has to be readable as a track, otherwise the portraits look like
   they are drifting rather than running in a groove. Darker than --rule, and
   it sits at z-index 1 so a face at the back passes BEHIND the line and a face
   at the front passes in front of it. That crossing is the whole illusion. */
.orbit__ring{z-index:1}
.orbit__band{fill:none;stroke:var(--muted);opacity:.42;stroke-width:1.4;vector-effect:non-scaling-stroke}
.orbit__band--far{stroke-dasharray:2 5;opacity:.26}
.orbit__face{
  position:absolute;left:0;top:0;width:38px;height:38px;border-radius:999px;
  object-fit:cover;margin:-19px 0 0 -19px;   /* centre the portrait on the path */
  background:var(--panel);box-shadow:0 0 0 3px var(--bone);
  offset-path:path("M173 60 A78 28 0 1 1 17 60 A78 28 0 1 1 173 60");
  offset-rotate:0deg;offset-distance:0%;
}
.is-in .orbit__face{animation:orbitRun 22s linear infinite}
.is-in .orbit__face:nth-of-type(2){animation-delay:-5.5s}
.is-in .orbit__face:nth-of-type(3){animation-delay:-11s}
.is-in .orbit__face:nth-of-type(4){animation-delay:-16.5s}
/* The path runs clockwise from the right edge, so 25% is the BOTTOM of the
   ellipse — nearest the viewer — and 75% is the top, furthest away. The scale
   and z-index were the wrong way round: the near face was being shrunk and
   pushed back, the far one blown up and brought forward. */
@keyframes orbitRun{
  0%   {offset-distance:0%;   transform:scale(1);    opacity:1;   z-index:2}
  25%  {offset-distance:25%;  transform:scale(1.18); opacity:1;   z-index:3}  /* front */
  50%  {offset-distance:50%;  transform:scale(1);    opacity:1;   z-index:2}
  75%  {offset-distance:75%;  transform:scale(.72);  opacity:.68; z-index:0}  /* behind the ring */
  100% {offset-distance:100%; transform:scale(1);    opacity:1;   z-index:2}
}
@media (max-width:680px){.orbit{margin-inline:auto}}


.fig__face img{width:2.25rem;height:2.25rem;border-radius:999px;object-fit:cover;
  border:1px solid var(--rule);background:var(--panel);display:block}
.fig__face i{font-family:var(--font-text);font-size:.75rem;font-weight:500;font-style:normal;
  border:1px solid var(--rule);border-radius:6px;padding:.125rem .375rem;background:var(--panel)}
.is-in .fig__face{animation:figLift 5s ease-in-out infinite}
.is-in .fig__face:nth-child(2){animation-delay:.3s}
.is-in .fig__face:nth-child(3){animation-delay:.6s}
.is-in .fig__face:nth-child(4){animation-delay:.9s}
@keyframes figLift{0%,72%,100%{transform:translateY(0)}80%{transform:translateY(-4px)}}

/* ---------- the portal that stays current ----------
   The motion is the whole point of the card: the contents of the window keep
   being replaced. Rows step up one at a time, a fresh one arrives from below,
   and the corner light blinks the moment it lands. Nothing scrolls smoothly —
   a steady glide reads as "busy", where a hold-then-step reads as "updated". */
.fig svg .fig__bar{fill:var(--black);stroke:none;opacity:.24}
.fig svg .fig__win{stroke-width:2}
.fig svg .fig__pip{fill:var(--bone);stroke:var(--black);stroke-width:2;
  transform-box:fill-box;transform-origin:center}

.is-in .fig__feed{animation:figFeed 8s cubic-bezier(.6,0,.2,1) infinite}
/* Eight rows, widths repeating every four, travelling exactly four rows per
   cycle — so the frame at 100% is identical to the frame at 0% and the loop
   has no seam. */
@keyframes figFeed{
  0%,17%   {transform:translateY(0)}
  25%,42%  {transform:translateY(-16px)}
  50%,67%  {transform:translateY(-32px)}
  75%,92%  {transform:translateY(-48px)}
  100%     {transform:translateY(-64px)}
}
/* One flash per arrival: 2s into an 8s feed, four times over. */
.is-in .fig__pip{animation:figPip 2s cubic-bezier(.4,0,.2,1) infinite}
@keyframes figPip{
  0%,5%    {fill:var(--black);transform:scale(1.3)}
  34%,100% {fill:var(--bone); transform:scale(1)}
}

.feat--split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1rem,1.6vw,1.5rem);align-items:center}
.feat--split .feat__side{display:flex;flex-direction:column;justify-content:center}
.feat--split .feat__title + .feat__body,
.feat--split .feat__side > div > .feat__title + .feat__body{margin-top:0.5rem}

/* The glyph stays a fixed band on purpose. Letting it absorb the row's leftover
   height pushed each card's label to a different line — and three parallel role
   cards want their labels on one line far more than they want their text pinned
   to the floor. The slack sits at the bottom, where a filled card hides it. */

@media (max-width:1000px){
  .bento--feat{grid-template-columns:repeat(3,1fr)}
  .feat--span2{grid-column:span 1}
  .feat--span3{grid-column:span 3}
  /* An even split wasted the whole right half on a small glyph and squeezed the
     copy into a narrow column. Give the words the room. */
  .feat--split{grid-template-columns:1.35fr 0.65fr}
}
@media (max-width:680px){
  .bento--feat{grid-template-columns:1fr}
  .feat--span2,.feat--span3{grid-column:1 / -1}
  .feat--split{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  .feat{transition:none}
  .feat:hover{transform:none}
  /* every figure holds its resting frame */
  .fig__conv rect,.fig__core,.fig__ring,.fig__lens,.fig__stem,
  .fig__runner,.fig__node--end,.fig__row,.fig__face,
  .fig__feed,.fig__pip,.orbit__face{animation:none !important}
  .fig__core{opacity:1;transform:none}
}



/* ---------- hero ---------- */
.hero{position:relative;overflow:hidden;padding-block:clamp(3.5rem,8vw,7rem)}
.hero .wrap{position:relative;z-index:1}
.hero__h1{
  font-family:var(--font-display);font-size:var(--fs-hero);font-weight:500;
  letter-spacing:-0.045em;line-height:0.90;max-width:min(23ch,78%);text-wrap:balance;
}
.hero__sub{margin-top:var(--sp-3);color:var(--muted);max-width:52ch}
.hero__cta{margin-top:var(--sp-3);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
@media (max-width:900px){
  .hero__h1{max-width:100%}
  .hero__sub{max-width:100%}
}

/* ---------- mascot ---------- */
/* `.mascot` is only a JS hook — it must carry no layout, or anything that
   opts into eye-tracking (the rail seal, the studio lineup) inherits the
   hero's absolute positioning. Layout belongs to the placement classes. */
.mascot{pointer-events:none;user-select:none}
.mascot__eye{transition:transform .12s linear}

/* ---------- who it is for ---------- */
.who{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
/* Grid items default to min-width:auto, so the 900px-wide poster in column
   02 set that column's minimum and crushed column 01 to one word per line. */
.who__col{min-width:0}

/* The right column runs shorter than the left, so it carries the one piece of
   media in this section rather than leaving the page to fall away. The video
   sits on top of its own poster and fades in once it can actually play. */
.who__media{margin:var(--sp-4) 0 0;position:relative}
/* The portrait sits closer to the line it follows than a normal media block
   would — at a full section gap it read as a separate thing. */
.who__media--portrait{margin-top:var(--sp-2)}

/* The portrait panel is dark on purpose: the falling front reads as a glow,
   and bone points on ink is the only way that lands without adding a colour. */
/* Free-form: no panel, no card, no rounded box. The photograph's backdrop is
   the same beige as the page, so once it is dropped the four of them stand on
   the page itself rather than inside a rectangle. */
/* Bigger than its column: it breaks out to the right, into the panel's own
   padding, so the four of them are not boxed in by the text measure. */
.portrait{position:relative;display:block;aspect-ratio:3/2;background:none;
  /* Full width of the panel now — it sits below both columns rather than
     inside one, so it is no longer bound by the text measure. */
  width:100%;margin-top:0}

.portrait canvas{display:block;width:100%;height:100%}
/* The photograph is never shown. The four of them are supposed to arrive
   because the rain draws them, so a picture sitting there first — even for a
   moment before the cloud is built — gives the whole thing away.
   It stays in the markup for one reason: with no JS, or no WebGL, there would
   otherwise be nothing at all. In those two cases only, it appears. */
.portrait__fallback{
  position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  opacity:0;
}
html:not(.js) .portrait__fallback,
.portrait--nogl .portrait__fallback{opacity:1}
@media (prefers-reduced-motion:reduce){
  .portrait__fallback{transition:none}
}
.who__media img,.who__media video{display:block;width:100%;max-width:100%;height:auto;
  border-radius:14px;background:var(--rule)}
/* Cover the poster only, not the whole figure — inset:0 would put the video
   over the caption as well. */
.who__media video{position:absolute;top:0;left:0;aspect-ratio:900/506;object-fit:cover;
  opacity:0;transition:opacity .6s ease}
.who__media video.is-on{opacity:1}
.who__cap{position:relative;margin:.625rem 0 0;font-family:var(--font-mono);font-size:.6875rem;
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.who__col > .meta{margin-bottom:var(--sp-1)}
/* Both headings reserve the same three lines, so the two columns start their
   body copy on the same line however the headings happen to wrap. Without it
   a two-line heading beside a three-line one throws every paragraph below it
   out of step. */
.who__title{
  min-height:calc(3 * 1.12em);
  font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;
  letter-spacing:-0.022em;line-height:1.1;margin-bottom:var(--sp-1);
}
.who__body{color:var(--muted);max-width:52ch}
.who__body + .who__body{margin-top:1rem}
/* The line that resolves both columns sits under both of them, at lead size —
   burying it in one column made it read as that column's conclusion. */
.who__close{
  margin-top:var(--sp-4);max-width:56ch;
  font-family:var(--font-deck);font-size:var(--fs-lead);
  letter-spacing:-0.014em;line-height:1.34;color:var(--black);
}
@media (max-width:900px){.who{grid-template-columns:1fr;gap:var(--sp-3)}}

/* The old .bento/.cell grid lived here and is gone: no page used .cell, and its
   .bento rule sat later in the file at equal specificity to .bento--feat — so
   it quietly won the column count on the live feature grid, which is why three
   cards kept landing as two-plus-an-orphan. */

/* ---------- method ---------- */
.method{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3)}
.step{border-top:1px solid var(--rule);padding-top:var(--sp-1)}
.step__num{margin-bottom:var(--sp-1)}
.step__name{
  font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;
  letter-spacing:-0.022em;line-height:1.1;margin-bottom:0.875rem;
}
.step__body{color:var(--muted)}
.method__coda{
  margin-top:var(--sp-4);font-family:var(--font-deck);font-size:var(--fs-lead);
  letter-spacing:-0.014em;line-height:1.34;max-width:38ch;margin-left:auto;text-align:right;
}
@media (max-width:820px){
  .method{grid-template-columns:1fr}
  .method__coda{margin-left:0;text-align:left;max-width:46ch}
}

/* ---------- proof ---------- */
.ventures{border-top:1px solid var(--rule)}
.section--deep .ventures,.section--deep .venture{border-color:#C2B9A6}
.venture{
  display:grid;grid-template-columns:minmax(0,4fr) minmax(0,7fr);
  gap:clamp(1rem,4vw,3rem);padding-block:clamp(1.5rem,2.6vw,2.125rem);
  border-bottom:1px solid var(--rule);align-items:baseline;
}
.venture__name{font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;letter-spacing:-0.022em}
.venture__desc{color:var(--muted)}
.venture__desc a{color:inherit;text-decoration:none;border-bottom:1px solid var(--link-rule)}
.venture__desc a:hover{color:var(--black);border-bottom-color:var(--black)}
.honesty{margin-top:var(--sp-3);color:var(--muted);max-width:58ch}
@media (max-width:760px){.venture{grid-template-columns:1fr;gap:0.5rem}}

/* ---------- the path (black band) ---------- */
.band{background:var(--black);color:var(--bone);padding-block:var(--section);border-top:1px solid var(--rule)}
.band .meta{color:var(--muted-inv)}
.band .lead{color:var(--muted-inv)}
.path{border-top:1px solid var(--rule-inv)}
.stage{
  display:grid;grid-template-columns:auto minmax(0,4fr) minmax(0,7fr);
  gap:clamp(1rem,3vw,2.5rem);padding-block:var(--sp-2);
  border-bottom:1px solid var(--rule-inv);align-items:baseline;
}
.stage__num{color:var(--muted-inv);min-width:2.5rem}
.stage__name{font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;letter-spacing:-0.022em;line-height:1.1}
.stage__body{color:var(--muted-inv);max-width:60ch}
@media (max-width:820px){
  .stage{grid-template-columns:1fr;gap:0.5rem}
  .stage__num{margin-bottom:0.25rem}
}
.band__close{
  margin-top:var(--sp-4);padding-top:var(--sp-3);border-top:1px solid var(--rule-inv);
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);flex-wrap:wrap;
}
.band__oneline{font-family:var(--font-deck);font-size:var(--fs-lead);letter-spacing:-0.014em;line-height:1.34;max-width:42ch}

/* ---------- faq ---------- */
.faq{border-top:1px solid var(--rule)}
.faq__item{border-bottom:1px solid var(--rule);padding-block:var(--sp-2)}
.faq__q{
  font-family:var(--font-deck);font-size:clamp(1.1875rem,1.7vw,1.5rem);font-weight:500;
  letter-spacing:-0.022em;line-height:1.15;margin-bottom:0.75rem;max-width:40ch;
}
.faq__a{color:var(--muted);max-width:66ch}

/* ---------- close ---------- */
.close__h2{
  font-family:var(--font-deck);font-size:clamp(2.75rem,7vw,6rem);font-weight:500;
  letter-spacing:-0.038em;line-height:0.92;max-width:14ch;
}
.close__body{margin-top:var(--sp-3);color:var(--muted)}
.close__cta{margin-top:var(--sp-3);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.close__email{
  font-family:var(--font-deck);font-size:var(--fs-lead);letter-spacing:-0.014em;
  text-decoration:none;border-bottom:1px solid var(--link-rule);padding-bottom:5px;
}
.close__email:hover{border-bottom-color:var(--black)}

/* ---------- footer ---------- */
.footer{border-top:1px solid var(--rule);padding-block:2rem}
.footer__inner{display:flex;justify-content:space-between;gap:1.5rem;flex-wrap:wrap}
.footer a{text-decoration:none;border-bottom:1px solid transparent}
.footer a:hover{border-bottom-color:var(--muted)}

/* ---------- centred statement (content-five shape) ---------- */
.statement{max-width:44ch;margin-inline:auto;text-align:center}
.statement .h2{max-width:none;margin-inline:auto}
.statement__body{margin-top:var(--sp-2);color:var(--muted)}

/* ---------- the studio ---------- */
/* Ground is beige-deep, not panel: the figures are bone (#F2ECE0) and would
   disappear against the panel tone. */
.lineup{
  margin-top:var(--sp-4);background:var(--beige-deep);border:1px solid var(--rule);
  border-radius:10px;padding:clamp(2rem,4vw,3.5rem) clamp(1rem,3vw,2.5rem);
  display:flex;align-items:flex-end;justify-content:center;
  gap:clamp(0.75rem,3vw,2.75rem);
}
.mascot--row{height:clamp(120px,17vw,208px);width:auto;flex:none;position:static;transform:none;display:block}
.traits{
  margin-top:var(--sp-4);display:grid;grid-template-columns:repeat(4,1fr);
  gap:var(--sp-2) clamp(1rem,2.5vw,2.5rem);
}
.trait__head{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.625rem}
.trait__head svg{width:16px;height:16px;flex:none}
.trait__name{font-family:var(--font-deck);font-size:1.0625rem;font-weight:500;letter-spacing:-0.018em}
.trait__body{font-size:0.9375rem;line-height:1.55;color:var(--muted)}
@media (max-width:820px){.traits{grid-template-columns:repeat(2,1fr)}}
@media (max-width:480px){.traits{grid-template-columns:1fr}}

/* ---------- split (content-seven shape) ---------- */
/* ---------- what we do ---------- */
/* The definition sits at lead size and full measure: it is the sentence a
   person scans first and the one an answer engine is most likely to quote. */
.say{max-width:60ch;margin-top:var(--sp-2);color:var(--black)}

/* Two columns that end together. The list alone was half the height of the
   photograph, which left a hole beside it and pushed everything below out of
   step — so the argument lives under the list, in the same column. */
.scope{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(1.5rem,4vw,3.5rem);
  align-items:stretch;margin-top:var(--sp-4)}
.scope__col{display:flex;flex-direction:column;gap:var(--sp-3)}
/* The photograph fills whatever height the text column ends up being, so the
   two always finish level — a fixed aspect ratio left one or the other short. */
.scope__shot{display:flex;flex-direction:column}
.scope__list{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,2.4vw,2rem)}
.scope__role{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);padding-bottom:.5rem;margin-bottom:.75rem;border-bottom:1px solid var(--rule);
}
.scope__group li{
  font-family:var(--font-text);font-size:clamp(.875rem,1vw,.9375rem);line-height:1.35;
  padding-block:.4375rem;color:var(--black);
}
.scope__group li + li{border-top:1px solid var(--rule)}

/* The photograph carries the section. It is the studio's own table, not a
   stock desk — the work laid out and weighed, which is what the copy claims. */
.scope__shot{margin:0}
.scope__shot img{border-radius:16px;background:var(--rule)}
/* Stated plainly, at caption size — small enough not to shout, plain enough
   that nobody could say it was hidden. */
.scope__note{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;margin-top:.75rem;
  font-size:.8125rem;line-height:1.5;color:var(--muted);max-width:46ch;
}
.scope__tag{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--black);border:1px solid var(--rule);border-radius:999px;
  padding:.125rem .4375rem;flex:none;
}
.scope__shot img{display:block;width:100%;flex:1;min-height:14rem;max-height:34rem;object-fit:cover}


p.stance__line{color:var(--muted);max-width:52ch;font-size:clamp(1rem,1.15vw,1.0625rem);line-height:1.55}
p.stance__ai{color:var(--muted);max-width:52ch;font-size:clamp(1rem,1.15vw,1.0625rem);line-height:1.55}
.stance__ai strong{color:var(--black)}
.stance__cta{display:flex;flex-wrap:wrap;align-items:center;gap:clamp(1rem,2vw,1.75rem);
  margin-top:var(--sp-4)}

@media (max-width:900px){
  .scope{grid-template-columns:1fr}
  .scope__shot{order:-1}
}
@media (max-width:560px){
  .scope__list{grid-template-columns:1fr}
}

.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,6rem);margin-top:var(--sp-4)}
.split__body p{color:var(--muted)}
.split__body p + p{margin-top:1rem}
.split__body strong{color:var(--black);font-weight:500}
.split__grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2);margin-top:var(--sp-3)}
.split__panel{
  background:var(--panel);border:1px solid var(--rule);border-radius:10px;
  padding:clamp(1.5rem,2.5vw,2.25rem);display:flex;align-items:center;justify-content:center;
}
.split__panel svg{width:100%;height:auto;max-width:420px}
@media (max-width:900px){
  .split{grid-template-columns:1fr}
  .split__grid{grid-template-columns:1fr 1fr}
}
@media (max-width:480px){.split__grid{grid-template-columns:1fr}}

/* ---------- community (hidden until the group programme exists) ---------- */
[hidden]{display:none !important}
.faces{
  margin-top:var(--sp-3);display:flex;flex-wrap:wrap;justify-content:center;
  gap:0.75rem;max-width:34rem;margin-inline:auto;
}
.face{
  width:64px;height:64px;border-radius:999px;border:1px solid var(--rule);
  background:var(--panel);display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.face svg{width:46px;height:46px}

/* ---------- stats ----------
   The panel behind these is gone: the cards carry the light ground and the
   page's own dark shows between them, the same way the feature grid works.

   They were four centred blocks joined by a 2px seam, which made the numbers
   line up but left the labels dangling at different depths. Now each card runs
   top to bottom — label, number, then the caption pushed to the floor — so the
   numbers align under the eyebrows AND the captions align along the bottom,
   however long they run. */
.stats{
  margin-top:var(--sp-4);display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(0.75rem,1.1vw,1rem);
}
@media (max-width:900px){.stats{grid-template-columns:repeat(2,1fr)}}
@media (max-width:480px){.stats{grid-template-columns:1fr}}
.stat{
  background:var(--bone);color:var(--black);border:0;border-radius:22px;
  padding:clamp(1.375rem,2.1vw,1.75rem);
  text-align:left;
  display:flex;flex-direction:column;
  min-height:clamp(10.5rem,14vw,12.5rem);
  transition:transform .45s cubic-bezier(.2,.7,.2,1);
}
.stat__eyebrow{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);
}
.stat__n{
  font-family:var(--font-deck);font-size:clamp(2.75rem,4.6vw,3.75rem);font-weight:500;
  letter-spacing:-0.045em;line-height:1;margin-top:clamp(1.25rem,2vw,1.75rem);
}
/* auto margin, not a fixed one — this is what puts every caption on the
   same floor no matter how many lines it takes. */
.stat__label{margin-top:auto;padding-top:0.75rem;color:var(--muted);
  font-size:0.875rem;line-height:1.45}
@media (prefers-reduced-motion:no-preference){
  .stat:hover{transform:translateY(-3px)}
}
@media (max-width:720px){
  .stat{min-height:0}
}

/* ---------- newsletter ---------- */
.news{background:var(--beige-deep);padding-block:var(--sp-4);border-top:1px solid var(--rule)}
.news__inner{max-width:44ch;margin-inline:auto;text-align:center}
.news__title{
  font-family:var(--font-deck);font-size:clamp(1.5rem,3vw,2.25rem);font-weight:500;
  letter-spacing:-0.03em;line-height:1.05;
}
.news__body{margin-top:0.875rem;color:var(--muted)}
.news__form{
  margin-top:var(--sp-2);display:grid;grid-template-columns:1fr auto;align-items:center;
  gap:0.5rem;background:var(--bone);border:1px solid var(--rule);
  border-radius:999px;padding:0.375rem 0.375rem 0.375rem 1.375rem;
}
.news__form:focus-within{border-color:var(--muted)}
.news__input{
  border:0;background:transparent;font:inherit;color:var(--black);
  padding-block:0.875rem;min-width:0;
}
.news__input::placeholder{color:var(--muted)}
.news__input:focus{outline:none}
.news__note{margin-top:0.875rem;font-size:0.8125rem;color:var(--muted)}
@media (max-width:420px){
  .news__form{grid-template-columns:1fr;border-radius:12px;padding:0.5rem}
  .news__input{padding-inline:0.875rem}
  .news__form .btn{width:100%;text-align:center}
}

/* ---------- pricing (hidden until Phil supplies real figures) ---------- */
.tiers{display:grid;grid-template-columns:2fr 3fr;margin-top:var(--sp-4)}
.tier{border:1px solid var(--rule);padding:clamp(1.75rem,3vw,2.75rem)}
.tier:first-child{border-radius:10px 0 0 10px;border-right:0;margin-block:0.5rem}
.tier:last-child{border-radius:0 10px 10px 0;background:var(--panel)}
.tier__name{font-family:var(--font-deck);font-size:1.0625rem;font-weight:500;letter-spacing:-0.018em}
.tier__price{
  font-family:var(--font-deck);font-size:clamp(1.75rem,3vw,2.25rem);font-weight:500;
  letter-spacing:-0.03em;line-height:1;margin-block:0.75rem;
}
.tier__note{font-size:0.9375rem;color:var(--muted)}
.tier__list{margin-top:var(--sp-2);border-top:1px solid var(--rule);padding-top:var(--sp-2)}
.tier__list li{display:flex;gap:0.625rem;align-items:flex-start;font-size:0.9375rem;line-height:1.5}
.tier__list li + li{margin-top:0.75rem}
.tier__list svg{width:14px;height:14px;flex:none;margin-top:0.3125rem}
.tier__split{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2)}
@media (max-width:820px){
  .tiers{grid-template-columns:1fr}
  .tier:first-child{border-radius:10px 10px 0 0;border-right:1px solid var(--rule);border-bottom:0;margin-block:0}
  .tier:last-child{border-radius:0 0 10px 10px}
  .tier__split{grid-template-columns:1fr}
}


/* ---------- team (team-two shape) ---------- */
.team{border-top:1px solid var(--rule);position:relative}
.team__tag{
  display:block;width:max-content;background:var(--beige);
  padding-right:1.25rem;transform:translateY(-0.5rem);
}
.section--deep .team__tag{background:var(--beige-deep)}
.team__intro{display:grid;grid-template-columns:2fr 3fr;gap:var(--sp-3);margin-top:var(--sp-3)}
.team__intro .h2{max-width:14ch}
.team__intro p{color:var(--muted);max-width:52ch}
.team__grid{
  margin-top:var(--sp-4);display:grid;
  grid-template-columns:repeat(4,1fr);gap:var(--sp-2);
}
.member__portrait{
  aspect-ratio:3/4;background:var(--panel);border:1px solid var(--rule);border-radius:8px;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
  transition:background-color .35s ease;
}
.member:hover .member__portrait{background:var(--bone)}
.member__portrait svg{width:62%;height:auto}
.member__row{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;margin-top:0.875rem}
.member__name{font-family:var(--font-deck);font-size:1.0625rem;font-weight:500;letter-spacing:-0.018em}
.member__idx{font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;color:var(--muted)}
.member__role{margin-top:0.25rem;font-size:0.9375rem;color:var(--muted)}
.member__tbc{font-style:normal;color:var(--muted)}
@media (max-width:900px){
  .team__intro{grid-template-columns:1fr}
  .team__grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:520px){.team__grid{grid-template-columns:1fr}}

/* ---------- page header (sub-pages) ---------- */
.pagehead{padding-block:clamp(4rem,9vw,8rem) var(--sp-4)}
.pagehead .meta{margin-bottom:var(--sp-1)}
.pagehead__h1{
  font-family:var(--font-deck);font-size:clamp(2.5rem,6vw,5rem);font-weight:500;
  letter-spacing:-0.04em;line-height:0.94;max-width:18ch;text-wrap:balance;
}
.pagehead__sub{margin-top:var(--sp-2);color:var(--muted)}
.prose > * + *{margin-top:1.25rem}
.prose p{color:var(--muted);max-width:64ch}
.prose h2,.prose h3{
  font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;
  letter-spacing:-0.022em;margin-top:var(--sp-3);
}
.nav__link.is-here{border-bottom-color:var(--black)}


/* ---------- logo cloud (owned ventures only) ---------- */
.cloud{border-block:1px solid var(--rule);padding-block:var(--sp-3)}
.cloud__label{text-align:center;margin-bottom:var(--sp-2)}
.cloud__row{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(2rem,7vw,6rem);
}
.cloud__mark{
  font-family:var(--font-deck);font-size:clamp(1.25rem,2.2vw,1.75rem);font-weight:500;
  letter-spacing:0.02em;color:var(--muted);text-decoration:none;
  transition:color .2s ease;
}
a.cloud__mark:hover{color:var(--black)}
.cloud__note{text-align:center;margin-top:var(--sp-2);color:var(--muted);font-size:0.875rem}

/* ---------- faq accordion ---------- */
.faqwrap{display:grid;grid-template-columns:1fr 2fr;gap:clamp(2rem,6vw,5rem)}
.faqwrap__aside{position:sticky;top:calc(var(--nav-h) + 2rem);align-self:start}
.faqwrap__aside p{margin-top:var(--sp-2);color:var(--muted)}
.acc{border:1px solid var(--rule);border-radius:10px;background:var(--panel)}
.acc + .acc{margin-top:0.5rem}
.acc > summary{
  list-style:none;cursor:pointer;display:flex;align-items:flex-start;gap:0.875rem;
  padding:clamp(1.125rem,2vw,1.375rem) clamp(1.125rem,2vw,1.5rem);
  font-family:var(--font-deck);font-size:clamp(1.0625rem,1.4vw,1.1875rem);
  font-weight:500;letter-spacing:-0.018em;line-height:1.3;
}
.acc > summary::-webkit-details-marker{display:none}
.acc__sign{margin-left:auto;flex:none;width:14px;height:14px;margin-top:0.25rem;transition:transform .2s ease}
.acc[open] .acc__sign{transform:rotate(45deg)}
.acc__icon{flex:none;width:18px;height:18px;margin-top:0.125rem}
.acc__body{padding:0 clamp(1.125rem,2vw,1.5rem) clamp(1.25rem,2vw,1.5rem) calc(clamp(1.125rem,2vw,1.5rem) + 18px + 0.875rem)}
.acc__body p{color:var(--muted);max-width:62ch}
@media (max-width:820px){
  .faqwrap{grid-template-columns:1fr}
  .faqwrap__aside{position:static}
  .acc__body{padding-left:clamp(1.125rem,2vw,1.5rem)}
}

/* ---------- big footer ---------- */
.bigfoot{border-top:1px solid var(--rule);background:var(--beige-deep);padding-top:var(--sp-4)}
.bigfoot__top{
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:1.5rem;padding-bottom:var(--sp-2);border-bottom:1px solid var(--rule);
}
.bigfoot__social{display:flex;flex-wrap:wrap;gap:1.25rem}
.bigfoot__social a{color:var(--muted);display:block;transition:color .2s ease}
.bigfoot__social a:hover{color:var(--black)}
.bigfoot__social svg{width:20px;height:20px;display:block}
.bigfoot__grid{
  display:grid;grid-template-columns:repeat(3,1fr) 1.4fr;
  gap:var(--sp-3);padding-block:var(--sp-3);
}
.fgroup__title{font-size:0.9375rem;font-weight:500;margin-bottom:1rem}
.fgroup a{display:block;color:var(--muted);text-decoration:none;font-size:0.9375rem;padding-block:0.3125rem}
.fgroup a:hover{color:var(--black)}
.bigfoot__bottom{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:1rem;border-top:1px solid var(--rule);padding-block:var(--sp-2);
}
@media (max-width:900px){.bigfoot__grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.bigfoot__grid{grid-template-columns:1fr}}

/* ---------- comparator (hidden) ---------- */
.compare{width:100%;overflow-x:auto;margin-top:var(--sp-4)}
.compare table{width:100%;min-width:620px;border-collapse:collapse;text-align:left}
.compare th,.compare td{padding:1rem 1.125rem;border-bottom:1px solid var(--rule);font-size:0.9375rem;vertical-align:top}
.compare thead th{
  font-family:var(--font-deck);font-size:1.0625rem;font-weight:500;letter-spacing:-0.018em;
  border-bottom:1px solid var(--black);
}
.compare tbody th{font-weight:400;color:var(--muted)}
.compare .is-yes svg{width:15px;height:15px}


/* ---------- forms ---------- */
.field{margin-top:var(--sp-2)}
.field__label{display:block;font-size:0.9375rem;font-weight:500;margin-bottom:0.5rem}
.field__opt{font-weight:400;color:var(--muted)}
.field__input{
  width:100%;font:inherit;color:var(--black);background:var(--bone);
  border:1px solid var(--rule);border-radius:8px;padding:0.875rem 1rem;
}
.field__input::placeholder{color:var(--muted)}
.field__input:focus{outline:none;border-color:var(--muted)}
.field__area{resize:vertical;min-height:9rem;line-height:1.55}
.field__note{margin-top:0;color:var(--muted);font-size:0.875rem;max-width:42ch}
.contact{max-width:44rem;margin-top:var(--sp-3)}
.contact__row{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2)}
.contact__row .field{margin-top:0}
.contact__foot{
  margin-top:var(--sp-3);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
}
@media (max-width:600px){.contact__row{grid-template-columns:1fr;gap:0}.contact__row .field + .field{margin-top:var(--sp-2)}}

/* ---------- signup ---------- */
.signup{display:flex;justify-content:center}
.signup__card{
  width:100%;max-width:26rem;background:var(--panel);
  border:1px solid var(--rule);border-radius:12px;padding:clamp(1.75rem,4vw,2.75rem);
}
.signup__title{font-family:var(--font-deck);font-size:1.75rem;font-weight:500;letter-spacing:-0.03em;line-height:1.05}
.signup__body{margin-top:0.875rem;color:var(--muted);font-size:0.9375rem;line-height:1.55}
.btn--ghost{
  background:transparent;color:var(--black);border:1px solid var(--rule);
}
.btn--ghost:hover{background:var(--bone);transform:none}
.signup__oauth{
  margin-top:var(--sp-2);width:100%;display:flex;align-items:center;justify-content:center;
  gap:0.625rem;font-size:0.9375rem;padding:0.875rem 1rem;
}
.signup__oauth[disabled]{opacity:.55;cursor:not-allowed}
.signup__oauth svg{width:16px;height:16px;flex:none}
.signup__or{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:0.875rem;
  margin-block:var(--sp-2);color:var(--muted);font-size:var(--fs-meta);
  letter-spacing:0.13em;text-transform:uppercase;
}
.signup__or::before,.signup__or::after{content:"";height:1px;background:var(--rule)}
.signup__submit{width:100%;margin-top:var(--sp-2);text-align:center}
.signup__note{margin-top:1rem}


/* ============================================================
   THE RAIL — fixed studio panel, left. Beige is the studio layer
   (paper, craft, people); black is the agentic layer (the machines).
   The split carries the meaning, which is why nothing needs an accent hue.
   Want Hubfolio's orange after all? Set --signal and use it on .btn.
   ============================================================ */
:root{
  --rail-w:19.5rem;
  --signal:var(--bone);          /* swap to e.g. #C2410C for an accent build */
  --signal-ink:var(--black);
}

body{padding-left:var(--rail-w)}

.rail{
  position:fixed;inset:0 auto 0 0;width:var(--rail-w);z-index:60;
  background:var(--black);color:var(--bone);
  display:flex;flex-direction:column;align-items:center;
  padding:1.75rem 1.75rem 2rem;overflow-y:auto;
  border-right:1px solid var(--rule-inv);
}
.rail__top{display:flex;width:100%;align-items:center;justify-content:space-between;gap:1rem}
/* The real script wordmark, not type set to look like one. It sits directly on
   the dark rail — the old pill existed to hold a text logo and has nothing to
   do once the mark can speak for itself. */
.rail__mark{display:inline-flex;align-items:center;color:var(--bone);text-decoration:none;
  transition:opacity .3s ease}
.rail__mark:hover{opacity:.78}
.rail__mark svg{display:block;width:clamp(104px,9vw,132px);height:auto}
.burger{
  background:none;border:0;padding:0.5rem;cursor:pointer;color:var(--bone);
  display:flex;flex-direction:column;gap:4px;align-items:flex-end;
}
.burger span{display:block;height:1.5px;background:currentColor;border-radius:1px}
.burger span:nth-child(1){width:20px}
.burger span:nth-child(2){width:14px}
.burger span:nth-child(3){width:17px}
.burger:hover span{width:20px;transition:width .2s ease}

.rail__seal{width:min(100%,13.5rem);margin:clamp(1.5rem,4vh,3rem) 0}
.seal{display:block;width:100%;height:auto}
.seal__ring{transform-origin:120px 120px;animation:sealspin 40s linear infinite}

.rail__contact{text-align:center;font-size:0.9375rem;line-height:1.7}
.rail__contact a{color:inherit;text-decoration:none;border-bottom:1px solid transparent}
.rail__contact a:hover{border-bottom-color:var(--muted-inv)}
.rail__legal{margin-top:1.25rem;color:var(--muted-inv);font-size:0.8125rem}
.rail__social{display:flex;gap:0.625rem;margin-top:1.5rem;justify-content:center}
.rail__social a{
  width:38px;height:38px;border-radius:999px;border:1px solid var(--rule-inv);
  display:flex;align-items:center;justify-content:center;color:var(--muted-inv);
  transition:color .2s ease,border-color .2s ease;
}
.rail__social a:hover{color:var(--bone);border-color:var(--muted-inv)}
.rail__social svg{width:15px;height:15px}
.rail__cta{width:100%;margin-top:auto;padding-top:2rem}
.rail__cta .btn{
  width:100%;display:flex;align-items:center;justify-content:center;gap:0.5rem;
  background:transparent;color:var(--bone);border:1px solid var(--rule-inv);
}
.rail__cta .btn:hover{background:var(--bone);color:var(--black);border-color:var(--bone)}
.rail__cta svg{width:15px;height:15px}

@media (max-width:1080px){
  body{padding-left:0}
  .rail{
    position:sticky;inset:auto;width:100%;flex-direction:row;align-items:center;
    justify-content:space-between;padding:0.875rem var(--gutter);
    border-right:0;border-bottom:1px solid var(--rule-inv);overflow:visible;top:0;
  }
  .rail__top{width:auto}
  .rail__seal,.rail__contact,.rail__legal,.rail__social{display:none}
  .rail__cta{width:auto;margin:0;padding:0}
  .rail__cta .btn{padding:0.6875rem 1.375rem;font-size:0.9375rem}
}
@media (max-width:520px){.rail__cta span{display:none}}

/* ---------- overlay menu ---------- */
.menu{
  position:fixed;inset:0;z-index:90;background:var(--black);color:var(--bone);
  display:grid;grid-template-columns:1.6fr 1fr;
  /* visibility flips instantly on open so the close button is focusable in the
     same tick, and is delayed on close so the fade-out is still visible. */
  opacity:0;visibility:hidden;
  transition:opacity .3s ease,visibility 0s linear .3s;
}
.menu.is-open{opacity:1;visibility:visible;transition:opacity .3s ease,visibility 0s linear 0s}
.menu__list{
  display:flex;flex-direction:column;justify-content:center;
  padding:clamp(2rem,7vw,6rem);border-right:1px solid var(--rule-inv);
}
.menu__link{
  display:flex;align-items:center;justify-content:space-between;gap:2rem;
  font-family:var(--font-deck);font-size:clamp(2rem,5vw,3.5rem);font-weight:500;
  letter-spacing:-0.04em;line-height:1.1;text-decoration:none;
  color:var(--muted-inv);padding-block:clamp(0.5rem,1.4vw,1rem);
  border-bottom:1px solid var(--rule-inv);transition:color .2s ease;
}
.menu__link:hover,.menu__link.is-here{color:var(--bone)}
.menu__link span{font-size:1.25rem;opacity:.5}
.menu__side{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1.5rem;text-align:center;padding:clamp(2rem,5vw,4rem);
}
.menu__close{font-family:var(--font-text);
  position:absolute;top:clamp(1.25rem,3vw,2.25rem);right:clamp(1.25rem,3vw,2.25rem);
  width:44px;height:44px;border-radius:999px;border:1px solid var(--rule-inv);
  background:none;color:var(--bone);cursor:pointer;font-size:1.25rem;line-height:1;
}
.menu__close:hover{background:var(--rule-inv)}
.menu__side .rail__social{margin-top:0}
@media (max-width:820px){
  .menu{grid-template-columns:1fr}
  .menu__side{display:none}
  .menu__list{border-right:0}
}
body.menu-open{overflow:hidden}

/* ---------- the agentic layer ---------- */
.agentic{background:var(--black);color:var(--bone);padding-block:var(--section)}
.agentic .meta,.agentic .lead{color:var(--muted-inv)}
.agentic .h2{color:var(--bone)}
.watch{
  margin-top:var(--sp-4);border:1px solid var(--rule-inv);border-radius:12px;
  padding:clamp(1.75rem,4vw,3rem);
}
.watch__row{display:flex;align-items:flex-end;justify-content:center;gap:clamp(1rem,4vw,3rem);flex-wrap:wrap}
.watch__unit{text-align:center}
.watch__unit svg{display:block;margin-inline:auto}
.watch__agent svg{width:clamp(52px,7vw,74px)}
.watch__super svg{width:clamp(84px,11vw,116px)}
/* Set the supervisor apart so the row reads "these three, watched by that one". */
.watch__super{margin-left:clamp(0.5rem,3vw,2.5rem)}
.watch__label{margin-top:0.875rem;font-size:var(--fs-meta);letter-spacing:0.13em;text-transform:uppercase;color:var(--muted-inv)}
.watch__super .watch__label{color:var(--bone)}
.watch__note{margin-top:var(--sp-3);text-align:center;color:var(--muted-inv);max-width:56ch;margin-inline:auto}
.agentic .stage{border-bottom-color:var(--rule-inv)}
.agentic .path{border-top-color:var(--rule-inv)}

/* ---------- portal ---------- */
.portal__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-2);margin-top:var(--sp-4)}
.portal__card{
  border:1px solid var(--rule-inv);border-radius:12px;
  padding:clamp(1.5rem,2.5vw,2.25rem);
}
.portal__card h3{
  font-family:var(--font-deck);font-size:var(--fs-h3);font-weight:500;
  letter-spacing:-0.022em;line-height:1.1;margin-bottom:0.875rem;
}
.portal__card p{color:var(--muted-inv);font-size:0.9375rem;line-height:1.55}
.portal__card .meta{margin-bottom:1.25rem}
@media (max-width:900px){.portal__grid{grid-template-columns:1fr}}


/* ============================================================
   FLOATING PANELS — the dark page ground shows between every
   section, and each section is a rounded card sitting on it.
   ============================================================ */
:root{--gap:0.75rem;--panel-r:26px}

body{background:var(--black)}

main{
  display:flex;flex-direction:column;gap:var(--gap);
  padding:var(--gap);
}
main > section{
  border-radius:var(--panel-r);
  overflow:hidden;
  background:var(--beige);
}
/* Cards don't need dividers — the gap is the divider. */
main > .section + .section{border-top:0}
main > section.section--deep{background:var(--beige-deep)}
/* Dark panels need to lift off the dark ground or they vanish into it. */
main > section.agentic,
main > section.band{
  background:#1C1916;
  border:1px solid var(--rule-inv);
}
main > section.news{background:var(--beige-deep);border-radius:var(--panel-r)}

.bigfoot{
  margin:0 var(--gap) var(--gap);
  border-radius:var(--panel-r);
  border-top:0;
  /* Dark, like the rail it sits under — the page closes on ink rather than
     handing the last panel back to beige. Everything inside has to flip with
     it: the rules, the link colours and the focus ring. */
  background:var(--black);
  color:var(--bone);
  --focus:var(--bone);
}
.bigfoot__top{border-bottom-color:var(--rule-inv)}
.bigfoot__bottom{border-top-color:var(--rule-inv)}
.bigfoot .meta{color:var(--muted-inv)}
.bigfoot__social a{color:var(--muted-inv)}
.bigfoot__social a:hover{color:var(--bone)}
.bigfoot .fgroup a{color:var(--muted-inv)}
.bigfoot .fgroup a:hover{color:var(--bone)}
.bigfoot .trait__body{color:var(--muted-inv)}
/* the signup pill stays light on purpose — it is the one thing down here
   that is meant to be pressed */
.bigfoot .news__form{background:var(--bone)}
.bigfoot .news__input{color:var(--black)}
.bigfoot .news__input::placeholder{color:var(--muted)}

/* The rail already owns the left edge; keep an even gutter beside it. */
@media (min-width:1081px){
  body{padding-left:calc(var(--rail-w) + var(--gap))}
  main{padding-left:0}
  .bigfoot{margin-left:0}
}
@media (max-width:1080px){
  main{padding:var(--gap)}
  :root{--panel-r:20px}
}
@media (max-width:520px){
  :root{--gap:0.5rem;--panel-r:16px}
}


/* ---------- turntable — the clay orb, scrubbed by cursor ---------- */
/* A sprite sheet of one full revolution. The cursor picks the frame, so the
   real rendered sphere turns to face you. Frame 0 (front-on) is the CSS
   default, so it still reads correctly with scripting off. */
.turntable{
  position:absolute;z-index:0;
  right:clamp(-1.5rem,-1vw,0rem);top:50%;transform:translateY(-50%);
  width:min(38%,460px);aspect-ratio:1;
  background-repeat:no-repeat;
  background-size:calc(var(--tt-cols) * 100%) calc(var(--tt-rows) * 100%);
  background-position:0% 0%;
  pointer-events:none;user-select:none;
  filter:drop-shadow(0 18px 26px rgba(60,48,32,.16));
}
@media (max-width:1080px){
  .turntable{width:min(38%,340px);right:-1.5rem;opacity:.85}
}
@media (max-width:700px){
  .turntable{position:static;transform:none;width:190px;margin:2rem 0 0 auto}
}


/* ============================================================
   HERO AS COMPOSITION — headline column + a stacked right rail,
   the way the reference does it. Not a headline in a box.
   ============================================================ */
/* The old card-grid hero needed a transparent shell; the open hero paints its
   own ground, so scope that to the grid variant only. */
.hero:has(.hero__grid){padding:0;background:transparent;overflow:visible}
.hero__grid{
  display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,0.85fr);
  gap:var(--gap);align-items:stretch;
}
.hero__main{
  background:var(--beige);border-radius:var(--panel-r);
  padding:clamp(2.25rem,4.5vw,4.5rem);
  display:flex;flex-direction:column;justify-content:center;
  position:relative;overflow:hidden;min-height:clamp(28rem,60vh,40rem);
}
.hero__eyebrow{margin-bottom:clamp(1.5rem,3vw,2.5rem)}
.hero__h1{
  font-family:var(--font-display);font-size:clamp(2.5rem,5.6vw,5.25rem);
  font-weight:500;letter-spacing:-0.045em;line-height:0.92;
  max-width:17ch;text-wrap:balance;
}
.hero__sub{margin-top:clamp(1.5rem,2.5vw,2.25rem);color:var(--muted);max-width:46ch}
.hero__cta{margin-top:clamp(2rem,3.5vw,3rem);display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}

.hero__rail{display:grid;grid-template-rows:1.25fr 1fr auto;gap:var(--gap)}
.hcard{
  border-radius:var(--panel-r);padding:clamp(1.5rem,2.2vw,2rem);
  display:flex;flex-direction:column;justify-content:space-between;overflow:hidden;position:relative;
}
.hcard--orb{background:var(--beige-deep);align-items:center;justify-content:center;min-height:13rem}
.hcard--tags{background:var(--panel);justify-content:flex-start}
.hcard--dark{background:var(--black);color:var(--bone);border:1px solid var(--rule-inv)}
.hcard--dark .meta{color:var(--muted-inv)}
.hcard__body{font-size:0.9375rem;line-height:1.5;color:var(--muted)}
.hcard--dark .hcard__body{color:var(--muted-inv)}

.tags{display:flex;flex-wrap:wrap;gap:0.5rem;margin-top:1.25rem}
.tag{
  font-size:0.8125rem;letter-spacing:-0.006em;padding:0.4375rem 0.8125rem;
  border:1px solid var(--rule);border-radius:999px;white-space:nowrap;
  transition:background-color .2s ease,color .2s ease,border-color .2s ease;
}
.tag:nth-child(3n+1){background:var(--black);color:var(--bone);border-color:var(--black)}
.tag:nth-child(4n+3):not(:nth-child(3n+1)){background:var(--bone);color:var(--black)}

.hcard--dark .hcard__foot{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:1.5rem}
.hcard__seal{width:3.25rem;flex:none}
.hcard__seal svg{width:100%;height:auto;display:block}

/* The orb lives in its own card now, not floating over the headline. */
.hero .turntable{
  position:static;transform:none;width:min(90%,15rem);margin:0;opacity:1;
}

@media (max-width:1080px){
  .hero__grid{grid-template-columns:1fr}
  .hero__rail{grid-template-rows:none;grid-template-columns:repeat(2,1fr)}
  .hcard--dark{grid-column:1 / -1}
}
@media (max-width:620px){
  .hero__rail{grid-template-columns:1fr}
}

/* ---------- marquee ---------- */
.marquee{
  background:var(--black);color:var(--bone);border-radius:var(--panel-r);
  padding-block:clamp(1.5rem,2.5vw,2.25rem);overflow:hidden;
  border:1px solid var(--rule-inv);
}
.marquee__track{display:flex;width:max-content;animation:slide 42s linear infinite}
.marquee:hover .marquee__track{animation-play-state:paused}
.marquee__item{
  display:flex;align-items:center;gap:clamp(1.75rem,3vw,3rem);
  padding-inline:clamp(0.875rem,1.5vw,1.5rem);
  font-family:var(--font-deck);font-size:clamp(1.5rem,3vw,2.5rem);
  font-weight:500;letter-spacing:-0.03em;white-space:nowrap;
}
.marquee__dot{width:0.5rem;height:0.5rem;border-radius:999px;background:var(--muted-inv);flex:none}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.marquee__track{animation:none}}

/* ---------- client row ---------- */
/* Greyscaled at rest so a dozen brand palettes can't fight the two-colour page;
   each mark takes its own colour when you point at it. */
/* This one row sits on the page's own dark ground rather than on a panel, so
   it has to opt out of the blanket panel background every other section gets. */
main > section.clients{background:transparent;border-radius:0;overflow:visible}

/* The ventures panel now sits on the dark ground too. The marks are dark ink
   — some with hardcoded hex and a gradient, not just currentColor — so they
   are inverted wholesale rather than recoloured one file at a time. */
main > section.cloud--ink{background:transparent}
.cloud--ink .cloud__label{color:var(--muted-inv)}
.cloud--ink .cloud__note{color:var(--muted-inv)}
.cloud--ink .cloud__logo svg{filter:grayscale(1) invert(1) brightness(1.12)}
.cloud--ink .cloud__logo{opacity:.62}
.cloud--ink .cloud__logo:hover{opacity:1}
.clients{padding-block:clamp(2.25rem,4.5vw,3.5rem)}
.clients__label{text-align:center;margin-bottom:clamp(1.25rem,2.2vw,1.75rem);color:var(--muted-inv)}
.clients__viewport{
  position:relative;overflow:hidden;
  /* the row runs off both edges rather than stopping at a hard crop */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.clients__track{
  display:flex;align-items:center;width:max-content;
  gap:clamp(2.5rem,5vw,4.5rem);
  animation:slide 46s linear infinite;
}
.clients__viewport:hover .clients__track{animation-play-state:paused}
.clients__item{flex:none;display:flex;align-items:center}
/* The marks are dark ink on transparent, so on the dark ground they are
   inverted to bone rather than shown in brand colour — which also keeps the
   page to its two colours instead of importing nine brand palettes. */
.clients__item img{
  display:block;width:auto;height:clamp(26px,3vw,38px);
  filter:grayscale(1) invert(1) brightness(1.15);opacity:.5;
  transition:opacity .35s ease;
}
.clients__item img:hover{opacity:.95}
@media (prefers-reduced-motion:reduce){
  .clients__track{animation:none;flex-wrap:wrap;justify-content:center;width:100%}
  .clients__item img{transition:none}
}


/* ---------- hover states — quiet, but they should exist ---------- */
.cell,.portal__card,.hcard,.member__portrait,.acc{
  transition:transform .28s cubic-bezier(.2,.7,.2,1),border-color .28s ease,background-color .28s ease;
}
.cell:hover,.portal__card:hover{transform:translateY(-3px);border-color:var(--muted)}
.agentic .portal__card:hover{border-color:var(--muted-inv)}
.acc:hover{border-color:var(--muted)}
/* The row hover was a flat wash of --panel across the full 1120px, hard-edged,
   in a page built out of rounded panels. Worse, it implied the row was
   clickable — only the URL inside it is a link, so the affordance was lying.

   What happens now says "you are reading this one" rather than "click me": the
   rule underneath draws itself in from the left, and the description lifts out
   of muted into full ink. Nothing moves position, because movement would read
   as navigation again. */
.venture{position:relative}
.venture::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--black);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .45s cubic-bezier(.2,.7,.2,1);
}
.venture:hover::after{transform:scaleX(1)}
.venture__desc{transition:color .3s ease}
.venture:hover .venture__desc{color:var(--black)}
@media (prefers-reduced-motion:reduce){
  .venture::after{transition:none}
}
.tag:hover{border-color:var(--black)}

/* Text links grow a travelling arrow rather than just changing colour. */
.textlink{position:relative}
.textlink::after{
  content:"\2192";display:inline-block;margin-left:.4em;
  transform:translateX(-4px);opacity:0;
  transition:transform .25s cubic-bezier(.2,.7,.2,1),opacity .25s ease;
}
.textlink:hover::after{transform:translateX(0);opacity:1}
@media (prefers-reduced-motion:reduce){
  .cell,.portal__card,.hcard,.acc,.textlink::after{transition:none}
  .cell:hover,.portal__card:hover{transform:none}
}


/* The 3D stage block that lived here was deleted. It reused the class name
   .stage — already the method/path row — and, being later in the file at equal
   specificity, it won: every stage row got height:clamp(15rem,26vw,20rem) plus
   overflow:hidden. Two of the four rows were silently losing their last lines
   ("The project" had 305px of copy in a 242px box). No page ever contained a
   3D stage element, so the whole block was dead code doing damage. */


/* Real portraits, not placeholders. */
.member__portrait img{width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.92);transition:filter .35s ease,transform .5s cubic-bezier(.2,.7,.2,1)}
.member:hover .member__portrait img{filter:saturate(1);transform:scale(1.03)}
.member__portrait{position:relative}
.member__pending{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-meta);letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
}


/* ---------- scroll progress ---------- */
.scrollbar{
  position:fixed;top:0;left:var(--rail-w);right:0;height:2px;z-index:70;
  background:transparent;pointer-events:none;
}
.scrollbar__fill{
  height:100%;background:var(--bone);opacity:.55;
  transform:scaleX(0);transform-origin:0 50%;will-change:transform;
}
@media (max-width:1080px){.scrollbar{left:0}}

/* The ring is driven by scroll now, not a timer. */
.seal__ring{animation:none}

/* Parallax and staggered reveals need their own transition so they don't
   fight the .reveal fade. */
[data-parallax]{will-change:transform}
[data-stagger] > *{will-change:opacity,transform}
@media (prefers-reduced-motion:reduce){
  [data-parallax]{transform:none !important}
  .scrollbar{display:none}
}


/* ---------- media ---------- */
.media{
  position:relative;border-radius:var(--panel-r);overflow:hidden;
  background:var(--beige-deep);aspect-ratio:16/9;
}
.media video,.media img{width:100%;height:100%;object-fit:cover;display:block}
.media video{position:absolute;inset:0;opacity:0;transition:opacity .6s ease}
.media video.is-playing{opacity:1}
.media--tall{aspect-ratio:4/3}
.media__cap{
  position:absolute;left:0;right:0;bottom:0;padding:1.25rem 1.5rem;
  background:linear-gradient(to top,rgba(20,18,16,.55),transparent);
  color:var(--bone);font-size:var(--fs-meta);letter-spacing:.13em;text-transform:uppercase;
}
.agentic .media,.band .media{background:#242019;border:1px solid var(--rule-inv)}
@media (prefers-reduced-motion:reduce){
  .media video{display:none}
}


/* ============================================================
   THE INDEX — a body of work as an instrument. Numbered rail,
   scroll scrubber, oversized titles, monospace read-outs.
   Mono is a deliberate third voice, used ONLY for read-outs:
   indices, tags, the HUD. Never for prose.
   ============================================================ */
:root{--font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace}

.index{position:relative;padding-block:var(--sp-3)}
.index__row{
  display:grid;
  grid-template-columns:5.5rem minmax(0,1fr) minmax(0,22rem);
  gap:clamp(1.5rem,3vw,3rem);
  padding-block:clamp(2.5rem,5vw,4.5rem);
  border-top:1px solid var(--rule);
  align-items:start;
  transition:opacity .45s ease;
}
.index__row:last-child{border-bottom:1px solid var(--rule)}
/* Everything dims except the row you're on. */
.js .index__row{opacity:.38}
.js .index__row.is-active{opacity:1}
@media (prefers-reduced-motion:reduce){.js .index__row{opacity:1}}

.index__num{font-family:var(--font-mono);line-height:1}
.index__num b{
  display:block;font-weight:400;
  font-size:clamp(2.25rem,4vw,3.25rem);letter-spacing:-0.04em;
  -webkit-text-stroke:1px var(--black);color:transparent;
  transition:color .45s ease;
}
.is-active .index__num b{color:var(--black)}
.index__num span{display:block;margin-top:.4rem;font-size:.6875rem;color:var(--muted);letter-spacing:.1em}

.index__title{
  font-family:var(--font-deck);
  font-size:clamp(2.25rem,5.6vw,4.25rem);font-weight:500;
  letter-spacing:-0.05em;line-height:.92;text-transform:uppercase;
  margin-bottom:clamp(1rem,2vw,1.5rem);
}
.index__tags{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.25rem}
.index__tag{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.08em;text-transform:uppercase;
  padding:.5rem .75rem;border:1px solid var(--rule);border-radius:6px;color:var(--muted);
  transition:border-color .3s ease,color .3s ease;
}
.is-active .index__tag{border-color:var(--muted);color:var(--black)}
.index__body{
  font-family:var(--font-mono);font-size:.75rem;line-height:1.9;letter-spacing:.02em;
  text-transform:uppercase;color:var(--muted);max-width:52ch;
}
.index__link{margin-top:1.5rem;display:inline-block}

.index__preview{
  border-radius:12px;overflow:hidden;background:var(--beige-deep);
  border:1px solid var(--rule);aspect-ratio:4/3;position:relative;
  transform:translateY(10px);opacity:.55;
  transition:transform .5s cubic-bezier(.2,.7,.2,1),opacity .5s ease;
}
.is-active .index__preview{transform:none;opacity:1}
.index__preview img,.index__preview video{width:100%;height:100%;object-fit:cover;display:block}
.index__preview video{position:absolute;inset:0;opacity:0;transition:opacity .6s ease}
.index__preview video.is-playing{opacity:1}
.index__preview--empty{
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);text-align:center;padding:1.5rem;
}

/* The scrubber — where you are through the body of work. */
/* The rail is the spine BETWEEN the numbers and the copy. At 2.35rem it sat
   inside the 5.5rem number column and drew a line straight through the middle
   of every digit, so it is pinned to the middle of the grid gutter instead. */
.index__rail{
  position:absolute;left:calc(5.5rem + clamp(1.5rem,3vw,3rem) / 2 - 1px);
  top:0;bottom:0;width:2px;
  background:var(--rule);
}
.index__thumb{
  position:absolute;left:-1px;width:4px;height:3.5rem;border-radius:2px;
  background:var(--black);will-change:transform;
}
@media (max-width:900px){
  .index__row{grid-template-columns:3.5rem minmax(0,1fr)}
  .index__preview{grid-column:1 / -1;max-width:26rem}
  .index__rail{left:calc(3.5rem + clamp(1.5rem,3vw,3rem) / 2 - 1px)}
}

/* Persistent HUD, bottom right of the pane. */
.hud{
  position:fixed;right:clamp(1rem,2vw,1.75rem);bottom:clamp(1rem,2vw,1.75rem);z-index:55;
  display:flex;align-items:center;gap:.75rem;
  background:var(--black);color:var(--bone);
  border-radius:999px;padding:.75rem 1.125rem;
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;text-transform:uppercase;
}
.hud__dot{width:.4375rem;height:.4375rem;border-radius:999px;background:var(--bone);opacity:.6}
.hud__count{color:var(--muted-inv)}
@media (prefers-reduced-motion:no-preference){
  .hud__dot{animation:pulse 2.4s ease-in-out infinite}
}
@keyframes pulse{0%,100%{opacity:.25}50%{opacity:.9}}


/* ============================================================
   OPEN HERO — the mascot gets the middle; type lives at the edges.
   ============================================================ */
.hero--open{
  position:relative;min-height:min(92vh,54rem);
  border-radius:var(--panel-r);overflow:hidden;
  background:var(--beige);
  padding:clamp(1.5rem,3vw,2.75rem);
  display:block;
}
/* Hold the cloud to the left so the headline never lands on the face. */
.hero__cloud{position:absolute;inset:0;z-index:0}
@media (min-width:901px){.hero__cloud{inset:0 calc(42% - 30px) 0 calc(-8% + 30px)}}
.hero__cloud canvas{display:block;width:100%;height:100%}

.hero__edge{position:absolute;z-index:1;max-width:min(30rem,42vw)}
.hero__edge--tl{top:clamp(1.5rem,3vw,2.75rem);left:clamp(1.5rem,3vw,2.75rem)}
.hero__edge--tr{top:clamp(1.5rem,3vw,2.75rem);right:clamp(1.5rem,3vw,2.75rem);text-align:right}
.hero__edge--bl{bottom:clamp(1.5rem,3vw,2.75rem);left:clamp(1.5rem,3vw,2.75rem)}
.hero__edge--br{bottom:clamp(1.5rem,3vw,2.75rem);right:clamp(1.5rem,3vw,2.75rem);text-align:right;max-width:min(40rem,58vw)}

.mono{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;
  text-transform:uppercase;line-height:2;color:var(--black);margin:0;
}
.mono--dim{color:var(--muted)}
.mono a{color:inherit;text-decoration:none;border-bottom:1px solid var(--rule)}
.mono a:hover{border-bottom-color:var(--black)}

.hero--open .hero__h1{
  /* Deck at every width. The clamp tops out at 76px and the site's own note
     says Banner only holds at ~96px+ — so the old "Banner on wide screens"
     switch could never fire correctly once the real fonts land. */
  font-family:var(--font-deck);font-weight:500;
  font-size:clamp(2.25rem,5.1vw,4.75rem);
  letter-spacing:-0.045em;line-height:0.92;text-transform:uppercase;
}
/* Each line is set where it was written, not where the column happens to break. */
.hero__h1 .ln{display:block;white-space:nowrap}
.hero__log{margin-top:1rem}
.hero--open .hero__sub{
  margin-top:.5rem;color:var(--muted);max-width:34ch;margin-left:auto;
  font-family:var(--font-deck);font-size:clamp(1rem,1.35vw,1.1875rem);
  letter-spacing:-0.012em;line-height:1.45;
}
.hero--open .hero__cta{margin-top:clamp(1.25rem,2.5vw,2rem);justify-content:flex-end}

@media (max-width:900px){
  .hero--open{min-height:auto;display:flex;flex-direction:column;gap:1.5rem;padding-block:2rem}
  .hero__cloud{position:relative;inset:auto;height:18rem;order:1}
  .hero__edge{position:static;max-width:none;text-align:left !important}
  .hero__edge--tr{display:none}
  .hero__edge--br{order:2}
  .hero__edge--bl{order:3}
  .hero--open .hero__sub{margin-left:0}
  .hero--open .hero__cta{justify-content:flex-start}
}


/* ---------- gooey ---------- */
/* The liquid-gooey package is React-only; this is the same technique done
   natively. Applied where shapes actually sit close enough to fuse. */
.goo-defs{position:absolute;width:0;height:0;overflow:hidden}
.lineup--goo{filter:url(#goo)}
.faces{filter:url(#goo-soft)}
@supports not (filter: url(#goo)) {
  .lineup--goo,.faces{filter:none}
}
@media (prefers-reduced-motion:reduce){
  .lineup--goo,.faces{filter:none}
}


/* Real venture marks, sized to optical weight rather than to the same height —
   a wordmark and a lettermark never balance at matching pixel heights. */
.cloud__logo{display:inline-flex;align-items:center;color:var(--black);text-decoration:none;
  opacity:.72;transition:opacity .3s ease}
.cloud__logo:hover{opacity:1}

/* Lining these up is not a matter of equal heights. Each mark carries a very
   different share of its own box as x-height — measured off the artwork:
   lawy .45, haloov .72, moro .95 — so matching box heights makes lawy look
   tiny and moro look huge. Size on x-height instead, then nudge each mark so
   those x-height bands sit on one line. The nudges are percentages of the
   mark's own height, so they hold at every clamp value.
   ARTLAS is stacked rather than a wordmark, so it centres on its whole box. */
.cloud__logo svg{width:auto;display:block}
.cloud__logo--lawy   svg{height:clamp(40px,4.2vw,56px);transform:translateY(-3.4%)}
.cloud__logo--haloov svg{height:clamp(25px,2.6vw,35px);transform:translateY(-11.5%)}
.cloud__logo--moro   svg{height:clamp(19px,2.0vw,26px);color:var(--black)}
.cloud__logo--artlas svg{height:clamp(46px,4.8vw,64px)}
.cloud__row{gap:clamp(2rem,5vw,4.5rem);align-items:center}

/* ---------- motion ---------- */
/* Gated on .js — with scripting off, nothing is ever hidden. */
.js .reveal{opacity:0;transform:translateY(12px);
  transition:opacity .5s cubic-bezier(.2,.7,.2,1),transform .5s cubic-bezier(.2,.7,.2,1)}
.js .reveal.is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .js .reveal{opacity:1;transform:none;transition:none}
  .seal__ring{animation:none}
  .menu{transition:none}
  .btn{transition:none}
  .btn:hover{transform:none}
}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}

/* ============================================================
   FOLIO — the back catalogue.

   Deliberately a different density from .index above it. The four
   ventures get a row each because they carry the page; the archive
   is an archive, so it reads as a register: hairline rules, mono
   meta, three across. The change in rhythm does the work that a
   subheading would otherwise have to explain.
   ============================================================ */
.folio{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(1.5rem,3vw,2.75rem) clamp(1.25rem,2.2vw,2rem);
}
.folio__item{display:flex;flex-direction:column}

.folio__shot{
  border-radius:12px;overflow:hidden;background:var(--beige-deep);
  border:1px solid var(--rule);aspect-ratio:4/3;
  transition:transform .4s cubic-bezier(.2,.7,.2,1);
}
.folio__shot img{width:100%;height:100%;object-fit:cover;display:block}
@media (prefers-reduced-motion:no-preference){
  .folio__item:hover .folio__shot{transform:translateY(-3px)}
}

/* The meta line is the register entry: what it was, and when. */
.folio__meta{
  display:flex;gap:.5rem;align-items:baseline;
  margin-top:clamp(.875rem,1.4vw,1.125rem);
  padding-top:.75rem;border-top:1px solid var(--rule);
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
}
.folio__meta b{font-weight:400;color:var(--black)}
.folio__name{
  font-family:var(--font-deck);font-weight:500;
  font-size:clamp(1.125rem,1.7vw,1.4375rem);letter-spacing:-0.03em;
  line-height:1.1;margin-top:.5rem;
}
.folio__line{
  margin-top:.4375rem;color:var(--muted);
  font-size:clamp(0.875rem,0.95vw,0.9375rem);line-height:1.55;
}

@media (max-width:900px){
  .folio{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .folio{grid-template-columns:minmax(0,1fr)}
}

/* A page head on ink. Same lift as .band — a pure black panel on a black
   ground has no edge, so it takes the same raised tone and hairline. */
main > section.pagehead.section--ink{
  background:#1C1916;
  border:1px solid var(--rule-inv);
}
.section--ink .pagehead__sub,
.section--ink .honesty{color:var(--muted-inv)}

/* Title cards. The section heads on the work page sit on ink so the page
   alternates: a dark card announces what's coming, the light card below it
   carries the work. Shallower than a full section — it is a title, not a
   section in its own right. */
main > section.headcard{
  background:#1C1916;
  border:1px solid var(--rule-inv);
  padding-block:clamp(2.75rem,5.5vw,4.5rem);
}
.headcard .section__head{margin-bottom:0}

/* The grid is introduced by a rule and a label rather than a headline —
   the page head above it has already said what this is. */
/* An h2 so the document doesn't jump from h1 straight to the h3 in each tile.
   It is a heading that behaves like a label — small on purpose. */
.folio__label{
  font-family:var(--font-mono);font-size:.6875rem;font-weight:400;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);
  padding-bottom:.875rem;margin-bottom:clamp(1.75rem,3vw,2.75rem);
  border-bottom:1px solid var(--rule);
}

/* A section that contributes no panel of its own — the page ground shows
   through and the cards inside do the work. Same idea as the client marquee. */
main > section.section--bare{background:transparent;border:0}

/* ---------- the stack ----------
   Five groups, each one a job rather than a category, because "what do you use
   for X" is the shape of the question people and answer engines actually ask.
   Tool names are set as type, not logos: nine tech logos would put nine brand
   palettes on a page that is meant to hold two colours. */
.stack__grid{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1.75rem,3vw,2.75rem) clamp(1.5rem,2.6vw,2.5rem);
}
.stack__group{
  border-top:1px solid var(--rule);
  padding-top:clamp(1rem,1.6vw,1.25rem);
}
.stack__role{
  font-family:var(--font-mono);font-size:.6875rem;font-weight:400;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);
}
.stack__tools{
  list-style:none;margin:.875rem 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:.4375rem;
}
.stack__tool{
  display:inline-flex;align-items:center;gap:.5rem;
  font-family:var(--font-deck);font-size:clamp(0.9375rem,1.15vw,1.0625rem);
  font-weight:500;letter-spacing:-0.02em;
  border:1px solid var(--rule);border-radius:8px;
  padding:.375rem .6875rem .375rem .5625rem;white-space:nowrap;
  transition:border-color .3s ease,background-color .3s ease;
}

/* The marks are drawn as CSS masks rather than <img>. Two reasons: the page
   holds two colours and a mask is monochrome by construction — Photoshop's blue
   and Google's four cannot leak in — and the glyph then inherits the ink of
   whatever it sits on, so the same file works on beige and on black. */
.stack__mark{
  flex:none;width:1.125em;height:1.125em;
  background:currentColor;
  -webkit-mask:center/contain no-repeat;mask:center/contain no-repeat;
}
.stack__mark[data-logo="claude"]     {-webkit-mask-image:url(logos/stack/claude.svg);      mask-image:url(logos/stack/claude.svg)}
.stack__mark[data-logo="openai"]     {-webkit-mask-image:url(logos/stack/openai.svg);      mask-image:url(logos/stack/openai.svg)}
.stack__mark[data-logo="grok"]       {-webkit-mask-image:url(logos/stack/grok.svg);        mask-image:url(logos/stack/grok.svg)}
.stack__mark[data-logo="cursor"]     {-webkit-mask-image:url(logos/stack/cursor.svg);      mask-image:url(logos/stack/cursor.svg)}
.stack__mark[data-logo="vscode"]     {-webkit-mask-image:url(logos/stack/vscode.svg);      mask-image:url(logos/stack/vscode.svg)}
.stack__mark[data-logo="figma"]      {-webkit-mask-image:url(logos/stack/figma.svg);       mask-image:url(logos/stack/figma.svg)}
.stack__mark[data-logo="photoshop"]  {-webkit-mask-image:url(logos/stack/photoshop.svg);   mask-image:url(logos/stack/photoshop.svg)}
.stack__mark[data-logo="illustrator"]{-webkit-mask-image:url(logos/stack/illustrator.svg); mask-image:url(logos/stack/illustrator.svg)}
.stack__mark[data-logo="premiere"]   {-webkit-mask-image:url(logos/stack/premiere.svg);    mask-image:url(logos/stack/premiere.svg)}
.stack__mark[data-logo="higgsfield"] {-webkit-mask-image:url(logos/stack/higgsfield.svg);  mask-image:url(logos/stack/higgsfield.svg)}
.stack__mark[data-logo="camera"]     {-webkit-mask-image:url(logos/stack/camera.svg);      mask-image:url(logos/stack/camera.svg)}
.stack__mark[data-logo="google"]     {-webkit-mask-image:url(logos/stack/google.svg);      mask-image:url(logos/stack/google.svg)}
.stack__mark[data-logo="bing"]       {-webkit-mask-image:url(logos/stack/bing.svg);        mask-image:url(logos/stack/bing.svg)}
.stack__mark[data-logo="linkedin"]   {-webkit-mask-image:url(logos/stack/linkedin.svg);    mask-image:url(logos/stack/linkedin.svg)}
.stack__mark[data-logo="instagram"]  {-webkit-mask-image:url(logos/stack/instagram.svg);   mask-image:url(logos/stack/instagram.svg)}
.stack__mark[data-logo="facebook"]   {-webkit-mask-image:url(logos/stack/facebook.svg);    mask-image:url(logos/stack/facebook.svg)}
.stack__mark[data-logo="tiktok"]     {-webkit-mask-image:url(logos/stack/tiktok.svg);      mask-image:url(logos/stack/tiktok.svg)}
.stack__group:hover .stack__tool{border-color:var(--muted)}
.stack__line{
  margin-top:.875rem;color:var(--muted);
  font-size:clamp(0.875rem,0.95vw,0.9375rem);line-height:1.55;
}
@media (max-width:680px){.stack__grid{grid-template-columns:minmax(0,1fr)}}

/* The hero's second door. It stays a text link rather than becoming a button —
   the brief allows one CTA and two pills would compete — but next to a solid
   black pill it was reading as a footnote. Deck weight, full ink, a heavier
   rule, and the arrow shows without waiting to be hovered, because an arrow is
   what tells you it goes somewhere. */
.hero__cta .textlink{
  font-family:var(--font-deck);font-weight:500;
  font-size:clamp(1rem,1.15vw,1.125rem);letter-spacing:-0.015em;
  color:var(--black);
  border-bottom-width:1.5px;border-bottom-color:var(--black);
  padding-bottom:6px;
}
.hero__cta .textlink::after{transform:translateX(0);opacity:1}
.hero__cta .textlink:hover::after{transform:translateX(3px)}

/* ---------- the six checks (audit page) ----------
   Same register as the folio grid: rule on top, mono-adjacent name, one line.
   Six of them, because that is how many lanes the audit actually checks. */
.checks{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(1.25rem,2.2vw,2rem)}
.check{border-top:1px solid #C2B9A6;padding-top:clamp(.875rem,1.4vw,1.125rem)}
.check__name{font-family:var(--font-deck);font-weight:500;font-size:clamp(1.0625rem,1.4vw,1.25rem);letter-spacing:-0.025em}
.check__line{margin-top:.4375rem;color:var(--muted);font-size:clamp(0.875rem,0.95vw,0.9375rem);line-height:1.55}
@media (max-width:900px){.checks{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.checks{grid-template-columns:minmax(0,1fr)}}

/* ---------- the conversation form ---------- */
/* One choice before any typing: which of the page's two readers you are.
   Pills, not a dropdown — two options don't need a menu. */
.choice{border:0;padding:0;margin:0 0 var(--sp-2)}
.choice legend{margin-bottom:.75rem}
.choice__pill{display:inline-flex;margin:0 .5rem .5rem 0;cursor:pointer}
.choice__pill input{position:absolute;opacity:0;pointer-events:none}
.choice__pill span{
  display:inline-block;padding:.625rem 1rem;border:1px solid var(--rule);
  border-radius:999px;font-size:.9375rem;background:var(--bone);
  transition:border-color .2s ease,background-color .2s ease,color .2s ease;
}
.choice__pill input:checked + span{background:var(--black);color:var(--bone);border-color:var(--black)}
.choice__pill input:focus-visible + span{outline:2px solid var(--focus);outline-offset:3px}
.field__save{color:var(--muted)}
.field__save.is-restored{color:var(--black)}

/* ============================================================
   THE PORTAL SHELL — the member app, previewed in place.
   Ported from the app-shell-2 block (sidebar + inset with a sticky
   header and wrapped content); same bones, this site's skin.
   ============================================================ */
.apshell{padding:0 !important}
.ap{display:flex;min-height:min(78vh,46rem);background:var(--beige)}

/* ---- sidebar ---- */
.ap__side{
  flex:0 0 15.5rem;display:flex;flex-direction:column;
  background:var(--bone);border-right:1px solid var(--rule);
  transition:flex-basis .3s cubic-bezier(.2,.7,.2,1);
  overflow:hidden;white-space:nowrap;
}
.ap__sidehead{
  display:flex;align-items:center;gap:.625rem;height:3.5rem;
  padding:0 1rem;border-bottom:1px solid var(--rule);flex:none;
}
.ap__logo{width:1.5rem;height:1.5rem;color:var(--black);flex:none}
.ap__logo svg{width:100%;height:100%;display:block}
.ap__wordmark{font-family:var(--font-mono);font-size:.8125rem;font-weight:500;letter-spacing:-0.02em}
.ap__nav{flex:1;padding:.75rem .5rem;overflow-y:auto}
.ap__group{margin-bottom:1rem}
.ap__grouplabel{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);padding:.25rem .625rem;margin:0 0 .125rem;
}
.ap__navbtn{
  display:flex;align-items:center;gap:.625rem;width:100%;
  padding:.5rem .625rem;border:0;border-radius:8px;background:none;
  font:inherit;font-size:.875rem;color:var(--black);opacity:.75;
  cursor:pointer;text-align:left;
  transition:background-color .15s ease,opacity .15s ease;
}
.ap__navbtn:hover{background:var(--beige-deep);opacity:1}
.ap__navbtn.is-on{background:var(--black);color:var(--bone);opacity:1}
.ap__ic{width:1rem;height:1rem;flex:none}
.ap__sidefoot{flex:none;border-top:1px solid var(--rule);padding:.75rem .5rem}
.ap__change{
  margin:0 .125rem .625rem;padding:.75rem;border:1px solid var(--rule);
  border-radius:10px;background:var(--panel);
}
.ap__changetitle{font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.ap__changebody{margin-top:.375rem;font-size:.8125rem;line-height:1.45;color:var(--muted);white-space:normal}

/* collapsed: the icon rail */
.ap.is-collapsed .ap__side{flex-basis:3.25rem}
.ap.is-collapsed .ap__wordmark,
.ap.is-collapsed .ap__grouplabel,
.ap.is-collapsed .ap__navbtn span,
.ap.is-collapsed .ap__change{display:none}
.ap.is-collapsed .ap__navbtn{justify-content:center;padding:.5rem}

/* ---- inset ---- */
.ap__main{flex:1;display:flex;flex-direction:column;min-width:0}
.ap__top{
  position:sticky;top:0;z-index:5;display:flex;align-items:center;
  justify-content:space-between;gap:.75rem;height:3.5rem;flex:none;
  padding:0 1.25rem;border-bottom:1px solid var(--rule);
  background:color-mix(in srgb, var(--beige) 92%, transparent);
  backdrop-filter:blur(6px);
}
.ap__topleft,.ap__topright{display:flex;align-items:center;gap:.75rem}
.ap__vr{width:1px;height:1rem;background:var(--rule)}
.ap__crumb{font-size:.8125rem;color:var(--muted)}
.ap__crumb b{color:var(--black);font-weight:500}
.ap__iconbtn{
  display:grid;place-items:center;width:1.75rem;height:1.75rem;
  border:1px solid var(--rule);border-radius:7px;background:var(--bone);
  color:var(--black);cursor:pointer;position:relative;
  transition:border-color .15s ease;
}
.ap__iconbtn:hover{border-color:var(--muted)}
.ap__iconbtn--dot::after{
  content:"";position:absolute;top:-2px;right:-2px;width:7px;height:7px;
  border-radius:999px;background:var(--black);border:1.5px solid var(--beige);
}
.ap__sample{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
  border:1px dashed var(--muted);border-radius:999px;padding:.25rem .625rem;
}
.ap__user{display:flex;align-items:center;gap:.5rem}
.ap__avatar{
  display:grid;place-items:center;width:1.75rem;height:1.75rem;border-radius:999px;
  background:var(--black);color:var(--bone);font-size:.75rem;font-weight:500;
}
.ap__username{font-size:.8125rem;font-weight:500}

/* ---- body + cards ---- */
.ap__body{flex:1;overflow-y:auto;padding:clamp(1rem,2vw,1.5rem)}
.ap__panel{display:none;max-width:56rem;margin-inline:auto}
.ap__panel.is-on{display:block}
.ap__hello{color:var(--muted);font-size:.9375rem;margin-bottom:1rem}
.ap__grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.75rem}
.ap__card{
  background:var(--bone);border:1px solid var(--rule);border-radius:14px;
  padding:1rem 1.125rem;
}
.ap__card--wide{grid-column:span 3}
.ap__cardmeta{
  display:flex;align-items:center;gap:.4375rem;
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
}
.ap__cardtitle{font-family:var(--font-deck);font-weight:500;font-size:1.0625rem;letter-spacing:-0.02em;margin-top:.5rem;line-height:1.25}
.ap__cardline{margin-top:.4375rem;color:var(--muted);font-size:.8125rem;line-height:1.5}
.ap__up{color:var(--black)}
.ap__big{font-family:var(--font-deck);font-weight:500;font-size:2rem;letter-spacing:-0.03em;margin-top:.5rem;line-height:1}
.ap__bar{height:6px;border-radius:3px;background:var(--beige-deep);margin-top:.75rem;overflow:hidden}
.ap__bar span{display:block;height:100%;border-radius:3px;background:var(--black)}
.ap__list{list-style:none;margin:.625rem 0 0;padding:0}
.ap__list li{display:flex;align-items:center;gap:.5rem;padding:.375rem 0;font-size:.875rem;border-top:1px solid var(--rule)}
.ap__list li:first-child{border-top:0}
.ap__dot{width:.5rem;height:.5rem;border-radius:999px;background:var(--rule);flex:none}
.ap__dot--ok{background:var(--black)}
.ap__chart{display:flex;align-items:flex-end;gap:4px;height:7.5rem;margin-top:.875rem}
.ap__chart span{flex:1;border-radius:3px 3px 0 0;background:var(--black);opacity:.85;min-height:4px}

@media (max-width:900px){
  .ap__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ap__card--wide{grid-column:span 2}
  /* Narrow screens get a drawer, not a rail. The sidebar is absolute here, and
     flex-basis means nothing to an absolute box — it slides, whole, instead.
     The icon-only state makes no sense at this size, so the collapsed class
     hides everything rather than shrinking it. */
  .ap{position:relative;overflow:hidden}
  .ap__side{
    position:absolute;inset:0 auto 0 0;z-index:20;width:15.5rem;
    box-shadow:8px 0 24px rgba(20,18,16,.08);
    transition:transform .3s cubic-bezier(.2,.7,.2,1);
  }
  .ap.is-collapsed .ap__side{transform:translateX(-100%);box-shadow:none}
  .ap.is-collapsed .ap__wordmark,
  .ap.is-collapsed .ap__grouplabel,
  .ap.is-collapsed .ap__navbtn span,
  .ap.is-collapsed .ap__change{display:revert}
  .ap.is-collapsed .ap__navbtn{justify-content:flex-start;padding:.5rem .625rem}
  .ap__sample{display:none}
}
@media (max-width:560px){
  .ap__grid{grid-template-columns:minmax(0,1fr)}
  .ap__card--wide{grid-column:span 1}
}

/* The hero's promise of an explanation is now a real link. Same quiet mono as
   before — the change is that it keeps the promise, not how it looks. */
a.hero__log{display:inline-block;text-decoration:none;transition:color .18s ease}
a.hero__log:hover{color:var(--black)}

/* ---------- the journal ---------- */
/* Long-form pages. The measure is the whole design: 66ch of body on the panel,
   images breaking slightly wider so the page breathes between arguments. */
.post{max-width:66ch;margin-inline:auto}
.post h2{
  font-family:var(--font-deck);font-weight:500;letter-spacing:-0.03em;
  font-size:clamp(1.375rem,2.2vw,1.75rem);line-height:1.15;
  margin:var(--sp-3) 0 0;
}
.post p{margin-top:1.05em;line-height:1.65;color:var(--black)}
.post p:first-child{margin-top:0}
.post ul,.post ol{margin:1.05em 0 0;padding-left:1.25em;line-height:1.65}
.post li+li{margin-top:.35em}
.post a{color:inherit;border-bottom:1px solid var(--link-rule)}
.post a:hover{border-bottom-color:var(--black)}
.post em{font-style:italic}
.post figure{margin:var(--sp-3) calc(-1 * clamp(0rem,3vw,3rem)) 0}
.post figure img{
  display:block;width:100%;height:auto;
  border-radius:14px;border:1px solid var(--rule);background:var(--beige-deep);
}
.post hr{border:0;border-top:1px solid var(--rule);margin:var(--sp-3) 0 0}
.post__lede{font-family:var(--font-deck);font-size:var(--fs-lead);line-height:1.45;letter-spacing:-0.014em}
.post__byline{
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted-inv);margin-top:var(--sp-2);
}
.section--ink .post__byline{color:var(--muted-inv)}
/* index cards ride on .folio; only the footer nav between posts is new */
.post__next{
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  margin-top:var(--sp-4);padding-top:var(--sp-2);border-top:1px solid var(--rule);
}

/* ---------- legal pages ---------- */
.legal{max-width:66ch;margin-inline:auto}
.legal h2{font-family:var(--font-deck);font-weight:500;letter-spacing:-0.025em;
  font-size:clamp(1.25rem,1.8vw,1.5rem);margin:var(--sp-3) 0 0}
.legal p,.legal ul{margin-top:1em;line-height:1.6;color:var(--muted)}
.legal ul{padding-left:1.25em}
.legal strong{color:var(--black);font-weight:500}

/* ---------- touch targets ----------
   The visual size of the small controls is the design; the HIT size is not.
   Padding grows the target and negative margin gives the space back, so
   nothing moves and every icon clears ~44px for a finger. */
.burger{padding:12px;margin:-12px;min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
.bigfoot__social a,.rail__social a{padding:12px;margin:-6px;display:inline-flex}
@media (pointer:coarse){
  .ap__iconbtn{width:2.5rem;height:2.5rem}
  .textlink{padding-block:6px}
}

/* A card paragraph that runs the full card is past 80ch on tablet — cap the
   measure; the card keeps its size, the text stops wallpapering it. */
.portal__card p{max-width:58ch}


/* ---------- the docked-rail window ----------
   The rail docks at 1081px and takes 19.5rem + gap out of the page, but every
   component breakpoint measures the VIEWPORT, not the space left over. Between
   1081 and 1340 that produced more columns in less room — the feature grid ran
   six ~96px cards where the same layout one pixel narrower gets four wide ones.
   This band applies the one-tier-down layout for exactly that window. */
@media (min-width:1081px) and (max-width:1340px){
  .bento--feat{grid-template-columns:repeat(3,1fr)}
  .feat--span2{grid-column:span 1}
  .feat--span3{grid-column:span 3}
  .feat--split{grid-template-columns:1.35fr 0.65fr}
  .team__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats{grid-template-columns:repeat(2,1fr)}
  .index__row{grid-template-columns:4rem minmax(0,1fr);gap:1.25rem 1.5rem}
  .index__preview{grid-column:1 / -1}
  .stack__grid{grid-template-columns:minmax(0,1fr)}
  .checks{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ---------- overlay menu on a short screen ----------
   Seven links at display size overflow a landscape phone, and the box didn't
   scroll — so the site's only CTA sat below the fold with no way to reach it. */
.menu{overflow-y:auto}

/* ---------- reduced motion: the marquee must still be readable ----------
   Stopping the animation left width:max-content inside overflow:hidden, so
   these readers saw the first two or three services and never the rest. The
   client row already solved this; the service marquee had been missed. */
@media (prefers-reduced-motion:reduce){
  .marquee__track{width:100%;flex-wrap:wrap;justify-content:center}
  .marquee__track > *:last-child{display:none}
}

/* ---------- portal toolbar vs the docked rail ----------
   Both were sticky at top:0; the rail bar (z-index 60) covered the portal's
   own toolbar and its sidebar toggle in the 901-1080 window. */
@media (min-width:901px) and (max-width:1080px){
  .ap__top{top:var(--rail-h,3.5rem);z-index:4}
}

/* ---------- coming-soon markers ----------
   The portal is real work in progress, not a live product. Both markers say so
   before anyone clicks: one in the nav, one at the top of the page itself. */
.soon{
  display:inline-block;margin-right:.5rem;padding:.1875rem .5rem;
  border:1px solid currentColor;border-radius:999px;
  font-size:.625rem;letter-spacing:.1em;
}
.menu__soon{
  display:inline-block;margin-left:.75rem;vertical-align:middle;
  padding:.1875rem .5625rem;border:1px solid var(--rule-inv);border-radius:999px;
  font-family:var(--font-mono);font-size:.625rem;font-weight:400;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted-inv);
}

/* ---------- language switcher ----------
   Lives at the foot of the dark footer on every localized page. Mono, quiet,
   current language in full ink — a read-out, not a control panel. */
.langs{
  display:flex;align-items:center;gap:.625rem;flex-wrap:wrap;
  margin-top:var(--sp-2);padding-top:var(--sp-2);border-top:1px solid var(--rule-inv);
  font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.1em;
}
.langs a{color:var(--muted-inv);text-decoration:none;padding:.375rem .25rem;transition:color .15s ease}
.langs a:hover{color:var(--bone)}
.langs a.is-lang{color:var(--bone);border-bottom:1px solid var(--bone)}
.langs span{color:var(--muted-inv);opacity:.5}
