/* ============================================================================
   AI SYSTEM DESIGN GUIDE — site additions
   Loaded AFTER book.css. book.css is frozen; this file only ADDS.

   Three jobs:
     1. the components the guide's renderer emits that the book never needed
        (toc cards, task lists, Q&A, reference lists, math, dead links, …)
     2. the two page types the book never had — a section hub, and a home page
     3. the shell furniture shell.js builds — search, keys, pager, breadcrumb

   No new colours. Seven semantic hues and the paper/ink ramp, exactly as
   book.css defines them. Where a component needs "whatever hue this thing is",
   it reads --h / --h-d / --h-f / --h-l, which §0 below binds to one of the seven.
   ========================================================================= */

/* ------------------------------------------------------------ 0. HUE BINDING
   The contract puts data-hue on <body>; a card carries its own data-hue when it
   speaks for a different section than the page it sits on. Declaring --h at the
   element that owns the hue means every descendant inherits the right one.

   NOTE: .rail redefines --clay … --olive for its dark ground, so nothing inside
   the rail may read --h (it would inherit the page's resolution). The rail uses
   --g, set on rail elements themselves, exactly as book.css expects. */
:root {
  --h: var(--ink-3); --h-d: var(--ink-2); --h-f: var(--paper-3); --h-l: var(--line-2);
}
[data-hue="clay"]    { --h: var(--clay);    --h-d: var(--clay-d);    --h-f: var(--clay-f);    --h-l: var(--clay-l); }
[data-hue="indigo"]  { --h: var(--indigo);  --h-d: var(--indigo-d);  --h-f: var(--indigo-f);  --h-l: var(--indigo-l); }
[data-hue="teal"]    { --h: var(--teal);    --h-d: var(--teal-d);    --h-f: var(--teal-f);    --h-l: var(--teal-l); }
[data-hue="amber"]   { --h: var(--amber);   --h-d: var(--amber-d);   --h-f: var(--amber-f);   --h-l: var(--amber-l); }
[data-hue="crimson"] { --h: var(--crimson); --h-d: var(--crimson-d); --h-f: var(--crimson-f); --h-l: var(--crimson-l); }
[data-hue="plum"]    { --h: var(--plum);    --h-d: var(--plum-d);    --h-f: var(--plum-f);    --h-l: var(--plum-l); }
[data-hue="olive"]   { --h: var(--olive);   --h-d: var(--olive-d);   --h-f: var(--olive-f);   --h-l: var(--olive-l); }

/* ------------------------------------------------- 0b. MOTION IS OPT-IN
   book.css starts .reveal at opacity:0 and shell.js reveals each block as it
   scrolls into view. That is correct while the script runs — and catastrophic
   when it does not: a blocked script, a crawler, reader mode or a stalled
   asset leaves every section of every page invisible, which for this site
   means the entire body of all 108 pages.

   So the hiding is armed by the script itself. shell.js puts .js-motion on
   <html> as its first statement, before first paint; until then, and forever
   if it never runs, .reveal is simply visible. */
html:not(.js-motion) .reveal,
html:not(.js-motion) figure.fig svg .fade,
html:not(.js-motion) figure.fig svg .fade-el,
html:not(.js-motion) figure.fig svg .fade2,
html:not(.js-motion) figure.fig svg .pop {
  opacity: 1;
}
html:not(.js-motion) .reveal { transform: none; }
html:not(.js-motion) .bars .bar-t > i { transform: none; }

/* A page with no sections of its own gets no minimap; reclaim its gutter. */
body.no-mm .book { margin-left: 0; }
body.no-mm #tg-minimap { display: none !important; }

/* ============================================================================
   1 · THE RENDERER'S COMPONENTS
   ========================================================================= */

/* ------------------------------------------------------- 1a. h5 / h6
   Below h4 the book stops using display type and switches to apparatus: h5 is
   a bold UI line, h6 is a label. Anything deeper than that is a list. */
h5, .h5 {
  font-family: var(--f-ui); font-weight: 700; font-size: var(--fs-sm);
  line-height: 1.4; margin: var(--sp-5) 0 var(--sp-2); color: var(--ink);
  letter-spacing: -.002em;
}
h6, .h6 {
  font-family: var(--f-ui); font-weight: 700; font-size: var(--fs-label);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  line-height: 1.4; margin: var(--sp-4) 0 var(--sp-2); color: var(--ink-3);
}

/* --------------------------------------------------------- 1b. .toc-card
   The in-file "## Table of Contents". The left minimap already navigates the
   page, so this is a compact card, not a second sidebar: numbered, two-up when
   there is room, quiet links that only colour on hover. */
