/* Adjacency Playbook — the approved v3 look (docs/design/home-v3.html).
   Dark petrol signage, one orange, Montserrat throughout, self-hosted.

   TWO HUES, and nothing else: petrol is the structural colour (top bar, hero,
   the "cases" band, cool type), the RX orange is the accent (the arrow's doing
   pair, the executive-summary pill, tile rules, warm type). Everything else is
   a neutral in the same grey-green family as the ground.

   Every fill that carries type is measured >= 4.5:1 against its ink; the table
   is in site/README.md and the values live only here. Where the mock's own
   colour failed that bar (its bright orange under white text, its pale ink-3)
   this file uses the deeper member of the same family instead — contrast wins
   over a swatch. */

/* ------------------------------------------------------------------- fonts
   Montserrat, self-hosted, because the site is read from mainland China and
   dist/ is handed over as an offline copy: a runtime <link> to Google would
   hang in the first case and be missing in the second. One variable file per
   subset carries 400-900, so every weight the design uses (400 body, 500/600
   labels, 700/800 headings, 800/900 hero and verbs) comes out of ~36 KB.
   latin-ext is declared with its own unicode-range and is fetched only if the
   page actually contains a character that needs it. Licence and provenance:
   static/fonts/LICENSE.txt. */
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("static/fonts/montserrat-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: italic;
  font-weight: 400 900;
  font-display: swap;
  src: url("static/fonts/montserrat-latin-italic-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("static/fonts/montserrat-latin-ext-var.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: italic;
  font-weight: 400 900;
  font-display: swap;
  src: url("static/fonts/montserrat-latin-ext-italic-var.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* ---- signage: the same in both themes ------------------------------
     These are the colours a reader recognises the book by — the bar, the
     hero, the arrow's seven stops, the pill. Their fill/ink pairs are
     measured, so pinning them across themes keeps ONE table true of both. */
  --petrol-900: #0F3A40;
  --petrol-800: #164F56;
  --petrol:     #1F6F78;
  --petrol-100: #CDE4E6;
  --petrol-50:  #E6F1F2;
  /* The type-safe orange. The mock's #D96A12 reaches only 3.49:1 under white,
     so it never carries text here; it survives as --orange-bright, a rule. */
  --orange:      #A85209;
  --orange-bright: #D96A12;
  --orange-900: #7A3C07;   /* ink on --orange-100 (6.28:1); #A85209 is 4.01 */
  --orange-100: #F7D9B6;
  --orange-50:  #FBEEDD;
  --sign-grey:      #E4E7E7;
  --sign-grey-ink:  #4F5B5A;
  --sign-grey-line: #BFC6C6;
  --slate: #3E4A49;        /* a destination, not a stage; also "example" */
  --on-dark:   #FFFFFF;
  --on-dark-2: #B9CACB;    /* secondary type on petrol-900 (7.61:1) */

  /* ---- surfaces and type: the dark blocks redefine these -------------- */
  --ground: #EEF1F1;
  --panel:  #FFFFFF;
  --ink:    #14201F;
  --ink-2:  #4F5B5A;
  --ink-3:  #616D6C;       /* 4.73:1 on --ground; the mock's #8A9695 is 2.69 */
  --line:   #D9DFDF;
  --line-2: #E9EDED;
  --tint:      #E6F1F2;    /* the "cases by show" band */
  --tint-line: #CDE4E6;
  --tint-fig:  #1F6F78;    /* the 52px counts on --tint */
  --accent-warm: #A85209;  /* orange AS TYPE on --panel */
  --accent-cool: #1F6F78;  /* petrol AS TYPE on --panel */
  --soft:       #FBEEDD;
  --muted-fill: #E4E7E7;
  --muted-ink:  #4F5B5A;
  --shadow-rgb: 20, 32, 31;

  /* ---- names the rest of this file already used ----------------------- */
  --brand-deep:     var(--orange);
  --brand-light:    var(--orange-100);
  --brand-ink-dark: var(--orange-900);
  --alt-deep:       var(--petrol);
  --alt-light:      var(--petrol-100);
  --alt-ink-dark:   var(--petrol-900);
  --tone-grey:      var(--sign-grey);
  --tone-grey-ink:  var(--sign-grey-ink);
  --tone-grey-line: var(--sign-grey-line);
  --bg:          var(--panel);
  --bg-2:        var(--ground);
  --orange-soft: var(--soft);

  --radius: 6px;
  --topbar-h: 96px;
  --wrap: 1240px;
  --gutter: 32px;
  --font: "Montserrat", "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB",
          "Microsoft YaHei", sans-serif;
}

/* The dark theme touches surfaces and type only — never the signage above —
   so the measured contrast table holds unchanged in both. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #111817; --panel: #1B2423;
    --ink: #ECF1F0; --ink-2: #B3BEBD; --ink-3: #8B9897;
    --line: #2C3736; --line-2: #232D2C;
    --tint: #16383D; --tint-line: #245056; --tint-fig: #A5DAE0;
    --accent-warm: #F0A968; --accent-cool: #8ECBD1;
    --soft: #3E2610; --muted-fill: #2A3332; --muted-ink: #B3BEBD;
    --shadow-rgb: 0, 0, 0;
  }
}
:root[data-theme="dark"] {
  --ground: #111817; --panel: #1B2423;
  --ink: #ECF1F0; --ink-2: #B3BEBD; --ink-3: #8B9897;
  --line: #2C3736; --line-2: #232D2C;
  --tint: #16383D; --tint-line: #245056; --tint-fig: #A5DAE0;
  --accent-warm: #F0A968; --accent-cool: #8ECBD1;
  --soft: #3E2610; --muted-fill: #2A3332; --muted-ink: #B3BEBD;
  --shadow-rgb: 0, 0, 0;
}

/* ---- tones ----------------------------------------------------------------
   One class per `tone` in overrides.yaml. Each sets three custom properties and
   nothing else, so the same class colours a big chevron, a bar chevron, a
   stage-page eyebrow and a card's stripe without any of them knowing which tone
   they got:
     --tone-fill    the chevron's background
     --tone-ink     text ON that fill (and the current-stop outline)
     --tone-accent  the same tone as TEXT on the page — the deep hue of the
                    family, since a light fill is not readable as type
     --tone-num     the big receding chapter number behind the verb
   Measured fill/ink ratios: alt-deep 5.83, brand-light 6.28, brand-deep 5.42,
   alt-light 9.32, grey 5.67, slate 9.21.

   --tone-num is a SOLID colour, not an opacity, for the same reason nothing
   else here fades: a validator has to read the value a reader sees. No fade of
   --tone-ink over --tone-fill reaches 4.5:1 while still looking faded (0.75
   opacity is still only 3.36:1 on grey), so the number is set at 3.2-5.5:1 —
   the AA bar that actually applies to it, since at 40px/900 it is large text
   and 3:1 is the threshold. Everything body-sized in the chevron (the verb, the
   chapter title) stays at the 4.5:1 bar. `tone-slate` is not a journey stop:
   it is the bar's Library chevron. */
.tone-brand-deep  { --tone-fill: var(--orange);      --tone-ink: var(--on-dark);       --tone-accent: var(--accent-warm); --tone-num: #E7CFBB; }
.tone-brand-light { --tone-fill: var(--orange-100);  --tone-ink: var(--orange-900);    --tone-accent: var(--accent-warm); --tone-num: #9C6636; }
.tone-alt-deep    { --tone-fill: var(--petrol);      --tone-ink: var(--on-dark);       --tone-accent: var(--accent-cool); --tone-num: #BCD4D6; }
.tone-alt-light   { --tone-fill: var(--petrol-100);  --tone-ink: var(--petrol-900);    --tone-accent: var(--accent-cool); --tone-num: #48696E; }
.tone-grey        { --tone-fill: var(--sign-grey);   --tone-ink: var(--sign-grey-ink); --tone-accent: var(--ink-2);       --tone-num: #79817F; }
.tone-slate       { --tone-fill: var(--slate);       --tone-ink: var(--on-dark);       --tone-accent: var(--ink-2);       --tone-num: #C5C9C8; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font: 400 16px/1.6 var(--font); -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-cool); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4, h5, h6 { font-weight: 700; line-height: 1.25; letter-spacing: -.01em; }

/* One container, used by every full-bleed strip on the homepage, so the hero,
   the arrow and the bands all start and end on the same two vertical lines. */
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); min-width: 0; }

/* ---------------------------------------------------------------- top bar
   Dark petrol, carrying the runway in miniature. Two rows rather than the
   mock's one: this bar also holds the aside stops and a Library chevron, and
   the second row is what lets the strip keep its measured no-cut-off
   behaviour (labels drop below 1000px, the strip scrolls below 640px). */
.topbar {
  position: sticky; top: 0; z-index: 40;
  background: var(--petrol-900); color: var(--on-dark);
}
.topbar-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; max-width: var(--wrap); margin: 0 auto;
  padding: 11px var(--gutter) 7px;
}
.brand {
  color: var(--on-dark); font-weight: 800; font-size: 15px; letter-spacing: .01em;
  white-space: nowrap;
}
.brand:hover { text-decoration: none; color: var(--orange-100); }
.back-link { font-size: 13px; color: var(--on-dark-2); white-space: nowrap; }
.back-link:hover { color: var(--on-dark); }

/* the homepage runway in miniature — same chevrons, same per-stop tones */
.journeybar { padding: 0 calc(var(--gutter) - 8px) 10px; }
.jb-scroll { display: flex; align-items: center; gap: 14px; max-width: calc(var(--wrap) - 16px); margin: 0 auto; }
.jb-aside {
  flex: 0 0 auto; font-size: 12.5px; color: var(--on-dark-2); white-space: nowrap;
}
.jb-aside:hover { color: var(--on-dark); text-decoration: none; }
.jb-aside.current { font-weight: 700; color: var(--on-dark); }
.jb-aside-n { font-weight: 700; margin-right: 5px; font-variant-numeric: tabular-nums; }
.jb-aside.greyed { color: #7F9698; }
.jb-band {
  display: flex; flex: 1 1 auto; min-width: 0; height: 30px;
}
.jb-chev {
  position: relative;          /* the progress fill is absolute inside it */
  flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center;
  gap: 6px; padding: 0 8px 0 14px; margin-left: -6px;
  font-size: 11px; font-weight: 700; line-height: 1; letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tone-ink); background: var(--tone-fill);
  white-space: nowrap; overflow: hidden;
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%, 9px 50%);
}
.jb-chev:first-child {
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%);
  margin-left: 0; padding-left: 10px;
}
/* :not(.current) — the current chevron's own filter draws its outline, and a
   second `filter` declaration would replace it rather than add to it */
.jb-chev:hover { text-decoration: none; }
.jb-chev:not(.current):hover { filter: brightness(1.07); }
/* no `opacity` on any chevron text: the ratio a validator computes has to be
   the ratio a reader actually sees */
.jb-n { font-variant-numeric: tabular-nums; font-weight: 800; }
.jb-l { overflow: hidden; text-overflow: ellipsis; font-weight: 800; }
/* A chevron with no number has nothing to fall back to below 1000px, so it
   never shrinks: the numbered ones (already down to a digit there) absorb the
   squeeze instead. Without this, "Scale / Stop" ellipsised to "Scale / S…" at
   760px — a cut a touch reader cannot undo, since title= needs a hover. */
.jb-chev:not(.has-num) { flex: 0 0 auto; }
/* The current stop, thickly outlined as in the design mock. `outline` alone is
   clipped by clip-path, so the two pointed edges lose it; the drop-shadow stack
   traces the chevron's real silhouette instead, and position/z-index keep the
   next chevron's negative margin from painting over it.

   The outline is drawn in the stop's OWN --tone-ink, not in one fixed dark
   colour: no single colour reaches 4.5:1 against both a deep fill and a light
   one (white needs a fill lighter than L=0.183, near-black one darker than
   L=0.236 — the two ranges do not overlap), so a fixed dark outline would be
   unreadable on the deep petrol and deep orange chevrons. Following the tone
   makes the outline's ratio the same measured number as the label's. */
.jb-chev.current {
  position: relative; z-index: 1; outline: 2px solid var(--tone-ink); outline-offset: -2px;
  filter: drop-shadow(1.5px 0 0 var(--tone-ink)) drop-shadow(-1.5px 0 0 var(--tone-ink))
          drop-shadow(0 1.5px 0 var(--tone-ink)) drop-shadow(0 -1.5px 0 var(--tone-ink));
}
/* a stop with no chapter yet keeps the dashed edge that says "not written" */
.jb-chev.tone-grey { border: 1px dashed var(--tone-grey-line); }
@media (max-width: 1100px) {
  /* Number-only chevrons; the full label stays in title= and on the homepage.
     1100px, not the 1000px this used to be: Montserrat sets these labels wider
     than the old system stack did, and uppercasing them with .06em tracking
     widened them again, so "1 UNDERSTAND" was ellipsising to "1 UNDERST…" at
     1024px. It is also the width at which the big band turns vertical, so the
     bar and the runway now change at one number rather than two. */
  .jb-chev.has-num .jb-l { display: none; }
  .jb-chev.has-num { padding: 0 6px 0 12px; }
}
@media (max-width: 640px) {
  /* nothing is dropped: the whole strip scrolls sideways instead */
  .journeybar { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
  .jb-scroll { min-width: max-content; }
  .jb-band { flex: 0 0 auto; }
  .jb-chev { flex: 0 0 auto; }
  .jb-chev.has-num { min-width: 38px; }
}

/* ------------------------------------------------------------- journey page
   The homepage is the one page that is not inside the shared .page container:
   the hero and the "cases by show" strip are full-bleed bands, and each part
   re-enters the same 1240px .wrap so nothing drifts out of line. */
.page { padding: 0 24px 64px; max-width: 1368px; margin: 0 auto; }
body[data-page="journey"] .page { padding: 0 0 0; max-width: none; }
.journey-page { padding: 0; }

/* ---- hero
   Dark petrol, the book's own title line at web scale, the eyebrow above it
   and the executive-summary pill under it. Nothing else: no intro sentence
   (the site never writes prose) and no diagram. */
.hero { background: var(--petrol-800); color: var(--on-dark); }
.hero .wrap { padding-top: 68px; padding-bottom: 148px; }
.hero-eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--orange-100); margin: 0;
}
.hero-title {
  font-size: clamp(38px, 6.4vw, 84px); font-weight: 900; line-height: .95;
  letter-spacing: -.025em; margin: 16px 0 0; max-width: 9em;
  color: var(--on-dark); text-wrap: balance;
}
/* Two classes, so the spacing beats the .sec-title { margin: 0 } the hero <h1>
   also carries (it is a commentable section heading as well as the hero). */
.hero .hero-title { margin: 14px 0 0; }
.cover { margin: 0; }
.cover-toc { margin: 2px 0; }
.page-h1 { font-size: 28px; margin: 0 0 18px; }

/* a stop placed aside: the orange pill under the hero title */
.aside-stops { margin: 26px 0 0; display: flex; flex-wrap: wrap; gap: 10px; }
.aside-stop {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--orange); color: var(--on-dark);
  font-weight: 800; font-size: 15px; padding: 12px 18px; border-radius: 4px;
}
a.aside-stop:hover { text-decoration: none; filter: brightness(1.08); }
.aside-stop.greyed { background: #2C6068; color: #DCE7E8; }
/* solid colours, not opacity: everything in the pill is measured, and an alpha
   would make the number a different ratio from the one a validator reads */
.aside-num { font-weight: 700; font-variant-numeric: tabular-nums; }
.aside-label { font-weight: 800; }
.aside-title { font-weight: 600; font-size: 13px; }
.aside-go { font-weight: 700; }

/* ---- the runway
   One bold arrow band, floating out of the hero on its own shadow, coloured
   per stop tone. It lives inside the SAME .wrap as everything else and every
   chevron carries min-width: 0, so the band is bounded by the container and
   can never push the page wider than the viewport — the shrink is absorbed by
   the type, whose size is a measured ceiling (see .chev-l). */
.runway-wrap { position: relative; z-index: 2; margin-top: -92px; }
.runway {
  display: flex; min-width: 0; min-height: 168px;
  filter: drop-shadow(0 16px 28px rgba(var(--shadow-rgb), .30));
}
.runway .chev {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  justify-content: flex-end; gap: 5px; position: relative;
  /* the right padding can never go below the 20px arrow tip: at the top of the
     chevron the clip-path already ends at calc(100% - 20px), so text set any
     closer to the edge is cut, not crowded */
  padding: 46px 20px 18px 30px; margin-left: -13px;
  color: var(--tone-ink); background: var(--tone-fill);
  overflow-wrap: anywhere;
  clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 50%, calc(100% - 20px) 100%, 0 100%, 20px 50%);
}
.runway .chev:first-child {
  clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 50%, calc(100% - 20px) 100%, 0 100%);
  margin-left: 0; padding-left: 22px; border-radius: 6px 0 0 6px;
}
.runway a.chev:hover { text-decoration: none; filter: brightness(1.06); }
/* the big receding number, set above its own verb */
.chev-n {
  position: absolute; top: 12px; left: 30px;
  font-size: 40px; font-weight: 900; line-height: 1; letter-spacing: -.03em;
  color: var(--tone-num, currentColor); font-variant-numeric: tabular-nums;
}
.runway .chev:first-child .chev-n { left: 22px; }
/* The verb IS the band: it has to be readable across the room, well above the
   chapter title that explains it. No `opacity` on .chev-l / .chev-t — the ratio
   a validator computes must be the one a reader sees.

   The size is a measured ceiling, not a wish. Seven chevrons overlapping by
   13px inside the 1240px container leave (1240 + 14)/7 - 50 = 129px of text
   width each, and the widest verb the book has — "Understand" — measures 119px
   at 19px/900 in Montserrat (a single word cannot wrap politely, so it is the
   one that sets the ceiling). The clamp holds that headroom all the way down to
   1100px, where the share is 109px and the clamp has fallen to 16px (text
   100px); below 1100px the band turns vertical and the verb gets its full size
   back. Swept and measured at 1101 / 1160 / 1240 / 1280 / 1440: see
   site/README.md. */
