/* ── OSY# — the site's design tokens ─────────────────────────────────────────────────────────────
   ⛔ THE PREVIOUS PALETTE WAS A CLICHÉ AND IT LOOKED LIKE ONE. Warm cream ground, a serif display
   face, a muted slate accent — that combination is the house style of machine-generated design, and
   on a docs site it reads as a corporate white paper. The audience here is a developer who will
   decide in a minute whether this looks like a tool they want to spend a weekend in.

   So: a COOL ground, WHITE cards, and colour that is actually saturated. Every hue below clears
   4.5:1 on the ground — measured, not eyeballed — because a palette that has to be apologised for
   in the body text is not a palette.

   The accent is an electric indigo. It is the one loud thing; everything else is ink and surface,
   and the second and third hues (green, amber, coral) are SEMANTIC — they mean allowed, marked,
   refused. Colour that means something can be bright without being noise. */
:root{
  --paper:#f1f3fb; --card:#ffffff; --wash:#e4e7f5; --rule:#cdd2e8; --rule-2:#aab2d4;
  --ink:#10121f; --ink-2:#494f68; --ink-3:#767d96;
  --accent:#4f2fe0;  --accent-wash:#e8e4fd;
  --allow:#0a7d55;   --allow-wash:#dcf5ea;
  --refuse:#d92b52;  --refuse-wash:#fde6ec;
  --mark:#a15c00;    --mark-wash:#fdf0dc;
  --lane:#e9ecf8;    --surface:#ffffff;
  /* THE THIRD REGISTER. A code card is dark in BOTH site themes, so it cannot borrow either one's
     tokens — it needs its own, and a palette that forgets them looks right until you open a guide. */
  --term-card:#14162b; --term-wash:#0e1020; --term-rule:#282d4c; --term-rule2:#3b4270;
  --term-ink:#eceefb;  --term-ink2:#b3badd; --term-ink3:#858cb4;
  --term-accent:#b0a2ff; --term-allow:#63dca8; --term-refuse:#ff8ba0; --term-mark:#ffc76b;
  --sans:'Bricolage Grotesque',system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,Menlo,monospace;
  --radius:8px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --paper:#0b0c14; --card:#15172a; --wash:#1c1f36; --rule:#2b3050; --rule-2:#3f4670;
  --ink:#eceefb; --ink-2:#a8afd0; --ink-3:#767d9e;
  --accent:#9b8bff; --accent-wash:#1d1a3d;
  --allow:#3ddc9a; --allow-wash:#0d2b22;
  --refuse:#ff7089; --refuse-wash:#2d1220;
  --mark:#f0b45e;   --mark-wash:#2b2010;
  --lane:#141628;   --surface:#1a1d33;
}}
:root[data-theme="dark"]{
  --paper:#0b0c14; --card:#15172a; --wash:#1c1f36; --rule:#2b3050; --rule-2:#3f4670;
  --ink:#eceefb; --ink-2:#a8afd0; --ink-3:#767d9e;
  --accent:#9b8bff; --accent-wash:#1d1a3d;
  --allow:#3ddc9a; --allow-wash:#0d2b22;
  --refuse:#ff7089; --refuse-wash:#2d1220;
  --mark:#f0b45e;   --mark-wash:#2b2010;
  --lane:#141628;   --surface:#1a1d33;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:74px}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{animation:none!important;transition:none!important}}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.62;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
a:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
h1,h2,h3{text-wrap:balance;letter-spacing:-.02em}
h1{font-weight:800}
h2,h3{font-weight:600}
code{font-family:var(--mono);font-size:.86em;background:var(--accent-wash);color:var(--accent);padding:1px 6px;border-radius:5px}
pre{background:var(--card);border:1px solid var(--rule);border-radius:var(--radius);padding:15px;
  overflow-x:auto;font-family:var(--mono);font-size:12.8px;line-height:1.68;margin:14px 0;color:var(--ink)}
pre code{background:none;padding:0;font-size:inherit}
table{width:100%;border-collapse:collapse;font-size:14.5px;margin:16px 0 24px;display:block;overflow-x:auto}
th{text-align:left;font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);border-bottom:1px solid var(--rule-2);padding:8px 14px 8px 0;font-weight:500;white-space:nowrap}
td{border-bottom:1px solid var(--rule);padding:11px 14px 11px 0;vertical-align:top;color:var(--ink-2)}
td strong,td b{color:var(--ink)}
blockquote{margin:16px 0;padding:2px 0 2px 16px;border-left:3px solid var(--rule-2);color:var(--ink-2)}
img{max-width:100%;height:auto}

/* ── masthead ── */
.masthead{border-bottom:1px solid var(--rule);background:var(--paper);position:sticky;top:0;z-index:30}
.masthead .in{max-width:1220px;margin-inline:auto;padding-inline:26px;height:56px;
  display:flex;align-items:center;gap:22px}
.mark{font-weight:700;font-size:16.5px;letter-spacing:-.01em;color:var(--ink)}
.mark span{font-family:var(--mono);color:var(--accent);font-weight:500}
/* ⚠ NOT `.tag` — that name was already taken by the spec page's status pills (`.tag.ok`, `.tag.soon`), and the
   collision was not theoretical: their rule sits later in the file so it won the uppercase and the size, while
   THIS rule's `border-left` and `padding-left` leaked onto every one of them. Caught by rendering it. */
.brandline{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);letter-spacing:.01em;white-space:nowrap;
  padding-left:13px;margin-right:3px;border-left:1px solid var(--rule-2)}
@media(max-width:1080px){.brandline{display:none}}
.masthead nav{display:flex;gap:17px;font-family:var(--mono);font-size:12.5px}
.masthead nav a{color:var(--ink-2)} .masthead nav a[aria-current]{color:var(--ink);font-weight:500}
.grow{flex:1}

/* ── THE GUIDE BAR — the guides, named, on every page ────────────────────────────────────────────────────────────
   A single `Guides` link asked the reader to click before learning that the durable engine or the security model
   had a page at all. Seven named ones are an offer rather than a filing cabinet. It sits UNDER the masthead and
   replaces that link, because two routes to the same place in one header is how a header stops being read. */
.guidebar{border-bottom:1px solid var(--rule);background:var(--card)}
.guidebar .in{max-width:1220px;margin-inline:auto;padding:9px 26px;display:flex;align-items:center;
  gap:7px;flex-wrap:wrap;font-family:var(--mono);font-size:12px}
.guidebar a{color:var(--ink-2);text-decoration:none;padding:4px 10px 5px;border-radius:999px;
  border:1px solid transparent;transition:color .16s,border-color .16s,background .16s;white-space:nowrap}
.guidebar a:hover{color:var(--ink);border-color:var(--rule-2)}
.guidebar a[aria-current]{color:var(--accent);font-weight:600;
  border-color:color-mix(in oklab,var(--accent) 32%,transparent);
  background:color-mix(in oklab,var(--accent) 9%,transparent)}
/* The index keeps its own place at the left, so nothing is unreachable — set apart, not competing. */
.gb-all{color:var(--ink-3) !important;letter-spacing:.13em;text-transform:uppercase;font-size:10.5px;
  padding-left:0 !important;margin-right:4px}
.gb-all:hover{border-color:transparent !important;color:var(--ink-2) !important}
@media(max-width:620px){.guidebar .in{padding:8px 16px;gap:5px}}
.find{border:1px solid var(--rule-2);border-radius:20px;background:var(--card);color:var(--ink);
  font-family:var(--mono);font-size:12px;padding:6px 13px;min-width:190px;max-width:100%}
/* Below this the nav, the search box and the wordmark cannot share one 56px row without one of them
   pushing the header past the viewport. The search goes; ⌘K still reaches it on a keyboard. */
/* Narrower still, the nav becomes its own scrollable row under the mark rather than pushing the page wider
   than the viewport — measured at 390px: the row of six links was 410px and the whole body scrolled sideways. */
@media(max-width:620px){.masthead .in{gap:14px;height:auto;flex-wrap:wrap;padding-block:12px 8px}.find{display:none}
  .masthead nav{flex-basis:100%;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}}
.find::placeholder{color:var(--ink-3)}

/* ── the three-column reading shell ── */
.shell{max-width:1320px;margin-inline:auto;padding-inline:26px;display:grid;gap:40px;align-items:start}
/* ⚠ `> article`, not `article`: the home page's marquee rows are <article>s too, and the descendant form squeezed
   the whole home page into a reading column. A reference page's article is main's direct child. */
.shell>main:has(> article){max-width:84ch}
/* The grid is sized to the columns that EXIST — a page with a rail and no table of contents must not reserve an
   empty 200px on the right. The classes come from the shell builder; the template lives here so the phone rule
   below can override it (an inline style could not be overridden, and was — see Shell.cs). */
.shell{grid-template-columns:minmax(0,1fr)}
.shell.has-rail{grid-template-columns:212px minmax(0,1fr)}
.shell.has-toc{grid-template-columns:minmax(0,1fr) 200px}
.shell.has-rail.has-toc{grid-template-columns:212px minmax(0,1fr) 200px}
@media(max-width:1040px){.shell,.shell.has-rail,.shell.has-toc,.shell.has-rail.has-toc{grid-template-columns:minmax(0,1fr)}.rail,.toc{display:none}}
.rail{position:sticky;top:56px;max-height:calc(100vh - 56px);overflow:auto;padding:26px 18px 60px 0;
  border-right:1px solid var(--rule)}
.rail h5{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);margin:20px 0 7px;font-weight:500}
.rail h5:first-child{margin-top:0}
.rail a{display:block;font-size:13.5px;color:var(--ink-2);padding:2.5px 0;line-height:1.45}
.rail a[aria-current]{color:var(--accent);font-weight:500}
.rail .n{float:right;margin-left:12px;font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
main{padding:30px 0 80px;min-width:0}
.toc{position:sticky;top:56px;padding:30px 0}
.toc h5{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 8px;font-weight:500}
.toc a{display:block;font-size:12.5px;color:var(--ink-2);padding:3px 0;line-height:1.4}

/* ── page head ── */
.crumbs{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);margin-bottom:12px}
.crumbs a{color:var(--ink-3)}
h1{font-size:clamp(25px,3.2vw,34px);line-height:1.18;letter-spacing:-.02em;margin:0 0 10px;font-weight:600}
.sig{font-family:var(--mono);font-size:13px;color:var(--ink-2);background:var(--wash);
  border:1px solid var(--rule);border-left:3px solid var(--accent);border-radius:0 var(--radius) var(--radius) 0;
  padding:10px 14px;margin:0 0 16px;overflow-x:auto;white-space:pre-wrap}
.summary{font-size:17px;color:var(--ink-2);max-width:66ch;margin:0 0 20px}
.badges{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 26px}
.badge{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;padding:3px 9px;border-radius:20px;
  border:1px solid var(--rule-2);color:var(--ink-2);background:var(--card)}