nav.toc-card {
  margin: var(--sp-5) 0 var(--sp-7); max-width: var(--w-wide);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-4) var(--sp-5);
  box-shadow: var(--sh-1);
}
.toc-k {
  font-family: var(--f-ui); font-size: var(--fs-label); font-weight: 700;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 var(--sp-3);
  display: flex; align-items: center; gap: var(--sp-3);
}
.toc-k::after { content: ""; flex: 1; height: 1px; background: var(--line); }
nav.toc-card ul {
  list-style: none; margin: 0; padding: 0; max-width: none;
  counter-reset: toc;
}
nav.toc-card > ul { column-gap: var(--sp-7); }
@media (min-width: 780px) { nav.toc-card > ul { column-count: 2; } }
nav.toc-card li {
  margin: 0 0 5px; break-inside: avoid;
  display: grid; grid-template-columns: 1.7rem 1fr; align-items: baseline;
  font-size: var(--fs-sm); line-height: 1.45;
}
nav.toc-card > ul > li::before {
  counter-increment: toc; content: counter(toc, decimal-leading-zero);
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
nav.toc-card li li { grid-template-columns: 1rem 1fr; font-size: var(--fs-xs); }
nav.toc-card li li::before { content: "\2013"; color: var(--line-3); }
nav.toc-card ul ul { grid-column: 1 / -1; padding-left: 1.7rem; margin-top: 5px; }
nav.toc-card a {
  color: var(--ink-2); background-image: none;
  transition: color .14s var(--ease);
}
nav.toc-card a:hover { color: var(--indigo); }

/* ------------------------------------------------- 1c. .checks — task lists
   A real drawn box, not a glyph: a 13px square in the paper's own line colour,
   ticked in teal because a done item is a verified item. */
ul.checks { list-style: none; margin: 0 0 var(--sp-4); padding: 0; max-width: var(--measure); }
li.chk {
  position: relative; display: grid; grid-template-columns: 1.35rem 1fr;
  align-items: start; margin-bottom: var(--sp-2);
  line-height: var(--lh-body);
}
li.chk::before {
  content: ""; width: 13px; height: 13px; margin-top: .34em;
  border: 1.5px solid var(--line-3); border-radius: 3px;
  background: var(--panel); box-sizing: border-box;
}
li.chk.is-done::before { background: var(--teal); border-color: var(--teal-d); }
li.chk.is-done::after {
  content: ""; position: absolute; left: 4px; top: .52em;
  width: 4px; height: 8px; box-sizing: border-box;
  border-right: 2px solid var(--panel); border-bottom: 2px solid var(--panel);
  transform: rotate(41deg);
}
li.chk.is-done { color: var(--ink-3); }
li.chk.is-done strong { color: var(--ink-2); }
li.chk > ul, li.chk > ol { grid-column: 2; margin-top: var(--sp-2); }

/* ------------------------------------------------- 1d. .qa — interview pairs
   Q is a claim being put to you (clay); A is the evidence you answer with
   (teal). The chips carry the hue so the prose does not have to. */
.qa {
  margin: var(--sp-4) 0; max-width: var(--w-wide);
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--clay); border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5);
  box-shadow: var(--sh-1);
}
.qa + .qa { margin-top: var(--sp-3); }
.qa-q, .qa-a { position: relative; padding-left: 2.1rem; max-width: none; }
.qa-q::before, .qa-a::before {
  position: absolute; left: 0; top: .1em;
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); font-weight: 700;
  width: 1.45rem; text-align: center; line-height: 1.5;
  border-radius: var(--r-sm); border: 1px solid;
}
.qa-q {
  font-weight: 650; color: var(--ink); margin: 0 0 var(--sp-3);
  font-size: var(--fs-body); line-height: 1.5;
}
.qa-q::before { content: "Q"; color: var(--clay-d); background: var(--clay-f); border-color: var(--clay-l); }
.qa-a { font-size: var(--fs-sm); line-height: 1.6; color: var(--ink-2); margin: 0; }
.qa-a::before { content: "A"; color: var(--teal-d); background: var(--teal-f); border-color: var(--teal-l); }
.qa-a > p { max-width: none; margin: 0 0 var(--sp-2); }
.qa-a > p:last-child { margin-bottom: 0; }
.qa-a ul, .qa-a ol { margin: var(--sp-2) 0 0; padding-left: 1.1rem; max-width: none; }

/* --------------------------------------------- 1e. .reflist — further reading
   A reference is a promise you can check, so the domain is shown, right-set,
   as a .tag. Hairlines between rows; no bullets. */
ul.reflist { list-style: none; margin: var(--sp-4) 0; padding: 0; max-width: var(--w-wide); }
ul.reflist > li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-3) 0; margin: 0; border-top: 1px solid var(--line);
  font-size: var(--fs-sm); line-height: 1.5;
}
ul.reflist > li:first-child { border-top: 0; padding-top: 0; }
/* the anchor must not stretch: a flex-grown <a> drags its underline gradient
   across the whole row, which reads as a rule, not a link */
ul.reflist > li > a, ul.reflist > li > .deadlink { flex: 0 1 auto; min-width: 0; }
ul.reflist .tag { margin-left: auto; flex: none; white-space: nowrap; }

/* ------------------------------------------------- 1f. .math — display maths
   Raw LaTeX, preserved verbatim. Centred, monospace, ruled top and bottom so
   it reads as a set-off equation rather than a code block. */
.math {
  margin: var(--sp-5) 0; padding: var(--sp-4) var(--sp-4);
  max-width: var(--w-wide); text-align: center; overflow-x: auto;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: linear-gradient(var(--paper-2), var(--paper-2));
  background-size: 100% 100%;
}
.math > code {
  font-family: var(--f-mono); font-size: var(--fs-mono); line-height: 1.7;
  color: var(--ink-2); background: none; border: 0; padding: 0;
  white-space: pre-wrap; display: inline-block; text-align: left;
}