.chev-l {
  font-size: clamp(16px, calc(2.35vw - 9.9px), 19px);
  font-weight: 900; line-height: 1.02; letter-spacing: -.015em;
}
/* Three lines are reserved whether the title needs them or not, and the box is
   rendered even for a stop that has no title ("Scale / Stop"), so all seven
   verbs sit on one line instead of stepping up and down with the length of the
   chapter title underneath them. */
.chev-t { font-size: 12px; line-height: 1.3; font-weight: 500; min-height: 3.9em; }
.runway .chev.tone-grey { border: 1px dashed var(--tone-grey-line); }

/* ---- the arrow as a progress bar -----------------------------------------
   A stop whose chapter(s) hold checklists carries their block ids in
   data-check-ids; app.js counts how many of them this reader has started (at
   least one item ticked) and draws the share as a thin fill along the bottom
   edge — of the big chevron on the homepage and of the same chevron in the top
   bar. Nothing is drawn at zero, and a stop with no checklists carries no
   attribute at all, so the band can never invent progress it does not have.
   Today only chapters 2 and 3 hold a checklist, so only those two chevrons can
   ever grow a bar.

   Both the track and the fill are `currentColor` — the chevron's own
   --tone-ink, already measured against its fill in every tone — so the bar
   needs no colour of its own and follows the theme and the tone for free. The
   track's alpha lives on a pseudo-element rather than on .prog itself, because
   an opacity on the parent would cap the fill's too.

   The bar is inset from both ends: a chevron is clipped to a pointed
   silhouette, so a rule running the full width would be cut off by the tip and
   by the notch on the left. */
