/* ── 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. */
@media(max-width:620px){.masthead .in{gap:14px}.find{display:none}}
.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}
.shell>main:has(article){max-width:84ch}
@media(max-width:1040px){.shell{grid-template-columns: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)}

/* ── HOME ────────────────────────────────────────────────────────────────────────────────────────
   The page is about getting from zero to running, so the terminal is the hero and everything else
   is subordinate to it. No feature grid: the reference is the feature grid, and it has 332 pages. */
.home{max-width:1240px;margin-inline:auto;padding:0 26px;position:relative}
.hero{padding-block:56px 40px}
/* ⚑ THE TWO COMMANDS GET THEIR OWN TITLED SECTION (owner, 2026-09-01). They used to sit inside the hero, unlabelled,
   so the page went from an argument straight into a terminal and the next heading — "What those two commands gave
   you" — referred back to something that had never been introduced. The hero keeps its own bottom padding, so this
   one opens tight against it. */
.start{padding-block:4px 40px}
.start>h2{font-size:20px;font-weight:600;margin:0 0 18px;letter-spacing:-.01em}
.eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 14px}
.hero h1{font-size:clamp(30px,4.4vw,46px);line-height:1.14;letter-spacing:-.025em;margin:0 0 16px;
  max-width:19ch;font-weight:600}
.lede{font-size:18px;color:var(--ink-2);max-width:64ch;margin:0 0 32px}

/* ── THE ROTATOR ─────────────────────────────────────────────────────────────────────────────────
   A claim on the left, the source or command that MAKES IT TRUE on the right. The right column used
   to be empty; a claim with its receipt beside it is the one thing a landing page for this product
   can do that a landing page for a framework cannot.

   Both halves are given a min-height, because twenty claims of different lengths through one box is
   how a hero ends up jumping half a line every seven seconds. */
.hero-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:40px;
  align-items:start;margin-bottom:30px}
.claims{min-width:0}
.rot{min-height:228px}
/* ⚑ SIZED TO THE TALLEST SLIDE, not the average, because the tab bar sits directly beneath it — anything less
   and the bar jumps every time slide 0 rotates off. Slide 0 is the tall one: it carries a full headline and a
   paragraph rather than a one-line claim. MEASURED at 1440px, where it renders 332px — read it off the page again if slide 0 s copy changes. */
.rot{min-height:332px}
@media (max-width:900px){.rot{min-height:0}}
/* The hero keeps ONE link — its own argument. Every guide is named in the bar at the top of the page, and
   repeating them here would be the second menu that bar exists to avoid. */
.rot-more{margin:30px 0 0}
.rot-more a{font-size:14.5px;font-weight:550;color:var(--accent);text-decoration:none;
  border-bottom:1px solid color-mix(in oklab,var(--accent) 35%,transparent);padding-bottom:1px}
.rot-more a:hover{border-bottom-color:var(--accent)}
.rot-head{font-size:clamp(27px,3.4vw,38px);line-height:1.1;letter-spacing:-.03em;margin:0 0 15px;
  font-weight:600;text-wrap:balance}
.rot-blurb{font-size:17px;line-height:1.55;color:var(--ink-2);margin:0;max-width:46ch}

/* Twenty tick marks, the live one filling over its dwell. It reads as a progress bar rather than a
   set of dots, which says "this is going somewhere" without a second element saying 3 / 20. */
.rot-bar{display:flex;gap:4px;margin-top:24px;max-width:440px}
.rot-tab{flex:1;height:16px;padding:6px 0 7px;background:none;border:0;cursor:pointer;
  -webkit-appearance:none;appearance:none}
.rot-tab i{display:block;height:3px;border-radius:2px;background:var(--rule-2);transition:background .2s}
.rot-tab:hover i{background:var(--ink-3)}
.rot-tab i{height:3px}
/* The live tab widens and carries the accent even at 0% fill — a tab that only becomes visible as the
   timer runs looks inactive for the first second of every slide, which is exactly the wrong second. */
.rot-tab{transition:flex-grow .35s cubic-bezier(.2,.7,.3,1)}
.rot-tab.on{flex-grow:2.2}
.rot-tab.on i{height:4px;margin-top:-1px;background:linear-gradient(90deg,
  var(--accent) 0 var(--fill,0%),
  color-mix(in srgb,var(--accent) 30%,var(--rule-2)) var(--fill,0%) 100%)}
.rot-tab.on.rot-run i{animation:rotfill var(--dwell,7s) linear forwards}
.rot-tab:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}
@keyframes rotfill{from{--fill:0%}to{--fill:100%}}
@property --fill{syntax:'<percentage>';inherits:false;initial-value:0%}