/* ----------------------------------------------- 1g. .deadlink — no target
   A link whose file is not in the repo. It must look like an editorial
   decision, not a broken anchor: ink, a dotted rule, and a dagger — the
   printer's mark for "see note". Never blue, never underlined solid. */
.deadlink {
  color: var(--ink-2); border-bottom: 1px dotted var(--line-3);
  cursor: help;
}
.deadlink::after {
  content: "\2020"; font-size: .78em; vertical-align: .34em;
  color: var(--ink-4); margin-left: .12em;
}

/* -------------------------------------------- 1h. .ext — external link mark
   A hairline arrow, sized to the type. Not an emoji: the book has no emoji. */
a.ext::after {
  content: "\2197"; font-size: .72em; line-height: 1;
  vertical-align: .18em; margin-left: .18em;
  color: var(--ink-4); font-family: var(--f-ui);
}
a.ext:hover::after { color: var(--indigo); }

/* ------------------------------------- 1i. .tbl--compare — pro / con columns
   Two columns, one claim each. Teal is what holds up, crimson is what breaks.
   The tint is the -f wash only; the text stays in ink so it stays readable. */
table.tbl--compare th:first-child {
  background: var(--teal-f); color: var(--teal-d); border-bottom-color: var(--teal-l);
}
table.tbl--compare th:nth-child(2) {
  background: var(--crimson-f); color: var(--crimson-d); border-bottom-color: var(--crimson-l);
}
table.tbl--compare tbody td:first-child,
table.tbl--compare tbody tr:hover td:first-child { background: var(--teal-f); }
table.tbl--compare tbody td:nth-child(2),
table.tbl--compare tbody tr:hover td:nth-child(2) { background: var(--crimson-f); }
table.tbl--compare tbody td:first-child  { box-shadow: inset 3px 0 0 -1px var(--teal-l); }
table.tbl--compare tbody td:nth-child(2) { box-shadow: inset 3px 0 0 -1px var(--crimson-l); }

/* ---------------------------------------- 1j. .term-copy — copy the code out
   Lives inside the dark component, so it wears the dark component's palette.
   Appears on hover or keyboard focus; the title bar reserves room for it so it
   can never sit on top of .term-meta. */
.term { position: relative; }
.term:has(.term-copy) .term-bar { padding-right: 5.6rem; }
button.term-copy {
  position: absolute; top: 9px; right: var(--sp-4); z-index: 2;
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); line-height: 1;
  padding: 6px 11px; border-radius: 6px; cursor: pointer;
  background: var(--t-panel); color: var(--t-dim);
  border: 1px solid var(--t-line);
  opacity: 0; transition: opacity .16s var(--ease), color .16s var(--ease),
                          border-color .16s var(--ease);
}
.term:hover button.term-copy,
button.term-copy:focus-visible { opacity: 1; }
button.term-copy:hover { color: var(--t-fg); border-color: var(--t-dim); }
button.term-copy.is-copied { opacity: 1; color: var(--t-green); border-color: var(--t-green); }
button.term-copy.is-failed { opacity: 1; color: var(--t-red); border-color: var(--t-red); }
@media (hover: none) { button.term-copy { opacity: 1; } }

/* --------------------------------------- 1k. .mermaid-fig — a drawn diagram
   Framed exactly like figure.fig .fig-frame, because that is what it is.

   The diagram itself belongs to design/mermaid-init.js, which owns the theme
   and injects its own <style> at run time. This rule only builds the frame and
   styles the un-rendered source — `pre-wrap`, matching mermaid-init, so a
   diagram that never draws is still readable rather than a clipped mess. */
figure.mermaid-fig {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--sp-4);
  box-shadow: var(--sh-2);
}
figure.mermaid-fig > pre.mermaid {
  margin: 0; padding: 0; background: none; border: 0;
  text-align: center; overflow-x: auto;
  font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  line-height: 1.6; color: var(--ink-3); white-space: pre-wrap;
}
figure.mermaid-fig svg { display: block; margin-inline: auto; max-width: 100%; height: auto; }
figure.mermaid-fig > figcaption { text-align: left; }

/* ============================================================================
   2 · SECTION HUB PAGE
   One card per page in the section. The book's .cards, one notch richer: a
   number chip, a real dek, the tags, and how long it takes.
   ========================================================================= */
