/* Banquet documentation.
   The palette is the app's own, lifted from its stylesheet at build time rather than
   transcribed here, so the two can never disagree about what terracotta is. */

:root {
  /* Banquet, warm minimal. Light, soft, one terracotta accent, mono only for numbers.
     No borders anywhere except hairline dividers and the receipt's dashed rules. */
  /* A fallback only. The real height is measured at runtime, so this survives any change
     to the nav's padding without having to be remembered. */
  --navh:58px;
  /* The strip the published build pins to the bottom, or nothing when there is none, and
     the bottom navigation's own height. Everything fixed to the foot of the screen is
     stacked from these two, and both are overwritten with measured pixels by
     `measureChrome`: these are the values for the frame before it first runs. */
  --strip:0px;
  --mbar:0px;
  --paper:#FBF8F4; --paper2:#FFFDFB; --warm:#F7F1E9; --paper3:#F5F0E9; --hover:#F3ECE3;
  --chip:#FBEEE0; --oven:#FDF3E9;

  --line:#F3ECE3; --line2:rgba(33,29,26,.06);
  --nav-bg:rgba(251,248,244,.90);

  --ink:#211D1A; --ink2:#6B6155; --mut:#6F6455; --faint:#C4B8A8;

  --acc:#C2703A; --acc-hi:#A85D2C; --acc-deep:#A8672E; --acc-warm:#8A5A2E;
  --cta:#A85D2C;
  --blue:#C2703A; --yellow:#EBC98A;
  --sand:#EBC98A; --sand2:#F0DCC4; --orange:#E2864A; --violet:#E2864A;
  --up:#3F9B72; --up-deep:#2F6B51; --up-tint:#F4F8F5; --up-tint2:#E4F0E9; --up-mut:#7FB79A;
  --down:#D96A6A; --down-txt:#B34141;

  /* 🔴 The same hues, dark enough to read as TEXT on cream.
     These accents were chosen as fills on a dark ground and reused unchanged for
     writing on paper, where they stop being colours and become suggestions.
     Measured, not judged by eye: the cover charge in the token header, which is the
     number telling a buyer what a trade costs them, ran at 1.50:1 against the page.
     WCAG asks 4.5. `--mut` alone carried fifty-one of these.
     The fill tokens above are untouched: a badge that uses --yellow as a background
     still wants the bright one, and darkening it there would break the pairing. */
  --sand-txt:#8A6A22; --yellow-txt:#8A6A22; --orange-txt:#A0541F; --violet-txt:#A0541F;
  --up-txt:#2E7454; --up-mut-txt:#35785A;

  /* receipts are paper: their own ink, and no radius */
  --pap:#FBF6EC; --pap-hi:#FFFCF6; --pap-ink:#2A241E; --pap-mut:#8C8073; --pap-dash:#C7BBA9; --stamp:#BE6A3C;
  /* 🔴 The receipt card's own palette, from the supplied design.
     `--pap-str` is the ink one step down from the heading, for a figure that must read as
     a number rather than as a title. `--pap-rail` is the unfilled part of the progress
     bar, which is paper rather than a hole. The two drop shadows follow the painted
     pixels, teeth included: a rectangular shadow under a torn card draws a straight line
     where the tear is. */
  --pap-str:#4A443A; --pap-rail:#E7DECE; --rail-served:#C7BBA9; --feed:#9E5628;
  --served-fg:#2F6B51; --served-bd:#8FBCA5;
  --cooking-fg:#8A5426; --cooking-bd:#E0AD7C;
  --tax-none-bg:#E4EDE6; --tax-none-fg:#2F6B51;
  --tax-lo-bg:#EFEADA;  --tax-lo-fg:#6E6035;
  --tax-mid-bg:#F3E4D2; --tax-mid-fg:#8A5426;
  --tax-hi-bg:#F3E1DD;  --tax-hi-fg:#94422F;
  /* 🔴 Named for what they are, not for their colour. `--warm` was already a solid paper
     tone used by the upload square and the bottom bar, and giving that name to a gradient
     turned both into a peach ramp. */
  --rail-warm:linear-gradient(90deg,#EBC98A,#E2864A);
  --rail-rose:linear-gradient(90deg,#E8A24A,#D96A6A);
  --stain:radial-gradient(56% 28% at 86% 5%,rgba(150,118,72,.13) 0%,rgba(249,245,234,0) 72%),
          radial-gradient(38% 20% at 8% 84%,rgba(150,118,72,.11) 0%,rgba(249,245,234,0) 74%);
  --stain-opacity:.4;
  --drop-1:drop-shadow(0 9px 20px rgba(90,60,30,.2));
  --tint0-bg:#F3E4D2; --tint0-fg:#8A5426; --tint1-bg:#E4EDE6; --tint1-fg:#2F6B51;
  --tint2-bg:#EDE4EE; --tint2-fg:#6B4269; --tint3-bg:#F3E1DD; --tint3-fg:#94422F;
  --tint4-bg:#EAEADC; --tint4-fg:#5E6A38; --tint5-bg:#E3E9F1; --tint5-fg:#3C5677;

  /* Two layers, soft and warm. Never a hard offset. */
  --sh:0 1px 2px rgba(90,60,30,.05), 0 10px 28px -18px rgba(90,60,30,.28);
  --sh-hi:0 2px 4px rgba(90,60,30,.06), 0 24px 48px -22px rgba(90,60,30,.36);
  --sh-sm:0 1px 2px rgba(90,60,30,.05), 0 12px 32px -22px rgba(90,60,30,.3);
  --sh-cta:0 8px 20px -10px rgba(194,112,58,.7);
  --sh-cta-hi:0 14px 28px -12px rgba(194,112,58,.75);
  --sh-chip:0 1px 3px rgba(90,60,30,.12);

  --g-warm:linear-gradient(90deg,#EBC98A,#E2864A);
  --g-rose:linear-gradient(90deg,#E8A24A,#D96A6A);
  --g-gold:linear-gradient(90deg,#EBC98A,#E2864A);
  --g-temp:linear-gradient(90deg,#E2664A,#E8A24A 45%,#EBC98A 72%,#8FC4A8);

  /* 🔴 `--amber` was used in two places and defined in none, so `background:var(--amber)`
     was an invalid declaration and the tile it painted had no background at all. */
  --amber:#EBC98A;

  /* Tokens for what used to be written as hex in the rules themselves. Nothing here is a
     new colour: they are the same values, named, so a second palette can move them. */
  --hover2:#EDE4D9;          /* the wallet button, hovered */
  --track:#F1EAE1;           /* the empty half of a progress bar */
  --sell-hi:#332C27;         /* the sell button, hovered */
  --dot:#403932;             /* the dotted leader in a receipt line */
  --warn-bg:#FBECEC; --warn-ink:#B4514F; --warn-strong:#8E2F2F;
  /* Text laid over a saturated fill, and over the oven tint. Both flip in dark, because
     the fills get lighter there rather than darker. */
  --onbright:#fff; --oven-ink:#000;

  --ease:cubic-bezier(.22,.61,.36,1);
}

:root { color-scheme: light; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --paper:#17130F; --paper2:#1F1A15; --warm:#241D17; --paper3:#272019; --hover:#2E261E;
  --chip:#33261A; --oven:#2C2015;

  --line:#2F2820; --line2:rgba(243,237,228,.08);
  --nav-bg:rgba(23,19,15,.90);

  --ink:#F3EDE4; --ink2:#BCAE9E; --mut:#928576; --faint:#6D6357;

  --acc:#E08A50; --acc-hi:#F0A268; --acc-deep:#C2703A; --acc-warm:#DFA070;
  --blue:#E08A50; --yellow:#EBC98A; --amber:#D8B778;
  --sand:#D8B778; --sand2:#4A3B26; --orange:#E2864A; --violet:#E2864A;
  --up:#4FB88A; --up-deep:#8FD9B4; --up-tint:#182420; --up-tint2:#1D3128; --up-mut:#72AC90;
  --down:#E88585; --down-txt:#E88585;
  --sand-txt:#D8B778; --yellow-txt:#D8B778; --orange-txt:#E2864A; --violet-txt:#E2864A;
  --up-txt:#4FB88A; --up-mut-txt:#72AC90;

  --hover2:#383026; --track:#2F2820; --sell-hi:#DCD5CB; --dot:#5A5045;
  --warn-bg:#331E1E; --warn-ink:#E6A8A8; --warn-strong:#FFD5D5;
  --onbright:#17130F; --oven-ink:#F3EDE4;
  --cta:var(--acc);
  --pap:#1C1712; --pap-hi:#251E17; --pap-ink:#EFE7DA; --pap-mut:#9A8D7E; --pap-dash:#4A4036; --stamp:#E08A50;
  /* The same card, printed on dark stock. */
  --pap-str:#D6CCBF; --pap-rail:#2E2822; --rail-served:#4A3F36; --feed:#E9A472;
  --served-fg:#7FD3A8; --served-bd:#3D6B57;
  --cooking-fg:#EDA167; --cooking-bd:#7A5330;
  --tax-none-bg:rgba(127,211,168,.14); --tax-none-fg:#7FD3A8;
  --tax-lo-bg:rgba(211,190,142,.12);   --tax-lo-fg:#D3BE8E;
  --tax-mid-bg:rgba(226,134,74,.16);   --tax-mid-fg:#EDA167;
  --tax-hi-bg:rgba(217,106,106,.18);   --tax-hi-fg:#EE9086;
  /* 🔴 Named for what they are, not for their colour. `--warm` was already a solid paper
     tone used by the upload square and the bottom bar, and giving that name to a gradient
     turned both into a peach ramp. */
  --rail-warm:linear-gradient(90deg,#EBC98A,#E2864A);
  --rail-rose:linear-gradient(90deg,#E8A24A,#D96A6A);
  --stain:radial-gradient(56% 28% at 86% 5%,rgba(255,220,170,.05) 0%,rgba(33,28,25,0) 72%),
          radial-gradient(38% 20% at 8% 84%,rgba(255,220,170,.04) 0%,rgba(33,28,25,0) 74%);
  --stain-opacity:1;
  --drop-1:drop-shadow(0 10px 22px rgba(0,0,0,.55));
  --tint0-bg:rgba(226,134,74,.18); --tint0-fg:#EDA167;
  --tint1-bg:rgba(127,211,168,.16); --tint1-fg:#7FD3A8;
  --tint2-bg:rgba(178,130,175,.18); --tint2-fg:#C79BC4;
  --tint3-bg:rgba(217,106,106,.18); --tint3-fg:#EE9086;
  --tint4-bg:rgba(160,175,110,.18); --tint4-fg:#B6C286;
  --tint5-bg:rgba(122,155,200,.18); --tint5-fg:#9DB6D8;

  --sh:0 1px 2px rgba(0,0,0,.5), 0 10px 28px -18px rgba(0,0,0,.8);
  --sh-hi:0 2px 4px rgba(0,0,0,.55), 0 24px 48px -22px rgba(0,0,0,.9);
  --sh-sm:0 1px 2px rgba(0,0,0,.5), 0 12px 32px -22px rgba(0,0,0,.8);
  --sh-chip:0 1px 3px rgba(0,0,0,.6);
}
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] {
  --paper:#17130F; --paper2:#1F1A15; --warm:#241D17; --paper3:#272019; --hover:#2E261E;
  --chip:#33261A; --oven:#2C2015;

  --line:#2F2820; --line2:rgba(243,237,228,.08);
  --nav-bg:rgba(23,19,15,.90);

  --ink:#F3EDE4; --ink2:#BCAE9E; --mut:#928576; --faint:#6D6357;

  --acc:#E08A50; --acc-hi:#F0A268; --acc-deep:#C2703A; --acc-warm:#DFA070;
  --blue:#E08A50; --yellow:#EBC98A; --amber:#D8B778;
  --sand:#D8B778; --sand2:#4A3B26; --orange:#E2864A; --violet:#E2864A;
  --up:#4FB88A; --up-deep:#8FD9B4; --up-tint:#182420; --up-tint2:#1D3128; --up-mut:#72AC90;
  --down:#E88585; --down-txt:#E88585;
  --sand-txt:#D8B778; --yellow-txt:#D8B778; --orange-txt:#E2864A; --violet-txt:#E2864A;
  --up-txt:#4FB88A; --up-mut-txt:#72AC90;

  --hover2:#383026; --track:#2F2820; --sell-hi:#DCD5CB; --dot:#5A5045;
  --warn-bg:#331E1E; --warn-ink:#E6A8A8; --warn-strong:#FFD5D5;
  --onbright:#17130F; --oven-ink:#F3EDE4;
  --cta:var(--acc);
  --pap:#1C1712; --pap-hi:#251E17; --pap-ink:#EFE7DA; --pap-mut:#9A8D7E; --pap-dash:#4A4036; --stamp:#E08A50;
  /* The same card, printed on dark stock. */
  --pap-str:#D6CCBF; --pap-rail:#2E2822; --rail-served:#4A3F36; --feed:#E9A472;
  --served-fg:#7FD3A8; --served-bd:#3D6B57;
  --cooking-fg:#EDA167; --cooking-bd:#7A5330;
  --tax-none-bg:rgba(127,211,168,.14); --tax-none-fg:#7FD3A8;
  --tax-lo-bg:rgba(211,190,142,.12);   --tax-lo-fg:#D3BE8E;
  --tax-mid-bg:rgba(226,134,74,.16);   --tax-mid-fg:#EDA167;
  --tax-hi-bg:rgba(217,106,106,.18);   --tax-hi-fg:#EE9086;
  /* 🔴 Named for what they are, not for their colour. `--warm` was already a solid paper
     tone used by the upload square and the bottom bar, and giving that name to a gradient
     turned both into a peach ramp. */
  --rail-warm:linear-gradient(90deg,#EBC98A,#E2864A);
  --rail-rose:linear-gradient(90deg,#E8A24A,#D96A6A);
  --stain:radial-gradient(56% 28% at 86% 5%,rgba(255,220,170,.05) 0%,rgba(33,28,25,0) 72%),
          radial-gradient(38% 20% at 8% 84%,rgba(255,220,170,.04) 0%,rgba(33,28,25,0) 74%);
  --stain-opacity:1;
  --drop-1:drop-shadow(0 10px 22px rgba(0,0,0,.55));
  --tint0-bg:rgba(226,134,74,.18); --tint0-fg:#EDA167;
  --tint1-bg:rgba(127,211,168,.16); --tint1-fg:#7FD3A8;
  --tint2-bg:rgba(178,130,175,.18); --tint2-fg:#C79BC4;
  --tint3-bg:rgba(217,106,106,.18); --tint3-fg:#EE9086;
  --tint4-bg:rgba(160,175,110,.18); --tint4-fg:#B6C286;
  --tint5-bg:rgba(122,155,200,.18); --tint5-fg:#9DB6D8;

  --sh:0 1px 2px rgba(0,0,0,.5), 0 10px 28px -18px rgba(0,0,0,.8);
  --sh-hi:0 2px 4px rgba(0,0,0,.55), 0 24px 48px -22px rgba(0,0,0,.9);
  --sh-sm:0 1px 2px rgba(0,0,0,.5), 0 12px 32px -22px rgba(0,0,0,.8);
  --sh-chip:0 1px 3px rgba(0,0,0,.6);
}
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

:root {
  --side-w: 250px;
  --toc-w: 200px;
  --topbar: 57px;
  --measure: 70ch;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 16.5px/1.72 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--ink); color: var(--paper); padding: 10px 16px; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; }

:where(a):focus-visible, :where(button):focus-visible {
  outline: 2px solid var(--acc); outline-offset: 2px; border-radius: 4px;
}

/* ------------------------------------------------------------------ */
/*  the bar                                                            */
/* ------------------------------------------------------------------ */

.top {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  height: var(--topbar); padding: 0 18px;
  background: var(--nav-bg);
  backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--ink); text-decoration: none; font-weight: 700; letter-spacing: -.01em;
}
/* Left at its own colour: it is the brand mark, not an icon taking the page accent. */
.brand .mk { width: 22px; height: 22px; display: block; }
.sep { width: 1px; height: 20px; background: var(--line2); }
.here { color: var(--mut); text-decoration: none; font-weight: 600; font-size: 14.5px; }
.here:hover { color: var(--ink); }
.grow { flex: 1; }

.ghost {
  border: 0; background: transparent; color: var(--mut); cursor: pointer;
  font: inherit; font-size: 15px; padding: 7px 10px; border-radius: 8px; line-height: 1;
}
.ghost:hover { background: var(--hover); color: var(--ink); }

.cta {
  background: var(--cta); color: #fff; text-decoration: none; font-weight: 600;
  font-size: 14px; padding: 8px 15px; border-radius: 999px; box-shadow: var(--sh-cta);
  white-space: nowrap;
}
.cta:hover { box-shadow: var(--sh-cta-hi); }
.menu { display: none; }

/* ------------------------------------------------------------------ */
/*  the three columns                                                  */
/* ------------------------------------------------------------------ */

.shell {
  display: grid;
  grid-template-columns: var(--side-w) minmax(0, 1fr);
  gap: 52px;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 26px;
  align-items: start;
}

.side {
  position: sticky; top: var(--topbar);
  max-height: calc(100vh - var(--topbar));
  overflow-y: auto;
  padding: 28px 8px 60px 0;
  font-size: 14.5px;
}
.stitle {
  margin: 26px 0 8px; padding: 0 10px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--faint);
}
.stitle:first-child { margin-top: 4px; }
.slist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.slist a {
  display: block; padding: 6px 10px; border-radius: 7px;
  color: var(--ink2); text-decoration: none; line-height: 1.4;
}
.slist a:hover { background: var(--hover); color: var(--ink); }
.slist a.on { background: var(--chip); color: var(--acc-hi); font-weight: 600; }

main { min-width: 0; padding: 34px 0 72px; }

/* ------------------------------------------------------------------ */
/*  the prose                                                          */
/* ------------------------------------------------------------------ */

/* A section of the one page. The rule above it is what a page break used to be. */
.chapter { max-width: var(--measure); padding: 8px 0 30px; scroll-margin-top: calc(var(--topbar) + 8px); }
.chapter + .chapter { border-top: 1px solid var(--line); padding-top: 38px; }
.chapter > h2 {
  margin: 0 0 22px;
  font-size: clamp(27px, 4vw, 34px); font-weight: 700; line-height: 1.16;
  letter-spacing: -.022em; text-wrap: balance;
}
/* The group the sidebar shows, printed where the group begins. */
.band {
  margin: 60px 0 6px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--acc);
}
.chapter:first-of-type, .band:first-child { padding-top: 0; margin-top: 0; }
.band + .chapter { border-top: 0; padding-top: 4px; }

.prose { max-width: var(--measure); }
.eyebrow {
  margin: 0 0 10px;
  font-size: 12px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--acc);
}
.prose h3 {
  margin: 40px 0 14px;
  font-size: 21px; font-weight: 700; line-height: 1.28; letter-spacing: -.015em;
  text-wrap: balance;
}
.prose h4 {
  margin: 32px 0 11px;
  font-size: 17.5px; font-weight: 600; line-height: 1.32; letter-spacing: -.008em;
}
.prose h5 {
  margin: 26px 0 9px;
  font-size: 15.5px; font-weight: 600; color: var(--ink2);
}
.prose p { margin: 0 0 18px; }
.prose ul, .prose ol { margin: 0 0 20px; padding-left: 24px; }
.prose li { margin: 0 0 8px; }
.prose li::marker { color: var(--faint); }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 42px 0; }
.prose strong { font-weight: 600; }

.prose a { color: var(--acc-hi); text-decoration-color: color-mix(in srgb, var(--acc) 35%, transparent); text-underline-offset: 2.5px; }
.prose a:hover { text-decoration-color: var(--acc); }

h2, h3, h4, h5 { position: relative; scroll-margin-top: calc(var(--topbar) + 18px); }
.anchor {
  position: absolute; left: -0.85em; top: 0;
  color: var(--faint); text-decoration: none; opacity: 0;
  font-weight: 400;
}
h3:hover .anchor, h4:hover .anchor, h5:hover .anchor, .anchor:focus { opacity: 1; }

code {
  font: 500 .875em/1.5 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--warm); color: var(--acc-warm);
  padding: .12em .38em; border-radius: 5px;
  overflow-wrap: break-word;
}
.prose a code { color: inherit; }

pre.code {
  margin: 0 0 22px; padding: 16px 18px;
  background: var(--paper3); border: 1px solid var(--line);
  border-radius: 12px; overflow-x: auto;
  font: 400 13.5px/1.62 'JetBrains Mono', ui-monospace, Menlo, monospace;
}
pre.code code { background: none; padding: 0; color: var(--ink); font-size: inherit; }
pre.code[data-lang]::before {
  content: attr(data-lang);
  display: block; margin: -4px 0 10px;
  font: 600 10.5px/1 'Inter Tight', sans-serif; letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint);
}

/* tables */
.tw { overflow-x: auto; margin: 0 0 24px; }
table { border-collapse: collapse; width: 100%; font-size: 15px; }
thead th {
  text-align: left; padding: 9px 14px 9px 0;
  border-bottom: 1.5px solid var(--line);
  font-weight: 600; font-size: 12.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--mut); white-space: nowrap;
}
tbody td {
  padding: 10px 14px 10px 0;
  border-bottom: 1px solid var(--line2);
  vertical-align: top;
}
tbody tr:last-child td { border-bottom: 0; }
td:last-child, th:last-child { padding-right: 0; }

