
/* Self-hosted, subset to latin, no external requests. Archivo carries a width
   axis (62–125%): the same family runs from condensed data labels to wide
   nameplate headings. Martian Mono is the readout voice. */
@font-face{
  font-family:"Archivo";
  src:url("/assets/fonts/archivo-var-latin.woff2") format("woff2-variations");
  font-weight:400 800;font-stretch:62% 125%;font-display:swap
}
@font-face{
  font-family:"Martian Mono";
  src:url("/assets/fonts/martianmono-var-latin.woff2") format("woff2-variations");
  font-weight:300 700;font-stretch:75% 112.5%;font-display:swap
}

:root{
  --bg:#08090a;
  --paper:#e8e9e7;

  /* One deliberate ink ramp and one rule ramp. v3 carried around sixty
     near-identical greys, almost none of them chosen — weight now varies by
     step rather than by inventing another hex two digits away. */
  --ink:#eceeed;        /* headlines */
  --ink-2:#b2b8bb;      /* secondary display */
  --muted:#9aa1a6;      /* body copy */
  --quiet:#848c92;      /* labels */
  --faint:#697077;      /* annotations */
  --dim:#4e555b;        /* hairline marks, near-threshold text */

  --rule-strong:#3b4146;
  --rule:#31373c;
  --rule-soft:#24282c;
  --surface-1:#0b0d0f;  /* row hover, footer */
  --surface-2:#101316;  /* lifted panels */

  --signal:#d8f76d;            /* measured */
  --oxide:#c1502e;             /* not yet proven */

  /* legacy aliases — older rules still reference these */
  --line:var(--rule-soft);
  --line-strong:var(--rule-strong);
  --bg-soft:var(--surface-1);

  /* Spacing steps. Every structural margin, padding and gap resolves to one of
     these; deliberate optical exceptions are marked where they occur. */
  --s1:4px;  --s2:8px;   --s3:13px;  --s4:18px;
  --s5:26px; --s6:38px;  --s7:54px;  --s8:78px;
  --s9:112px; --s10:160px;

  --rail:94px;
  --pad:clamp(22px,3.2vw,54px);
  /* Content stops widening past --maxw and centres instead. Below the cap this
     collapses to --pad, so narrow layouts are untouched. Without it the work
     rows' fr columns kept growing and left everything adrift at 2560. */
  --maxw:1560px;
  --gutter:max(var(--pad),calc((100% - var(--maxw)) / 2));
  --sans:"Archivo","Helvetica Neue",Arial,ui-sans-serif,system-ui,sans-serif;
  --tech:"Martian Mono","IBM Plex Mono","SFMono-Regular",Consolas,monospace;
  /* display is set wide and lightly tracked — equipment lettering, not the
     tight condensed grotesque every other page uses */
  --disp-wdth:118%;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;background:var(--bg)}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);font-weight:400;overflow-x:hidden}
/* The grain is not a fixed value. It tracks scroll depth off the same --scroll
   the rail gauge reads, so the page is measurably coarser at the bottom than
   at the top — the same rule the content follows, applied to the surface. Over
   a full page that is .020 to .038; frame to frame it is nothing, which is the
   intent. It also comes in heavy and settles once, marking arrival rather than
   decorating it. */
body:before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:50;
  opacity:calc(.020 + var(--scroll,0) * .018);transition:opacity 1.1s ease;
  background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")
}
html:not(.settled) body:before{opacity:.085}
@media (prefers-reduced-motion:reduce){body:before{transition:none}}
/* Headings carry the outline, not the look. Every heading on this site is
   styled by the class it wears, so the UA's size, weight and margin would only
   fight it — reset once here rather than defending against it in each rule.
   This is what let the markup take real headings without moving a pixel. */
h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit;margin:0}
/* Section labels that were inline spans stay inline as headings. A block box
   sets its own line box (12px) where the inline one took the parent's strut
   (~18px), which walked everything under it 6px up the page. Where the parent
   is a flex or grid container the item is blockified and this is ignored,
   which is also correct — those were already blockified as spans. */
h2.tech{display:inline}
a{color:inherit;text-decoration:none}
/* v3 defined no focus state at all, so keyboard users got the browser default
   over a near-black ground — effectively nothing. A registration mark rather
   than a generic ring: same vocabulary as the rest of the page. */
:focus-visible{outline:1px solid var(--signal);outline-offset:4px}
.work-row:focus-visible{outline-offset:-2px}
.wordmark:focus-visible{outline-offset:6px}
/* the rail is rotated, so an outline on the link itself rotates with it and
   still reads correctly against the vertical text */
.main-nav a:focus-visible{outline-offset:3px}
.tech{font-family:var(--tech);font-size:9.5px;font-stretch:87.5%;letter-spacing:.08em;text-transform:uppercase}
/* Every page opens with the rail's five links. Offscreen until focused, and on
   :focus rather than :focus-visible — a skip link is only ever reached by
   keyboard, so it must appear the moment it is. Above the boot overlay, since
   a keyboard user can arrive before the overlay clears. */
.skip-link{position:fixed;top:-120px;left:var(--rail);z-index:1100;
  background:var(--surface-2);color:var(--ink);padding:11px 16px;
  border:1px solid var(--rule-strong);font-family:var(--tech);font-size:10px;
  letter-spacing:.1em;text-transform:uppercase}