.hub-grid {
  display: grid; gap: var(--sp-4); margin: var(--sp-6) 0;
  grid-template-columns: repeat(auto-fill, minmax(17.5rem, 1fr));
  max-width: var(--w-full);
}
a.hub-card {
  display: flex; flex-direction: column; gap: var(--sp-2);
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--h); border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5) var(--sp-4) var(--sp-4);
  box-shadow: var(--sh-1); background-image: none; color: var(--ink);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease),
              transform .16s var(--ease);
}
a.hub-card:hover {
  border-color: var(--h-l); border-left-color: var(--h);
  box-shadow: var(--sh-2); transform: translateY(-2px);
}
.hub-top { display: flex; align-items: center; gap: var(--sp-3); }
.hub-n {
  font-family: var(--f-mono); font-size: var(--fs-xs); font-weight: 600;
  color: var(--h-d); background: var(--h-f); border: 1px solid var(--h-l);
  padding: 2px 8px; border-radius: var(--r-sm); flex: none;
  font-variant-numeric: tabular-nums;
}
.hub-mins {
  margin-left: auto; font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  color: var(--ink-4); white-space: nowrap;
}
.hub-t {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: 1.04rem; line-height: 1.28; letter-spacing: -.014em;
  color: var(--ink); margin: 0;
}
a.hub-card:hover .hub-t { color: var(--h-d); }
.hub-d {
  font-size: var(--fs-sm); line-height: 1.52; color: var(--ink-2); margin: 0;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.hub-card .pillrow { margin: auto 0 0; padding-top: var(--sp-2); gap: 6px; }
.hub-card .pill { font-size: .64rem; padding: 3px 8px; }

/* the hub's own header strip: what this section is, and how big it is */
.hub-meta {
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); color: var(--ink-3);
  margin: 0 0 var(--sp-4); line-height: 1.7;
}
.hub-meta b { color: var(--h-d); font-weight: 600; }
/* the renderer separates the facts with an empty <span>; make it the middot */
.hub-meta > span:empty { display: inline-block; width: 1.6rem; text-align: center; }
.hub-meta > span:empty::before { content: "\00b7"; color: var(--line-3); }

/* ============================================================================
   3 · HOME PAGE
   The front door. Generous, spacious, and the one place all seven hues are
   allowed on screen at once — because all eighteen sections are on screen.
   ========================================================================= */
.home-hero {
  position: relative; padding: var(--sp-8) 0 var(--sp-7);
  border-bottom: 1px solid var(--line); margin-bottom: var(--sp-7);
}
.home-hero::after {
  content: ""; position: absolute; left: 0; bottom: -1px;
  width: 180px; height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, var(--clay), var(--amber) 34%,
              var(--teal) 66%, var(--indigo));
}
.home-kicker {
  font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 var(--sp-4);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3);
}
.home-kicker .sep { width: 18px; height: 1px; background: var(--line-2); }
/* book.css scopes .ch-num to .ch-eyebrow; the home kicker uses one too */
.home-kicker .ch-num {
  font-family: var(--f-mono); font-size: var(--fs-xs); letter-spacing: .04em;
  color: var(--panel); background: var(--clay);
  padding: 3px 9px; border-radius: var(--r-sm); font-weight: 600;
  text-transform: none;
}
h1.home-title {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: clamp(2.3rem, 5vw, 3.7rem); line-height: 1.04;
  letter-spacing: -.038em; margin: 0 0 var(--sp-4); color: var(--ink);
  text-wrap: balance; max-width: 20ch;
}
p.home-dek {
  font-size: clamp(1.1rem, 1.5vw, 1.28rem); line-height: 1.48;
  color: var(--ink-2); margin: 0 0 var(--sp-5); max-width: 42rem;
}
.home-hero .stats { margin: var(--sp-6) 0 0; max-width: var(--w-full); }

/* -- the eighteen sections ------------------------------------------------ */
.home-grid {
  display: grid; gap: var(--sp-4); margin: var(--sp-5) 0 var(--sp-8);
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  max-width: var(--w-full);
}
a.home-card {
  display: flex; flex-direction: column; gap: var(--sp-2);
  position: relative; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line);
  border-top: 3px solid var(--h); border-radius: var(--r-lg);
  padding: var(--sp-5); background-image: none; color: var(--ink);
  box-shadow: var(--sh-1); min-height: 10.5rem;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease),
              transform .18s var(--ease), background-color .18s var(--ease);
}
a.home-card:hover {
  transform: translateY(-3px); box-shadow: var(--sh-2);
  border-color: var(--h-l); border-top-color: var(--h);
  background-color: var(--h-f);
}
.home-card .home-n {
  font-family: var(--f-mono); font-size: var(--fs-xs); font-weight: 600;
  color: var(--h-d); background: var(--h-f); border: 1px solid var(--h-l);
  padding: 2px 8px; border-radius: var(--r-sm);
  align-self: flex-start; font-variant-numeric: tabular-nums;
}
a.home-card:hover .home-n { background: var(--panel); }
.home-h {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: 1.12rem; line-height: 1.24; letter-spacing: -.018em;
  color: var(--ink); margin: var(--sp-1) 0 0;
}
.home-b {
  font-size: var(--fs-sm); line-height: 1.52; color: var(--ink-2); margin: 0;
  /* a dek is one sentence in the data and four in practice; cap the card */
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}
.home-count {
  margin-top: auto; padding-top: var(--sp-3);
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); color: var(--ink-4);
  display: flex; align-items: center; gap: var(--sp-2);
}
.home-count::before {
  content: ""; width: 14px; height: 1px; background: var(--h); flex: none;
}