.badge.stable{border-color:var(--allow);color:var(--allow);background:var(--allow-wash)}
.badge.preview{border-color:var(--mark);color:var(--mark);background:var(--mark-wash)}

/* ── body ── */
article h2{font-size:20px;letter-spacing:-.015em;margin:34px 0 10px;font-weight:600;
  padding-top:8px;border-top:1px solid var(--rule)}
article h3{font-size:16.5px;margin:24px 0 8px;font-weight:600}
article p{max-width:68ch}
article ul,article ol{max-width:68ch;padding-left:22px}
article li{margin:4px 0}
article h2 a.anchor,article h3 a.anchor{opacity:0;margin-left:8px;font-family:var(--mono);
  font-size:.7em;color:var(--ink-3);text-decoration:none}
article h2:hover a.anchor,article h3:hover a.anchor{opacity:1}

/* A DECLARED forward reference — a page the contract says is owed. Marked rather than linked, because a link to
   a page that does not exist is worse than an honest "not written yet". */
.planned{border-bottom:1px dotted var(--ink-3);color:var(--ink-2);cursor:help}

/* ── index/listing cards ── */
.cards{display:grid;gap:13px;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));margin:18px 0 30px}
.card{border:1px solid var(--rule);border-radius:var(--radius);padding:15px 16px;background:var(--card)}
.card a{display:block;font-weight:600;font-size:15px;margin-bottom:4px;color:var(--ink)}
.card a:hover{color:var(--accent);text-decoration:none}
.card p{margin:0;font-size:13.5px;color:var(--ink-2);max-width:none}
.card .n{float:right;font-family:var(--mono);font-size:11px;color:var(--ink-3);font-weight:400}

/* ── search ── */
#results{position:absolute;top:50px;right:26px;width:min(560px,calc(100vw - 52px));max-height:66vh;overflow:auto;
  background:var(--card);border:1px solid var(--rule-2);border-radius:8px;box-shadow:0 18px 46px -14px rgba(0,0,0,.3);
  z-index:40;padding:6px;display:none}
#results.on{display:block}
#results a{display:block;padding:9px 11px;border-radius:5px;color:var(--ink)}
#results a:hover,#results a:focus-visible{background:var(--wash);text-decoration:none}
#results b{display:block;font-size:14px;font-weight:600}
#results span{display:block;font-size:12.5px;color:var(--ink-3);margin-top:1px}
#results .none{padding:14px 12px;color:var(--ink-3);font-size:13.5px}

footer{border-top:1px solid var(--rule);margin-top:40px}
footer .in{max-width:1220px;margin-inline:auto;padding:26px;color:var(--ink-3);font-size:13px}
/* The contact line sits on its own row so it reads as an invitation rather than as the tail of a sentence
   about how examples are verified. */
footer .contact{display:block;margin-top:10px;color:var(--ink-2)}
footer .contact a{color:var(--accent);text-decoration:none;border-bottom:1px solid transparent}
footer .contact a:hover{border-bottom-color:var(--accent)}

/* ── A TERMINAL IS DARK ──────────────────────────────────────────────────────────────────────────
   A token swap rather than a restyle: every syntax class reads `var(--accent)`, `var(--allow)` and
   friends, so redefining those tokens INSIDE the card recolours the whole listing with no second
   stylesheet. The card is dark in both site themes, which is what a terminal is. */
.term{
  --card:var(--term-card); --wash:var(--term-wash); --rule:var(--term-rule); --rule-2:var(--term-rule2);
  --ink:var(--term-ink); --ink-2:var(--term-ink2); --ink-3:var(--term-ink3);
  --accent:var(--term-accent); --allow:var(--term-allow);
  --refuse:var(--term-refuse); --mark:var(--term-mark);
  --accent-wash:color-mix(in srgb,var(--term-accent) 18%,var(--term-card));
  background:var(--card);border-color:var(--rule);color:var(--ink);
}
.term pre{background:var(--card);color:var(--ink)}
/* the receipt vocabulary shared by every terminal on the site */
pre .p{color:var(--accent);font-weight:500}   /* prompt */
pre .d{color:var(--ink-2)}                    /* machine output — ink-2, never ink-3 (measured) */
pre .u{color:var(--allow)}                    /* the URL it hands you */
pre .c{color:var(--ink-3)}                    /* source comment */
pre .k{color:var(--accent)}                   /* keyword */
pre .s{color:var(--allow)}                    /* string */
pre .t{color:var(--mark);font-weight:600}     /* entity · component · class */
pre .e{color:var(--mark)}                     /* enum member · policy */
pre .f{color:var(--ink);font-weight:500}      /* function being called */
pre .n{color:var(--refuse)}                   /* number */
pre .r{color:var(--refuse);font-weight:600}   /* a refusal, or a durability verdict */
pre .a{color:var(--accent);opacity:.75}       /* [Attribute] */
pre.term{border:1px solid var(--rule);border-radius:6px;padding:16px 17px}

/* ── spec + samples ──────────────────────────────────────────────────────────────────────────── */
.note{background:var(--accent-wash);border-left:3px solid var(--accent);padding:12px 16px;
  border-radius:0 var(--radius) var(--radius) 0;margin:18px 0;font-size:14.5px;max-width:68ch}
/* A section that is not written yet. Shown, never linked — a contents page that hides what is missing
   is worse than none, because the reader cannot tell a gap from an oversight. */
.unwritten{display:block;font-size:13.5px;color:var(--ink-3);padding:2.5px 0;line-height:1.45}
td .unwritten{display:inline}
.run{border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;max-width:520px;margin:0 0 26px}
.run-head{margin:0;padding:9px 15px;background:var(--wash);border-bottom:1px solid var(--rule);
  font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3)}
.run pre{margin:0;border:0;border-radius:0;background:var(--card);padding:14px 15px}
details.src{border:1px solid var(--rule);border-radius:var(--radius);margin:10px 0;background:var(--card)}
details.src summary{cursor:pointer;padding:10px 15px;font-family:var(--mono);font-size:12.5px;
  color:var(--ink-2);list-style:none;display:flex;align-items:center}
details.src summary::-webkit-details-marker{display:none}
details.src summary::before{content:"▸";margin-right:9px;color:var(--ink-3)}
details.src[open] summary::before{content:"▾"}
details.src summary:hover{color:var(--ink)}
details.src summary .n{margin-left:auto;color:var(--ink-3);font-size:11px}
details.src pre{margin:0;border:0;border-top:1px solid var(--rule);border-radius:0}

/* A sample's screenshot. Framed like a window rather than bled to the edge, because these are apps and the
   frame is what says so. `aspect-ratio` + explicit width/height on the img means the card reserves its space
   before the picture arrives — a grid that reflows as 13 images load reads as broken. */
.card.sample{padding:0;overflow:hidden;display:flex;flex-direction:column}
.card.sample .shot{display:block;border-bottom:1px solid var(--rule);background:var(--wash)}
.card.sample img{display:block;width:100%;height:auto;aspect-ratio:960/640;object-fit:cover;object-position:top}
.card.sample > a:not(.shot){padding:14px 16px 0}
.card.sample p{padding:4px 16px 15px}
/* a package card: the blurb, its `use` line, then Source · Latest release · Reference along the bottom */
.card.sample.pkg p{padding:4px 16px 8px}
.card.sample.pkg p.use code{font-size:12px}
.card.sample.pkg p.links{margin-top:auto;padding:6px 16px 15px;display:flex;flex-wrap:wrap;gap:4px 14px}
.card.sample.pkg p.links a{display:inline;padding:0;margin:0;font-size:13px;font-weight:500;color:var(--accent)}
.shotframe{margin:0 0 26px;border:1px solid var(--rule);border-radius:7px;overflow:hidden;background:var(--wash);max-width:760px}
.shotframe img{display:block;width:100%;height:auto;aspect-ratio:960/640;object-fit:cover;object-position:top;
  border-bottom:1px solid var(--rule)}
.shotframe figcaption{padding:10px 15px;font-size:13px;color:var(--ink-3);background:var(--card)}

/* ── SYNTAX COLOURING, from the compiler ─────────────────────────────────────────────────────────
   The classes are what the LEXER and the LANGUAGE SERVER decided, not a grammar written twice. Kept
   to few hues on purpose: a listing where nine things are coloured is a listing where nothing is. */
pre .t-comment{color:var(--ink-3);font-style:italic}
pre .t-kw     {color:var(--accent);font-weight:600}
pre .t-string {color:var(--allow)}
pre .t-num    {color:var(--refuse)}
pre .t-type   {color:var(--mark);font-weight:600}   /* entity · class */
pre .t-component{color:var(--mark);font-weight:600}
pre .t-enum   {color:var(--mark)}
pre .t-attr   {color:var(--accent);opacity:.72}     /* [Attribute] */
pre .t-fn,pre .t-prop,pre .t-var,pre .t-ident{color:inherit}

/* THE EXECUTION SIDE — wired, and currently never emitted (measured: 1,276 function tokens, zero with a
   side). Kept so that the day the provider attaches one, this is all that has to change. */
pre .s-server{border-bottom:1px dotted color-mix(in srgb, var(--accent) 55%, transparent)}

/* THE COLOUR SWATCH — what the editor shows beside a hex literal in a theme. `--c` is the colour itself, so
   the chip is the value rather than a description of it. Bordered, because a swatch of the page's own
   background against the page's own background is an invisible square that reads as a rendering bug. */
pre .swatch{display:inline-block;width:.72em;height:.72em;margin-right:.35em;vertical-align:-.04em;
  border-radius:2px;background:var(--c);box-shadow:inset 0 0 0 1px rgba(128,128,128,.45)}

/* ── MOTION, sparingly and only on things you point at. A page that animates on its own is a page
   that gets in the way; a page where the thing under the cursor answers feels built rather than
   printed. Everything here is disabled under prefers-reduced-motion by the rule at the top. */
a,.card,.badge,#dirpick button{transition:color .12s ease,background-color .12s ease,
  border-color .12s ease,transform .12s ease}
.card{transition:border-color .14s ease,transform .14s ease,box-shadow .14s ease}
.card:hover{border-color:var(--accent);transform:translateY(-2px);
  box-shadow:0 6px 20px -8px color-mix(in srgb, var(--accent) 40%, transparent)}
.card.sample:hover img{filter:saturate(1.06)}
.rail a:hover{color:var(--accent)}
.rail a[aria-current]{color:var(--accent);font-weight:600}


/* Badges stop being grey outlines and start meaning something at a glance. */
.badge{border-width:1px;font-weight:500}
.badge.stable{background:var(--allow-wash);border-color:var(--allow);color:var(--allow)}
.badge.preview{background:var(--mark-wash);border-color:var(--mark);color:var(--mark)}

/* The eyebrow and section numbers carry the accent instead of grey. */
.eyebrow,.sec-no{color:var(--accent)}
.rail .n,.card .n{color:var(--accent);opacity:.75}