.prog { position: absolute; height: 4px; border-radius: 999px; pointer-events: none; }
.prog::before {
  content: ""; position: absolute; inset: 0; border-radius: 999px;
  background: currentColor; opacity: .22;
}
.prog-fill {
  position: absolute; left: 0; top: 0; bottom: 0; min-width: 4px;
  border-radius: 999px; background: currentColor;
}
.runway .chev .prog { left: 30px; right: 30px; bottom: 10px; }
.runway .chev:first-child .prog { left: 22px; }
.jb-chev .prog { left: 12px; right: 14px; bottom: 3px; height: 3px; }

/* ---- the three bands under the arrow -------------------------------------
   Full width, stacked, in overrides.home_bands order. Each row is one block of
   the book (a tool, a checklist) or one case tag; nothing is hand-picked, so a
   tool added to the Word appears here without anyone editing this file. */
.bands { padding-bottom: 24px; }
.band { padding: 68px 0 0; }
.band-cases { background: var(--tint); margin-top: 68px; padding: 0; }
.band-cases .band-inner { padding: 52px 0 56px; }
.band-head {
  display: flex; align-items: baseline; gap: 18px; margin: 0 0 26px;
  font-weight: 700;
}
.band-idx {
  font-size: 13px; font-weight: 900; letter-spacing: .2em;
  color: var(--accent-warm); font-variant-numeric: tabular-nums;
}
.band-name { font-size: clamp(24px, 3vw, 34px); font-weight: 800; letter-spacing: -.02em; }
.band-count {
  margin-left: auto; font-size: 14px; font-weight: 600; color: var(--ink-3);
  text-align: right;
}

/* ---- band 00: "Start here" ------------------------------------------------
   Three blocks the book already has, re-rendered as wide cards: the definition
   figure, the growth-journey figure and the section takeaway. `auto-fit` with a
   1fr track collapses the tracks nothing landed in, so three cards share the
   row in three equal columns and two share it in two — the band never leaves a
   hole where a card in overrides.start_here could not be resolved.

   The card is the tile's material (white panel, rule on top) but the block
   inside keeps its own look: a figure stays a figure, and a takeaway keeps the
   highlighted box it wears in the reading column, because a reader should
   recognise it again when they meet it in chapter 2. */
.starts { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }
.start-card {
  display: flex; flex-direction: column; background: var(--panel);
  border: 1px solid var(--line); border-top: 4px solid var(--petrol);
  border-radius: var(--radius); padding: 16px 18px 12px;
}
.start-body { flex: 1 1 auto; min-width: 0; }
.start-body > .blk { margin: 0; }
/* fit the card, never upscale: a 300px-wide figure stays 300px wide */
.start-body .figure img { max-height: 360px; }
.start-foot {
  margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 12px;
}
.start-sec { font-weight: 700; font-variant-numeric: tabular-nums; }
/* "When is THIS the card to start from" — the short phrase above the section
   link. It is the line a reader scans to choose between three cards, so it is
   darker and heavier than the link under it, and it is a full row of its own:
   three cards side by side must break at the same place, and a phrase sharing a
   line with the section number would wrap differently in each. Absent when
   overrides.start_here_when has no entry for that block — no empty slot. */
.start-when {
  display: block; margin: 0 0 5px;
  font-size: 12.5px; font-weight: 700; line-height: 1.45; color: var(--ink-2);
}
/* Clears every apb:check:<source>:* key this browser holds, after a confirm().
   Small and right-aligned: it undoes work, so it must never be the first thing
   a thumb finds. */
.reset-all-row { margin: 18px 0 0; text-align: right; }
.btn-reset-all {
  font: inherit; font-size: 12px; font-weight: 700; padding: 5px 13px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--ink-2);
}
.btn-reset-all:hover { border-color: var(--accent-warm); color: var(--accent-warm); }