/* hints */
.hint {
  margin: 0 0 24px; padding: 15px 18px;
  border-radius: 12px; border-left: 3px solid var(--acc);
  background: var(--warm);
}
.hint > p:last-child { margin-bottom: 0; }
.hlabel {
  margin: 0 0 6px !important;
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
}
.hint.danger { border-left-color: var(--down); background: var(--warn-bg); }
.hint.danger .hlabel { color: var(--warn-strong); }
.hint.warning { border-left-color: var(--sand); background: var(--oven); }
.hint.warning .hlabel { color: var(--sand-txt); }
.hint.info { border-left-color: var(--acc); background: var(--warm); }
.hint.info .hlabel { color: var(--acc-warm); }
.hint.success { border-left-color: var(--up); background: var(--up-tint2); }
.hint.success .hlabel { color: var(--up-txt); }

/* ------------------------------------------------------------------ */
/*  maths                                                              */
/* ------------------------------------------------------------------ */

.math, .mathblock {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: .94em;
}
.mathblock {
  margin: 0 0 22px; padding: 18px 20px;
  background: var(--paper3); border-radius: 12px;
  text-align: center; font-size: 16px; overflow-x: auto;
}
.math .op, .mathblock .op { padding: 0 .22em; color: var(--mut); }
.math .txt, .mathblock .txt { font-family: 'Inter Tight', sans-serif; font-size: .92em; }
.sp { display: inline-block; width: .18em; }
.quad { display: inline-block; width: .9em; }