.skip-link:focus{top:14px}
main:focus{outline:none}
.boot{position:fixed;inset:0;background:#08090a;z-index:1000;display:grid;place-items:center;transition:opacity .36s ease,visibility .36s ease}
.boot.done{opacity:0;visibility:hidden}
.boot-cross{width:34px;height:34px;position:relative}
.boot-cross:before,.boot-cross:after{content:"";position:absolute;background:var(--faint)}
.boot-cross:before{left:16px;top:0;width:1px;height:34px}
.boot-cross:after{top:16px;left:0;width:34px;height:1px}
/* Real load state, not a progress bar: three things the page waited on, each
   stamped with what it actually cost. Left-aligned as a block so the numbers
   form a column; the block itself is centred. */
.boot-readout{position:absolute;left:50%;top:calc(50% + 38px);transform:translateX(-50%);
  color:var(--quiet);white-space:nowrap;display:grid;gap:5px;justify-items:start}
.boot-id{color:var(--faint);margin-bottom:4px}
.boot-readout span[data-b]{display:grid;grid-template-columns:48px auto;gap:12px;color:var(--dim)}
.boot-readout b{font-weight:400;color:var(--quiet);font-variant-numeric:tabular-nums}
.rail{
  position:fixed;left:0;top:0;bottom:0;width:var(--rail);z-index:40;
  border-right:1px solid var(--line);background:rgba(8,9,10,.86);backdrop-filter:blur(12px);
  display:flex;align-items:center;flex-direction:column
}
.rail:after{content:"";position:absolute;right:-1px;top:0;width:1px;height:calc(var(--scroll,0) * 100%);background:var(--signal);opacity:.65;box-shadow:0 0 8px color-mix(in srgb,var(--signal) 30%,transparent)}
.wordmark{width:46px;margin-top:var(--s5)}
.wordmark svg{width:100%;height:auto;fill:var(--ink)}
/* rotate(-90deg) turns a left-to-right row into a bottom-to-top column, so the
   visual order is reversed. row-reverse corrects what the reader sees while DOM
   order — and therefore tab and screen-reader order — stays in page order. */
.main-nav{position:absolute;top:50%;left:50%;display:flex;flex-direction:row-reverse;gap:var(--s5);transform:translate(-50%,-50%) rotate(-90deg);white-space:nowrap}
.main-nav a{font-size:12px;color:var(--muted);position:relative}
.main-nav a:before{content:"";position:absolute;left:0;right:100%;bottom:-7px;height:1px;background:var(--signal);transition:right .22s ease}
.main-nav a:hover:before,.main-nav a.current:before{right:0}
.ai-link span{color:var(--signal)}
/* Rotated about its own centre like .main-nav, with the centre parked far enough
   up the rail that the full strip clears the bottom edge instead of clipping. */
.rail-meta{position:absolute;left:50%;bottom:95px;display:flex;flex-direction:row-reverse;gap:18px;transform:translate(-50%,50%) rotate(-90deg);white-space:nowrap;color:var(--faint)}
.live i,.status-active i{width:5px;height:5px;border-radius:50%;background:var(--signal);display:inline-block;margin-right:6px;box-shadow:0 0 12px var(--signal)}
main,footer{margin-left:var(--rail)}
.stage{position:relative}
.hero{
  min-height:100svh;padding:var(--pad) var(--gutter);padding-top:clamp(85px,10vh,130px);
  display:flex;flex-direction:column;justify-content:center;overflow:hidden
}
.hero-index{position:absolute;right:var(--gutter);top:var(--pad);color:var(--faint)}
.hero-title{container-type:inline-size;position:relative;z-index:2;width:min(100%,1320px);padding-right:clamp(0px,3vw,48px)}
.hero-line{display:block;overflow:hidden;line-height:.80}
.hero-line span{display:block;width:max-content;max-width:100%;font-weight:750;font-stretch:var(--disp-wdth);font-size:clamp(28px,11.2cqw,124px);letter-spacing:.004em;transform:translateY(115%);transition:transform .9s cubic-bezier(.16,1,.3,1)}
.hero.active .hero-line span{transform:none}
.hero-line.offset{margin-left:9%}
.hero-line.thin{line-height:.9}
.hero-line.thin span{font-size:clamp(15px,4.6cqw,52px);font-weight:400;font-stretch:100%;letter-spacing:.006em;color:var(--ink-2)}
.hero-line.offset-2{margin-left:20%}
/* QUALIPUGNUS is longer than any word on the front page and overruns the
   standard hero clamp at narrow widths, so this size is set to fit it. */
.hero-title.long .hero-line span{font-size:clamp(22px,8.6cqw,104px)}
.hero-title.long .hero-line.thin span{font-size:clamp(15px,3.2cqw,38px)}
.hero-line:nth-child(2) span{transition-delay:.08s}.hero-line:nth-child(3) span{transition-delay:.16s}.hero-line:nth-child(4) span{transition-delay:.22s}
.hero-note{position:absolute;right:var(--gutter);bottom:14vh;width:250px;border-top:1px solid var(--line-strong);padding-top:13px}
.hero-note .tech{color:var(--faint)}.hero-note p{font-size:14px;line-height:1.55;color:var(--muted)}
.registration{position:absolute;color:var(--faint);pointer-events:none;opacity:0;transition:opacity .4s ease}
.hero.active .registration{opacity:1;transition-delay:.65s}
.registration b{display:block;width:30px;height:30px;position:relative;margin-bottom:8px}
.registration b:before,.registration b:after{content:"";position:absolute;background:var(--dim)}
.registration b:before{left:14px;top:0;width:1px;height:30px}.registration b:after{top:14px;left:0;width:30px;height:1px}
.registration span{display:block;margin-top:5px}
.registration-a{left:44vw;top:16vh}.registration-b{right:9vw;top:38vh}
.hero-scroll{position:absolute;left:var(--gutter);bottom:34px;color:var(--faint)}.hero-scroll span{margin-left:var(--s3);color:var(--signal)}
.work{border-top:1px solid var(--line)}
/* An annotation on the list below, not a band across the page: it borrows the
   work rows' own column grid and drops the full-width rule that read as a break. */
.index-head{height:66px;padding:0 var(--gutter);display:grid;grid-template-columns:90px 160px minmax(280px,1.2fr) minmax(240px,.78fr);align-items:center;gap:var(--s5)}
.index-head .tech{color:var(--faint)}
.index-head h2{font-size:14px;font-weight:450;margin:0;color:var(--muted)}
.index-rule{grid-column:3 / -1;height:1px;background:var(--line)}
.work-row{
  min-height:440px;display:grid;grid-template-columns:90px 160px minmax(280px,1.2fr) minmax(240px,.78fr);
  gap:var(--s5);padding:var(--s6) var(--gutter);border-bottom:1px solid var(--line);position:relative;overflow:hidden;
  transition:background .35s ease
}
.work-row:hover{background:var(--surface-1)}
.work-no,.work-family{color:var(--faint)}.work-name{align-self:center;z-index:2}
/* All three headlines share one rule, sized in cqw against the column that holds
   them, so MANUFACTURING — the longest unbreakable word — fits without a per-row
   override and every row renders at the same scale. */
.work-name{container-type:inline-size}
.work-name h3{font-size:clamp(19px,8.9cqw,74px);line-height:.86;letter-spacing:.004em;margin:0;font-weight:750;font-stretch:var(--disp-wdth)}
.work-name h3 span{font-weight:400;font-stretch:100%;color:var(--ink-2)}
.work-name p{margin:var(--s5) 0 0;color:var(--muted);font-size:15px;line-height:1.5;max-width:410px}
.work-state{align-self:end;justify-self:end;text-align:right;z-index:3}
.work-state .tech{display:block;color:var(--quiet);margin-bottom:13px}.work-state strong{font-size:13px;font-weight:500;letter-spacing:.06em}
.state-dot{display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--signal);margin-right:7px;box-shadow:0 0 10px var(--signal)}