/* ── GUIDES ──────────────────────────────────────────────────────────────────────────────────────
   A guide is one subject top to bottom, so it needs devices the reference does not: a source
   specimen with numbered call-outs pointing INTO it, and a consequences grid. Both exist because
   the question a reader actually has is "show me, and tell me what this costs me later". */
.standfirst{font-size:18.5px;line-height:1.55;color:var(--ink-2);margin:0 0 34px;
  padding-bottom:26px;border-bottom:1px solid var(--rule)}

.gsec{padding-block:14px 34px}
.gsec .sec-no{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--accent);
  margin:0 0 6px}
.gsec h2{font-size:26px;letter-spacing:-.022em;margin:0 0 10px;font-weight:600;text-wrap:balance}
.gsec h3{font-size:16.5px;margin:26px 0 8px;font-weight:600;letter-spacing:-.012em}
/* ⛔ NO `ch` CAP ON GUIDE PROSE. A guide sits beside the rail, so its column is ~1016px where the home page has
   1268 — and a 60-62ch measure then stopped the text two-thirds of the way across, beside nothing. The owner
   asked for the full width on the wba guide first and then for "all guides"; these are the rest of them. */
.gsec .say{font-size:16.5px;color:var(--ink-2);margin:0 0 22px}
.gsec.next h2{font-size:20px}

/* The specimen: source on the left, the call-outs it carries on the right. On a narrow screen the
   notes fall UNDER the source rather than beside it — a note beside a horizontally-scrolling code
   block is unreadable either way. */
/* The source runs FULL WIDTH and the call-outs sit under it in two columns. Beside-the-code was the
   first shape and it was wrong twice over: a real file has long lines, so the source column scrolled
   while half the width sat under prose; and note 4 ended up level with line 12, which is worse than
   no alignment because it reads as an alignment. */
.specimen{margin:6px 0 30px}
.specimen .src{border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;
  background:var(--card);min-width:0}
.src-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;padding:9px 14px;
  background:var(--wash);border-bottom:1px solid var(--rule);
  font-family:var(--mono);font-size:11px}
.src-head .path{color:var(--ink-2)}
.src-head .stance{color:var(--allow);margin-left:auto}
pre.code{margin:0;border:0;border-radius:0;background:var(--card);padding:14px 14px 16px;
  font-size:12.4px;line-height:1.62;overflow-x:auto}
pre.code.plain{border:1px solid var(--rule);border-radius:var(--radius);margin:0 0 22px;padding:15px 16px}
/* The gutter is always there, so a marked line does not shift sideways relative to its neighbours. */
pre.code .ln{display:inline-block;width:22px;user-select:none}
.cal{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;
  border-radius:50%;background:var(--accent);color:#fff;font-family:var(--mono);font-size:10px;
  font-weight:500;font-style:normal;line-height:1}

.notes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px 30px;margin-top:16px}
@media(max-width:760px){.notes{grid-template-columns:minmax(0,1fr)}}
.cnote{display:grid;grid-template-columns:18px minmax(0,1fr);gap:11px;align-items:start}
.cnote .cal{margin-top:2px}
.cnote p{margin:0;font-size:14px;line-height:1.55;color:var(--ink-2)}
.cnote p b{color:var(--ink);font-weight:600}

/* An aside is a claim about consequences, so it is coloured by which way it cuts. */
.gnote{border-left:3px solid var(--rule-2);background:var(--card);border-radius:0 var(--radius) var(--radius) 0;
  padding:13px 16px;margin:0 0 24px}
.gnote-head{margin:0 0 4px;font-weight:600;font-size:14.5px;color:var(--ink)}
.gnote p{margin:0;font-size:14.5px;color:var(--ink-2);line-height:1.55;max-width:none}
/* ⛔ THE NEUTRAL ASIDE IS `.info`, NOT `.note`, AND THE RENAME IS THE FIX. `.note` is the REFERENCE pages'
   own callout — accent wash, `max-width:68ch` — and a guide aside written as `class="gnote note"` picked both
   up: every neutral aside on every guide has been rendering two-thirds width, in the wrong colour, since the
   guides were written. Measured 2026-09-01: 642px beside its own section's 876px. Same failure as the `.tag`
   collision — a modifier word that another component already owns. */
.gnote.info{border-left-color:var(--rule-2)}
.gnote.ok{border-left-color:var(--allow);background:color-mix(in srgb,var(--allow) 6%,var(--card))}
.gnote.warn{border-left-color:var(--mark);background:color-mix(in srgb,var(--mark) 8%,var(--card))}

.deftable{overflow-x:auto;margin:0 0 24px}
.deftable table{margin:0;font-size:14px;display:table;width:100%}
.deftable th{text-align:left;font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);font-weight:500;padding:7px 12px 7px 0;
  border-bottom:1px solid var(--rule)}
.deftable td{padding:7px 12px 7px 0;border-bottom:1px solid var(--rule);color:var(--ink-2);vertical-align:top}
.deftable td.y{color:var(--allow);font-weight:600}
.deftable td.n{color:var(--refuse);font-weight:600}

/* The consequences grid — a change somebody will make, the verdict, and why. */
.whw{border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;background:var(--card);margin:4px 0 8px}
.whw-head{margin:0;padding:10px 15px;background:var(--wash);border-bottom:1px solid var(--rule);
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.whw-row{display:grid;grid-template-columns:minmax(0,1fr) 92px minmax(0,1.5fr);gap:16px;
  padding:12px 15px;border-bottom:1px solid var(--rule);align-items:start;font-size:14px}
.whw-row:last-child{border-bottom:0}
.whw-row .q{color:var(--ink);font-weight:500}
.whw-row .v{font-family:var(--mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;
  padding:2px 8px;border-radius:20px;justify-self:start;white-space:nowrap}
.whw-row .v.ok{color:var(--allow);background:color-mix(in srgb,var(--allow) 12%,transparent)}
.whw-row .v.no{color:var(--refuse);background:color-mix(in srgb,var(--refuse) 12%,transparent)}
.whw-row .a{color:var(--ink-2);line-height:1.5}
@media(max-width:720px){.whw-row{grid-template-columns:minmax(0,1fr);gap:6px}}

/* The two-colour markers: which half of the program a line becomes. Client and server are given the
   two accents the rest of the site already uses for "your code" and "declared fact", so the reader
   is not learning a third colour language on this page. */
.cal.c{background:var(--accent)}
.cal.s{background:var(--mark)}
/* ⛔ THE NUMBER STAYS WHITE INSIDE A CODE BLOCK, and it takes this rule to keep it there. A CLASS-NAME COLLISION:
   the markers are `.cal.c` (client) and `.cal.s` (server), and `c` and `s` are ALSO the syntax tokens for a
   comment and a string. `.cal{color:#fff}` is one class (0,1,0); `pre .c{…}` is an element plus a class (0,1,1),
   so inside a listing the token rule won and the digit took the comment's grey or the string's green — on the
   marker's own dark fill. Measured 2026-09-01: rgb(107,135,141) on rgb(0,86,111), and rgb(13,114,86) on
   rgb(141,102,6). Legible in the legend underneath, effectively invisible in the source view they index.
   Two classes (0,2,0) beats the token rule wherever it appears, so this does not depend on source order. */
.cal.c,.cal.s{color:#fff}
.legend{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 14px;
  font-size:13.5px;color:var(--ink-2)}
.legend .cal{width:14px;height:14px;margin-left:10px}
.legend .cal:first-child{margin-left:0}
.legend-say{color:var(--ink-3);margin-left:4px}


/* ─────────────────────────────────────────────────────────────────────────────────────────────────────────
   THE "WRITTEN BY AGENTS" PAGE. The only page on this site that is allowed its own visual register, because it
   is the only one making an ARGUMENT about the world rather than explaining a construct. Everything here is
   scoped under `.wba` so no other page can pick it up by accident.

   The register is: one very large claim, then proof in the machine's own voice. The terminal blocks are not
   decoration on this page — they ARE the argument, so they are given full width and room to breathe rather
   than being tucked beside prose. */
.wba-hero{margin:0 0 8px;padding-block:8px 46px;border-bottom:1px solid var(--rule)}
.wba-eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--accent);margin:0 0 18px}
.wba-hero h1{font-size:clamp(34px,5.6vw,62px);line-height:1.04;letter-spacing:-.035em;font-weight:650;
  margin:0 0 22px;text-wrap:balance}
.wba-hero h1 em{font-style:normal;color:var(--accent)}
.wba-lede{font-size:clamp(17px,1.9vw,21px);line-height:1.5;color:var(--ink-2);margin:0}

/* The four verbs, as a strip. A machine's whole vocabulary for interrogating an app fits on one line, and
   showing that is more persuasive than saying it. */
.wba-verbs{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;margin:38px 0 0;
  background:var(--rule);border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden}
.wba-verbs>div{background:var(--card);padding:16px 17px 17px}
.wba-verbs code{font-size:13.5px;color:var(--accent);background:none;padding:0;font-weight:600}
.wba-verbs p{margin:7px 0 0;font-size:13.5px;line-height:1.5;color:var(--ink-2)}
@media (max-width:820px){.wba-verbs{grid-template-columns:1fr 1fr}}
@media (max-width:480px){.wba-verbs{grid-template-columns:1fr}}

/* A section on this page is a claim, then its evidence. The number is small and the claim is not. */
.wba-sec{padding-block:52px 6px;border-top:1px solid var(--rule)}
.wba-sec:first-of-type{border-top:0}
.wba-no{font-family:var(--mono);font-size:11px;letter-spacing:.16em;color:var(--accent);margin:0 0 10px;
  display:flex;align-items:center;gap:11px}
/* ⛔ THE VERB THE SECTION IS ABOUT, AT THE SECTION HEAD (owner, 2026-09-01). The page makes a large claim about the
   CLI and then only ever named the command inside a terminal sample — so a reader scanning the headings could not
   see which question each one answers, and had to read a code block to find out. Two sections carry no pill on
   purpose: §01 is the framing and §06 is the security posture. A pill on those would be decoration, and decoration
   is what teaches people to stop reading the real ones. */
.wba-cmd{font-family:var(--mono);font-size:11.5px;letter-spacing:0;text-transform:none;
  color:var(--accent);background:color-mix(in oklab,var(--accent) 11%,transparent);
  border:1px solid color-mix(in oklab,var(--accent) 26%,transparent);
  border-radius:999px;padding:3px 10px 4px;font-weight:600;white-space:nowrap}
.wba-sec h2{font-size:clamp(25px,3.3vw,38px);line-height:1.12;letter-spacing:-.03em;font-weight:620;
  margin:0 0 16px;text-wrap:balance}
.wba-sec>p{line-height:1.62}
.wba-say{font-size:17.5px;line-height:1.55;color:var(--ink-2);margin:0 0 26px}
.wba-sec pre{margin:24px 0 0}
.wba-after{font-size:15.5px;line-height:1.62;color:var(--ink-2);margin:20px 0 0}
.wba-after b{color:var(--ink);font-weight:600}

/* THE PULL. One line per page-half, set large, doing the work a headline cannot because it needs the sections
   around it to have happened first. */
.wba-pull{margin:44px 0 8px;padding:30px 0 0;border-top:2px solid var(--accent)}
.wba-pull p{font-size:clamp(21px,2.7vw,30px);line-height:1.28;letter-spacing:-.022em;font-weight:600;
  margin:0;text-wrap:balance}
.wba-pull span{color:var(--accent)}

/* The closing pair: discoverable AND bounded, side by side, because the whole point is that neither alone is
   worth anything. */
.wba-pair{display:grid;grid-template-columns:1fr 1fr;gap:28px;margin:30px 0 0}
.wba-pair>div{border:1px solid var(--rule);border-radius:var(--radius);background:var(--card);padding:22px 24px}
.wba-pair h3{margin:0 0 9px;font-size:16.5px;font-weight:640;letter-spacing:-.012em}
.wba-pair p{margin:0;font-size:15px;line-height:1.6;color:var(--ink-2)}
.wba-pair .k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);display:block;margin:0 0 10px}
@media (max-width:760px){.wba-pair{grid-template-columns:1fr;gap:18px}}