/* -- curated learning paths ----------------------------------------------- */
.home-paths {
  display: grid; gap: var(--sp-6); margin: var(--sp-5) 0 var(--sp-8);
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  max-width: var(--w-full);
}
.path {
  background: var(--panel); border: 1px solid var(--line);
  /* the path's own hue names it; the numbered rail below stays plum, because
     a sequence of steps is a process wherever it appears */
  border-top: 3px solid var(--h);
  border-radius: var(--r-lg); padding: var(--sp-5) var(--sp-5) var(--sp-4);
  box-shadow: var(--sh-1);
}
.path-h {
  display: flex; align-items: baseline; gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
}
.path-h h3 {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: 1.08rem; line-height: 1.26; letter-spacing: -.016em;
  color: var(--ink); margin: 0; flex: 1;
}
.path-time {
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); color: var(--h-d);
  white-space: nowrap;
}
.path-d {
  font-size: var(--fs-sm); line-height: 1.52; color: var(--ink-3);
  margin: 0 0 var(--sp-4); max-width: none;
}
ol.path-steps {
  list-style: none; margin: 0; padding: 0; max-width: none;
  counter-reset: pstep;
}
ol.path-steps > li {
  display: grid; grid-template-columns: 1.7rem 1fr; gap: var(--sp-3);
  align-items: baseline; margin: 0;
  padding: var(--sp-3) 0; border-top: 1px solid var(--line);
}
ol.path-steps > li::before {
  counter-increment: pstep; content: counter(pstep);
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); font-weight: 700;
  color: var(--plum-d); background: var(--plum-f); border: 1px solid var(--plum-l);
  border-radius: var(--r-sm); text-align: center; line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
ol.path-steps > li > a {
  /* start-aligned, so the link's underline stops at the end of the words
     instead of ruling the whole grid cell */
  justify-self: start;
  font-size: var(--fs-sm); line-height: 1.45; color: var(--ink);
  background-image: linear-gradient(var(--line-2), var(--line-2));
}
ol.path-steps > li > a:hover { color: var(--indigo); }
ol.path-steps .path-why {
  grid-column: 2; font-size: var(--fs-xs); line-height: 1.5;
  color: var(--ink-3); margin: 3px 0 0;
  /* a path is a rail you scan, not a page you read; two lines of why is the
     most it can carry before the four paths stop fitting on one screen */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ============================================================================
   4 · SHELL FURNITURE  (built by shell.js)
   ========================================================================= */

/* ------------------------------------------------------------ 4a. .crumb */
nav.crumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  color: var(--ink-4); margin: 0 0 var(--sp-4);
}
nav.crumb a {
  color: var(--ink-3); background-image: none;
  transition: color .14s var(--ease);
}
nav.crumb a:hover { color: var(--h-d); }
nav.crumb .sep { color: var(--line-3); }
nav.crumb .here { color: var(--ink-2); }

/* Below 900px both rails become fixed drawer toggles pinned at the top
   corners, and the breadcrumb — the first thing in the column — runs
   underneath them. Give it their height plus the gutter. */
@media (max-width: 900px) {
  nav.crumb { padding-left: 52px; min-height: 40px; align-items: center; }
}
@media (max-width: 620px) {
  nav.crumb { padding-left: 48px; }
}

/* --------------------------------------------- 4b. rail search field
   A button dressed as a field. The rail is dark, so it wears the rail's own
   tokens, never --h. */
.rail-find {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%;
  margin-top: var(--sp-3); padding: 7px 9px; cursor: text;
  border-radius: var(--r-md); border: 1px solid var(--r-line);
  background: rgba(255,255,255,.05); color: var(--r-faint);
  font-family: var(--f-ui); font-size: var(--fs-xs); text-align: left;
  transition: border-color .16s var(--ease), color .16s var(--ease);
}
.rail-find:hover { border-color: rgba(255,255,255,.2); color: var(--r-dim); }
.rail-find .ic { font-size: .92rem; line-height: 1; flex: none; }
.rail-find .lbl { flex: 1; }
.rail-find .k {
  font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  border: 1px solid var(--r-line); border-radius: 4px; padding: 0 5px;
  color: var(--r-faint); flex: none;
}

/* --------------------------------------------- 4c. minimap prev / next
   Guide order, not page order: [ and ] leave the page entirely. */
.mm-pager {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  border-top: 1px solid var(--line); background: var(--line);
}
a.mm-pg {
  display: block; padding: var(--sp-3) var(--sp-3);
  background: var(--paper-2); background-image: none;
  text-decoration: none; min-width: 0;
  transition: background .14s var(--ease);
}
a.mm-pg:hover { background: var(--panel); }
a.mm-pg .k {
  display: block; font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 2px;
}
a.mm-pg .t {
  display: block; font-size: var(--fs-xs); line-height: 1.3; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.mm-pg:hover .t { color: var(--ink); }
a.mm-pg--next { text-align: right; }
.mm-pager--one { grid-template-columns: 1fr; }
.mm-pager--one a.mm-pg--next { text-align: left; }

/* ------------------------------------------------------ 4d. page pager
   The end-of-page prev / next pair. Two doors, plainly labelled. */
.pager {
  display: grid; gap: var(--sp-3); margin: var(--sp-6) 0 0;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  max-width: var(--w-wide);
}
a.pager-a {
  display: block; padding: var(--sp-4) var(--sp-5);
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--r-md); background-image: none; color: var(--ink-2);
  transition: border-color .16s var(--ease), transform .16s var(--ease),
              box-shadow .16s var(--ease);
}
a.pager-a:hover {
  border-color: var(--clay); transform: translateY(-1px); box-shadow: var(--sh-2);
}
a.pager-a .k {
  display: block; font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--ink-4); margin-bottom: var(--sp-2);
}
a.pager-a .t {
  display: block; font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: 1rem; line-height: 1.3; letter-spacing: -.014em; color: var(--ink);
}
a.pager-a:hover .t { color: var(--clay-d); }
a.pager-a .s {
  display: block; font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  color: var(--ink-4); margin-top: var(--sp-2);
}
a.pager-a--next { text-align: right; }
.pager > span { display: none; }
@media (min-width: 700px) { .pager > span { display: block; } }