.hardware-row{min-height:520px}
/* Struck through with a real line-through rather than a positioned bar: the
   old one was a 5px block offset to 45%, which read as tilted against the
   letter-spacing. Text decoration is horizontal by definition and follows the
   glyph metrics. Oxide tint is the palette's not-yet-proven colour. */
.withheld{color:#c58a76;text-decoration:line-through;
  text-decoration-thickness:2px;text-decoration-color:var(--rule-strong)}



.measure{margin-top:var(--s3);color:var(--faint)}

.method{min-height:980px;padding:var(--s10) var(--gutter) var(--s9);display:grid;grid-template-columns:1.1fr .9fr;gap:8%;border-bottom:1px solid var(--line)}
.method-lead .tech{color:var(--faint)}.huge-copy{font-size:clamp(30px,4.9vw,74px);line-height:1.0;letter-spacing:.002em;font-stretch:110%;font-weight:700;margin:var(--s7) 0 0;max-width:770px}
.huge-copy em{font-style:normal;color:var(--quiet);font-weight:400;font-stretch:100%}
.method-body{padding-top:160px}.method-body>p{font-size:20px;line-height:1.55;color:var(--muted);max-width:560px;margin:0 0 var(--s8)}
.ledger{margin:0}.ledger>div{display:grid;grid-template-columns:140px 1fr;border-top:1px solid var(--line);padding:var(--s4) 0}
.ledger>div:last-child{border-bottom:1px solid var(--line)}
.ledger dt{color:var(--faint);padding-top:.24em}
/* dd inherited full-brightness ink at default leading while every other body
   element nearby sits at --muted / 1.55. Same treatment as the rest of the
   running copy, which is what it should have had. */
.ledger dd{margin:0;font-size:15.5px;line-height:1.6;color:var(--muted);max-width:56ch;font-weight:400}
.ledger-close{display:block;margin-top:var(--s5);color:var(--faint)}
/* The instrument reads the section it belongs to: --p is the reader's progress
   through the four operating principles, so the scale measures something real. */