/* PAIRED PANES: the source, and what the tool said about it. CSS-ONLY — radio inputs and sibling selectors,
   no JavaScript. A page whose argument is "the machine can read this" should not need a script to show it, and
   a tab that fails with JS off is a tab that fails in a fetch, a reader-mode view and a printout.

   The inputs are visually hidden but focusable, so the pair is keyboard-operable and announces as a radio group. */
.pane{margin:24px 0 0;border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;background:var(--card)}
.pane>input{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px}
.pane-bar{display:flex;gap:0;background:var(--wash);border-bottom:1px solid var(--rule)}
.pane-bar label{padding:10px 16px 9px;font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);cursor:pointer;border-bottom:2px solid transparent;
  margin-bottom:-1px;transition:color .15s,border-color .15s;user-select:none}
.pane-bar label:hover{color:var(--ink-2)}
.pane-body{display:none}
.pane-body pre{margin:0;border:0;border-radius:0}
/* ⛔ THE BODIES CARRY EXPLICIT `.a`/`.b` CLASSES, NOT `:nth-of-type`. The first cut used nth-of-type and BOTH
   panes rendered blank: nth-of-type counts among siblings of the same ELEMENT — and `.pane-bar` is a div too, so
   `.pane-body:nth-of-type(1)` asked for "the first div, which also has class pane-body", which is never true.
   The tab bar looked perfect while the content underneath it was gone, which is exactly the kind of silent
   failure a screenshot catches and a build does not. */
.pane>input.a:checked~.pane-bar label.a,
.pane>input.b:checked~.pane-bar label.b{color:var(--accent);border-bottom-color:var(--accent)}
.pane>input.a:checked~.pane-body.a,
.pane>input.b:checked~.pane-body.b{display:block}
.pane>input:focus-visible~.pane-bar label{outline:2px solid var(--accent);outline-offset:-2px}
/* The source pane is paper, the output pane is terminal — so which one you are looking at is obvious before
   you read a word of it. */
.pane-body.src-pane pre{background:var(--card);color:var(--ink);padding:18px 20px}

/* The four questions an agent can ask. A 2×2 rather than a list: they are peers, not steps, and a numbered
   sequence would imply an order that does not exist. Collapses to one column on a narrow screen. */
.asks{display:grid;grid-template-columns:1fr 1fr;gap:22px 34px;margin:26px 0 0;max-width:72ch}
.asks>div{min-width:0}
.ask-k{font-weight:600;font-size:15px;margin:0 0 5px;letter-spacing:-.01em}
.asks p:last-child{margin:0;font-size:15px;line-height:1.58;color:var(--ink-2)}
@media (max-width:720px){.asks{grid-template-columns:1fr;gap:20px}}

/* The ledger: what you would build, and what replaces it. Two columns, hairline rows, and the word
   "Nothing" is the whole point — so it is the one thing painted. */
.ledger{border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;background:var(--card);margin:4px 0 0}
.ledger-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:24px;padding:10px 18px;
  background:var(--wash);border-bottom:1px solid var(--rule);font-family:var(--mono);font-size:11px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.lr{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:24px;padding:13px 18px;
  border-bottom:1px solid var(--rule);font-size:15px;align-items:baseline}
.ledger .lr:last-child{border-bottom:0}
.lr .q{color:var(--ink-2)}
.lr .a{color:var(--ink-2)}
.lr .a b{color:var(--ink);font-weight:600}
.lr .a b.none{color:var(--allow)}
.lr .a b.stop{color:var(--refuse)}
.ledger.tight .lr{padding:15px 18px}
@media(max-width:760px){.ledger-head{display:none}.lr{grid-template-columns:minmax(0,1fr);gap:5px}}


/* The row LABEL carries the semantics; the examples beside it are just examples. `td.n` painted the
   whole cell, which made three ordinary nouns look like an error message. */
.deftable td b.ext{color:var(--refuse)}

/* ── screenshot + source panes (the UI guide's §4) ───────────────────────────────────────────
   The image is the pane's whole body: no padding, no frame of its own, so the app's own edge is
   the edge. A shot is 2× the pane's width, which is why it is scaled by `width:100%` rather than
   given intrinsic size — a 1× asset would read as soft on every retina display. */
.shotpane{margin:28px 0 0}
.shotpane figcaption{margin:0 0 8px;font-size:14.5px;color:var(--ink-2);line-height:1.5}
.shotpane figcaption b{color:var(--ink);font-weight:600}
.pane-body img.shot{display:block;width:100%;height:auto;background:var(--wash)}

/* ── the app shells (the UI guide's §5) ─────────────────────────────────────────────────────────
   Two columns of real screenshots. A shell whose phone arrangement is the interesting half carries a
   phone frame beside its desktop one: at 22% of the width a 390×844 frame comes out the same height as
   a 16:10 desktop frame at 78%, so the two sit on one baseline without any cropping. */
.shells{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:26px 22px;margin:26px 0 0}
.shellfig{margin:0}
.shellfig .frames{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;align-items:end}
.shellfig .frames.two{grid-template-columns:minmax(0,1fr) 22%}
.shellfig img{display:block;width:100%;height:auto;border:1px solid var(--rule);border-radius:var(--radius);background:var(--wash)}
.shellfig figcaption{margin:10px 0 0;font-size:14.5px;color:var(--ink-2);line-height:1.5}
.shellfig figcaption b{color:var(--ink);font-weight:600}
.shellfig figcaption .for{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--accent);margin-left:10px}
.shellfig figcaption p{margin:4px 0 0}
.shellfig figcaption a{color:var(--ink-2);white-space:nowrap}
.shellfig figcaption a:hover{color:var(--accent)}
.shells-soon{list-style:none;padding:0;margin:10px 0 0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 22px}
.shells-soon li{font-size:14px;color:var(--ink-2);line-height:1.5;padding:9px 0;border-top:1px solid var(--rule)}
.shells-soon li b{color:var(--ink);font-weight:600;margin-right:8px}
.shells-soon li .tag{margin-right:8px;vertical-align:1px}
@media (max-width:760px){.shells,.shells-soon{grid-template-columns:1fr}}

/* ── the guide teasers (the UI guide's four screens, above the fold) ─────────────────────────────
   Thumbnails of the REAL screenshots, cropped by CSS rather than as separate assets — one file per
   shot, so a re-captured screenshot cannot disagree with its own teaser. `object-position: top left`
   because the recognisable part of an app screenshot is its top-left: the masthead, the first rows,
   the thing with the colour in it. */
.teasers{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:12px;margin:0 0 34px}
.teaser{display:block;text-decoration:none;border:1px solid var(--rule);border-radius:var(--radius);
  overflow:hidden;background:var(--card);transition:border-color .12s ease,transform .12s ease}
.teaser img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top left;
  background:var(--wash)}
.teaser span{display:block;padding:8px 10px 9px;font-size:12.5px;color:var(--ink-2);
  border-top:1px solid var(--rule);letter-spacing:-.005em}
.teaser:hover{border-color:var(--accent);transform:translateY(-1px)}
.teaser:hover span{color:var(--accent)}
.teaser:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* The sticky masthead would otherwise sit on top of whatever an anchor jumps to. */
.shotpane{scroll-margin-top:96px}
@media (max-width:820px){ .teasers{grid-template-columns:repeat(2,1fr)} }

/* A strip of EDITOR shots: three VS Code windows are the same grey rectangle at thumbnail size, so the strip
   magnifies and looks at the LEFT of the window — the explorer, the test tree and the debugger's stack are what
   differ between them, and that is where they live.
   ⚠ `transform: scale` on the fitted image, NOT `object-fit: none`: the sources are 2880px wide, so `none` renders
   them at natural size and a thumbnail becomes four filenames at 40px tall. Measured by looking at it. */
.teasers.zoom .teaser>div{aspect-ratio:16/10;overflow:hidden;display:block}
.teasers.zoom .teaser img{display:block;width:100%;height:auto;aspect-ratio:auto;object-fit:fill;
  transform:scale(1.85);transform-origin:14% 34%}

/* ── COMPILED AWAY — the type roles, the masthead and the two containers ─────────────────────────
   (owner, 2026-09-03 — the direction chosen from the four in website/design/; IMPLEMENT.md is the brief.)

   Two rules carry the whole look and everything below is their consequence. ONE: there are exactly two kinds
   of container — the TERMINAL (surface, 1px rule, 6px radius, a small mono label) and the FIGURE (an image on
   the ground with an ember glow) — and everything else is type on the ground, separated by space and a single
   hairline. No cards on the home page or the chapters. TWO: why, then how, then proof — so the type roles are a
   reading order (eyebrow → display heading → deck → prose → receipt), not a set of decorations.

   The display face is the SAME family at a different optical size: Bricolage at opsz 96 is a different drawing
   from Bricolage at 14, and `--display` is how a heading asks for it without a second font. */