/* ---- band 01: the AI tool tiles */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(292px, 1fr)); gap: 18px; }
.tile {
  background: var(--panel); border-radius: 6px; padding: 20px 24px 16px;
  display: flex; flex-direction: column; gap: 9px;
  border-top: 4px solid var(--orange-bright);
  box-shadow: 0 1px 2px rgba(var(--shadow-rgb), .06),
              0 12px 28px -18px rgba(var(--shadow-rgb), .35);
  transition: transform .18s, box-shadow .18s;
}
.tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 2px 4px rgba(var(--shadow-rgb), .09),
              0 22px 40px -18px rgba(var(--shadow-rgb), .45);
}
.tile-no { font-size: 12px; font-weight: 900; letter-spacing: .14em; color: var(--ink-3); }
.tile-name { font-size: 19px; font-weight: 800; line-height: 1.2; letter-spacing: -.015em; margin: 0; }
.tile-name a { color: var(--ink); }
.tile-name a:hover { color: var(--accent-warm); text-decoration: underline; }
.tile-tagline {
  margin: 0; font-style: italic; font-size: 16px; line-height: 1.4;
  color: var(--accent-warm); flex: 1;
}
.tile-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  margin: 0; padding-top: 9px; border-top: 1px solid var(--line);
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
}
.tile-open { color: var(--accent-cool); }
.tile-sec { color: var(--ink-3); font-weight: 600; font-variant-numeric: tabular-nums; }
.tile-pending {
  background: var(--muted-fill); color: var(--muted-ink);
  padding: 3px 9px; border-radius: 3px; font-size: 11px; font-weight: 700;
}

/* ---- band 02: cases by show, on the light-petrol strip */
.shows {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(176px, 1fr));
  border-left: 1px solid var(--tint-line);
}
.show {
  padding: 16px 22px 20px; border-right: 1px solid var(--tint-line);
  display: flex; flex-direction: column; gap: 2px; color: var(--ink);
  transition: background .15s; min-width: 0;
}
a.show:hover { background: rgba(255, 255, 255, .55); text-decoration: none; }
.show-n {
  font-size: 52px; font-weight: 900; line-height: 1; letter-spacing: -.03em;
  color: var(--tint-fig); font-variant-numeric: tabular-nums;
}
.show-name { font-size: 17px; font-weight: 800; margin-top: 10px; line-height: 1.15; }

/* ---- band 03: the checklists, two columns of square boxes */
.checks { display: grid; grid-template-columns: 1fr 1fr; gap: 0 40px; }
.chk {
  display: grid; grid-template-columns: 22px 1fr; column-gap: 14px;
  padding: 13px 0; border-bottom: 1px solid var(--line); align-items: start;
  color: var(--ink);
}
a.chk:hover { text-decoration: none; }
a.chk:hover .chk-lead { color: var(--accent-warm); }
.chk-box {
  width: 18px; height: 18px; border: 2px solid var(--accent-cool);
  border-radius: 3px; margin-top: 3px;
}
.chk-lead { font-size: 16px; font-weight: 700; line-height: 1.3; }
.chk-sec {
  grid-column: 2; font-size: 13.5px; font-weight: 500; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.empty { color: var(--ink-3); font-size: 14px; padding: 8px 2px; }

/* ---- the runway turns downwards ----------------------------------------
   Seven chapter titles cannot share one row below 1100px without the verb
   dropping under its readable floor, so the band changes direction rather
   than truncating: the same stops, the same colours, each row pointing at the
   next. Nothing is dropped and nothing is clipped. */
@media (max-width: 1100px) {
  .runway { display: block; min-height: 0; filter: none; }
  .runway-wrap { margin-top: -72px; filter: drop-shadow(0 14px 24px rgba(var(--shadow-rgb), .28)); }
  .runway .chev, .runway .chev:first-child {
    display: block; margin: 0 0 3px; padding: 12px 18px 24px; border-radius: 0;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px),
                       calc(50% + 17px) calc(100% - 12px), 50% 100%,
                       calc(50% - 17px) calc(100% - 12px), 0 calc(100% - 12px));
  }
  .runway .chev:first-child { border-radius: 6px 6px 0 0; }
  .runway .chev:last-child { clip-path: none; padding-bottom: 13px; }
  .chev-n, .chev-l, .chev-t { display: inline; position: static; min-height: 0; }
  /* the vertical chevron points DOWNWARDS: its bottom 12px is the notch, so the
     bar sits above it rather than being clipped in half by it */
  .runway .chev .prog, .runway .chev:first-child .prog { left: 18px; right: 18px; bottom: 16px; }
  .runway .chev:last-child .prog { bottom: 5px; }
  .chev-n { font-size: 20px; margin-right: 12px; }
  .chev-t { margin-left: 12px; }
  /* full-width rows: the verb gets its full size back, no clamp needed */
  .chev-l { font-size: 24px; }
  .hero .wrap { padding-top: 52px; padding-bottom: 118px; }
}
@media (max-width: 900px) {
  .tiles { grid-template-columns: 1fr; }
  .checks { grid-template-columns: 1fr; }
  .shows { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  :root { --gutter: 18px; }
  .hero .wrap { padding-top: 36px; padding-bottom: 96px; }
  .hero-title { max-width: none; }
  .runway-wrap { margin-top: -62px; }
  .runway .chev, .runway .chev:first-child { padding: 10px 14px 20px; }
  .chev-n { font-size: 16px; margin-right: 9px; }
  .chev-l { font-size: 19px; }
  .chev-t { display: block; margin: 2px 0 0; font-size: 11.5px; min-height: 0; }
  .band { padding-top: 44px; }
  .band-cases { margin-top: 44px; }
  .band-cases .band-inner { padding: 36px 0 40px; }
  .shows { grid-template-columns: 1fr; }
  .show-n { font-size: 42px; }
}

/* -------------------------------------------------------------- stage page */
/* The four framework sub-stops. Underlined text, not pills: a chapter page now
   carries no rounded control at all, so the eye has nothing to sort through
   before it reaches the writing. The current one is the only coloured item, and
   it is marked twice — colour AND a 2px rule — because colour alone is not a
   state a colour-blind reader can read. */
.substops {
  display: flex; flex-wrap: wrap; gap: 4px 22px;
  max-width: var(--wrap); margin: 0 auto; padding: 18px 0 0;
  border-bottom: 1px solid var(--line);
}
.pill {
  padding: 6px 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
  font-size: 13px; font-weight: 600; color: var(--ink-2); background: transparent;
}
.pill:hover { color: var(--accent-warm); text-decoration: none; border-bottom-color: var(--orange-100); }
.pill.current { color: var(--accent-warm); font-weight: 800; border-bottom-color: var(--accent-warm); }
.pill.current .sec-num { color: var(--accent-warm); }
.sec-num { color: var(--ink-3); font-weight: 600; margin-right: 8px; font-variant-numeric: tabular-nums; }

/* ---- Overview / Full, the two reading modes --------------------------------
   Overview is the default: for every section it keeps the heading, the
   checklists (lead + items, verbatim, exactly as in Full), the takeaway and the
   chips that stand for the rail's cards, and folds that section's own
   paragraphs, lists, tables and images behind its own "Show N more". Full is
   the rendering this site has always had.

   Two rules make this safe rather than clever:

   1. The hide lives inside `@media screen`, so **paper always gets Full** — a
      PDF of a stage page can never be a summary of the book.
   2. The `>` combinators keep a section's state its own: expanding 5.2.3 does
      not expand 5.2, and collapsing 5.2 does not re-collapse a child the reader
      opened. Blocks sit either directly in a level-1 `.sec` or inside a level-2+
      section's `details > .sec-body`, which is what the two selectors are.

   Headings are never folded, and no `<details>` is ever closed by a mode: the
   outline is whole in both, so a reader in Overview still sees the shape of the
   chapter and every deep link still lands. */
/* The reading column's header row. The eyebrow's own margins move onto this
   row (26px above, -16px below, the exact spacing the eyebrow had before it
   gained a neighbour), so `align-items: center` centres two boxes rather than
   two boxes plus one asymmetric margin — otherwise the toggle floats a dozen
   pixels above the word it sits beside at narrow widths. The page below is
   unmoved: the numbers are the ones that were on .stage-eyebrow. */
.col-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 26px 0 -16px;
}
.col-head .stage-eyebrow { margin: 0; }
/* library.html's header is the book title, which carried its own 18px */
.library .col-head { margin: 0 0 18px; }
.library .col-head .page-h1 { margin: 0; }
.mode-bar { flex: 0 0 auto; }
/* Two words and a hairline between them, not a segmented pill: it is the only
   control in the reading column's header and it should read as a choice of
   words, the way the rest of the page does. Still two real buttons in a
   role="group", so aria-pressed says which state EACH is in. */