.company{min-height:760px;padding:var(--s9) var(--gutter);display:grid;grid-template-columns:.8fr 1.2fr;gap:9%;border-bottom:1px solid var(--line)}
.company-left>.tech{color:var(--faint)}
.company-copy{padding-top:78px}.company-intro{font-size:clamp(27px,3.7vw,54px);letter-spacing:.003em;line-height:1.06;font-stretch:110%;font-weight:700;margin:0 0 var(--s7)}
.company-copy>p:not(.company-intro){font-size:17px;line-height:1.7;color:var(--muted);max-width:560px}
.inline-link{border-bottom:1px solid var(--dim);transition:border-color .2s ease,color .2s ease}
.inline-link:hover{color:var(--signal);border-bottom-color:var(--signal)}
.text-link{display:inline-block;margin-top:var(--s6);padding-bottom:8px;border-bottom:1px solid var(--faint);font:10px var(--tech);letter-spacing:.12em}.text-link span{color:var(--signal);margin-left:var(--s3)}
.founder{min-height:720px;padding:var(--s9) var(--gutter);display:flex;flex-direction:column;justify-content:center}.founder-label{color:var(--faint)}
.founder blockquote{font-size:clamp(28px,4.3vw,66px);line-height:1.06;letter-spacing:.002em;margin:var(--s8) 0 var(--s6);max-width:1200px;font-weight:600;font-stretch:106%}
.founder blockquote span{display:block;color:var(--quiet);font-weight:300;margin-top:var(--s4)}
.founder-gloss{font-size:16.5px;line-height:1.6;color:var(--muted);max-width:56ch;margin:0 0 var(--s7)}
.founder-rule{height:1px;background:var(--rule);transform-origin:left;transform:scaleX(.08);transition:transform 1.2s cubic-bezier(.16,1,.3,1)}
.founder.active .founder-rule{transform:scaleX(1)}
footer{--gutter:max(var(--pad),calc((100% - var(--rail) - var(--maxw)) / 2));min-height:260px;padding:var(--s6) var(--gutter);display:flex;justify-content:space-between;align-items:flex-end;background:var(--surface-1)}
.footer-logo{font-size:74px;font-weight:800;font-stretch:var(--disp-wdth);letter-spacing:.01em}.footer-meta{display:flex;gap:var(--s5);color:var(--faint)}

