/* base.css :: tokens, typography, layout primitives, shared chrome.
   Design direction: field atlas. Paper ground, ink type, road-marking yellow
   used once per viewport, lidar cyan for live/selected state. */

/* Self-hosted faces, latin subsets, axes limited to what the site uses.
   Licensing and regeneration recipe: assets/fonts/README.md */
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-var.woff2') format('woff2-variations');
  font-weight: 400 900;
  font-stretch: 100% 118%;
  font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-var.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-var-italic.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/plex-mono-600.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}

:root {
  --paper:   #FAFAF7;
  --paper-2: #FFFFFF;
  --ink:     #12130F;
  --ink-2:   #3B3E36;
  --muted:   #6E7268;
  --rule:    #DEDFD8;
  --yellow:  #F2B705;
  --cyan:    #00A5B8;
  --cyan-text: #007A8A; /* cyan as text, focus ring, or selection stroke: 4.84:1 on paper (bright --cyan measures 2.84:1, fails WCAG) */
  --alert:   #C4453B;

  /* eleven layers, one hue wheel; chroma dropped for a paper ground */
  --h-driver: 265; --h-sensing: 200; --h-data: 150; --h-middleware: 105;
  --h-vehicle: 40; --h-demand: 20; --h-fleet: 320; --h-connectivity: 230;
  --h-capital: 60; --h-regulators: 290; --h-standards: 340;
  --layer-l: 0.62; --layer-c: 0.075;
  --tile-l: 0.66; --tile-c: 0.06; --tile-ink: #FFFFFF;
  --med-bg: #F4F2E9; --med-ink: #12130F; --med-sub: #63665C; /* 5.22:1 on med-bg; #6E7268 measured 4.39:1, failed AA */
  --road: #E4E2D8; --road-line: #FFFFFF;

  --r-chip: 8px; --r-card: 14px; --r-medallion: 20px; --r-pill: 999px;

  --font-display: 'Archivo', system-ui, sans-serif;
  --font-serif: 'Source Serif 4', Georgia, serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;

  --col: 1240px;
  --measure: 68ch;

  /* Type scale. There were ~50 hand-picked font-size literals across five
     stylesheets and no tokens at all, so a one-step size change meant hunting.
     These six cover most of the site; the fluid headline clamps stay as they
     are. Each is a step up from where it was, which is the 1-2pt lift the
     review asked for. */
  --fs-micro: 11px;
  --fs-xs:    12px;
  --fs-sm:    13.5px;
  --fs-base:  15.5px;
  --fs-md:    16px;
  --fs-lg:    19px;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --paper:   #14150F;
  --paper-2: #1C1E17;
  --ink:     #F2F2EC;
  --ink-2:   #C4C7BB;
  --muted:   #8B8F82;
  --rule:    #2E3128;
  --yellow:  #FFC931;
  --cyan:    #22C4D6;
  --cyan-text: #22C4D6; /* dark cyan already passes (8.69:1) */
  --alert:   #E0655B;
  --layer-l: 0.74; --layer-c: 0.09;
  --tile-l: 0.42; --tile-c: 0.055; --tile-ink: #E9EAE2;
  --med-bg: #24261D; --med-ink: #F2F2EC; --med-sub: #9DA095;
  --road: #2B2E24; --road-line: #6E7268;
  color-scheme: dark;
}
[hidden] { display: none !important; }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  /* Mobile browsers inflate long text blocks in landscape while leaving short
     flex items such as the wordmark alone, which inverts the type hierarchy.
     Opt out and let the scale below do the work. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  background: var(--paper); color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-base); line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; height: auto; }
a { color: inherit; text-underline-offset: 2px; text-decoration-color: var(--muted); }
a:hover { text-decoration-color: var(--cyan-text); color: var(--cyan-text); }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, select { font: inherit; color: inherit; }
::selection { background: var(--yellow); color: #12130F; }

:focus-visible { outline: 3px solid var(--cyan-text); outline-offset: 2px; border-radius: 2px; }
.skip-link {
  position: absolute; left: 8px; top: -48px; z-index: 200;
  background: var(--ink); color: var(--paper); padding: 8px 16px;
  border-radius: var(--r-chip); font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: 8px; color: var(--paper); }

/* Touch targets: the chip controls render at ~32px, which reads right at
   desktop density but is under the 44px floor for fingers. On coarse
   pointers only, an invisible hit-area extension makes up the difference;
   nothing changes visually anywhere. */