:root{--accent-2:color-mix(in srgb,var(--accent) 70%,#fff);--on-accent:#fff;--display:'opsz' 96}
body{font-variation-settings:'opsz' 14}
.display,h1{font-variation-settings:var(--display)}

/* the masthead: wordmark, the beta mark, what-it-is, the nav, search. Borderless; the chapter bar under it
   carries the one hairline. Not sticky: the page is read top to bottom and a 60px band that follows you is
   60px of every screen spent on a thing you already read. */
.masthead{border:0;background:var(--paper);position:relative}
.masthead .in{max-width:1180px;padding-inline:32px;height:62px;gap:18px}
.mark{font-size:18px;font-weight:700}
.beta{display:inline-block;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);border:1px solid color-mix(in srgb,var(--accent) 55%,transparent);border-radius:4px;
  padding:2px 7px 3px;line-height:1;vertical-align:middle;margin-left:-8px}
.brandline{font-size:12.5px;color:var(--ink-2)}
.masthead nav a{white-space:nowrap}
.masthead nav a.get{color:var(--accent);font-weight:500}
/* ⚠ MEASURED, NOT EYEBALLED: with Playwright at 1300 the row was 1325px wide and at 768 it was 841 — the search
   box's min-width and the brandline were pushing the page past the viewport on every page. So the brandline goes
   first (below 1280), the search box next (below 900; ⌘K still reaches it), and the row never exceeds the page. */
.masthead .in{flex-wrap:nowrap;min-width:0}
.masthead .find{min-width:150px;width:190px;flex:0 1 190px}
/* ⚠ THE BRANDLINE SHOWS ONLY WHERE THE WHOLE ROW FITS THE WINDOW. Brandline + nav + search is wider than the 1180px
   column, so the row spills into the right margin; at 1280px it hid too late and the page scrolled sideways between
   1280 and ~1300, and one more nav entry (Packages) pushed that to ~1460. Measured, not reasoned: see the commit. */
@media(max-width:1479px){.brandline{display:none}}
@media(max-width:900px){.masthead .find{display:none}}
#results{top:56px;right:32px}
/* THE CHAPTER BAR — a row of plain mono links, the page you are on underlined in the accent. The pills are
   gone: nine bordered chips read as nine buttons, and a bar of buttons is a second menu. */
.guidebar{border-bottom:1px solid var(--rule);background:var(--paper)}
.guidebar .in{max-width:1180px;padding:4px 32px 14px;gap:20px;font-size:12px;flex-wrap:nowrap;overflow-x:auto;white-space:nowrap;scrollbar-width:none}
.guidebar a{padding:0;border:0;border-radius:0;transition:color .16s}
.guidebar a:hover{color:var(--ink);border:0}
.guidebar a[aria-current]{color:var(--ink);font-weight:400;background:none;border:0;
  text-decoration:underline;text-decoration-color:var(--accent);text-underline-offset:6px}
.gb-all{color:var(--accent) !important;font-size:10.5px;padding-top:1px}
.gb-all:hover{color:var(--accent-2) !important}
/* ⚠ RE-ASSERTED HERE because the `nowrap` above outranks the phone rule higher up (same selector, later in the
   file). Without this the nav shared the wordmark's row at 390px and `Get it` — the one call to action — sat past
   the right edge. The nav takes its own row; the guide row still scrolls sideways, and the fade at its right edge
   is what says so. */
@media(max-width:620px){.masthead{position:static}.masthead .in{flex-wrap:wrap;height:auto;padding:12px 16px 10px;gap:12px 16px}.masthead nav{flex-basis:100%;flex-wrap:wrap;overflow:visible;gap:6px 16px;padding-bottom:0}
  .guidebar .in{padding:4px 16px 12px;gap:16px;mask-image:linear-gradient(to right,#000 calc(100% - 36px),transparent);-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 36px),transparent)}}

/* type roles */
.eb{font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin:0 0 22px}
.eb.dim{color:var(--ink-3)}
.big{font-size:clamp(34px,4.4vw,58px);line-height:1.02;letter-spacing:-.035em;font-weight:700;
  font-variation-settings:var(--display);max-width:22ch;margin:0 0 22px;color:var(--ink);text-wrap:balance}
.deck{font-size:clamp(18px,1.5vw,21px);line-height:1.45;color:var(--ink-2);max-width:60ch;margin:0 0 20px}
.deck b{color:var(--ink);font-weight:600}
.prose{max-width:62ch;color:var(--ink-2);font-size:17px;line-height:1.6}
.prose p{margin:0;max-width:none}
.prose p+p{margin-top:14px}
.prose b{color:var(--ink);font-weight:600}
.home :not(pre)>code,.chapter :not(pre)>code{font-family:var(--mono);font-size:.9em;color:var(--accent);background:none;padding:0}
.more{display:inline-block;margin-top:22px;font-weight:600;color:var(--ink);text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,var(--accent) 55%,transparent);padding-bottom:1px}
.more::after{content:" →";color:var(--accent)}
.more:hover{text-decoration:none;border-bottom-color:var(--accent)}
/* two links in a row stack, always: side by side they wrap at exactly the widths people read at, and a
   wrapped second link then hangs indented on its own line */
.more+.more{margin-left:0;display:block;margin-top:12px}
.btn{display:inline-block;padding:12px 20px;border-radius:6px;font-weight:600;font-size:15px;line-height:1;text-decoration:none}
.btn.f{background:var(--accent);color:var(--on-accent)}
.btn.f:hover{text-decoration:none;background:var(--accent-2);color:var(--on-accent)}
.btn.t{color:var(--ink);padding-inline:0}
.btn.t::after{content:" →";color:var(--accent)}
.ctas{display:flex;gap:22px;align-items:center;flex-wrap:wrap}

/* sections: 110px of air and one hairline, no backgrounds */
.sec{padding:110px 0 0}
.sec .rule{border-top:1px solid var(--rule);margin-bottom:64px}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:start}
.two>*{min-width:0}
@media(max-width:860px){.two{grid-template-columns:1fr;gap:36px}.sec{padding-top:80px}.sec .rule{margin-bottom:44px}}

/* THE TERMINAL — the one bordered thing. `pre.term` is the token-swapped card the site already had; this is
   its shape in the new direction: no window dots, a mono label at the top, 13px, and machine output in
   --ink-2 (never --ink-3, which is reserved for comments — see "Muted text on dark, measured"). */
pre.term,.term pre{font-size:13px;line-height:1.72;padding:18px 20px;border-radius:6px;margin:0}
pre.term{box-shadow:none}
.term .lbl{display:block;font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  margin:-4px 0 12px;white-space:normal}
pre .d{color:var(--ink-2)}
pre .ok{color:var(--allow)} pre .am{color:var(--mark)} pre .at{color:var(--accent);opacity:.8}
.term b{color:var(--ink);font-weight:600}
.term .cn{display:inline-grid;place-items:center;width:16px;height:16px;border-radius:50%;background:var(--accent);
  color:var(--on-accent);font-size:10px;font-weight:700;margin-left:10px;vertical-align:1px;font-style:normal}

/* THE FIGURE — no border; the image sits on the ground with an ember glow beneath it */
.figure{position:relative;margin:0}
.figure img{display:block;width:100%;height:auto;border-radius:6px;
  box-shadow:0 60px 140px -70px color-mix(in srgb,var(--accent) 55%,transparent),0 0 0 1px var(--rule)}
.figure figcaption{font-family:var(--mono);font-size:12.5px;color:var(--ink-2);margin-top:12px;line-height:1.6}
.figure figcaption b{color:var(--ink-2);font-weight:500}

/* STRUCK LISTS — a rule draws through each item when it scrolls into view (`data-strike` + the observer in
   Home); resting state under reduced motion is struck, so the page says the same thing with scripts off. */
.struck{list-style:none;margin:0;padding:0;font-family:var(--mono);font-size:14px;line-height:1.9;color:var(--ink-2)}
.struck li{display:table;position:relative;padding-right:4px;margin:0}
.struck li::after{content:"";position:absolute;left:0;right:0;top:53%;height:2px;background:var(--accent);
  transform:scaleX(0);transform-origin:left;transition:transform .35s cubic-bezier(.2,.7,.3,1)}
.struck.go li::after{transform:scaleX(1)}
.struck.go li:nth-child(2)::after{transition-delay:.07s}.struck.go li:nth-child(3)::after{transition-delay:.14s}
.struck.go li:nth-child(4)::after{transition-delay:.21s}.struck.go li:nth-child(5)::after{transition-delay:.28s}
.struck.go li:nth-child(6)::after{transition-delay:.35s}.struck.go li:nth-child(7)::after{transition-delay:.42s}
.struck.go li:nth-child(8)::after{transition-delay:.49s}.struck.go li:nth-child(9)::after{transition-delay:.56s}
.struck.go li:nth-child(10)::after{transition-delay:.63s}.struck.go li:nth-child(11)::after{transition-delay:.7s}
.struck.go li:nth-child(12)::after{transition-delay:.77s}

/* THE LEDGER — two columns of type, no box. Left struck on scroll; "Nothing." in --allow; the three answers
   that are not "nothing" in --ink. */
.ledger{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:0 48px;font-size:16px;line-height:1.45;
  border:0;background:none;border-radius:0;margin-top:44px}
.ledger>div{padding:13px 0;border-top:1px solid var(--rule);color:var(--ink-2)}
.ledger .q span{position:relative;display:inline-block;font-family:var(--mono);font-size:13.5px}
.ledger .q span::after{content:"";position:absolute;left:0;right:0;top:53%;height:2px;background:var(--accent);
  transform:scaleX(0);transform-origin:left;transition:transform .35s cubic-bezier(.2,.7,.3,1)}
.ledger.go .q span::after{transform:scaleX(1)}
.ledger .a b{color:var(--allow);font-weight:600}
.ledger .a b.x{color:var(--ink)}
.ledger .a b.stop{color:var(--refuse)}
@media(max-width:760px){.ledger{grid-template-columns:1fr;gap:0}.ledger .a{padding-top:0;border-top:0}}

/* BIG FIGURES — three numbers, measured at build time */
.nums{display:flex;gap:40px 56px;flex-wrap:wrap;margin:44px 0 0}
.nums div{flex:1 1 220px;max-width:300px;font-family:var(--mono);font-size:13px;color:var(--ink-2);letter-spacing:.02em}
.nums b{display:block;font-family:var(--sans);font-weight:800;font-variation-settings:var(--display);
  font-size:clamp(40px,4.6vw,64px);letter-spacing:-.04em;line-height:1;color:var(--ink);margin-bottom:8px;
  font-variant-numeric:tabular-nums}
.nums b i{font-style:normal;color:var(--accent)}

/* the paragraph after the ledger and its pull statement sit side by side (owner, 2026-09-03) */
.after-ledger{margin-top:44px;align-items:center}
.after-ledger .pull{margin-top:0}
@media(max-width:860px){.after-ledger .pull{margin-top:36px}}
/* THE PULL STATEMENT — one sentence with an accent rule */
.pull{margin:64px 0 0;padding-left:26px;border-left:3px solid var(--accent);font-size:clamp(24px,2.6vw,34px);
  font-weight:700;line-height:1.15;letter-spacing:-.03em;max-width:26ch;font-variation-settings:var(--display);color:var(--ink)}
.pull small{display:block;margin-top:12px;font-family:var(--mono);font-size:12.5px;letter-spacing:.02em;color:var(--ink-2);font-weight:400}

/* status tags — the same three words the reference uses for a surface's state */
.tag{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;padding:3px 9px;
  border-radius:20px;font-weight:500;vertical-align:2px;margin-left:8px;white-space:nowrap}
.tag.ok{color:var(--allow);background:color-mix(in srgb,var(--allow) 14%,transparent)}
.tag.soon{color:var(--mark);background:color-mix(in srgb,var(--mark) 15%,transparent)}
.tag.no{color:var(--refuse);background:color-mix(in srgb,var(--refuse) 15%,transparent)}

/* ── HOME ────────────────────────────────────────────────────────────────────────────────────────
   Nine sections in a reading order (00 Get it … 08 Nineteen apps), the numbers on the page as eyebrows and
   as the contents row under the hero. The hero PERFORMS the argument: the twelve things every web app makes
   you build type in, get struck through, collapse, and the twelve-line component rises in their place. */
.home{max-width:1180px;margin-inline:auto;padding:0 32px;position:relative}
.shell:has(> main > .home),.shell:has(> main > .chapter){max-width:none;padding-inline:0}
main:has(> .home),main:has(> .chapter){padding-top:0}
.home::before,.home::after{content:none}
.hero{padding:72px 0 0}
.hero .grid{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:64px;align-items:start}
.hero .grid>*{min-width:0}
.hero h1{font-size:clamp(42px,6.4vw,84px);line-height:.98;letter-spacing:-.04em;font-weight:800;
  font-variation-settings:var(--display);margin:0 0 28px;max-width:none;color:var(--ink)}
.hero .lede{font-size:clamp(17px,1.5vw,20px);line-height:1.5;color:var(--ink-2);max-width:56ch;margin:0 0 32px}
.hero .lede b{color:var(--ink);font-weight:600}
.strip{margin:40px 0 0;font-family:var(--mono);font-size:12.5px;color:var(--ink-2);line-height:1.9}
.strip b{color:var(--ink);font-weight:500}
.strip a{color:var(--ink-2);text-decoration:none}
.strip a:hover{text-decoration:underline;text-decoration-color:var(--accent);text-underline-offset:4px}
@media(max-width:900px){.hero .grid{grid-template-columns:1fr;gap:40px}.hero{padding-top:44px}}
/* THE PHONE HERO IS THINNER (owner, 2026-09-09: "too much clutter — the links and the strike-throughs"). No
   on-this-page list, the twelve struck lines become one sentence, and the code wraps instead of clipping. */
/* ⭐ ON A PHONE THE BAND COMES BEFORE THE LEDGER (owner, 2026-09-09) — "SaaS you own", the company line, then the
   three ways in, and only then what is compiled away. The band is a SIBLING SECTION of the hero, so ordering it
   against a child OF the hero needs both wrappers flattened: `.home` becomes the flex container and `.hero` /
   `.hero .grid` become `display:contents`, which makes the hero's text column, the band and the ledger three flex
   children that `order` can sort. Desktop is untouched — the whole block is inside the 620px query. */
@media(max-width:620px){
  .home{display:flex;flex-direction:column}
  .hero,.hero .grid{display:contents}
  .hero .grid>div:not(.fig){order:-3;padding-top:44px}
  #own{order:-2;padding-top:72px}
  .hero .fig{order:-1;padding-top:64px}
  .hero .fig::before{content:"";display:block;border-top:1px solid var(--rule);margin-bottom:40px}
  .hero .contents{display:none}
  /* THE STRUCK LIST STAYS ON A PHONE — it is the argument, and the "clutter" it was blamed for was the stray bar
     bug above (owner, 2026-09-09). Tighter, and the caption stacks instead of wrapping into a four-line column. */
  .hero .fig .cap{display:block;margin-bottom:10px}
  .hero .fig .cap i{display:block;margin-top:3px}
  .hero ul.led{font-size:12px;line-height:1.75}
  .fig .term{white-space:pre-wrap;word-break:normal;font-size:12px}
  .strip{margin-top:26px}
}

/* THE ANIMATED LEDGER (see Home.HeroLedger). CSS keyframes and delays, no library: the twelve items fade in
   70ms apart, a strike sweeps each one from 2.0s, the list shrinks at 3.7s, "Nothing." appears at 4.0s and
   the component rises at 4.25s. Click replays it (the node is cloned, which restarts every animation).
   ⚠ REDUCED MOTION IS THE RESTING STATE, not an empty column: struck, compact at 72%/12px, the code showing. */
.fig{cursor:pointer;padding-top:6px}
.fig .cap{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  margin-bottom:14px;display:flex;justify-content:space-between;gap:12px}
.fig .cap i{font-style:normal;color:var(--accent);opacity:0;animation:capin .4s 4.6s forwards;white-space:nowrap}
@keyframes capin{to{opacity:1}}
ul.led{list-style:none;margin:0;padding:0;font-family:var(--mono);font-size:13px;line-height:1.85;color:var(--ink-2);
  animation:shrink .6s cubic-bezier(.4,0,.2,1) 3.7s forwards}
@keyframes shrink{to{font-size:12px;line-height:1.6;opacity:.72}}
/* ⛔ NOT display:table. WebKit does not treat a relatively positioned table element as a containing block, so each
   li::after strike positioned against .home instead — all twelve at 53% of the page, drawn as one orange bar across
   whatever paragraph sat there (an iPhone photo of the "Three ways in" band, 2026-09-09). width:fit-content shrink-wraps
   the same way and is a real containing block everywhere. */
ul.led li{position:relative;display:block;width:fit-content;opacity:0;animation:lin .25s forwards;margin:0}
ul.led li::after{content:"";position:absolute;left:0;right:0;top:53%;height:2px;background:var(--accent);
  transform:scaleX(0);transform-origin:left;animation:lstrike .18s ease-out forwards}
ul.led li:nth-child(1){animation-delay:.05s}ul.led li:nth-child(1)::after{animation-delay:2.0s}
ul.led li:nth-child(2){animation-delay:.12s}ul.led li:nth-child(2)::after{animation-delay:2.07s}
ul.led li:nth-child(3){animation-delay:.19s}ul.led li:nth-child(3)::after{animation-delay:2.14s}
ul.led li:nth-child(4){animation-delay:.26s}ul.led li:nth-child(4)::after{animation-delay:2.21s}
ul.led li:nth-child(5){animation-delay:.33s}ul.led li:nth-child(5)::after{animation-delay:2.28s}
ul.led li:nth-child(6){animation-delay:.40s}ul.led li:nth-child(6)::after{animation-delay:2.35s}
ul.led li:nth-child(7){animation-delay:.47s}ul.led li:nth-child(7)::after{animation-delay:2.42s}
ul.led li:nth-child(8){animation-delay:.54s}ul.led li:nth-child(8)::after{animation-delay:2.49s}
ul.led li:nth-child(9){animation-delay:.61s}ul.led li:nth-child(9)::after{animation-delay:2.56s}
ul.led li:nth-child(10){animation-delay:.68s}ul.led li:nth-child(10)::after{animation-delay:2.63s}
ul.led li:nth-child(11){animation-delay:.75s}ul.led li:nth-child(11)::after{animation-delay:2.70s}
ul.led li:nth-child(12){animation-delay:.82s}ul.led li:nth-child(12)::after{animation-delay:2.77s}
@keyframes lin{to{opacity:1}}
@keyframes lstrike{to{transform:scaleX(1)}}
.fig .none{font-family:var(--mono);font-size:15px;color:var(--accent);margin:14px 0 12px;opacity:0;animation:lin .4s 4.0s forwards}
.fig pre.term{opacity:0;transform:translateY(8px);animation:rise .5s cubic-bezier(.2,.7,.3,1) 4.25s forwards;
  box-shadow:0 40px 120px -60px color-mix(in srgb,var(--accent) 45%,transparent);font-size:12.5px}
@keyframes rise{to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  ul.led{font-size:12px;line-height:1.6;opacity:.72}ul.led li{opacity:1}ul.led li::after{transform:scaleX(1)}
  .fig .none,.fig pre.term,.fig .cap i{opacity:1;transform:none}
  .struck li::after,.ledger .q span::after{transform:scaleX(1)}
}
/* the contents row under the hero — `.contents`, because `.toc` is the reference pages' own side column */
.contents{display:flex;gap:26px;flex-wrap:wrap;margin-top:72px;padding-top:24px;border-top:1px solid var(--rule);
  font-family:var(--mono);font-size:12.5px;color:var(--ink-2)}
.contents a{color:var(--ink-2);text-decoration:none}
.contents a:hover{color:var(--ink)}
.contents a b{color:var(--accent);font-weight:500;letter-spacing:.12em;margin-right:8px}

/* 00 get it */
.soon-banner{margin:0 0 22px;padding:14px 18px;border:1px solid color-mix(in srgb,var(--mark) 55%,transparent);border-radius:6px;
  background:color-mix(in srgb,var(--mark) 8%,transparent);font-size:15px;line-height:1.55;color:var(--ink-2);max-width:60ch}
.soon-banner .tag{margin:0 8px 0 0;vertical-align:1px}
.soon-banner b{color:var(--ink);font-weight:600}
.soon-banner p{margin:0 0 12px}
.soon-banner:has(> p:only-child) p{margin:0}
/* The sign-up sits UNDER the install block, in the right column, so it reads as part of "get it" rather than as a
   banner ahead of the headline (owner, 2026-09-05). Same wash as the banner, tucked to the terminal's width. */
.news-card{margin:14px 0 0;max-width:none}
.news label{display:block;font-size:14.5px;color:var(--ink-2);margin:0 0 8px}
.news .picks{display:flex;gap:6px 18px;flex-wrap:wrap;margin:0 0 12px;font-size:14px;color:var(--ink-2)}
.news .picks label{display:inline-flex;gap:6px;align-items:center;margin:0}
.news .picks input{accent-color:var(--accent)}
/* The fields sit on the banner's tinted wash, so they take the CARD surface and the stronger rule — on a phone the
   wash and a pale field were one colour (measured on the owner's phone, 2026-09-05). */
.news input[type=email],.news select,.news .msg{display:block;width:100%;box-sizing:border-box;margin:0 0 8px;font:inherit;
  font-size:15px;padding:10px 12px;border:1.5px solid var(--rule-2);border-radius:6px;background:var(--card);color:var(--ink)}
.news select{appearance:auto;-webkit-appearance:menulist}
.news textarea.msg{resize:vertical;min-height:4.6em;line-height:1.45}
.news select:has(option[value=""]:checked){color:var(--ink-3)}
.news ::placeholder{color:var(--ink-3);opacity:1}
.news input:focus,.news select:focus,.news textarea:focus{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:1px;border-color:var(--accent)}
.news .row{display:flex;gap:8px;flex-wrap:wrap;margin-top:2px}
.news button{font:inherit;font-size:14.5px;font-weight:600;padding:10px 18px;border:0;border-radius:6px;cursor:pointer;
  background:var(--accent);color:var(--on-accent,#fff)}
.news button:disabled{opacity:.6;cursor:wait}
.news .hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
/* `.reply`, not `.note` — `.note` is the site's callout class and drew its orange left border on this empty line. */
.news .reply{margin:8px 0 0;font-size:14px;min-height:1.2em}
.news .reply[data-ok="1"]{color:var(--ink)}
.news .reply[data-ok="0"]{color:var(--mark)}
.soon-banner a{color:var(--accent);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--accent) 55%,transparent)}
.got{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:12px;font-size:15.5px;color:var(--ink-2)}
.got li{display:grid;grid-template-columns:130px minmax(0,1fr);gap:16px;padding-top:12px;border-top:1px solid var(--rule);line-height:1.5;margin:0}
.got li b{color:var(--ink);font-weight:600}
.got .tag{margin-left:6px}
@media(max-width:520px){.got li{grid-template-columns:1fr;gap:4px}}

/* 03 the marquee features — six alternating rows, each a why-headline and one receipt */
.feat{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:center;padding:56px 0;border-top:1px solid var(--rule)}
.feat>*{min-width:0}
.feat:nth-of-type(even) .txt{order:2}
.feat .no{font-family:var(--mono);font-size:12px;letter-spacing:.14em;color:var(--accent);margin:0 0 14px;text-transform:uppercase}
.feat h3{font-size:clamp(28px,3vw,40px);line-height:1.05;letter-spacing:-.035em;font-weight:800;
  font-variation-settings:var(--display);margin:0 0 16px;max-width:18ch;color:var(--ink)}
.feat p{color:var(--ink-2);max-width:48ch;font-size:16.5px;margin:0}
.feat .how{margin-top:12px;font-family:var(--mono);font-size:12.5px;color:var(--ink-2);line-height:1.7}
.feat .how b{color:var(--ink);font-weight:500}
@media(max-width:860px){.feat{grid-template-columns:1fr;gap:28px;padding:44px 0}.feat:nth-of-type(even) .txt{order:0}}

/* 04 the first session: the player and the six beats beside it */
.stage{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:40px;align-items:start;margin-top:36px}
@media(max-width:960px){.stage{grid-template-columns:1fr;gap:26px}}
.stage video{display:block;width:100%;height:auto;border-radius:8px;background:var(--wash);
  box-shadow:0 60px 140px -70px color-mix(in srgb,var(--accent) 55%,transparent),0 0 0 1px var(--rule)}
/* the poster the page shows when there is no recording yet — the same frame the video would rest on, drawn
   in type, so the section is not a hole while the tape is being made (07-first-session.md, honesty rule 5) */
.poster-frame{position:relative;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:14px;padding:16px;
  border-radius:8px;background:var(--wash);box-shadow:0 60px 140px -70px color-mix(in srgb,var(--accent) 55%,transparent),
  0 0 0 1px var(--rule);aspect-ratio:16/9;overflow:hidden}
.poster-term{background:var(--term-wash);border-radius:6px;padding:14px 16px;font-family:var(--mono);font-size:11.5px;
  line-height:1.7;color:var(--term-ink);min-width:0;overflow:hidden}
.poster-term pre{margin:0;padding:0;border:0;background:none;font-size:inherit;line-height:inherit;color:inherit}
.poster-term .lbl{display:block;font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--term-ink3);margin:0 0 10px}
.poster-term .p{color:var(--term-accent)}.poster-term .d{color:var(--term-ink2)}.poster-term .u,.poster-term .ok{color:var(--term-allow)}
.poster-term .caret{display:inline-block;width:7px;height:12px;background:var(--term-ink);vertical-align:-2px;margin-left:2px}
.poster-app{background:var(--card);border-radius:6px;border:1px solid var(--rule);overflow:hidden;display:flex;flex-direction:column;min-width:0}
.poster-app .ub{display:flex;align-items:center;gap:6px;padding:8px 10px;border-bottom:1px solid var(--rule);font-family:var(--mono);font-size:10.5px;color:var(--ink-2)}
.poster-app .ub i{width:8px;height:8px;border-radius:50%;background:var(--rule-2)}.poster-app .ub span{margin-left:6px}
.poster-app .app-body{padding:26px 22px}
.poster-app .app-h{font-weight:800;font-size:28px;letter-spacing:-.03em;font-variation-settings:var(--display);margin-bottom:8px;color:var(--ink)}
.poster-app .app-p{font-size:13px;color:var(--ink-2);line-height:1.5}
@media(max-width:600px){.poster-frame{grid-template-columns:1fr}.poster-app{display:none}}
.beats{list-style:none;margin:0;padding:0;counter-reset:b;display:grid;gap:0}
.beats li{counter-increment:b;position:relative;padding:12px 0 12px 34px;border-top:1px solid var(--rule);font-size:14.5px;color:var(--ink-2);line-height:1.5;margin:0}
.beats li::before{content:counter(b);position:absolute;left:0;top:13px;font-family:var(--mono);font-size:11.5px;color:var(--accent)}
.beats li b{display:block;color:var(--ink);font-weight:600}
.beats li code{display:block;font-family:var(--mono);font-size:12.5px;color:var(--ink);margin:3px 0 2px;background:none;padding:0}
h3.sub{margin:64px 0 0;font-size:clamp(22px,2.2vw,28px);font-weight:700;letter-spacing:-.025em;font-variation-settings:var(--display);color:var(--ink)}
.didnt{margin:26px 0 0;font-size:15px;color:var(--ink-2);border:0;background:none;max-width:none;border-radius:0}
.didnt>p{margin:0 0 8px;font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2)}
.didnt .struck{font-family:var(--sans);font-size:15.5px;line-height:1.7}
.didnt .struck li::after{background:var(--rule-2)}
.didnt .struck b{color:var(--ink);font-weight:600}
.didnt small{display:block;margin-top:12px;font-family:var(--mono);font-size:12.5px;color:var(--ink-2)}