/* MegaCrunch */
.mc-body{--signal:#d5ff59}
.mc-hero{min-height:100svh;padding:var(--pad) var(--gutter);padding-top:var(--s9);position:relative;overflow:hidden}
.mc-meta{position:absolute;left:var(--gutter);top:var(--pad);color:var(--faint)}
.mc-title{font-size:clamp(44px,9.2vw,150px);line-height:.92;letter-spacing:.004em;margin:16vh 0 0;font-weight:750;font-stretch:var(--disp-wdth);position:relative;z-index:2;width:min-content}
.mc-title span{display:block;width:max-content}.mc-title span:nth-child(2){margin-left:8%;margin-top:-.02em;color:var(--ink-2);font-weight:400;font-stretch:100%;letter-spacing:.006em}
.mc-thesis{font-size:clamp(19px,2.3vw,34px);line-height:1.25;letter-spacing:.002em;margin:var(--s7) 0 0 40%;position:relative;z-index:3;color:var(--quiet)}
.mc-thesis strong{color:var(--ink);font-weight:520}
.mc-scroll{position:absolute;left:var(--gutter);bottom:28px;color:var(--faint)}.mc-scroll span{color:var(--signal);margin-left:var(--s3)}
.mc-idea{min-height:960px;padding:var(--s10) var(--gutter);display:grid;grid-template-columns:120px 1fr;gap:var(--s6);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.mc-side{color:var(--faint)}.mc-big{font-size:clamp(30px,5.1vw,80px);line-height:1.02;letter-spacing:.003em;margin:0;max-width:1100px;font-weight:700;font-stretch:110%}.mc-big em{font-style:normal;color:var(--quiet);font-weight:400;font-stretch:100%}
.mc-explain{font-size:19px;line-height:1.65;color:var(--muted);max-width:570px;margin:var(--s8) 0 0 44%}



.mc-process{padding:var(--s9) var(--gutter);border-bottom:1px solid var(--line)}
.process-head{display:grid;grid-template-columns:180px 1fr;margin-bottom:var(--s8)}.process-head .tech{color:var(--faint)}.process-head p{font-size:clamp(24px,3.2vw,48px);letter-spacing:.002em;line-height:1.12;font-weight:700;font-stretch:110%;margin:0;max-width:760px}
.process-list{list-style:none;padding:0;margin:0}.process-list li{display:grid;grid-template-columns:100px 260px 1fr;gap:var(--s5);padding:38px 0;border-top:1px solid var(--line);align-items:center;position:relative}
.process-list li:last-child{border-bottom:1px solid var(--line)}.process-list li>span{color:var(--faint)}.process-list strong{font-size:clamp(22px,2.7vw,42px);letter-spacing:.004em;font-weight:750;font-stretch:var(--disp-wdth)}.process-list p{max-width:56ch;color:var(--muted);line-height:1.6;font-size:15.5px;margin:0}
.process-line{position:absolute;left:0;bottom:-1px;height:1px;width:0;background:var(--signal);transition:width 1s cubic-bezier(.16,1,.3,1)}
.process-list li.active .process-line{width:100%}
.mc-proof{min-height:720px;padding:var(--s9) var(--gutter);display:grid;grid-template-columns:1.3fr .7fr;align-items:center;border-bottom:1px solid var(--line)}
.proof-main>.tech{color:var(--faint)}.proof-main p{font-size:clamp(28px,4.3vw,66px);line-height:1.06;letter-spacing:.002em;margin:var(--s7) 0 0;font-weight:700;font-stretch:110%}.proof-main em{font-style:normal;color:var(--quiet);font-weight:400;font-stretch:100%}
/* The second rule, set at body weight under the first: it is the
   counterintuitive one, and it earns its place by being explained rather than
   declared. */
.proof-main p.proof-note{font-size:17px;line-height:1.65;font-weight:400;font-stretch:100%;
  letter-spacing:normal;color:var(--muted);max-width:52ch;margin:var(--s6) 0 0}
.proof-readout{align-self:end;border-top:1px solid var(--rule-strong);color:var(--faint)}.proof-readout span{display:block;padding:var(--s3) 0;border-bottom:1px solid var(--rule-soft)}
.mc-status{padding:var(--s9) var(--gutter);min-height:760px}.mc-status-top{display:flex;justify-content:space-between}.mc-status-top>.tech{color:var(--faint)}.status-active{color:var(--muted)!important}
.mc-status-grid{display:grid;grid-template-columns:1.25fr .75fr;gap:8vw;margin-top:var(--s9)}.mc-status-grid>p{font-size:clamp(30px,4.9vw,74px);line-height:1.04;letter-spacing:.003em;margin:0;color:var(--quiet);font-weight:700;font-stretch:110%}.mc-status-grid>p strong{color:var(--ink);font-weight:750;font-stretch:var(--disp-wdth)}
.status-copy{padding-top:var(--s6)}.status-copy>.tech{color:var(--faint)}.status-copy p{font-size:17px;line-height:1.7;color:var(--muted);margin-top:var(--s5)}


/* authored details / v3 */
.hero:after{
  content:"";position:absolute;left:var(--gutter);right:var(--gutter);bottom:0;height:1px;
  background:linear-gradient(90deg,var(--dim) 0 9%,transparent 9% 13%,var(--rule-soft) 13% 68%,transparent 68% 72%,var(--rule-strong) 72% 100%);
}
.hero-title:before{
  content:attr(data-datum);position:absolute;left:-2px;top:-28px;color:var(--faint);font:9px var(--tech);letter-spacing:.14em;
}
.hero-title:after{
  content:"";position:absolute;left:0;top:-11px;width:72px;height:1px;background:var(--dim);
}
.work-row:before{
  content:"";position:absolute;left:calc(var(--gutter) + 250px);top:0;bottom:0;width:1px;background:rgba(255,255,255,.025);
}
.work-row:after{
  content:attr(data-coordinate);position:absolute;right:var(--gutter);top:27px;color:var(--dim);font:9px var(--tech);letter-spacing:.12em;
}
.work-row .work-name h3{transition:letter-spacing .45s cubic-bezier(.16,1,.3,1),color .3s ease}
.work-row:hover .work-name h3{letter-spacing:-.068em}
.work-row .cursor-register{
  position:absolute;left:var(--mx,50%);top:var(--my,50%);width:22px;height:22px;opacity:0;pointer-events:none;transform:translate(-50%,-50%);transition:opacity .16s ease;
}
.work-row:hover .cursor-register{opacity:.36}
.cursor-register:before,.cursor-register:after{content:"";position:absolute;background:var(--quiet)}
.cursor-register:before{width:1px;height:22px;left:10px;top:0}.cursor-register:after{height:1px;width:22px;left:0;top:10px}
.cursor-register i{position:absolute;left:8px;top:8px;width:5px;height:5px;border:1px solid var(--signal)}
.index-head{position:relative}
.index-head:after{content:"CURRENT / PUBLIC";position:absolute;right:var(--gutter);bottom:13px;color:var(--dim);font:8px var(--tech);letter-spacing:.14em}
.mc-hero:after{
  content:"";position:absolute;left:var(--gutter);right:var(--gutter);bottom:0;height:1px;background:linear-gradient(90deg,var(--signal) 0 4%,var(--rule-soft) 4% 100%);opacity:.55
}
.mc-idea,.method,.company,.founder,.mc-process,.mc-proof,.mc-status{background-image:linear-gradient(90deg,transparent calc(50% - .5px),rgba(255,255,255,.018) 50%,transparent calc(50% + .5px));background-size:100% 100%}
@media(max-width:700px){
  .work-row:before,.work-row:after,.hero-title:before,.hero-title:after{display:none}
}

/* ---- ambient marks ------------------------------------------------------
   Two layers. A few confident hairlines hold the space at rest; a dense
   technical layer sits far back in the value range until the cursor comes
   near. Ambient, not explanatory — they set the register, they do not teach. */
.work-row{grid-template-rows:1fr auto}
.work-no{grid-column:1;grid-row:1;align-self:start}
.work-family{grid-column:2;grid-row:1;align-self:start}
.work-name{grid-column:3;grid-row:1 / -1;align-self:center}
.work-state{grid-column:4;grid-row:2;align-self:end}
.mark{grid-column:4;grid-row:1;align-self:center;justify-self:end;position:relative;width:100%;--near:0}
.mark svg{width:100%;height:auto;display:block;overflow:visible}
.mark .sparse{fill:none;stroke:var(--quiet);stroke-width:1}
.mark .thin{fill:none;stroke:var(--dim);stroke-width:1}
.mark .dot{fill:var(--dim)}
.mark text{font-family:var(--tech);font-size:5.6px;font-stretch:87.5%;letter-spacing:.08em;
  fill:var(--dim);text-transform:uppercase}
.mark .dense{opacity:calc(.2 + var(--near) * .68);transition:opacity .3s ease}
.mark .measure{margin-top:var(--s4);color:var(--faint)}

/* ---- company plate -----------------------------------------------------
   A square engraved nameplate, exact and unrotated. The wordmark is the real
   art, centred on its ink: the source viewBox carries 41.5 units of trailing
   space, so centring on the box would sit it 20 units left of true centre. */
.plate{position:relative;width:min(100%,400px);margin-top:var(--s7);--near:0}
.plate svg{width:100%;height:auto;display:block;overflow:visible}
.plate .edge{fill:none;stroke:var(--quiet);stroke-width:1}
.plate .inner{fill:none;stroke:var(--faint);stroke-width:1}
.plate .thin{fill:none;stroke:var(--dim);stroke-width:1}
.plate .dot{fill:var(--dim)}
.plate .wm{fill:var(--ink)}
.plate .dense{opacity:calc(.2 + var(--near) * .68);transition:opacity .3s ease}
.plate text{font-family:var(--tech);font-size:7px;font-stretch:87.5%;letter-spacing:.15em;
  fill:var(--quiet);text-transform:uppercase}
.plate .micro{font-size:5.6px;letter-spacing:.1em;fill:var(--dim)}
.plate .val{fill:var(--faint)}

/* no pointer to approach with, so resolve part-way and stay there */
@media (hover:none){.mark,.plate{--near:.5}}


/* ---- static ambient lattice (MegaCrunch hero) ---------------------------
   Two repeating gradients, no script and no elements. The second runs at a
   slightly different pitch and is masked to one region, so it drifts out of
   register with the first — a printed moiré where the lattice has been locally
   rewritten. Static by choice: decorative motion is the thing that dates a
   page, and texture is not. */
/* First child, so every later sibling paints over it without needing a
   stacking rule of its own. An earlier blanket `.mc-hero > *` reset .mc-meta
   and .mc-scroll off absolute and knocked both 46px off the page datum, and
   z-index:-1 dropped the lattice behind main's own background. */
.lattice{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px, rgba(126,136,144,.30) 1.4px, transparent 1.6px);
  background-size:24px 24px;
  -webkit-mask-image:linear-gradient(#000 62%, transparent 100%);
          mask-image:linear-gradient(#000 62%, transparent 100%)}
.lattice:after{content:"";position:absolute;inset:0;
  background-image:radial-gradient(circle at 1px 1px, rgba(213,255,89,.52) 1.7px, transparent 1.9px);
  background-size:25.4px 24.6px;
  -webkit-mask-image:radial-gradient(34% 42% at 70% 40%, #000 0%, rgba(0,0,0,.55) 45%, transparent 72%);
          mask-image:radial-gradient(34% 42% at 70% 40%, #000 0%, rgba(0,0,0,.55) 45%, transparent 72%)}

/* ---- research appendix --------------------------------------------------
   Real tables, not drawn text: selectable, screen-reader legible, and larger
   than SVG text can be at this size. This is the dense end of the site. */
.appendix{padding:var(--s9) var(--gutter);border-top:1px solid var(--rule)}
/* The one centred block on the site. Everything above it hangs off the left
   datum; the appendix is a document rather than a layout, so it sits on the
   page's own axis. */
.ap-w{max-width:1080px;margin-inline:auto}
/* Centred on the viewport, not on the content column — the rail is chrome, and
   a block centred inside `main` sits half a rail to the right of where the eye
   puts the middle. Same compensation the footer already makes. Only once there
   is slack to give: below this the block is full width anyway. */
@media (min-width:1200px){.appendix{padding-right:calc(var(--gutter) + var(--rail))}}
.ap-head{display:flex;justify-content:space-between;align-items:baseline;
  border-bottom:1px solid var(--rule-strong);padding-bottom:var(--s3);margin-bottom:var(--s7)}
.ap-head h2{font-size:clamp(22px,2.6vw,38px);font-weight:700;font-stretch:110%;letter-spacing:.002em;margin:0}
.ap-head .tech{color:var(--faint)}
.ap-sec{font-family:var(--tech);font-size:10px;font-weight:400;font-stretch:87.5%;letter-spacing:.16em;color:var(--ink-2);
  text-transform:uppercase;margin:var(--s8) 0 var(--s3);display:flex;justify-content:space-between;gap:var(--s4)}
.ap-sec b{font-weight:400;color:var(--faint)}
.appendix table{width:100%;border-collapse:collapse;font-family:var(--tech);font-size:11.5px;
  font-stretch:87.5%;letter-spacing:.04em}
.appendix caption{text-align:left;font-size:10px;letter-spacing:.1em;color:var(--faint);
  text-transform:uppercase;padding-bottom:var(--s2)}
.appendix th,.appendix td{text-align:right;padding:9px 10px;border-bottom:1px solid var(--rule-soft);
  color:var(--quiet);white-space:nowrap}
.appendix th:first-child,.appendix td:first-child{text-align:left;font-weight:400;color:var(--faint);
  text-transform:uppercase;letter-spacing:.08em;font-size:10px;white-space:normal}
.appendix thead th{border-bottom:1px solid var(--rule-strong);color:var(--faint);font-weight:400;
  text-transform:uppercase;font-size:10px;letter-spacing:.1em}
.appendix thead th.bad{color:var(--oxide)} .appendix thead th.on{color:var(--signal)}
.appendix td.bad{color:#c58a76} .appendix td.on{color:var(--signal)} .appendix td.hi{color:var(--ink)}
.appendix tr:last-child td{border-bottom:1px solid var(--rule)}
/* tables that follow a table or a note belong to the same section head, so
   they get separation without one — otherwise a caption reads as a row */
.appendix table + table,.appendix p + table{margin-top:var(--s6)}
/* Deliberately not an adjacency rule. A hidden `.deep` sibling still counts for
   `+`, so every earned block placed above a note silently moved it — twice now.
   Notes take one fixed margin regardless of what sits above them, which is the
   only version of this that hidden content cannot disturb. */
/* Narrow: let values wrap rather than pushing the page sideways. A four-column
   table of nowrap figures needs 486px, and a horizontally scrolling table is
   worse to read than a wrapped one. */
@media(max-width:760px){
  .appendix th,.appendix td{white-space:normal;padding:8px 6px}
  .appendix table{font-size:10.5px;letter-spacing:.02em}
}
.ap-note{font-family:var(--tech);font-size:9.5px;font-stretch:87.5%;letter-spacing:.09em;
  color:var(--dim);text-transform:uppercase;margin-top:var(--s4);line-height:1.9}

/* ---- earned depth -------------------------------------------------------
   Hidden with display, not opacity: a screen reader should not be made to
   read out what a sighted reader has not been given. `revert` hands each
   element back its own default, so a row becomes a row and a table a table.
   Nothing here marks the hidden state — no placeholder, no count, no hint. */
.deep{display:none}
/* Earned material is set at reading weight, not as an aside: a reader who got
   here worked for it, so it should not arrive looking like a footnote. The rule
   above it is the only thing marking it as a different register. */
.deep-s{margin-top:var(--s7)}
.deep-label{display:block;color:var(--faint);border-top:1px solid var(--rule-strong);
  padding-top:var(--s3);margin-bottom:var(--s4)}
.deep-why{font-size:15.5px;line-height:1.7;color:var(--muted);max-width:56ch;margin:var(--s5) 0 0}
/* Commentary, earned by reading the section it belongs to. Body register, not
   an aside — and the one place on the site permitted to undercut the statement
   above it, so it must not read as a disclaimer. */
/* Vocabulary, earned by following the links. Deliberately undefined: the terms
   are the reward, and a gloss would end the chase rather than extend it. Set as
   instrument labels, the same LABEL / VALUE pairs the rest of the site uses. */
.vocab{margin-top:var(--s6);border-top:1px solid var(--rule);color:var(--faint);
  flex-wrap:wrap;gap:0 var(--s6);padding-top:var(--s3);max-width:70ch}
/* the layout mode lives on the reveal, not on .vocab: setting display:flex in
   the component rule tied with .deep{display:none} on specificity and won on
   source order, which showed every term to every reader */
[data-earned~="vocab"] .deep-v.vocab{display:flex}
.vocab span{padding:var(--s2) 0;white-space:nowrap}
.deep-r{margin-top:var(--s7);max-width:60ch}
.deep-r p{font-size:16px;line-height:1.72;font-weight:400;font-stretch:100%;
  letter-spacing:normal;color:var(--muted);margin:0}
.deep-hero{margin-left:40%;max-width:52ch}
.mc-status-grid .deep-r{margin-top:var(--s6)}
.appendix .deep-r{margin-top:var(--s8);max-width:66ch}
[data-earned~="numbers"] .deep-n{display:revert}
[data-earned~="vocab"]    .deep-v{display:revert}
[data-earned~="structure"] .deep-s{display:revert}
/* `read` is only ever set on main > section[id], and not every one of those is
   a .stage — the appendix is not, so keying this on .stage silently locked its
   commentary shut. */
section.read .deep-r{display:revert}
/* the one motion here is functional: it marks the change of state rather than
   letting rows appear under the reader with no account of themselves */
@media (prefers-reduced-motion:no-preference){
  .deep{animation:earn .45s ease both}
}
@keyframes earn{from{opacity:0}to{opacity:1}}

/* state/motion */
.stage .work-no,.stage .work-family,.stage .work-name,.stage .work-state{transition:opacity .6s ease,transform .7s cubic-bezier(.16,1,.3,1)}
.work-row:not(.active) .work-no,.work-row:not(.active) .work-family,.work-row:not(.active) .work-name,.work-row:not(.active) .work-state{opacity:.42}
.work-row:not(.active) .work-name{transform:translateX(18px)}
.mc-idea-copy,.method-lead,.method-body,.company-copy,.plate,.mc-status-grid,.proof-main,.proof-readout{transition:opacity .8s ease,transform .9s cubic-bezier(.16,1,.3,1)}
.stage:not(.active) .mc-idea-copy,.stage:not(.active) .method-lead,.stage:not(.active) .method-body,.stage:not(.active) .company-copy,.stage:not(.active) .plate,.stage:not(.active) .mc-status-grid,.stage:not(.active) .proof-main,.stage:not(.active) .proof-readout{opacity:.25;transform:translateY(18px)}
.stage.active .mc-idea-copy,.stage.active .method-lead,.stage.active .method-body,.stage.active .company-copy,.stage.active .plate,.stage.active .mc-status-grid,.stage.active .proof-main,.stage.active .proof-readout{opacity:1;transform:none}

@media(max-width:980px){
  :root{--rail:66px}
  .rail-meta{display:none}.wordmark{width:38px}
  .work-row{grid-template-columns:55px 110px 1fr}.work-state{grid-column:3}
  .mark{grid-column:3;width:min(100%,300px)}
  .index-head{grid-template-columns:55px 110px 1fr;gap:var(--s5)}.index-rule{grid-column:3}
  
  .method{grid-template-columns:1fr;min-height:auto}.method-body{padding-top:var(--s2)}
  .company{grid-template-columns:1fr}.company-copy{padding-top:0}
  .mc-thesis{margin-left:18%}
  .mc-idea{grid-template-columns:80px 1fr}.mc-explain{margin-left:20%}
  .mc-proof,.mc-status-grid{grid-template-columns:1fr;gap:var(--s7)}
}
@media(max-width:700px){
  :root{--rail:0px}
  .rail{position:sticky;top:0;width:100%;height:64px;bottom:auto;flex-direction:row;padding:0 18px;border-right:0;border-bottom:1px solid var(--line)}
  .wordmark{margin:0;width:38px}
  /* The rail is horizontal here and the rotation is gone, so the row-reverse that
     corrects the rotated order would flip this one the wrong way. */
  .main-nav{position:static;transform:none;flex-direction:row;margin-left:auto;gap:var(--s4)}
  /* Drop the in-page anchors on a phone but keep the first one and every link to
     another page. Stated by kind rather than by position, so adding a nav item
     cannot silently hide the wrong thing. */
  .main-nav a[href^="#"]:not(:first-child){display:none}
  main,footer{margin-left:0}
  .hero{min-height:calc(100svh - 64px);padding-top:var(--s8)}.hero-title{width:100%;padding-right:0}.hero-line.offset{margin-left:4vw}.hero-line.offset-2{margin-left:10vw}
  .hero-note{right:22px;bottom:105px;width:190px}.registration-a{left:55vw}.registration-b{display:none}
  .index-head{grid-template-columns:70px auto}.index-rule{display:none}
  /* One column, so every part needs its own row. The desktop layout has the
     name spanning rows 1-2 beside a state block in row 2; collapsed into a
     single column that span put the state straight through the body copy —
     22px into it on the hardware row. Explicit rows, stacked in reading order. */
  .work-row{min-height:480px;grid-template-columns:44px 1fr;grid-template-rows:auto auto auto auto;padding-top:var(--s5)}
  .work-no{grid-row:1}
  .work-family{grid-column:2;grid-row:1}
  .work-name{grid-column:2;grid-row:2;align-self:start}
  .work-state{grid-column:2;grid-row:3;justify-self:start;text-align:left;align-self:start;margin-top:var(--s5)}
  /* single content column here: the mark sits under the text, not beside it */
  .mark{grid-column:2;grid-row:4;justify-self:start;width:min(100%,300px);margin-top:var(--s5)}
  .plate{width:min(100%,300px)}
  
  .measure{font-size:8px;letter-spacing:.03em}
  .method{padding-top:var(--s8)}.huge-copy{margin-top:var(--s6)}.method-body>p{font-size:17px}.ledger>div{grid-template-columns:110px 1fr}
  .company{padding-top:var(--s8)}.founder{min-height:590px;padding-top:var(--s8)}
  footer{min-height:220px}.footer-logo{font-size:68px}.footer-meta{flex-direction:column;gap:6px;align-items:flex-end}
  /* the field bleeds off-screen here by design; its labels only get clipped */
  .mc-title{margin-top:22vh;font-size:clamp(40px,18.4vw,118px)}.mc-thesis{margin:var(--s7) 0 0 7vw}
  .mc-idea{grid-template-columns:1fr;padding-top:var(--s9)}.mc-side{margin-bottom:var(--s4)}.mc-explain{margin-left:0}
  .process-head{grid-template-columns:1fr;gap:var(--s5)}.process-list li{grid-template-columns:45px 1fr}.process-list p{grid-column:2}
  .mc-proof{padding-top:var(--s9)}.mc-status-grid{margin-top:var(--s8)}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*:before,*:after{animation:none!important;transition:none!important}
  .boot{display:none}.hero-line span{transform:none!important}
  .stage *{opacity:1!important;transform:none!important}
}