@media (pointer: coarse) {
  .chip, .np-more, .cc-close, #theme-toggle { position: relative; }
  .chip::after, .np-more::after, .cc-close::after, #theme-toggle::after {
    content: ''; position: absolute; inset: -7px;
  }
}

/* The layer-grouped organisation index that renders when JavaScript is off.
   Lives inside <noscript>, so with JS on none of this paints. */
.ns-index { margin: 24px auto; }
.ns-index section { margin: 20px 0; }
.ns-index h2 {
  font-size: 17px; font-weight: 700; font-variation-settings: 'wdth' 112;
  margin: 0 0 8px;
}
.ns-index .ns-n { font-family: var(--font-mono); font-size: 12px; color: var(--muted); font-weight: 600; }
.ns-index ul {
  list-style: none; columns: 220px 4; column-gap: 28px;
  font-size: var(--fs-sm); line-height: 1.9;
}
.ns-index a { text-decoration-color: var(--rule); }

/* ---------------------------------------------------------------- type */
.eyebrow {
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.eyebrow .tick { color: var(--yellow); }
/* Clamp floors are the phone sizes: the fluid middle term dies below ~690px,
   so the floor must itself be a deliberate mobile step — nothing here should
   dwarf the 15px wordmark in the bar. */
h1.page-title {
  font-size: clamp(26px, min(5.5vw, 9vh), 76px); font-weight: 800; line-height: 1.06;
  letter-spacing: -0.03em; font-variation-settings: 'wdth' 118;
  margin: 10px 0 0; text-wrap: balance;
}
h2.section-head, .section-head {
  font-size: clamp(20px, min(3vw, 4.6vh), 38px); font-weight: 800; line-height: 1.1;
  letter-spacing: -0.02em; font-variation-settings: 'wdth' 112;
}
.standfirst {
  font-size: var(--fs-lg); line-height: 1.55; color: var(--ink-2);
  max-width: var(--measure); margin-top: 16px; text-wrap: pretty;
}
.prose {
  font-family: var(--font-serif); font-size: var(--fs-lg); line-height: 1.62;
  max-width: var(--measure);
}
.prose p + p { margin-top: 16px; }
.prose h3 { font-family: var(--font-display); font-weight: 800;
  font-size: clamp(18px, min(2.6vw, 4vh), 22px);
  letter-spacing: -0.01em; font-variation-settings: 'wdth' 112; margin: 40px 0 12px; }
.prose ul, .prose ol { padding-left: 22px; margin: 14px 0; }
.prose li + li { margin-top: 8px; }
.prose strong { font-weight: 700; }
.mono, .num {
  font-family: var(--font-mono); font-size: 14px; font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.caption { font-size: var(--fs-sm); color: var(--muted); }
small { font-size: 13px; }

/* ---------------------------------------------------------------- layout */
.container { max-width: var(--col); margin-inline: auto; padding-inline: clamp(16px, 4vw, 32px); }
.page-head { padding: clamp(40px, 7vh, 88px) 0 clamp(24px, 4vh, 48px); }
section + section, .stack > * + * { margin-top: clamp(48px, 8vh, 96px); }
.hairline { border: 0; border-top: 1px solid var(--rule); }

/* ---------------------------------------------------------------- chrome */
header.site {
  position: sticky; top: 0; z-index: 90;
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
header.site .bar {
  max-width: var(--col); margin-inline: auto;
  padding: 10px clamp(16px, 4vw, 32px);
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
.wordmark {
  display: flex; align-items: center; gap: 10px;
  font-weight: 800; font-size: 15px; letter-spacing: -0.01em;
  font-variation-settings: 'wdth' 118; text-decoration: none; white-space: nowrap;
}
.wordmark:hover { color: inherit; }
.wordmark .dash {
  width: 22px; height: 6px; border-radius: 3px; background: var(--yellow); flex: none;
}
nav.primary { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; }
nav.primary::-webkit-scrollbar { display: none; }
nav.primary a {
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; text-decoration: none;
  color: var(--ink-2); padding: 7px 10px; border-radius: var(--r-chip);
  white-space: nowrap; transition: background 120ms, color 120ms;
}
nav.primary a:hover { color: var(--ink); background: var(--paper-2); }
nav.primary a[aria-current="page"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--yellow); }
.chrome-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; }
#site-search { position: relative; }
#site-search input {
  font-family: var(--font-mono); font-size: 12.5px;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-chip);
  padding: 7px 12px; width: min(220px, 38vw); outline-offset: 0;
}
#site-search input:focus { border-color: var(--cyan-text); }
#search-results {
  position: absolute; top: calc(100% + 6px); right: 0;
  width: min(360px, calc(100vw - 32px)); max-height: 380px; overflow: auto;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: 10px;
  box-shadow: 0 14px 40px rgba(18, 19, 15, .16); display: none; z-index: 120;
}
#search-results.open { display: block; }
#search-results .hit {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 9px 12px; border-bottom: 1px solid var(--rule); text-align: left;
}
#search-results .hit:last-child { border-bottom: 0; }
#search-results .hit:hover, #search-results .hit.active { background: color-mix(in oklab, var(--cyan) 9%, var(--paper-2)); }
#search-results .hit .hn { font-weight: 700; font-size: 14px; }
#search-results .hit .hc { font-size: 11.5px; color: var(--muted); margin-left: auto; white-space: nowrap; }
#theme-toggle {
  width: 34px; height: 34px; border: 1px solid var(--rule); border-radius: var(--r-chip);
  display: grid; place-items: center; color: var(--ink-2); flex: none;
  transition: border-color 120ms, color 120ms;
}
#theme-toggle:hover { border-color: var(--cyan-text); color: var(--cyan-text); }
#theme-toggle .moon { display: none; }
[data-theme="dark"] #theme-toggle .sun { display: none; }
[data-theme="dark"] #theme-toggle .moon { display: block; }