/* 07 three places to run it — labelled by WHERE, never by plan (06-positioning.md) */
.places{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px;margin-top:40px;align-items:start}
.places>*{min-width:0}
.places h4{margin:0 0 12px;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.places pre.term{font-size:12px;line-height:1.7}
.places .soon pre.term{border-style:dashed;opacity:.9}
.places .own{margin:14px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink-2)}
.places .own b{color:var(--ink);font-weight:600}
@media(max-width:1000px){.places{grid-template-columns:1fr}}

/* 08 the filmstrip — real screenshots, one `osy init` each, scroll-snapped */
.film{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(300px,34%);gap:22px;overflow-x:auto;
  scroll-snap-type:x mandatory;padding:8px 0 26px;margin-top:8px;scrollbar-width:thin;scrollbar-color:var(--rule-2) transparent}
.film figure{margin:0;scroll-snap-align:start}
.film a{display:block;text-decoration:none;color:inherit}
.film img{display:block;border-radius:6px;box-shadow:0 0 0 1px var(--rule);aspect-ratio:3/2;object-fit:cover;object-position:top left;width:100%;height:auto}
.film figcaption{margin-top:10px;font-size:14px;color:var(--ink-2);line-height:1.45}
.film figcaption code{font-family:var(--mono);font-size:12.5px;color:var(--accent);display:block;margin-bottom:2px;background:none;padding:0}
.film figcaption .repo{font-family:var(--mono);font-size:12.5px;color:var(--ink-3);display:block;margin-bottom:2px}
.next{display:flex;gap:36px;flex-wrap:wrap;font-family:var(--mono);font-size:13px;margin-top:8px}
.next a{color:var(--ink);text-decoration:none}
.next a:hover{text-decoration:underline;text-decoration-color:var(--accent);text-underline-offset:4px}
.next a span{color:var(--accent);margin-right:8px;font-weight:500}
.next a small{display:block;color:var(--ink-2);font-size:12.5px;margin-top:3px}