/* The receipt. Same chrome as the terminal below it, so the two read as one family. */
.proof{border:1px solid var(--rule);border-radius:var(--radius);background:var(--card);
  overflow:hidden;box-shadow:0 1px 0 var(--rule),0 14px 34px -26px rgba(16,18,31,.45)}
.proof-head{display:flex;align-items:center;gap:6px;padding:10px 15px;background:var(--wash);
  border-bottom:1px solid var(--rule)}
.proof-head .dot{width:8px;height:8px;border-radius:50%;background:var(--rule-2)}
.proof-head .dot:first-child{background:color-mix(in srgb,var(--refuse) 55%,var(--rule-2))}
.proof-head .dot:nth-child(2){background:color-mix(in srgb,var(--mark) 55%,var(--rule-2))}
.proof-head .dot:nth-child(3){background:color-mix(in srgb,var(--allow) 55%,var(--rule-2))}
.proof-head #proof-label{margin-left:8px;font-family:var(--mono);font-size:11px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3)}
.proof pre{margin:0;border:0;border-radius:0;background:var(--card);padding:17px 18px;
  font-size:12.7px;line-height:1.75;min-height:172px;overflow-x:auto}

/* Motion is the whole point of the ask, so it is a real crossfade — but it is opt-out, and the tabs
   still work by hand when it is off. */
.rot.in .rot-head,.rot.in .rot-blurb{animation:rise .42s cubic-bezier(.2,.7,.3,1) both}
.rot.in .rot-blurb{animation-delay:.05s}
.proof.in pre{animation:rise .42s cubic-bezier(.2,.7,.3,1) both;animation-delay:.06s}
@keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .rot.in .rot-head,.rot.in .rot-blurb,.proof.in pre,.rot-tab.on.rot-run i{animation:none}
  .rot-tab.on i{background:var(--accent)}
}
@media (max-width:860px){
  .hero-grid{grid-template-columns:minmax(0,1fr);gap:26px}
  .rot{min-height:0}
  .proof pre{min-height:0}
}

/* The rest of the receipt vocabulary. `p`/`d`/`u`/`c`/`k`/`s` are declared with the terminal below. */
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] */

.zero{border:1px solid var(--rule);border-radius:var(--radius) var(--radius) 0 0;
  background:var(--card);overflow:hidden;max-width:760px}
.zero-head{margin:0;padding:11px 17px;border-bottom:1px solid var(--rule);background:var(--wash);
  font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.zero pre{margin:0;border:0;border-radius:0;background:var(--card);padding:17px;font-size:13px;line-height:1.75}
.zero-note{margin:0;padding:12px 17px;border-top:1px solid var(--rule);background:var(--card);
  font-size:14px;color:var(--ink-2);font-weight:500}
pre .p{color:var(--accent);font-weight:500}   /* prompt */
pre .d{color:var(--ink-3)}                    /* machine output */
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 */

.split{display:grid;grid-template-columns:1fr 1fr;gap:40px;padding-block:26px 40px;
  border-top:1px solid var(--rule)}
/* ⚠ A grid item's default min-width is min-content, so a <pre> that does not wrap makes its COLUMN as
   wide as its longest line — the pre's own overflow-x never gets a chance to fire, and the whole page
   scrolls sideways on a phone instead. Measured at 390px: the body was 691px wide. */
.split>*{min-width:0}
@media(max-width:900px){.split{grid-template-columns:1fr;gap:8px}}
.split h2{font-size:20px;margin:0 0 10px;font-weight:600;letter-spacing:-.015em}
.split p{color:var(--ink-2);max-width:60ch}
.split .after{font-size:14.5px;margin-top:12px}
.paths{padding-block:26px 60px;border-top:1px solid var(--rule)}
.paths h2{font-size:20px;margin:0 0 16px;font-weight:600}
.fine{font-size:14px;color:var(--ink-3);margin:6px 0 0}

/* ── 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}
.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)}

/* WHAT YOU DID NOT DO — the second half of the hero. The two commands show how little you type; this shows how
   much of the usual setup is simply absent, which is the part a reader has to be TOLD because an absence leaves
   no trace on screen. Sits inside the same frame as the terminal so it reads as one claim, not a sales list. */
.didnt{max-width:760px;border:1px solid var(--rule);border-top:0;
  border-radius:0 0 var(--radius) var(--radius);background:var(--wash);margin-top:-1px}
.didnt-head{margin:0;padding:11px 17px 0;font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3)}
.didnt ul{margin:8px 0 0;padding:0 17px 0 34px;list-style:none}
.didnt li{position:relative;font-size:14.5px;color:var(--ink-2);margin:0 0 9px;max-width:none}
/* A ruled-through bullet: the item is a thing that did NOT happen, and the glyph says so before the words do. */
.didnt li::before{content:"—";position:absolute;left:-17px;color:var(--ink-3);font-family:var(--mono)}
.didnt li b{color:var(--ink);font-weight:600}
.didnt-note{margin:4px 0 0;padding:10px 17px 13px;font-size:13.5px;color:var(--ink-3);
  border-top:1px solid var(--rule)}