footer.site {
  margin-top: clamp(64px, 10vh, 128px); border-top: 1px solid var(--rule);
  padding: 48px 0 64px; font-size: 14px; color: var(--ink-2);
}
footer.site .fine { margin-top: 24px; font-size: 12.5px; color: var(--muted); max-width: 82ch; }
footer.site .fine + .fine { margin-top: 8px; }
footer.site .bio {
  margin-bottom: 36px; padding-bottom: 32px; border-bottom: 1px solid var(--rule);
}
footer.site .bio-name {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 600;
  letter-spacing: .12em; color: var(--muted);
}
footer.site .bio-text { margin-top: 10px; max-width: var(--measure); line-height: 1.55; }
footer.site .bio-text a { color: var(--cyan-text); }
footer.site .bio-cta { margin-top: 16px; }

/* ---------------------------------------------------------------- pieces */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; text-decoration: none;
  border: 1px solid var(--rule); border-radius: var(--r-chip);
  padding: 9px 14px; background: var(--paper-2); color: var(--ink);
  transition: border-color 120ms, background 120ms, transform 120ms;
}
.btn:hover { border-color: var(--cyan-text); color: var(--ink); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn.primary:hover { border-color: var(--cyan-text); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 600;
  border: 1px solid var(--rule); border-radius: var(--r-pill);
  padding: 4px 11px; background: var(--paper-2); cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
  user-select: none;
}
.chip:hover { border-color: var(--cyan-text); }
.chip[aria-pressed="true"], .chip.on {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.chip .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.card {
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r-card); padding: 20px;
}
.card.ruled { border-top: 6px solid var(--layer, var(--ink)); }
.gold-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--yellow); flex: none; }