/* ── CHAPTERS (the guides, under `Why Osy#`) ─────────────────────────────────────────────────────
   Opener (why + one receipt) → why, no code → how, numbered → proof, a verdict table → next chapter. */
.chapter{max-width:1180px;margin-inline:auto;padding:0 32px}
.open{padding:64px 0 0}
/* 1/1, not 7/5: a chapter's receipt is a real listing (the Security chapter's is a composed policy), and at 7/5 its
   column was 436px against a 465px widest line. Measured with Playwright; the H1 wraps one word earlier and reads fine. */
.open .grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:start}
.open .grid>*{min-width:0}
.open .crumb{font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);margin:0 0 22px}
.open .crumb b{color:var(--accent);font-weight:500}
.open .crumb a{color:var(--ink-2);text-decoration:none}
.open h1{font-size:clamp(40px,5.8vw,76px);line-height:.98;letter-spacing:-.04em;font-weight:800;
  font-variation-settings:var(--display);margin:0 0 26px;max-width:none;color:var(--ink)}
.open .stand{font-size:clamp(18px,1.6vw,22px);line-height:1.45;color:var(--ink-2);max-width:56ch;margin:0 0 30px}
.open .stand b{color:var(--ink);font-weight:600}
.kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px 22px;font-size:15.5px;color:var(--ink-2);max-width:60ch;align-items:baseline}
.kv b{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);font-weight:500;white-space:nowrap}
.kv .struck{display:flex;flex-wrap:wrap;gap:2px 14px;font-size:13.5px;line-height:1.7}
.kv .struck li{display:inline-table}
.open pre.term{box-shadow:0 40px 120px -60px color-mix(in srgb,var(--accent) 45%,transparent);font-size:12.5px}
.open .figure{margin-top:0}
.chapters{display:flex;gap:26px;flex-wrap:wrap;margin-top:56px;padding-top:22px;border-top:1px solid var(--rule);
  font-family:var(--mono);font-size:12.5px;color:var(--ink-2)}
.chapters a{color:var(--ink-2);text-decoration:none}
.chapters a:hover{color:var(--ink)}
.chapters a b{color:var(--accent);font-weight:500;letter-spacing:.12em;margin-right:8px}
@media(max-width:900px){.open .grid{grid-template-columns:1fr;gap:36px}.open{padding-top:40px}}

/* THE STANDALONE /why/ PAGE reads as an essay, so its column is centred rather than left in a 1180px frame with
   an empty right half — every other chapter puts a listing there and this one has no code by design. */
.chapter.why{max-width:920px}
.chapter.why .open{padding-top:56px}
.chapter.why .gsec .pull{max-width:34ch}

/* the why: bigger type, room, red ✗ for the failures, and no code */
.why .prose{font-size:19px;line-height:1.55;max-width:60ch}
.fails{list-style:none;margin:36px 0 0;padding:0;display:grid;gap:12px;max-width:60ch;font-size:17px;color:var(--ink-2)}
.fails li{padding-left:26px;position:relative;margin:0}
.fails li::before{content:"✗";position:absolute;left:0;top:0;color:var(--refuse);font-family:var(--mono);font-weight:700}
.fails li b{color:var(--ink);font-weight:600}
/* ⚠ THE SAME LIST, BUT ASKING. A red ✗ beside "Why was this payment made?" marks the QUESTION as the failure,
   which is not what it is: these are the questions nobody can answer today. An amber "?" says that instead. */