.frac { display: inline-flex; flex-direction: column; vertical-align: middle; text-align: center; margin: 0 .18em; }
.frac .num { border-bottom: 1px solid currentColor; padding: 0 .3em .1em; }
.frac .den { padding: .1em .3em 0; }

.sqrt { display: inline-flex; align-items: stretch; }
.sqrt .rad { transform: scaleY(1.1); }
.sqrt .rand { border-top: 1px solid currentColor; padding: 0 .2em; margin-top: .16em; }

.cases { display: inline-flex; align-items: stretch; gap: .3em; vertical-align: middle; }
.cases .brace { font-size: 2.4em; line-height: .95; color: var(--faint); }
.cases .rows { display: flex; flex-direction: column; gap: .35em; justify-content: center; text-align: left; }
.cases .crow { display: flex; gap: 1.4em; }

sub, sup { font-size: .72em; line-height: 0; }

/* ------------------------------------------------------------------ */
/*  diagrams                                                           */
/* ------------------------------------------------------------------ */

.flow {
  margin: 0 0 26px; padding: 24px 18px;
  background: var(--paper3); border-radius: 14px;
  overflow-x: auto;
}
/* As wide as the tree needs. max-content is what makes it scroll instead of wrapping the
   branches, and margin auto keeps a narrow diagram centred rather than pinned left. */