.doors { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 16px; margin-top: 32px; }
.door {
  display: flex; flex-direction: column; gap: 8px; min-height: 132px;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-card);
  padding: 18px; text-decoration: none; position: relative; overflow: hidden;
  transition: border-color 120ms, transform 120ms;
}
.door:hover { border-color: var(--cyan-text); color: inherit; transform: translateY(-2px); }
.door .num { font-size: 22px; font-weight: 600; }
.door .dn { font-weight: 800; font-size: 17px; font-variation-settings: 'wdth' 112; }
.door .dd { font-size: 13px; color: var(--muted); line-height: 1.45; }
.door .arrow { position: absolute; right: 16px; top: 16px; color: var(--muted); transition: color 120ms, transform 120ms; }
.door:hover .arrow { color: var(--cyan-text); transform: translateX(2px); }


table.data { border-collapse: collapse; width: 100%; font-size: 14px; }
table.data th {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--ink);
  white-space: nowrap;
}
table.data td { padding: 10px 12px; border-bottom: 1px solid var(--rule); vertical-align: top; }
table.data tr:hover > td { background: color-mix(in oklab, var(--cyan) 5%, transparent); }
.table-scroll { overflow-x: auto; }

.stat-row { display: flex; gap: clamp(20px, 4vw, 48px); flex-wrap: wrap; }
.stat .num { font-size: clamp(26px, min(3vw, 4.6vh), 40px); font-weight: 600; display: block; }
.stat .lbl { font-size: 12.5px; color: var(--muted); }

.note {
  border: 1px solid var(--rule); border-left: 4px solid var(--yellow);
  border-radius: 0 var(--r-card) var(--r-card) 0;
  background: var(--paper-2); padding: 14px 18px; font-size: 14px;
  color: var(--ink-2); max-width: var(--measure);
}
.note.alert { border-left-color: var(--alert); }
.note.live { border-left-color: var(--cyan-text); }