.mode-toggle {
  display: inline-flex; align-items: center; gap: 10px;
}
.mode-btn {
  font: inherit; font-size: 12.5px; font-weight: 700; padding: 3px 0; cursor: pointer;
  border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--ink-2);
}
.mode-btn + .mode-btn { border-left: 0; }
.mode-toggle .mode-btn:first-child { padding-right: 10px; border-right: 1px solid var(--line); }
.mode-btn:hover { color: var(--accent-warm); }
.mode-btn[aria-pressed="true"] { color: var(--accent-warm); border-bottom-color: var(--accent-warm); }
.mode-toggle .mode-btn:first-child[aria-pressed="true"] { border-bottom-color: var(--accent-warm); }
.mode-btn:focus-visible { outline: 2px solid var(--accent-warm); outline-offset: 2px; }

/* Outline mode. A collapsed section is exactly three lines — heading, summary,
   indicator — whatever it holds, because the fold takes the whole of the
   section's own body and nothing else. The children are SIBLINGS of that body,
   not inside it, so opening 5.2.3 cannot open 5.2 and collapsing 5.2 cannot
   re-collapse a child the reader opened: the `>` is doing that on its own. And
   the rule sits inside `@media screen`, so paper always carries the full text. */
@media screen {
  body.mode-overview .sec:not(.ov-open) > .sec-body > .ov-hide { display: none; }
  /* `.sec-body > .checklist-plain { display: none }` stood here until
     2026-09-14. It made the verbatim checklist a PAPER-ONLY rendering, because
     on screen the tickable card in the rail was the single place a checklist
     appeared. That rail tab is gone (the whole checklist feature came out), so
     keeping this rule would have deleted nine blocks of the book's own
     methodology from the screen while leaving them in the HTML — invisible to a
     reader and invisible to the gate, which counts ids and not pixels. The block
     carries `ov-hide` now instead, so it folds with everything else. */
}

/* The arrow band's word for this stop, above the chapter's own title, in that
   stop's own tone. --tone-accent is the deep hue of the tone's family, because
   a light fill (brand-light, alt-light) is not readable as type on the page;
   the fallback keeps the eyebrow visible if a stop ever loses its tone class. */
.stage-eyebrow {
  margin: 26px 0 -16px; font-size: 12px; font-weight: 800; letter-spacing: .18em;
  text-transform: uppercase; color: var(--tone-accent, var(--accent-warm));
}

.split {
  display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 36px;
  max-width: var(--wrap); margin: 0 auto; padding-top: 18px;
}
/* The reading column is a panel on the ground, wearing its stop's own tone as
   a top stripe — the same material the homepage's tiles are made of, and the
   same colour the bar gives that stop. --tone-accent (not --tone-fill) so the
   stripe is the DEEP hue of the family: a 4px rule in brand-light's pale peach
   is not a signal, it is a smudge. --tone-* comes from the tone-* class the
   template puts on this element. */
.col-left {
  min-width: 0; background: var(--panel); border-radius: var(--radius);
  padding: 6px 28px 28px; border-top: 4px solid var(--tone-accent, var(--petrol));
}
.col-left.wide { max-width: 900px; margin: 0 auto; }
.library { padding-top: 18px; max-width: var(--wrap); margin: 0 auto; }

.sec { scroll-margin-top: calc(var(--topbar-h) + 12px); }
/* Levels 2 and below are indented behind a hairline, which is what the old
   <details> frame gave the outline; the frame itself is gone, because the
   heading is now the one control and a second collapsible box around it was the
   "too many buttons" problem in miniature. */
.sec-l2, .sec-l3, .sec-l4, .sec-l5, .sec-l6 {
  margin: 14px 0; border-left: 2px solid var(--line-2); padding-left: 14px;
}
.sec-l2 { border-left-color: var(--line); }
.sec-title {
  scroll-margin-top: calc(var(--topbar-h) + 12px);
  display: inline-block; margin: 0;
}
/* Inside a section the heading is a row: title (the disclosure button, which
   takes the slack), the anchor link, then the Feedback icon app.js appends. */
.sec > .sec-title { display: flex; align-items: center; gap: 8px; width: 100%; }
.sec-l1 > .sec-title { font-size: 26px; font-weight: 800; margin: 26px 0 10px; padding-bottom: 8px; border-bottom: 3px solid var(--orange-bright); width: 100%; }
.sec-l2 .sec-title { font-size: 19px; font-weight: 800; }
.sec-l3 .sec-title, .sec-l4 .sec-title { font-size: 16px; font-weight: 700; }
.anchor-link { margin-left: 8px; color: var(--line); font-weight: 400; }
.sec > .sec-title > .anchor-link { margin-left: 0; flex: 0 0 auto; }
.sec-title:hover .anchor-link { color: var(--ink-3); }

/* The heading IS the disclosure control, so it inherits the heading's own type
   and carries no chrome at all — no border, no fill, no radius. The only thing
   that marks it as pressable is the caret and the cursor. */
.sec-toggle {
  font: inherit; color: inherit; text-align: left; background: none; border: 0;
  padding: 0; margin: 0; flex: 0 1 auto; min-width: 0;
  display: inline-flex; align-items: baseline; gap: 8px; cursor: pointer;
}
.sec-toggle-static { cursor: default; }
.sec-toggle:hover .sec-name { color: var(--accent-warm); }
.sec-toggle:focus-visible { outline: 2px solid var(--accent-warm); outline-offset: 3px; border-radius: 2px; }
.sec-name { min-width: 0; }
.sec-caret {
  flex: 0 0 auto; width: 10px; font-size: 10px; line-height: 1; color: var(--ink-3);
  transition: transform .15s; transform-origin: 50% 55%;
}
.sec.ov-open > .sec-title .sec-caret { transform: rotate(90deg); }
.sec-caret-none { visibility: hidden; }
.sec > .sec-title .sec-num { margin-right: 0; }

/* The summary: one grey line of the section's own subject. Never a button — the
   heading above it already is one — but it is a click target, which is why it
   takes the pointer. */
.sec-summary {
  margin: 4px 0 0 18px; max-width: 70ch;
  font-size: 14px; line-height: 1.55; color: var(--ink-3);
}
.sec-summary.is-toggle { cursor: pointer; }
.sec-summary.is-toggle:hover { color: var(--ink-2); }
.sec-l1 > .sec-summary { margin-left: 0; font-size: 15px; }

/* The indicator line: what this section holds, faintest thing on the page
   except for the rule under it. Everything is --ink-3 grey but the tool names,
   which are the warm accent — a tool is the one item here a reader can go and
   use right now, and the whole book uses orange for exactly that. */