.ftree {
  display: flex; flex-direction: column; align-items: center;
  min-width: max-content; margin: 0 auto;
}
.fnode {
  background: var(--paper2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 14px;
  font-size: 13.5px; line-height: 1.42; text-align: center;
  max-width: 250px; box-shadow: var(--sh-sm);
}
.fnode.diamond {
  border-color: var(--acc); background: var(--chip); color: var(--acc-hi);
  border-radius: 999px; font-weight: 600;
}
.fnode.round { border-radius: 999px; }
.fnode .loop {
  display: block; margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--line);
  font-size: 11.5px; color: var(--mut);
}

/* The connectors. A line down the middle, and a pill on it when the edge is named. */
.farrow, .fstem {
  position: relative; align-self: center;
  display: flex; align-items: center; justify-content: center;
}
.farrow { min-height: 30px; padding: 4px 0; }
.fstem { height: 18px; }
.farrow::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: 1.5px solid var(--faint);
}
/* 🔴 No line into a fork, and none out of one.
   A line drawn there runs down the gap between the arms and past both of them, which
   reads as a third path going around the choice rather than through it. Where the arms
   are panels, the panels are the connection: spacing is enough to say "then". */
.fstem, .farrow.merge { height: 14px; }
.fstem::before, .farrow.merge::before { display: none; }
.elabel {
  position: relative; z-index: 1;
  background: var(--paper3); padding: 2px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; color: var(--mut);
  text-align: center; max-width: 210px;
}