/* ── 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}

/* The masthead earns one saturated stripe. It is the only decorative colour on the page. */
.masthead{border-bottom:1px solid var(--rule);
  background:linear-gradient(var(--paper),var(--paper)) padding-box,
             linear-gradient(90deg,var(--accent),var(--refuse) 55%,var(--mark)) border-box;
  border-top:3px solid transparent}
.mark span{color:var(--accent)}

/* 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 HOME PAGE HAS A GROUND, NOT A BACKGROUND ────────────────────────────────────────────────
   Owner, 2026-08-29: "quite boring, very little colour, and very much unused background." It was:
   one flat paper tone from the masthead to the footer, with the only colour in the syntax. Three
   things fix that, and none of them is a gradient hero.

   ① An ambient wash, ASYMMETRIC and off to one side, so the empty half of the viewport is doing
      something. ② A hairline dot grid — a drafting surface rather than a marketing gradient, and the
      one device on this page that says "tool" before you have read a word. ③ Dark code cards, below. */
.home::before{
  content:"";position:fixed;inset:0;z-index:-2;pointer-events:none;
  background:
    radial-gradient(58% 46% at 82% -4%, color-mix(in srgb,var(--accent) 15%,transparent), transparent 68%),
    radial-gradient(46% 38% at 2% 6%,   color-mix(in srgb,var(--mark)   11%,transparent), transparent 70%),
    radial-gradient(40% 34% at 96% 52%, color-mix(in srgb,var(--allow)   8%,transparent), transparent 72%);
}
.home::after{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(color-mix(in srgb,var(--ink) 16%,transparent) 1px,transparent 1px);
  background-size:26px 26px;
  /* fades out well before the fold, so it is texture at the top and nothing at all where you read */
  -webkit-mask-image:linear-gradient(to bottom,#000 0,transparent 62vh);
          mask-image:linear-gradient(to bottom,#000 0,transparent 62vh);
  opacity:.42;
}

/* ── A TERMINAL IS DARK ──────────────────────────────────────────────────────────────────────────
   The single biggest change, and it is a token swap rather than a restyle: every syntax class on
   this site already reads `var(--accent)`, `var(--allow)` and friends, so redefining those tokens
   INSIDE the card recolours the whole listing with no second stylesheet. It also means the dark
   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);
  box-shadow:0 18px 46px -30px rgba(10,12,30,.75), 0 1px 0 rgba(255,255,255,.04) inset;
}
.term pre{background:var(--card);color:var(--ink)}
.term .proof-head,.term .zero-head{background:var(--wash);border-bottom-color:var(--rule);color:var(--ink-3)}
.term .zero-note{background:var(--wash);border-top-color:var(--rule);color:var(--ink-2)}
.term .proof-head .dot{background:var(--rule-2)}

/* The blocks that carry the page's argument get a tint apiece, so the column is not one flat sheet
   from the fold to the footer. Kept to a wash — the colour is the frame, never the text's ground. */
.didnt{background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 7%,var(--card)),var(--card))}
.split{position:relative}
.split::before{content:"";position:absolute;left:0;top:0;width:52px;height:2px;
  background:linear-gradient(90deg,var(--accent),var(--mark))}
.paths{border-top:1px solid var(--rule);padding-top:30px}
.home .card{transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease}
.home .card:hover{transform:translateY(-2px);box-shadow:0 12px 26px -20px rgba(16,18,31,.5)}

/* The two-command terminal and the list of things it saved you are ONE argument, so they sit side by
   side rather than stacked in a 760px column with the other half of the page empty. */
.zero-grid{display:grid;grid-template-columns:minmax(0,1.22fr) minmax(0,1fr);gap:26px;align-items:stretch}
@media(max-width:900px){.zero-grid{grid-template-columns:minmax(0,1fr)}}
.zero-grid .zero{max-width:none;border-radius:var(--radius);height:100%;display:flex;flex-direction:column}
.zero-grid .zero pre{flex:1}
.zero-grid .didnt{max-width:none;border-top:1px solid var(--rule);border-radius:var(--radius);height:100%}