[aria-hidden="true"].decor { pointer-events: none; }
.visually-hidden {
  position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: -1px; /* pinned: an absolute box at its static position inside a wide scrolled table extends the document */
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

@media (max-width: 860px) {
  header.site .bar { gap: 10px; }
  /* The nav wraps into visible rows instead of scrolling off-screen: every
     chapter and its caret is always on the glass, no blind horizontal swipe. */
  nav.primary {
    order: 3; flex-basis: 100%; margin: 0; padding: 0 0 4px;
    flex-wrap: wrap; overflow-x: visible; gap: 2px 4px;
  }
  #site-search input { width: min(180px, 34vw); }
}
/* The hamburger only exists on phones; everywhere else the chapters live on
   the glass. */
.nav-toggle {
  display: none; width: 34px; height: 34px; flex: none;
  border: 1px solid var(--rule); border-radius: var(--r-chip);
  place-items: center; color: var(--ink-2);
  transition: border-color 120ms, color 120ms;
}
.nav-toggle:hover { border-color: var(--cyan-text); color: var(--ink); }
.nav-toggle .ic-close { display: none; }
header.site.nav-open .nav-toggle .ic-menu { display: none; }
header.site.nav-open .nav-toggle .ic-close { display: block; }
@media (max-width: 640px) {
  /* the portrait-phone step for long-form copy: 19px serif reads oversized
     against a 15px wordmark on a 390px screen */
  :root { --fs-lg: 17px; }

  /* One tidy row: wordmark, a search box that takes the slack, the theme
     toggle, and a hamburger. The chapters fold behind the hamburger — and
     unfold as ALL of them at once, every page visible, so nothing on a phone
     is more than one tap past the button. */
  .wordmark { font-size: 13px; }
  header.site .bar { gap: 8px; }
  .nav-toggle { display: grid; }
  .chrome-tools { flex: 1 1 auto; min-width: 0; }
  #site-search { flex: 1 1 0; min-width: 0; }
  #site-search input { width: 100%; min-width: 0; }
  nav.primary { display: none; }
  /* the open state carries the header class, so these outrank the desktop
     dropdown rules that sit later in this file */
  header.site.nav-open nav.primary {
    display: grid; grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(3, auto); grid-auto-flow: column;
    gap: 14px 16px; padding: 12px 2px 16px;
    border-top: 1px solid var(--rule); margin-top: 8px;
  }
  /* each chapter is a group: its name, then every page beneath it — the
     per-chapter dropdowns and their carets have nothing left to hide */
  header.site.nav-open nav.primary .np { display: block; min-width: 0; }
  header.site.nav-open nav.primary .np > a { display: inline-block; padding: 2px 0; }
  header.site.nav-open nav.primary .np-more { display: none; }
  header.site.nav-open nav.primary .np-sub {
    position: static; display: block; min-width: 0; padding: 3px 0 0;
    background: none; border: 0; border-radius: 0; box-shadow: none;
  }
  header.site.nav-open nav.primary .np-sub a { white-space: normal; padding: 4px 0; }
}
@media (max-width: 480px) {
  .doors { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  /* one rule for every hover lift; !important so later page sheets cannot re-lift */
  .door:hover, .op-card:hover, .md-tile:hover { transform: none !important; }
}
@media print {
  header.site, footer.site, #theme-toggle, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ---------------------------------------------------------------- short viewports
   In practice a phone held sideways: plenty of width, very little height. The
   fluid type scale above already stops headings growing here, since every
   clamp tracks the shorter dimension. What is left is vertical rhythm, which
   was tuned for tall screens and wastes the little height available. Body copy
   is deliberately not reduced; it is already at its portrait size, which is
   the size that reads correctly. */
@media (orientation: landscape) and (max-height: 560px) {
  header.site .bar { padding: 6px clamp(12px, 3vw, 24px); gap: 12px; flex-wrap: nowrap; }
  /* The width breakpoint below wraps the nav onto its own row, which costs a
     quarter of a landscape phone's height. There is enough width here to keep
     one row and let the nav scroll instead. */
  nav.primary { order: 0; flex: 1 1 auto; min-width: 0; margin: 0; padding: 0; }
  .chrome-tools { flex: none; }
  #site-search input { width: min(140px, 22vw); }
  .page-head { padding: 24px 0 16px; }
  section + section, .stack > * + * { margin-top: 40px; }
  footer.site { margin-top: 48px; padding: 28px 0 36px; }
  .doors { gap: 12px; }
  .door { min-height: 0; }
}

/* ------------------------------------------------------------- logo tile */
/* A monogram in the layer's colour, with the real mark laid over it once it
   loads. Used on the chart, in the ledger and on every card, so it lives here
   rather than in one surface's stylesheet. */
.mono-tile {
  display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: 10px; color: #fff; font-weight: 800; font-size: 18px;
  background: var(--tile, var(--ink-2));
  position: relative; overflow: hidden;
}
/* Once a real mark mounts it covers the tile completely; the monogram
   letters underneath leave the paint so nothing unreadable sits behind it. */
.mono-tile.has-mark { visibility: hidden; }
.mono-tile.has-mark img { visibility: visible; }
.mono-tile img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; background: #fff; border-radius: inherit;
  opacity: 0; transition: opacity 220ms ease;
}

/* ------------------------------------------------------------- chapters */
/* Sits after the content, where a reader who has finished looks for what is
   next. One deliberate band: six equal columns with a rule between each, so no
   chapter ever wraps alone, and the whole block answers hover — the auto-fit
   grid this replaces fit five columns and orphaned Media on its own row. */
.chapters-wrap { margin-top: clamp(48px, 8vh, 96px); padding-bottom: clamp(32px, 5vh, 56px); }
.chapters { border-top: 1px solid var(--rule); padding-top: 24px; }
.ch-list {
  list-style: none; margin-top: 14px;
  display: grid; grid-template-columns: repeat(6, 1fr);
  border-block: 1px solid var(--rule);
}
.ch {
  min-width: 0; padding: 18px 18px 22px;
  border-left: 1px solid var(--rule);
  transition: background 140ms ease;
}
.ch:first-child { border-left: 0; }
.ch:hover, .ch:focus-within { background: var(--paper-2); }
/* Two equal columns, three rows, when six abreast would not fit. The grid
   fills column-first so the chapters read 01-02-03 down the left and 04-05-06
   down the right, and every cell keeps a rule on each shared edge — one
   divider down the middle, one between every stacked pair. */
@media (max-width: 960px) {
  .ch-list {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(3, auto);
    grid-auto-flow: column;
  }
  .ch { border-left: 0; border-top: 1px solid var(--rule); }
  .ch:nth-child(1), .ch:nth-child(4) { border-top: 0; }
  .ch:nth-child(n+4) { border-left: 1px solid var(--rule); }
}
.ch-head { display: flex; align-items: baseline; gap: 9px; text-decoration: none; }
.ch-n { font-family: var(--font-mono); font-size: 12px; color: var(--muted); flex: none; }
.ch-name { font-size: 17px; font-weight: 700; font-variation-settings: 'wdth' 112; }
.ch.is-here .ch-name { box-shadow: inset 0 -2px 0 var(--yellow); }
.ch.is-here .ch-n { color: var(--ink); }
.ch-pages { list-style: none; margin-top: 8px; display: grid; gap: 4px; }
.ch-pages a {
  font-size: 13.5px; color: var(--muted); text-decoration: none;
  display: inline-block; padding: 1px 0;
}
.ch-pages a:hover { color: var(--cyan-text); }
.ch-pages a[aria-current="page"] { color: var(--ink); }
.ch-pages a[aria-current="page"]::before { content: "▸ "; color: var(--yellow); }

/* --------------------------------------------------- sections, floating */
.secnav {
  /* Parked bottom-left at every width — the reading eye starts on the left, so
     that is where the index lives. */
  position: fixed; z-index: 60; left: 16px; bottom: 16px;
  max-width: min(260px, calc(100vw - 32px));
  background: color-mix(in oklab, var(--paper-2) 92%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--rule); border-radius: var(--r-card);
  box-shadow: 0 10px 30px rgba(18, 19, 15, .12);
  overflow: hidden;
}
.sn-toggle {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 12px; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2);
}
.sn-caret { margin-left: auto; transition: transform 180ms ease; }
.secnav.open .sn-caret { transform: rotate(90deg); }
.sn-body { list-style: none; display: none; padding: 0 12px 12px; max-height: 52vh; overflow: auto; }
.secnav.open .sn-body { display: block; }
.sn-body a {
  display: flex; gap: 9px; align-items: baseline; padding: 4px 0;
  font-size: 13px; color: var(--muted); text-decoration: none; line-height: 1.35;
}
.sn-body a:hover { color: var(--cyan-text); }
.sn-body a[aria-current] { color: var(--ink); }
.sn-n { font-family: var(--font-mono); font-size: 10.5px; flex: none; }
.sn-body a[aria-current] .sn-n { color: var(--yellow); }

@media (min-width: 1800px) {
  .secnav { left: 24px; bottom: 24px; }
}
@media (max-width: 720px) {
  /* full width along the bottom edge, so it never covers the column it indexes */
  .secnav { left: 8px; right: 8px; bottom: 8px; max-width: none; }
}
@media print { .secnav { display: none; } .chapters-wrap { display: none; } }

/* ------------------------------------------------- spoken with directly */
/* The most expensive fact on this site to acquire, so it is spelled out rather
   than hinted at. It used to be a filled yellow pill, which made a label look
   like a button you could press. It is a mark and a word now: the same gold dot
   the chart uses, so the two agree. */
.spoken-bar, .spoken-tag {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-family: var(--font-mono); font-weight: 600; letter-spacing: .1em;
  color: var(--ink-2); background: none; padding: 0; border-radius: 0;
}
.spoken-bar::before, .spoken-tag::before {
  content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--yellow);
}
.spoken-tag { font-size: 9px; }
.spoken-bar { font-size: 10px; margin-top: 10px; }