/* A fork.
   Each arm is a panel headed by the answer that opens it, and the answer is what the
   reader follows. This used to be two bare columns with a label floating above each and
   a short line stub beside it: nothing joined the question to its answers, nothing joined
   the answers back, and a connector that ends in mid-air is worse than no connector at
   all. CSS cannot draw a line between two boxes whose positions it does not know, so
   containment does the work that geometry could not. */
.fbranch { display: flex; gap: 12px; align-items: stretch; justify-content: center; }
.fcol {
  display: flex; flex-direction: column; align-items: center;
  min-width: 0; padding: 10px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--paper);
}
/* A fork inside a fork. Each level of panel adds its own padding and border, and three
   of them nested push a chart past the width of the page for no gain: by then the outer
   panel is already doing the containing, and the label alone separates the arms. */
.fcol .fcol {
  padding: 8px 6px; background: none; border-color: var(--line2); border-radius: 10px;
}
.fcol .fcol .fcol { border: 0; padding: 6px 2px; }
.fcol > .elabel {
  margin-bottom: 12px;
  background: var(--chip); color: var(--acc-hi);
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  font-size: 11px; padding: 3px 12px;
}
/* An arm that skips the step its sibling takes, named rather than drawn. */
.fcol.bypass { justify-content: flex-start; }
.fskip {
  margin: 0; padding: 10px 4px;
  font-size: 13px; color: var(--mut); text-align: center;
}
.fskip b { color: var(--ink2); font-weight: 600; }