/* A bare `pre.term` (no card wrapper) still needs the frame the .proof/.zero wrappers gave it. */
pre.term{border:1px solid var(--rule);border-radius:var(--radius);padding:16px 17px}

/* Five cards, not four — and they wrap rather than squeezing to an unreadable column. */
.paths .cards{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}

/* ── THE ARGUMENT SECTIONS ───────────────────────────────────────────────────────────────────────
   Owner, 2026-08-30: the home page must ARGUE the execution model rather than headline it, in a
   voice that challenges the status quo — "just because you used to have to do something does not
   mean that has to stay true." So these are wider, louder and slower than the two-column splits
   above them, and each carries a number because they ARE a sequence: what you no longer build, why
   it survives a crash, what happens to your data when you change your mind, and how it ships. */
.arg{padding-block:44px 8px;border-top:1px solid var(--rule)}
.arg:first-of-type{border-top:0}
.arg-no{font-family:var(--mono);font-size:11px;letter-spacing:.16em;color:var(--accent);margin:0 0 8px}
.arg h2{font-size:clamp(24px,2.9vw,34px);line-height:1.15;letter-spacing:-.028em;margin:0 0 14px;
  font-weight:600;text-wrap:balance}
.arg-say{font-size:17.5px;line-height:1.55;color:var(--ink-2);margin:0 0 26px}
.arg-after{font-size:15.5px;line-height:1.6;color:var(--ink-2);margin:22px 0 0}
.arg-after b{color:var(--ink);font-weight:600}
.arg-after a{font-weight:500;white-space:nowrap}
.arg pre{margin:18px 0 0}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────────────
   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}}

/* Local and cloud as ONE line, with the half that is not open yet marked in the reader's eye rather
   than in a footnote — the same word the reference uses for a surface that does not exist yet. */
.journey{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:20px;margin:6px 0 0}
.journey .leg{min-width:0}
.leg-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 10px;font-weight:600;font-size:15.5px}
.tag{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  padding:3px 9px;border-radius:20px;font-weight:500}
.tag.ok{color:var(--allow);background:color-mix(in srgb,var(--allow) 13%,transparent)}
.tag.soon{color:var(--mark);background:color-mix(in srgb,var(--mark) 15%,transparent)}
.leg.soon pre{opacity:.82;border-style:dashed}
.leg pre{margin:0}

/* 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 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%}

/* ── palette override ── */
:root{--paper:#eef3f3; --card:#ffffff; --wash:#dbe8e8; --rule:#c1d4d4; --rule-2:#98b3b3;--ink:#0b1f25; --ink-2:#3d585f; --ink-3:#6b878d;--accent:#00566f; --accent-wash:#d7ecf3;--allow:#0d7256; --allow-wash:#d8f1e7;--refuse:#b33a48; --refuse-wash:#fbe5e8;--mark:#8d6606;  --mark-wash:#f9eecd;--lane:#e6eeee;  --surface:#ffffff;--term-card:#0d2028; --term-wash:#08161b; --term-rule:#23454f; --term-rule2:#356472;--term-ink:#eaf4f5; --term-ink2:#a6c2c6; --term-ink3:#75949a;--term-accent:#66d0ee; --term-allow:#5fd8ab; --term-refuse:#ff929d; --term-mark:#ecc754;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--paper:#08161b; --card:#0f2229; --wash:#163038; --rule:#22444f; --rule-2:#34606e;--ink:#e7f1f2; --ink-2:#9fbdc1; --ink-3:#6e8f96;--accent:#5fc8e8; --accent-wash:#0a2a35;--allow:#4fd6a6; --allow-wash:#0a2620;--refuse:#ff8b98; --refuse-wash:#2a141a;--mark:#e8c04a;  --mark-wash:#2a2310;--lane:#0c1e24;  --surface:#12262e;}}
:root[data-theme="dark"]{--paper:#08161b; --card:#0f2229; --wash:#163038; --rule:#22444f; --rule-2:#34606e;--ink:#e7f1f2; --ink-2:#9fbdc1; --ink-3:#6e8f96;--accent:#5fc8e8; --accent-wash:#0a2a35;--allow:#4fd6a6; --allow-wash:#0a2620;--refuse:#ff8b98; --refuse-wash:#2a141a;--mark:#e8c04a;  --mark-wash:#2a2310;--lane:#0c1e24;  --surface:#12262e;}