.sec-meter {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 7px;
  margin: 6px 0 0 18px; padding: 0 0 8px;
  font-size: 12px; font-weight: 600; letter-spacing: .01em;
}
.sec-l1 > .sec-meter { margin-left: 0; }
.sec-meter-item {
  font: inherit; background: none; border: 0; padding: 0; margin: 0;
  color: var(--ink-3); line-height: 1.5;
}
button.sec-meter-item { cursor: pointer; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
button.sec-meter-item:hover { color: var(--accent-warm); text-decoration-color: currentColor; }
button.sec-meter-item:focus-visible { outline: 2px solid var(--accent-warm); outline-offset: 2px; border-radius: 2px; }
.sec-meter-item.is-toggle { cursor: pointer; }
.sec-meter-item.is-toggle:hover { color: var(--ink-2); }
.sec-meter-item.mi-tool, .sec-meter-item.mi-tool-label { color: var(--accent-warm); }
.sec-meter-item.mi-tool-label { cursor: default; text-decoration: none; }
.sec-meter-dot { color: var(--ink-3); opacity: .55; }

.sec-body { padding: 2px 0 4px; }

/* ------------------------------------------- subsection cards (preset a4) */
/* With `subsections: cards` a level-2 section is a card: 5.1 is one box, 5.2
   the next, and the level-3 sections live INSIDE, folded away until asked for.
   The card is a container, not a control — a hairline, a faint ground and a
   radius, and nothing that reads as a button. The A-variant contract is "no
   pills in the reading column", and this keeps it: the only control here is
   still the heading, which carries no chrome at all. */
.sec-card {
  margin: 14px 0; padding: 12px 16px 6px;
  border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: var(--radius); background: var(--ground);
}
/* The open card is the one the reader is in: its left edge takes the warm
   accent and it sits on the page's own white, so an open card and a closed one
   are told apart by two things, not by colour alone. */
.sec-card.ov-open { border-left-color: var(--accent-warm); background: var(--panel); }
.sec-card > .sec-summary, .sec-card > .sec-meter { margin-left: 18px; }
.sec-card > .sec-meter { padding-bottom: 2px; }
/* Inside a card the level-3 rows drop their own left rule: the card is already
   the frame, and two nested rules read as a mistake. */
.sec-kids { margin-top: 6px; }
.sec-kids > .sec-l3 { border-left: 0; padding-left: 0; margin: 12px 0; }
.sec-kids > .sec-l3 + .sec-l3 { border-top: 1px solid var(--line-2); padding-top: 10px; }

/* The count of sections inside a closed card — the one item on the indicator
   line that says how much is behind the fold. Darker than the rest of the line
   because it is the thing being offered, not a tally of contents. */
.sec-meter-item.mi-sections { color: var(--ink-2); font-weight: 700; }

@media screen {
  /* The sections inside a closed card. Same `.ov-open` class the body fold uses,
     so one click, one state, and every existing path that opens a section — deep
     link, comment drawer, Full-text mode — opens the card too with no card-aware
     code of its own. Inside `@media screen`, so paper always carries all of it. */
  body.mode-overview .sec-card:not(.ov-open) > .sec-kids { display: none; }
}

/* -------------------------------------------------------------- left blocks */
.blk { margin: 10px 0; }
.p { color: var(--ink); }
.list { padding-left: 22px; }
.list li { margin: 4px 0; }
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.table-wrap table { border-collapse: collapse; width: 100%; font-size: 14px; }
.table-wrap th, .table-wrap td {
  border-bottom: 1px solid var(--line); border-right: 1px solid var(--line-2);
  padding: 8px 10px; text-align: left; vertical-align: top; min-width: 140px;
}
.table-wrap thead th { background: var(--ground); font-weight: 700; white-space: nowrap; }
.table-wrap tr:last-child td { border-bottom: none; }
.cell-img { display: block; margin-top: 6px; max-width: 100%; max-height: 320px; width: auto; height: auto; }
/* a table Word nested inside a cell (5.4.5 Branding holds one) — boxed so it
   reads as a sub-table rather than as a break in the outer one */
.cell-table { margin: 8px 0 2px; border: 1px solid var(--line); border-radius: var(--radius); overflow-x: auto; }
.cell-table table { font-size: 13px; }
.cell-table th, .cell-table td { min-width: 0; }
.cell-table tr:last-child td { border-bottom: none; }
.figure { margin: 16px 0; text-align: center; }
.figure img {
  display: inline-block; max-width: 100%; max-height: 520px; width: auto; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.card-figure { margin: 8px 0; text-align: center; }
/* The image is its own link to the full-size file; a data-table figure is
   unreadable at the 240px cap above. zoom-in is the only affordance — no
   button, because the outline design keeps the reading column button-free. */
/* The inert marker an offline copy shows in place of the live Feedback button:
   dashed, so it reads as a placeholder rather than a control that is broken. */
.fb-preview { cursor: help; opacity: .55; border: 1px dashed var(--line); border-radius: 4px; }
.fb-preview:hover { opacity: 1; border-color: var(--accent-cool); }
.figure-zoom { display: inline-block; line-height: 0; cursor: zoom-in; border-radius: 3px; }
.figure-zoom:focus-visible { outline: 2px solid var(--accent-cool); outline-offset: 2px; }
.card-figure img { max-width: 100%; max-height: 240px; width: auto; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius); }
.figure figcaption { font-size: 13px; color: var(--ink-3); margin-top: 6px; }
.img-missing {
  display: inline-block; padding: 18px 20px; border: 1px dashed var(--line);
  border-radius: var(--radius); color: var(--ink-3); font-size: 13px; background: var(--ground);
}
/* checklists render verbatim here and tickable in the rail */
.checklist-plain { border-left: 2px solid var(--line); padding: 2px 0 2px 14px; }
.cl-lead { margin: 0 0 6px; font-weight: 700; }
.cl-items { margin: 0; padding-left: 20px; }
.cl-items li { margin: 4px 0; }

/* One-line marker left where a rail card sits in the methodology. It used to be
   a dashed pill; it is now a quiet underlined line, because it points somewhere
   rather than doing something, and a page full of pills was the report. Two
   hues plus a neutral keep field insight / example / tool three distinguishable
   things without a third and fourth colour: petrol, slate, orange. */
.jump-line {
  display: inline-flex; align-items: baseline; gap: 6px; max-width: 100%;
  font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer;
  padding: 2px 0; margin: 2px 18px 2px 0; border: 0; background: none; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.jump-line:hover { color: var(--accent-warm); border-bottom-color: var(--accent-warm); }
.jump-line:focus-visible { outline: 2px solid var(--accent-warm); outline-offset: 2px; }
.jump-line-field_insight { color: var(--accent-cool); border-bottom-color: var(--tint-line); }
.jump-line-example { color: var(--ink-2); }
.jump-line-tool { color: var(--accent-warm); border-bottom-color: var(--orange-100); }
.jump-arrow { opacity: .7; }
.card.flash { box-shadow: 0 0 0 2px var(--orange-bright); }

.takeaway {
  border-left: 3px solid var(--petrol); background: var(--tint);
  padding: 12px 16px; border-radius: 0 var(--radius) var(--radius) 0; color: var(--ink);
}

.prevnext {
  display: flex; justify-content: space-between; gap: 16px;
  margin: 48px 0 0; padding-top: 16px; border-top: 1px solid var(--line); font-size: 14px;
  font-weight: 600;
}

/* ---------------------------------------------------------------- the rail
   Same materials as the homepage's bands: a tool card is a tile (orange top
   rule, italic tagline, footer rule), a checklist is a list of square boxes,
   and a case card carries its type's tone as a left stripe. */
.col-right { min-width: 0; }
.rail-inner {
  position: sticky; top: calc(var(--topbar-h) + 14px);
  max-height: calc(100vh - var(--topbar-h) - 30px);
  display: flex; flex-direction: column;
  border: 1px solid var(--line); background: var(--panel); overflow: hidden;
}
.tabs { display: flex; gap: 2px; padding: 6px; border-bottom: 1px solid var(--line); background: var(--panel); }
.tablist { display: flex; gap: 2px; flex: 1 1 auto; min-width: 0; }
/* named only when the three panels print stacked; see @media print */
.print-only { display: none; }
.tab {
  flex: 1; border: 0; background: transparent; font: inherit; font-size: 13.5px;
  font-weight: 600; color: var(--ink-2); padding: 7px 4px; border-radius: 4px; cursor: pointer;
}
.tab:hover { background: var(--line-2); }
.tab.active { background: var(--soft); color: var(--accent-warm); font-weight: 800; }
.rail-close { display: none; }
.tabpanel { display: none; overflow-y: auto; padding: 12px; background: var(--ground); }
.tabpanel.active { display: block; }
.filter-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-size: 13px; }
.filter-row select { font: inherit; font-size: 13px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); color: var(--ink); }