.fgroups { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; justify-content: center; width: 100%; }
.fgroup {
  flex: 1 1 260px; min-width: 240px;
  display: flex; flex-direction: column; align-items: center;
  padding: 14px; border: 1px dashed var(--line); border-radius: 12px;
}
.fgtitle {
  margin: 0 0 12px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--mut); text-align: center;
}

@media (max-width: 640px) {
  /* On a phone there is no width to scroll into, so the arms stack and the labels that
     head them are what keeps the branches apart. */
  .ftree { min-width: 0; }
  .fbranch { flex-direction: column; align-items: center; gap: 10px; }
}

.chart { margin: 0 0 26px; padding: 18px; background: var(--paper3); border-radius: 14px; }
.chart figcaption {
  margin: 0 0 10px;
  font-size: 13px; font-weight: 600; color: var(--ink2); text-align: center;
}
.chart svg { display: block; width: 100%; height: auto; }
.chart .g { stroke: var(--line); stroke-width: 1; }
.chart .t { font: 500 11px 'JetBrains Mono', monospace; fill: var(--mut); }
.chart .ty { text-anchor: end; }
.chart .tx { text-anchor: middle; }
.chart .ax { font: 600 11.5px 'Inter Tight', sans-serif; fill: var(--faint); text-anchor: middle; }
/* The y-axis label sits along the top rather than rotated up the side, where a name
   longer than the plot is tall would run off both ends of the drawing. */