.fails.asked li::before{content:"?";color:var(--accent)}

/* the how: the numbered sections the guides already had (`.gsec`), in the new type */
.chapter .gsec{padding:72px 0 0}
.chapter .gsec .sec-no{font-size:12px;letter-spacing:.16em;margin:0 0 12px}
.chapter .gsec h2{font-size:clamp(26px,2.8vw,38px);line-height:1.1;letter-spacing:-.03em;font-weight:700;
  font-variation-settings:var(--display);margin:0 0 16px;max-width:26ch;color:var(--ink)}
.chapter .gsec .say{font-size:18px;color:var(--ink-2);max-width:60ch;line-height:1.5;margin:0 0 22px}
.chapter .gsec>p:not(.pull):not(.eb):not(.say):not(.sec-no){color:var(--ink-2);max-width:62ch;font-size:16.5px;line-height:1.6}
.chapter .gsec.why h2{font-size:clamp(34px,4.4vw,58px);line-height:1.02;letter-spacing:-.035em;max-width:22ch;margin-bottom:22px}
.chapter .gsec>p b{color:var(--ink)}
.chapter .gsec pre.term{margin:22px 0 0;max-width:820px}
.chapter .gsec.proof{padding-top:110px}
.chapter .gsec.proof .rule{border-top:1px solid var(--rule);margin-bottom:64px}
/* the aside is a marginal note now, not a box: a left rule and the ground */
.chapter .gnote{background:none;border-radius:0;padding:4px 0 4px 18px;margin:22px 0 26px;max-width:62ch;border-left-width:2px}
.chapter .gnote-head{font-size:15px}
.chapter .gnote p{font-size:15px}
/* the specimen keeps its shape (a real file, numbered call-outs) and takes the terminal's surface */
.chapter .specimen .src{border-radius:6px}
.chapter pre.code{font-size:12.5px}
.chapter .deftable table{font-size:15px}
.chapter .deftable th{font-size:11.5px;color:var(--ink-2);border-bottom-color:var(--rule-2);padding:0 18px 10px 0}
.chapter .deftable td{padding:13px 18px 13px 0}
.chapter .deftable td:first-child{font-family:var(--mono);font-size:13px;color:var(--ink)}
.chapter .deftable td:first-child code{background:none;padding:0;color:inherit;font-size:inherit}

/* the proof: You do this · Verdict · Because — a table, not a card grid */
.verdicts{width:100%;border-collapse:collapse;font-size:15px;margin:26px 0 0;display:table}
.verdicts th{text-align:left;font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-2);font-weight:500;padding:0 18px 10px 0;border-bottom:1px solid var(--rule-2);white-space:nowrap}
.verdicts td{padding:13px 18px 13px 0;border-bottom:1px solid var(--rule);color:var(--ink-2);vertical-align:top}
.verdicts td:first-child{color:var(--ink);font-weight:500}
.verdicts td b{color:var(--ink);font-weight:600}
.verdicts td code{background:none;padding:0;color:var(--accent);font-size:.9em}
.verdict{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;padding:3px 9px;border-radius:20px;font-weight:500;white-space:nowrap}
.verdict.ok{color:var(--allow);background:color-mix(in srgb,var(--allow) 14%,transparent)}
.verdict.no{color:var(--refuse);background:color-mix(in srgb,var(--refuse) 15%,transparent)}
@media(max-width:720px){.verdicts,.verdicts tbody,.verdicts tr,.verdicts td{display:block}.verdicts thead{display:none}
  .verdicts td{padding:4px 0;border:0}.verdicts tr{padding:12px 0;border-bottom:1px solid var(--rule)}}

/* next chapter · in the reference — two links, no cards */
.nextch{display:grid;grid-template-columns:1fr 1fr;gap:40px;margin-top:64px}
.nextch a{display:block;padding-top:16px;border-top:1px solid var(--rule);text-decoration:none;color:inherit}
.nextch a:hover{text-decoration:none}
.nextch a:hover b{color:var(--accent)}
.nextch a small{display:block;font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin-bottom:8px}
.nextch a b{display:block;font-size:22px;font-weight:700;letter-spacing:-.025em;margin-bottom:6px;font-variation-settings:var(--display);color:var(--ink)}
.nextch a span{color:var(--ink-2);font-size:15px}
@media(max-width:760px){.nextch{grid-template-columns:1fr;gap:24px}}

/* the chapter index: the nine, as a numbered list of whys — no cards */
.chlist{list-style:none;margin:44px 0 0;padding:0}
.chlist li{display:grid;grid-template-columns:110px minmax(0,1fr);gap:24px;padding:26px 0;border-top:1px solid var(--rule);margin:0}
.chlist li .n{font-family:var(--mono);font-size:12px;letter-spacing:.14em;color:var(--accent);padding-top:6px}
.chlist li a{display:block;font-size:clamp(22px,2.4vw,30px);font-weight:700;letter-spacing:-.03em;line-height:1.1;
  font-variation-settings:var(--display);color:var(--ink);text-decoration:none;margin-bottom:8px}
.chlist li a:hover{color:var(--accent);text-decoration:none}
.chlist li p{margin:0;color:var(--ink-2);font-size:16px;max-width:62ch}
.chlist li .lbl{font-family:var(--mono);font-size:12px;color:var(--ink-3);margin-bottom:6px}
@media(max-width:600px){.chlist li{grid-template-columns:1fr;gap:6px}}

/* the reference-and-samples pages take the palette, the type and the two containers; nothing is restructured */
.note{background:none;border-left:2px solid var(--accent);border-radius:0;padding:4px 0 4px 18px;margin:18px 0}
.run{border-radius:6px}
/* a sample's screens: one wide, the rest side by side, each with the shooter's caption */
.screens{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 20px;margin:0 0 30px;max-width:900px}
.screens figure:first-child{grid-column:1/-1}
.screens img{aspect-ratio:960/640;object-fit:cover;object-position:top}
@media(max-width:700px){.screens{grid-template-columns:1fr}}
.shotframe{border:0;background:none;border-radius:0;box-shadow:none}
.shotframe img{border-radius:6px;border:0;box-shadow:0 60px 140px -70px color-mix(in srgb,var(--accent) 55%,transparent),0 0 0 1px var(--rule)}
.shotframe figcaption{background:none;padding:12px 0 0;font-family:var(--mono);font-size:12.5px;color:var(--ink-2)}
.card{border-radius:6px}
.masthead nav{gap:18px;font-size:13px}
footer{margin-top:120px;border-top:1px solid var(--rule)}
footer .in{max-width:1180px;padding:36px 32px 64px;font-family:var(--mono);font-size:13px;color:var(--ink-2);line-height:1.8}
/* /releases/ — one section per version, the notes as prose */
.release{margin:34px 0 0;padding-top:26px;border-top:1px solid var(--rule)}
.release h2{margin:0 0 12px;font-size:26px}
.release h2 small{font-family:var(--mono);font-size:12px;letter-spacing:.08em;color:var(--ink-3);margin-left:12px;font-weight:400}
.release .more-small{font-size:14px;margin:10px 0 0}


/* ── palette override (dark-first) ── */
:root{color-scheme:dark;--paper:#0e1016; --card:#151822; --wash:#1b1f2b; --rule:#262b3a; --rule-2:#3a4154;--ink:#f2efe9; --ink-2:#bcc0cb; --ink-3:#8f95a4;--accent:#ff8a3d; --accent-2:#ffc48a; --accent-wash:#2b1a0f;--allow:#5fd6a3; --allow-wash:#10261d;--refuse:#ff7b8e; --refuse-wash:#2c1418;--mark:#f2c35b;  --mark-wash:#2b2110;--lane:#12141c;  --surface:#151822;--on-accent:#1a0d04;--term-card:#12151d; --term-wash:#0b0d13; --term-rule:#2a3040; --term-rule2:#3a4154;--term-ink:#f3f0eb; --term-ink2:#b6b0a7; --term-ink3:#8f95a4;--term-accent:#ff8a45; --term-allow:#6fe0aa; --term-refuse:#ff9090; --term-mark:#ffc46b;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){color-scheme:dark;--paper:#0e1016; --card:#151822; --wash:#1b1f2b; --rule:#262b3a; --rule-2:#3a4154;--ink:#f2efe9; --ink-2:#bcc0cb; --ink-3:#8f95a4;--accent:#ff8a3d; --accent-2:#ffc48a; --accent-wash:#2b1a0f;--allow:#5fd6a3; --allow-wash:#10261d;--refuse:#ff7b8e; --refuse-wash:#2c1418;--mark:#f2c35b;  --mark-wash:#2b2110;--lane:#12141c;  --surface:#151822;--on-accent:#1a0d04;}}
:root[data-theme="dark"]{color-scheme:dark;--paper:#0e1016; --card:#151822; --wash:#1b1f2b; --rule:#262b3a; --rule-2:#3a4154;--ink:#f2efe9; --ink-2:#bcc0cb; --ink-3:#8f95a4;--accent:#ff8a3d; --accent-2:#ffc48a; --accent-wash:#2b1a0f;--allow:#5fd6a3; --allow-wash:#10261d;--refuse:#ff7b8e; --refuse-wash:#2c1418;--mark:#f2c35b;  --mark-wash:#2b2110;--lane:#12141c;  --surface:#151822;--on-accent:#1a0d04;}
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){color-scheme:light;--paper:#f6f3ee; --card:#ffffff; --wash:#ece7df; --rule:#dcd5ca; --rule-2:#b9b0a2;--ink:#1b1917; --ink-2:#4f4a44; --ink-3:#7d766e;--accent:#c8410a; --accent-2:#f2a56b; --accent-wash:#fce6da;--allow:#13684a; --allow-wash:#daf0e6;--refuse:#b0104a; --refuse-wash:#fbe0ea;--mark:#8a5a05;  --mark-wash:#faeed6;--lane:#efebe5;  --surface:#ffffff;--on-accent:#ffffff;}}
:root[data-theme="light"]{color-scheme:light;--paper:#f6f3ee; --card:#ffffff; --wash:#ece7df; --rule:#dcd5ca; --rule-2:#b9b0a2;--ink:#1b1917; --ink-2:#4f4a44; --ink-3:#7d766e;--accent:#c8410a; --accent-2:#f2a56b; --accent-wash:#fce6da;--allow:#13684a; --allow-wash:#daf0e6;--refuse:#b0104a; --refuse-wash:#fbe0ea;--mark:#8a5a05;  --mark-wash:#faeed6;--lane:#efebe5;  --surface:#ffffff;--on-accent:#ffffff;}