/* ------------------------------------------------------- company links */
/* A company name that goes somewhere looked different in all four places it was
   rendered: no cue at all on the funding timeline, a muted underline in the
   table and on partnerships, colour with no underline on the map card. One
   treatment now, whether the target is another page or a selection on this one. */
.co-link {
  color: var(--cyan-text); text-decoration: underline; text-underline-offset: 2px;
  text-decoration-color: color-mix(in oklab, var(--cyan) 45%, transparent);
}
.co-link:hover { text-decoration-color: var(--cyan-text); }

/* The leadership links sat an inline-flex box in a run of text, so their
   baseline came from the 13px icon inside rather than from the words around
   them, and every one of them rode high. Inline text with the icon nudged onto
   the text baseline instead. */
a.li svg, .d-site a svg, .cc-site a svg { vertical-align: -2px; margin-right: 4px; }

/* --------------------------------------------------- chapters in the bar */
/* The bar carries the same five chapters as the foot of every page, so the two
   agree. Chapters with more than one page get a disclosure, which is how
   economics/, safety/ and owning-one/ became reachable from anywhere. */
nav.primary .np { position: relative; display: inline-flex; align-items: center; }
nav.primary .np.is-here > a { color: var(--ink); box-shadow: inset 0 -2px 0 var(--yellow); }
/* The caret is a real control, so it reads as one: ink-2 at rest rather than
   near-invisible muted, and enough padding to be a finger target. flex:none
   guards it against ever being the element a squeezed row collapses. */