.card-group { margin-bottom: 14px; border-radius: var(--radius); padding: 4px; transition: background .2s; }
.card-group.current { background: var(--soft); }
.group-head { margin: 0 0 6px; font-size: 12px; font-weight: 700; color: var(--ink-3); }
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  border-left: 3px solid var(--line); padding: 12px 12px 12px 13px; margin-bottom: 10px;
}
.card-field_insight { border-left-color: var(--petrol); }
.card-example { border-left-color: var(--slate); }
.check-card { border-left-color: var(--orange-100); }
.card-head { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.chip { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--ink-2); }
.chip-field_insight { border-color: var(--tint-line); background: var(--tint); color: var(--accent-cool); }
.chip-example { border-color: var(--line); background: var(--ground); color: var(--ink-2); }
.chip-case { border-color: var(--orange-100); background: var(--soft); color: var(--accent-warm); }
.card-text { margin: 0 0 8px; font-size: 14px; color: var(--ink); }
.card-foot { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; color: var(--ink-3); }
.card-link { font-size: 12px; font-weight: 600; }
.also-in a { margin: 0 1px; }
/* a tool in the rail is the homepage tile, at rail width */
.tool-card { border-left: 1px solid var(--line); border-top: 4px solid var(--orange-bright); padding-left: 12px; }
.tool-name { margin: 0 0 5px; font-size: 15px; font-weight: 800; line-height: 1.25; }
.tool-tagline { margin: 0 0 8px; font-size: 14px; font-style: italic; color: var(--accent-warm); }
.tool-lines { margin: 0 0 8px; padding-left: 18px; font-size: 13px; color: var(--ink-2); }
.tool-lines li { margin: 3px 0; }
.tool-links { margin: 0; padding-top: 8px; border-top: 1px solid var(--line); font-size: 12.5px; font-weight: 700; word-break: break-all; }
.tool-links a { color: var(--accent-cool); }
.check-lead { margin: 0 0 8px; font-size: 14px; font-weight: 700; }
.check-list { list-style: none; margin: 0 0 10px; padding: 0; }
.check-list li { margin: 6px 0; font-size: 14px; }
.check-list label { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
/* the homepage's square box, here as a real checkbox */
.check-list input {
  appearance: none; -webkit-appearance: none; flex: 0 0 auto;
  width: 18px; height: 18px; margin: 2px 0 0; cursor: pointer;
  border: 2px solid var(--accent-cool); border-radius: 3px; background: var(--panel);
}
/* The tick is an inline data: URI, not a fetched file, so dist/ stays a
   self-contained offline copy. The checked box is --petrol in BOTH themes
   rather than --accent-cool: the tick inside it is white (5.83:1 on petrol),
   and a token that goes pale in the dark theme would have hidden it. */
.check-list input:checked {
  background-color: var(--petrol); border-color: var(--petrol);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M3.4 8.4l3.1 3.1 6.1-6.6'/%3E%3C/svg%3E");
  background-size: 100% 100%; background-position: center; background-repeat: no-repeat;
}
.check-list input:focus-visible { outline: 2px solid var(--accent-warm); outline-offset: 2px; }
.check-list input:checked + span { color: var(--ink-3); text-decoration: line-through; }
.btn-reset {
  font: inherit; font-size: 12px; font-weight: 600; padding: 4px 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 4px; background: var(--panel); color: var(--ink-2);
}
.btn-reset:hover { border-color: var(--accent-warm); color: var(--accent-warm); }

/* -------------------------------------------------------------- library page */
.collection { margin-top: 40px; }
/* #cases-<tag> is a link target from the journey page's "Cases by show" band,
   so it needs the same sticky-bar offset every other anchor has */
.show-group { margin: 18px 0 26px; scroll-margin-top: calc(var(--topbar-h) + 12px); }
.show-head { font-size: 16px; font-weight: 800; margin: 0 0 10px; color: var(--ink); }
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.card-grid .card { margin-bottom: 0; }

/* ------------------------------------------------------------------- footer */
.foot {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  max-width: var(--wrap); margin: 44px auto 0; padding: 22px var(--gutter) 40px;
  border-top: 1px solid var(--line); font-size: 13px; font-weight: 500; color: var(--ink-3);
}

/* ------------------------------------------------------------- comment widget */
/* A comment bubble at the right-hand end of the heading row, not a pill in the
   middle of the reading. Quiet by default — half-tone ink, which is as faint as
   it can go and still clear WCAG's 3:1 bar for a control you have to be able to
   find (measured 3.25:1 light / 4.57:1 dark; the same icon at 45% of --ink-3
   measures 1.92:1, which is why it is not that) — and solid on hover or focus.
   The open-thread count is a corner badge; the words are in aria-label and
   title, which app.js writes with the section's own name. */
.fb-btn {
  position: relative; flex: 0 0 auto; margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  border: 0; border-radius: 6px; background: transparent;
  color: var(--ink); opacity: .5; cursor: pointer; vertical-align: middle;
  transition: opacity .12s, color .12s, background-color .12s;
}
.fb-btn:hover { opacity: 1; color: var(--accent-warm); background: var(--soft); }
.fb-btn:focus-visible {
  opacity: 1; color: var(--accent-warm);
  outline: 2px solid var(--accent-warm); outline-offset: 2px;
}
.fb-btn.has-open { opacity: 1; color: var(--accent-warm); }
.fb-count {
  position: absolute; top: -1px; right: -1px; min-width: 14px; height: 14px;
  padding: 0 3px; border-radius: 999px;
  background: var(--orange); color: #FFFFFF;
  font-size: 10px; font-weight: 800; line-height: 14px; text-align: center;
}
.fb-count[hidden] { display: none; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 400px; max-width: 92vw; z-index: 60;
  background: var(--panel); border-left: 1px solid var(--line); box-shadow: -2px 0 16px rgba(var(--shadow-rgb), .10);
  display: flex; flex-direction: column; transform: translateX(102%); transition: transform .18s ease;
}
.drawer[hidden] { display: none; }
.drawer.open { transform: translateX(0); }
.drawer-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.drawer-head h3 { margin: 0; font-size: 15px; font-weight: 800; }
.drawer-body { flex: 1; overflow-y: auto; padding: 12px 16px; }
.drawer-foot { border-top: 1px solid var(--line); padding: 12px 16px; }
.cmt { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px; margin-bottom: 10px; }
.cmt-meta { font-size: 12px; color: var(--ink-3); display: flex; gap: 8px; flex-wrap: wrap; }
.cmt-status { border-radius: 999px; padding: 1px 8px; border: 1px solid var(--line); }
.cmt-status.resolved { background: var(--tint); border-color: var(--tint-line); color: var(--accent-cool); }
.cmt-quote { border-left: 2px solid var(--line); padding-left: 8px; margin: 6px 0; font-size: 13px; color: var(--ink-2); }
.cmt-text { margin: 6px 0 0; font-size: 14px; white-space: pre-wrap; }
.cmt-reply { margin: 8px 0 0; padding: 8px; background: var(--ground); border-radius: 4px; font-size: 13.5px; white-space: pre-wrap; }
.cmt-admin { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.drawer textarea {
  width: 100%; font: inherit; font-size: 14px; padding: 8px; resize: vertical;
  border: 1px solid var(--line); border-radius: 4px; min-height: 74px;
  background: var(--panel); color: var(--ink);
}
.drawer .btn {
  font: inherit; font-size: 13px; font-weight: 700; padding: 6px 15px; cursor: pointer;
  border: 1px solid var(--orange); border-radius: 4px; background: var(--orange); color: var(--on-dark);
}
.drawer .btn.ghost { background: var(--panel); color: var(--ink-2); border-color: var(--line); }
.drawer .btn:hover { opacity: .9; }
.err { color: #b3261e; font-size: 13px; margin: 6px 0 0; }
/* shown when the backend is up but this visitor has no identity */
.sign-in-notice {
  max-width: var(--wrap); margin: 12px auto 0; padding: 7px 13px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  color: var(--ink-3); font-size: 13px;
}
.quote-prefill { font-size: 12px; color: var(--ink-3); margin: 0 0 6px; }

/* -------------------------------------------------------------- narrow screens */
.rail-toggle { display: none; }
@media (max-width: 900px) {
  :root { --topbar-h: 92px; }
  .page { padding: 0 16px 72px; }
  .col-left, .library { padding: 4px 18px 22px; }
  .split { display: block; }
  .rail-toggle {
    display: block; position: fixed; left: 50%; transform: translateX(-50%); bottom: 14px; z-index: 45;
    font: inherit; font-size: 13.5px; font-weight: 700; padding: 10px 20px; cursor: pointer;
    border: 1px solid var(--orange); border-radius: 999px; background: var(--orange); color: var(--on-dark);
  }
  .col-right {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; max-height: 78vh;
    transform: translateY(102%); transition: transform .18s ease; background: var(--panel);
    border-top: 1px solid var(--line); box-shadow: 0 -2px 16px rgba(var(--shadow-rgb), .10);
  }
  .col-right.open { transform: translateY(0); }
  .rail-inner { position: static; max-height: 78vh; border: 0; border-radius: 0; }
  .rail-close { display: block; flex: 0 0 auto; border: 0; background: transparent; font: inherit; font-size: 13px; color: var(--ink-2); cursor: pointer; padding: 6px 10px; }
  .tabpanel { max-height: 62vh; }
  .drawer { width: 100%; }
}

/* ------------------------------------------------------------------- print
   A printed page has no tabs, no rail to stick and no bottom sheet, so the
   three rail panels print stacked under the methodology with their tab names as
   headings — otherwise a PDF of a stage page silently loses every case, tool
   and checklist card (`.tabpanel { display: none }` plus a scrolling
   `.rail-inner` clipped to one viewport).

   This block MUST stay last in the file: a printed page is about 816 CSS px
   wide, so the `max-width: 900px` bottom-sheet rules above match on paper too,
   and only a later rule of equal specificity undoes them. */
@media print {
  :root { --topbar-h: 0px; }
  html { scroll-behavior: auto; }
  body { font-size: 11pt; background: #fff; color: #000; }

  /* Controls carry nothing a reader can use on paper. .mode-bar and
     .reset-all-row go with them, and because the Outline hide rule lives in
     `@media screen` a printed page always carries the FULL reading whatever
     mode the screen was in. .prog is a live localStorage fact, not content.

     .sec-summary and .sec-meter are hidden too, and that is a contract, not
     housekeeping: the summary is an aid to choosing what to open, and on paper
     nothing is closed — the section's own words are right there underneath, so
     a one-line restatement above them would be the only sentence on the page
     that is not simply the book. */
  .topbar, .rail-toggle, .rail-close, .tabs, .fb-btn, .btn-reset, .anchor-link,
  .filter-row, .jump-line, .sign-in-notice, .prevnext, .substops,
  .mode-bar, .reset-all-row, .prog,
  .sec-summary, .sec-meter, .sec-caret { display: none !important; }
  .drawer { display: none !important; }

  /* the homepage's dark bands are a screen device; on paper they are plain */
  .journey-page { max-width: none; padding-top: 0; }
  body[data-page="journey"] .page { padding: 0; }
  .wrap { max-width: none; padding: 0; }
  .hero, .band-cases { background: transparent !important; color: inherit !important; }
  .hero .wrap { padding: 0 !important; }
  .hero-eyebrow { color: var(--ink-2) !important; }
  .hero-title { font-size: 20pt; color: inherit !important; max-width: none; }
  .aside-stops { margin: 8px 0 0; }
  .aside-stop {
    background: transparent !important; color: inherit !important;
    border: 1px solid var(--line); padding: 3px 8px; font-size: 11pt;
  }
  /* the arrow is a colour device; on paper it is a plain list of the same
     links, so a printed index.html still carries every stop */
  .runway-wrap { margin: 12px 0 0; filter: none; }
  .runway { display: block; min-height: 0; filter: none; }
  .runway .chev, .runway .chev:first-child {
    display: block; clip-path: none; margin: 0; padding: 3px 0; border-radius: 0;
    background: transparent !important; color: inherit !important;
    border: 0; border-bottom: 1px solid var(--line); filter: none;
  }
  .chev-n, .chev-l, .chev-t { display: inline; position: static; min-height: 0; font-size: 11pt; color: inherit !important; }
  .chev-n { min-width: 26px; display: inline-block; margin-right: 6px; }
  .chev-t { margin-left: 10px; color: var(--ink-2); }
  /* the bands lose their grid and their card materials and print as three
     lists, so a printed index.html still carries every tool, show and checklist */
  .bands { padding: 0; }
  .band, .band-cases { padding: 14px 0 0; margin: 0; }
  .band-cases .band-inner { padding: 0; }
  .band-head { margin-bottom: 8px; }
  .band-name { font-size: 14pt; }
  .tiles, .checks, .shows, .starts { display: block; border: 0; }
  /* a Start here card prints as the block it re-renders, nothing more */
  .start-card {
    border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
    padding: 3px 0; break-inside: avoid; page-break-inside: avoid;
  }
  .start-foot { border: 0; margin: 2px 0 0; padding: 0; }
  .tile, .chk, .show {
    display: block; border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
    box-shadow: none; padding: 3px 0; break-inside: avoid; page-break-inside: avoid;
    background: transparent !important; transform: none;
  }
  .tile-tagline, .tile-foot, .tile-name, .chk-lead, .chk-sec { margin: 1px 0 0; padding: 0; border: 0; }
  .tile-foot { display: block; }
  .tile-sec { margin-left: 10px; }
  .chk-box { display: none; }
  /* the show and its card count belong on one printed line */
  .show-n, .show-name { display: inline; font-size: 11pt; color: inherit; }
  .show-n { min-width: 26px; margin-right: 6px; }
  .tile-pending { background: transparent; border: 1px solid var(--line); }

  /* one column, the rail after the methodology, nothing clipped */
  .page { padding: 0; max-width: none; }
  .split { display: block; max-width: none; padding-top: 0; }
  .col-left, .col-left.wide, .library {
    max-width: none; margin: 0; padding: 0; border: 0; background: transparent;
  }
  .col-right {
    position: static; transform: none; max-height: none; z-index: auto;
    margin: 28px 0 0; border: 0; border-top: 1px solid var(--line);
    box-shadow: none; background: #fff;
  }
  .rail-inner {
    position: static; max-height: none; overflow: visible;
    display: block; border: 0; border-radius: 0; background: #fff;
  }
  .tabpanel { display: block; max-height: none; overflow: visible; padding: 0; background: transparent; }
  .print-only { display: block; }
  .rail-panel-title {
    font-size: 13pt; margin: 18px 0 8px; padding-bottom: 4px;
    border-bottom: 1px solid var(--line);
  }
  .card-group { break-inside: auto; }
  .card-group.current { background: transparent; box-shadow: none; }

  /* A folded section still holds its content; print it. `:not(.jump-line)` is
     load-bearing: the jump lines are ov-hide too, and without it this rule (which
     is later, and equally !important) would undo the hide list above and put
     "Field insight · RX China →" on paper next to the card it points at. */
  .sec-body { display: block !important; }
  .sec-body > .ov-hide:not(.jump-line) { display: block !important; }
  /* the heading's disclosure button is plain text on paper; the flex `gap` that
     separates the number from the title on screen goes with the flex box, so the
     number gets its margin back or it prints as "3.1Strategic Fit" */
  .sec-toggle { display: inline !important; font: inherit; color: inherit; }
  .sec > .sec-title .sec-num { margin-right: 8px; }
  /* the nesting hairline is a screen device; on paper the heading sizes carry it */
  .sec-l2, .sec-l3, .sec-l4, .sec-l5, .sec-l6 { border-left: 0; padding-left: 0; margin: 10px 0; }
  /* On paper nothing is folded and nothing is a box: the card frame would only
     draw a rectangle round a third of the book. `display: block` on .sec-kids is
     belt and braces — the screen-only rule above cannot reach here anyway. */
  .sec-card { border: 0; padding: 0; background: none; }
  .sec-kids { display: block !important; margin: 0; }
  .sec-kids > .sec-l3 + .sec-l3 { border-top: 0; padding-top: 0; }

  /* keep a card, a table or a figure off a page boundary */
  .card, .takeaway, .checklist-plain, .table-wrap, .figure, .card-figure,
  .show-group, tr, .cell-table { break-inside: avoid; page-break-inside: avoid; }
  .sec-title, .rail-panel-title, .show-head, .group-head {
    break-after: avoid; page-break-after: avoid;
  }
  .card { border-color: #ccc; border-left-color: #ccc; }
  .foot { max-width: none; margin: 0; padding: 12px 0 0; }
  a { color: inherit; text-decoration: none; }
}