.chart .ay { text-anchor: start; }
.chart .line { fill: none; stroke: var(--acc); stroke-width: 2.2; stroke-linejoin: round; }
.chart .area { fill: var(--acc); opacity: .09; stroke: none; }
.chart .dot { fill: var(--acc); }

.seq { margin: 0 0 26px; padding: 18px; background: var(--paper3); border-radius: 14px; }
.seq .cast { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.seq .cast span {
  background: var(--chip); color: var(--acc-hi);
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
}
.seq ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.seq li {
  display: grid; grid-template-columns: 22px auto 18px auto 1fr; gap: 8px;
  align-items: baseline; padding: 5px 0; font-size: 13.5px;
  border-bottom: 1px solid var(--line2);
}
.seq li:last-child { border-bottom: 0; }
.seq .n { color: var(--faint); font: 500 11px 'JetBrains Mono', monospace; }
.seq .who { font-weight: 600; white-space: nowrap; }
.seq .arr { color: var(--acc); text-align: center; }
.seq .msg { font-family: 'JetBrains Mono', monospace; font-size: 12.5px; color: var(--ink2); }
.seq li.ret .msg { color: var(--mut); font-style: italic; }
.seq li.note { display: block; color: var(--mut); font-style: italic; padding-left: 30px; }

pre.diagram { font-size: 12px; }

/* ------------------------------------------------------------------ */
/*  the foot                                                           */
/* ------------------------------------------------------------------ */

.foot {
  display: flex; justify-content: space-between; gap: 12px;
  margin-top: 44px; padding-top: 20px; border-top: 1px solid var(--line);
  max-width: var(--measure);
  font-size: 13px; color: var(--mut);
}
.commit { font-family: 'JetBrains Mono', monospace; color: var(--faint); }

/* ------------------------------------------------------------------ */
/*  narrower                                                           */
/* ------------------------------------------------------------------ */

@media (max-width: 1040px) {
  .shell { gap: 34px; padding: 0 20px; }
}

@media (max-width: 860px) {
  .shell { grid-template-columns: minmax(0, 1fr); padding: 0 18px; }
  .menu { display: inline-block; }
  .cta { display: none; }
  .side {
    display: none;
    position: static; max-height: none; overflow: visible;
    padding: 14px 0 20px; border-bottom: 1px solid var(--line);
  }
  .side.open { display: block; }
  main { padding-top: 24px; }
}