nav.primary .np-more { padding: 9px 7px; color: var(--ink-2); line-height: 1; flex: none; }
nav.primary .np-more svg { display: block; flex: none; transition: transform 160ms ease; }
nav.primary .np.open .np-more svg { transform: rotate(180deg); }
/* Resting on the chapter is what opens its menu, so the whole item — name and
   caret together — answers the hover in the accent colour. */
nav.primary .np:hover > a,
nav.primary .np.open > a { color: var(--cyan-text); background: var(--paper-2); }
nav.primary .np:hover .np-more,
nav.primary .np.open .np-more { color: var(--cyan-text); }
/* The nav strip scrolls horizontally, and a container that clips one axis clips
   both — an absolutely-positioned menu inside it can never be seen. So the menu
   is fixed to the viewport instead, and core.js places it under its button. */
nav.primary .np-sub {
  position: fixed; z-index: 200; display: none;
  min-width: 190px; padding: 6px; list-style: none;
  background: var(--paper-2); border: 1px solid var(--rule);
  border-radius: var(--r-card); box-shadow: 0 12px 30px rgba(18, 19, 15, .14);
}
nav.primary .np.open .np-sub { display: block; }
nav.primary .np-sub a {
  display: block; padding: 6px 9px; border-radius: var(--r-chip);
  font-family: var(--font-display); font-size: 12.5px; letter-spacing: 0;
  text-transform: none; color: var(--ink-2); white-space: nowrap;
}
nav.primary .np-sub a:hover { background: var(--paper); color: var(--ink); }
nav.primary .np-sub a[aria-current="page"] { color: var(--ink); }
nav.primary .np-sub a[aria-current="page"]::before { content: "▸ "; color: var(--yellow); }