/* ---------------------------------------------------- 4f. SITE ATTRIBUTION
   Sits below the reading column on every page, inside the same gutters the
   rails leave. Quiet, but never hidden: this is someone else's writing and
   the MIT notice has to travel with it. */
.site-attrib {
  margin: 0 var(--w-rail) 0 var(--w-minimap);
  padding: var(--sp-6) var(--pad-x) var(--sp-7);
  border-top: 1px solid var(--line);
  background: var(--paper-2);
  font-family: var(--f-ui); font-size: var(--fs-xs); line-height: 1.6;
  color: var(--ink-3);
}
.site-attrib p { margin: 0 auto; max-width: var(--w-full); }
.site-attrib p + p { margin-top: var(--sp-2); }
.site-attrib a { color: var(--ink-2); }
.site-attrib a:hover { color: var(--clay-d); }
.site-attrib-b { color: var(--ink-4); }
@media (max-width: 1140px) { .site-attrib { margin-left: 0; } }
@media (max-width: 900px)  { .site-attrib { margin-right: 0; } }

/* ============================================================ 4e. OVERLAYS
   Search and the key sheet share one form: a scrim over the paper, and a
   panel raised off it with --sh-3. Nothing else in the book floats. */
.ov { position: fixed; inset: 0; z-index: 70; display: none; }
.ov.is-open { display: block; }
.ov-scrim {
  position: absolute; inset: 0; background: rgba(34,31,26,.38);
  animation: ov-fade .16s var(--ease);
}
@keyframes ov-fade { from { opacity: 0; } to { opacity: 1; } }
.ov-panel {
  position: absolute; left: 50%; transform: translateX(-50%);
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
  overflow: hidden; display: flex; flex-direction: column;
  animation: ov-rise .18s var(--ease);
}
@keyframes ov-rise { from { opacity: 0; transform: translate(-50%, 8px); } }

/* -- search ---------------------------------------------------------------- */
#sx .ov-panel {
  top: 9vh; width: min(44rem, calc(100vw - 2 * var(--sp-4)));
  max-height: 78vh;
}
.sx-field {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
  background: var(--paper-2); flex: none;
}
.sx-ic { font-size: 1.05rem; line-height: 1; color: var(--ink-4); flex: none; }
input.sx-input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  font-family: var(--f-body); font-size: 1.06rem; color: var(--ink);
  letter-spacing: -.01em; padding: 0;
}
input.sx-input::placeholder { color: var(--ink-4); }
.sx-esc {
  font-family: var(--f-mono); font-size: var(--fs-mono-sm); color: var(--ink-4);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 1px 6px; flex: none;
}
.sx-results { overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-2) 0; }
a.sx-row {
  display: grid; grid-template-columns: 10px 1fr auto; gap: var(--sp-3);
  align-items: center; padding: 8px var(--sp-5);
  background-image: none; color: var(--ink-2); text-decoration: none;
  border-left: 2px solid transparent;
}
a.sx-row .sw {
  width: 8px; height: 8px; border-radius: 2px; background: var(--h);
  box-shadow: 0 0 0 3px var(--h-f);
}
a.sx-row .mid { min-width: 0; }
a.sx-row .t {
  display: block; font-size: var(--fs-sm); font-weight: 600; color: var(--ink);
  line-height: 1.34; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.sx-row .hd {
  display: block; font-family: var(--f-mono); font-size: var(--fs-mono-sm);
  color: var(--h-d); line-height: 1.4; margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.sx-row .hd::before { content: "\2937  "; color: var(--ink-4); }
a.sx-row .sx-sec {
  font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--ink-4); white-space: nowrap; flex: none; text-align: right;
}
a.sx-row.is-sel {
  background: var(--h-f); border-left-color: var(--h);
}
a.sx-row.is-sel .sx-sec { color: var(--h-d); }
.sx-empty {
  padding: var(--sp-7) var(--sp-5); text-align: center;
  font-size: var(--fs-sm); color: var(--ink-3);
}
.sx-empty b { color: var(--ink); font-weight: 650; }
.sx-foot {
  display: flex; flex-wrap: wrap; gap: var(--sp-4); flex: none;
  padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line);
  background: var(--paper-2);
  font-family: var(--f-ui); font-size: var(--fs-xs); color: var(--ink-4);
}
.sx-foot span { display: inline-flex; align-items: center; gap: 6px; }
.sx-foot kbd { font-size: .72em; }

/* -- key sheet ------------------------------------------------------------- */
#kx { z-index: 72; }
#kx .ov-panel {
  top: 14vh; width: min(30rem, calc(100vw - 2 * var(--sp-4)));
  max-height: 72vh;
}
.kx-head {
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}
.kx-head p {
  margin: 0; font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase; color: var(--ink-4);
}
.kx-head h2 {
  margin: 4px 0 0; font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: 1.1rem; letter-spacing: -.02em; color: var(--ink); line-height: 1.2;
}
.kx-body { overflow-y: auto; padding: var(--sp-3) var(--sp-5) var(--sp-5); }
.kx-row {
  display: grid; grid-template-columns: 6.5rem 1fr; gap: var(--sp-4);
  align-items: baseline; padding: var(--sp-3) 0; border-top: 1px solid var(--line);
}
.kx-row:first-child { border-top: 0; }
.kx-keys { display: flex; flex-wrap: wrap; gap: 5px; }
.kx-row span { font-size: var(--fs-sm); line-height: 1.45; color: var(--ink-2); }
.kx-grp {
  font-family: var(--f-ui); font-size: var(--fs-label);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--ink-4); margin: var(--sp-5) 0 0; padding-top: var(--sp-3);
  border-top: 1px solid var(--line-2);
}
.kx-grp:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* ============================================================================
   5 · NARROW SCREENS
   book.css already moves both rails off-canvas at 1140 / 900. Everything added
   here has to survive 620 without a horizontal scrollbar.
   ========================================================================= */
@media (max-width: 900px) {
  .home-hero { padding-top: var(--sp-6); }
  .home-paths { gap: var(--sp-4); }
}
@media (max-width: 620px) {
  .hub-grid, .home-grid { grid-template-columns: 1fr; gap: var(--sp-3); }
  .home-paths { grid-template-columns: 1fr; }
  a.home-card { min-height: 0; padding: var(--sp-4); }
  .home-hero { padding: var(--sp-6) 0 var(--sp-6); margin-bottom: var(--sp-6); }
  h1.home-title { font-size: 2.05rem; letter-spacing: -.03em; }
  nav.toc-card { padding: var(--sp-4); }
  .qa { padding: var(--sp-4); }
  .qa-q, .qa-a { padding-left: 1.85rem; }
  .pager { grid-template-columns: 1fr; }
  a.pager-a--next { text-align: left; }
  .pager > span { display: none; }
  #sx .ov-panel { top: 0; width: 100vw; max-height: 100vh; height: 100%;
                  border-radius: 0; border-width: 0 0 1px; }
  #kx .ov-panel { top: 6vh; width: calc(100vw - 1.75rem); }
  .kx-row { grid-template-columns: 1fr; gap: 4px; }
  .sx-field { padding: var(--sp-3) var(--sp-4); }
  a.sx-row { grid-template-columns: 10px 1fr; padding: 8px var(--sp-4); }
  a.sx-row .sx-sec { display: none; }
  .sx-foot { display: none; }
  ul.reflist .tag { margin-left: 0; }
  .math { padding: var(--sp-3) var(--sp-2); }
  button.term-copy { opacity: 1; top: 7px; right: var(--sp-3); padding: 5px 9px; }
}

/* ============================================================================
   5 · CARD REDESIGN — no coloured bars
   book.css draws a 3px hue bar on .stat (top) and this file used to draw one on
   .home-card (top) and .hub-card (left). Eighteen cards each wearing a coloured
   stripe reads as decoration applied to a grid, not as design: the stripe is the
   loudest thing on the card and it says nothing the card does not already say.

   The hue is kept — it still identifies the section — but it moves into the
   type: the ordinal, the rule under the title, and the hover. The card itself
   is quiet paper with one hairline. Structure now comes from typography and
   space, which is what the rest of the book already does.
   ========================================================================= */

/* -- stat strip: not boxes at all ---------------------------------------- */
.stats {
  gap: 0; border-top: 1px solid var(--line-2);
  border-bottom: 1px solid var(--line-2);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.stats .stat,
.stats .stat--clay, .stats .stat--indigo, .stats .stat--teal,
.stats .stat--amber, .stats .stat--crimson, .stats .stat--plum,
.stats .stat--olive {
  background: none; border: 0; border-radius: 0;
  border-left: 1px solid var(--line);
  padding: var(--sp-5) var(--sp-5) var(--sp-5) var(--sp-4);
}
.stats .stat:first-child { border-left: 0; padding-left: 0; }
.stats .stat-v { font-size: clamp(1.9rem, 3.2vw, 2.5rem); letter-spacing: -.035em; }
.stats .stat-l { color: var(--ink-4); }
@media (max-width: 620px) {
  .stats .stat { border-left: 0; border-top: 1px solid var(--line); padding-left: 0; }
  .stats .stat:first-child { border-top: 0; }
}

/* -- home + hub cards: hairline paper, hue in the type ------------------- */
a.home-card, a.hub-card {
  border: 1px solid var(--line);
  border-top-width: 1px; border-left-width: 1px;
  border-top-color: var(--line); border-left-color: var(--line);
  box-shadow: none;
}
a.home-card:hover, a.hub-card:hover {
  border-color: var(--h); box-shadow: var(--sh-2);
  background-color: var(--panel);
}

/* the ordinal stops being a chip and becomes a numeral */
.home-card .home-n, .hub-card .hub-n {
  background: none; border: 0; padding: 0;
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.02em;
  color: var(--h); opacity: .55;
  transition: opacity .16s var(--ease);
}
a.home-card:hover .home-n, a.hub-card:hover .hub-n { opacity: 1; }

/* a short hue rule under the title carries the identity the bar used to */
.home-h, .hub-t { position: relative; padding-bottom: var(--sp-3); }
.home-h::after, .hub-t::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 26px; height: 2px; border-radius: 1px;
  background: var(--h); opacity: .5;
  transition: width .22s var(--ease), opacity .22s var(--ease);
}
a.home-card:hover .home-h::after, a.hub-card:hover .hub-t::after {
  width: 46px; opacity: 1;
}
.home-count::before { background: var(--line-2); }

/* ============================================================================
   6 · MOTION + PRINT
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  a.hub-card, a.home-card, a.pager-a, a.mm-pg,
  button.term-copy, nav.toc-card a, nav.crumb a, .rail-find {
    transition: none !important;
  }
  a.hub-card:hover, a.home-card:hover, a.pager-a:hover { transform: none; }
  .ov-scrim, .ov-panel { animation: none; }
}

@media print {
  .ov, .rail-find, .mm-pager, button.term-copy, .pager { display: none !important; }
  a.hub-card, a.home-card, .qa, nav.toc-card, .path, figure.mermaid-fig {
    box-shadow: none; break-inside: avoid;
  }
  a.ext::after { content: " (" attr(href) ")"; font-size: .72em; color: var(--ink-3); }
  .deadlink::after { content: " \2020 not in repo"; }
}

/* ============================================================================
   6 · AUTHORED DIAGRAMS
   An SVG that replaces a block of ASCII art. It reuses book.css's figure
   furniture (.fig / .fig-frame / .fig-num / .fig-thesis / .fig-cap) and adds
   one thing: the original text, kept in a disclosure beneath the picture, so
   nothing the source said is lost and the boxes stay copyable.
   ========================================================================= */
figure.fig.diagram { margin: var(--sp-6) 0; }
figure.fig.diagram .fig-frame {
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  background: var(--panel);
  overflow-x: auto;
}
figure.fig.diagram svg { display: block; width: 100%; height: auto; }

details.fig-text { margin-top: var(--sp-3); }
details.fig-text > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center;
  gap: var(--sp-2); font-family: var(--f-ui); font-size: var(--fs-xs);
  color: var(--ink-3); padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--paper-2);
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
details.fig-text > summary::-webkit-details-marker { display: none; }
details.fig-text > summary::before {
  content: ""; width: 7px; height: 7px; flex: none;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); margin-left: 2px;
  transition: transform .18s var(--ease);
}
details.fig-text[open] > summary::before { transform: rotate(45deg); }
details.fig-text > summary:hover { color: var(--ink); border-color: var(--line-3); }
details.fig-text .term { margin-top: var(--sp-3); }

/* diagram type scale — one place, so 70 figures cannot drift apart */
svg text.d-t   { font-family: var(--f-ui);   font-size: 12.5px; font-weight: 650; fill: var(--ink); }
svg text.d-s   { font-family: var(--f-ui);   font-size: 10.5px; font-weight: 500; fill: var(--ink-3); }
svg text.d-m   { font-family: var(--f-mono); font-size: 10px;   fill: var(--ink-3); }
svg text.d-k   { font-family: var(--f-ui);   font-size: 9px; font-weight: 700; letter-spacing: .12em;
                 text-transform: uppercase; fill: var(--ink-4); }
svg text.d-n   { font-family: var(--f-display); font-size: 17px; font-weight: 700; fill: var(--ink); }
svg .d-box     { fill: var(--panel); stroke: var(--line-2); stroke-width: 1.2; }
svg .d-zone    { fill: var(--paper-3); stroke: var(--line); stroke-width: 1; }
svg .d-flow    { fill: none; stroke: var(--ink-4); stroke-width: 1.5;
                 stroke-linecap: round; stroke-linejoin: round; }
svg .d-flow-2  { fill: none; stroke: var(--ink-3); stroke-width: 2;
                 stroke-linecap: round; stroke-linejoin: round; }

/* -- editorial recap ------------------------------------------------------
   The one block on a page that is not the author's writing, so it is marked
   as such in its eyebrow and given a quieter ground than the prose above it. */
.sec--recap { background: var(--paper-2); border-radius: var(--r-lg);
  padding: var(--sp-6) var(--sp-5); border-top: 1px solid var(--line-2); }
.sec--recap .sec-n { background: none; border: 0; color: var(--ink-4); padding: 2px 0; }
.sec--recap .recap { margin-bottom: 0; }
.sec--recap .recap-card { box-shadow: none; border-color: var(--line-2); }
.sec--recap .recap-card::before { background: var(--h); opacity: .55; }
.sec--recap .recap-k { color: var(--h); font-weight: 700; }

/* -- fenced prose: a spoken answer, not a file ---------------------------- */
figure.say {
  margin: var(--sp-5) 0; max-width: var(--w-wide);
  background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--h); border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5);
}
.say-k {
  font-family: var(--f-ui); font-size: var(--fs-label); font-weight: 700;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--h-d); margin: 0 0 var(--sp-3);
  display: flex; align-items: center; gap: 6px;
}
.say-k::before { content: "\201C"; font-family: var(--f-display);
  font-size: 1.5em; line-height: 0; position: relative; top: .22em; }
figure.say blockquote { margin: 0; padding: 0; border: 0; }
figure.say p { margin: 0 0 var(--sp-3); font-size: var(--fs-body);
  line-height: 1.62; color: var(--ink); max-width: var(--measure); }
figure.say p:last-child { margin-bottom: 0; }
/* the source's own line breaks are kept, so the answer reads in its beats */
.say-body { white-space: pre-wrap; }
