/* ==========================================================================
   Global Distillation — application stylesheet
   Light mode only. Tokens per DESIGN.md §2, components per DESIGN.md §4.

   CLASS INVENTORY (the contract other modules render against)
   --------------------------------------------------------------------------
   Shell      .nav .nav__inner .nav__brand .nav__mark .nav__word .nav__links
              .nav__link .nav__actions .nav__search .nav__kbd .nav__menu
              .shell .rail .rail__heading .rail__list .rail__item .rail__num
              .rail__text .rail__name .rail__sub .rail__foot .rail__pulse
              .rail__scrim .main .view .skip-link
   Sections   .section .section__head .section__eyebrow .section__title
              .section__standfirst .section__meta .section__aside
              .eyebrow .eyebrow__dot
   Layout     .grid .grid--2 .grid--3 .grid--4 .span-3 .span-4 .span-6 .span-8
              .span-12 .split .cluster .stack
   Hero       .hero .hero__copy .hero__title .hero__standfirst .hero__actions
              .hero__facts .hero__figure .hero__canvas .hero__legend
              .hero__key .hero__swatch
   Figures    .kpi-row .kpi .kpi__label .kpi__figure(.kpi__value) .kpi__unit
              .kpi__delta(--up --down --flat --good --bad) .kpi__source
   Surfaces   .panel .panel__head .panel__title .panel__sub .panel__unit
              .panel__tools .panel__body .panel__chart .panel__note
              .panel__sources .panel__foot .chart .chart--tall .chart--short
   Controls   .btn .btn--primary .btn--ghost .btn--link .btn--sm .btn--icon
              .seg .seg__btn .chips .chip .chip__count .chip__dot
              .field .field__input .field__label .select
   Data       .table-wrap .table .table__sort .table__caption .table__source
              .table--zebra .num .cell-bar .cell-bar__track .cell-bar__fill
   Content    .card-grid .card .card__eyebrow .card__title .card__desc
              .card__more .method-grid .method-card .method-card__top
              .method-card__family .method-card__name .method-card__desc
              .method-card__foot .dots .dots i .badge(--good --bad --warn
              --info --accent --neutral) .callout(--bad --good --warn --info)
              .quote .quote__source .findings .finding .finding__title
              .finding__detail .sources .source .source__title .source__meta
              .footnote .glossary .empty .empty__title .empty__text
              .signals .signal .signal__label .signal__figure .newslist
   Timeline   .timeline .timeline__legend .timeline__item .timeline__year
              .timeline__marker .timeline__dot .timeline__date .timeline__title
              .timeline__detail .timeline__source .cat--research/product/
              market/policy/legal
   Overlays   .drawer .drawer__scrim .drawer__panel .drawer__close
              .drawer__body .drawer__eyebrow .drawer__lede .drawer__section
              .formula .proscons .proscons__col .related
              .palette .palette__scrim .palette__panel .palette__input
              .palette__list .palette__group .palette__item .palette__label
              .palette__type .palette__hint .palette__empty
   States     .is-active .is-open .is-locked .is-hidden .skeleton
              .skeleton--page .skeleton--text .skeleton--chart .sr-only
   ========================================================================== */

/* ==========================================================================
   1. Tokens (DESIGN.md §2, verbatim)
   ========================================================================== */

:root {
  color-scheme: light;

  /* Surfaces — warm paper (A) over cool white (C) */
  --paper:      #FAF8F4;   /* page ground */
  --surface:    #FFFFFF;   /* cards, panels, table body */
  --surface-2:  #F3F0EA;   /* subtle fills, zebra, skeletons */
  --surface-3:  #EBE6DC;   /* pressed states, chart plot bands */
  --rule:       #E4DED2;   /* hairlines */
  --rule-strong:#CEC6B6;   /* table header underline, dividers that must read */

  /* Ink */
  --ink:        #1A1814;   /* headlines, table figures */
  --ink-2:      #4C4740;   /* body */
  --ink-3:      #6B655C;   /* labels, captions, axis text: 5.6:1 on surface, 5.3:1 on paper */
  --ink-4:      #B2AA9D;   /* disabled, gridline labels */

  /* Accent — burnt sienna, used sparingly */
  --accent:     #B5451B;
  --accent-ink: #8E3412;   /* accent text on paper: 5.9:1 */
  --accent-soft:#F6E5DC;

  /* Categorical — 8 slots. Adjacent pairs separate under deuteranopia and
     protanopia; every slot >= 3:1 against --surface and --paper. */
  --cat-1: #B5451B;  /* OpenAI      */
  --cat-2: #1F6A99;  /* DeepSeek    */
  --cat-3: #2E7D53;  /* Google      */
  --cat-4: #9A6C10;  /* Anthropic   */
  --cat-5: #6B4FA8;  /* Meta        */
  --cat-6: #A8324E;  /* Alibaba     */
  --cat-7: #3F6470;  /* Microsoft   */
  --cat-8: #7A6A57;  /* Other/open  */

  /* Sequential (single-hue, light to dark) — use for magnitude only */
  --seq-1: #F2E6DE; --seq-2: #E2C4B3; --seq-3: #CE9E85;
  --seq-4: #B87759; --seq-5: #9E5433; --seq-6: #7C3A17;

  /* Diverging (teacher-favouring <-> student-favouring), midpoint neutral */
  --div-neg-2:#8E3412; --div-neg-1:#CE9E85; --div-mid:#EFEAE1;
  --div-pos-1:#7FA8B8; --div-pos-2:#1F6A99;

  /* Semantic — always paired with an icon or a word, never colour alone */
  --good:#2E7D53; --good-soft:#E4F0E8;
  --bad:#B23127;  --bad-soft:#FAE6E3;
  --warn:#9A6C10; --warn-soft:#F7EDD8;
  --info:#1F6A99; --info-soft:#E4EEF4;

  /* Type */
  --serif: "Newsreader", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans:  "Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --mono:  "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Type scale (px, 1.25 ratio off a 15px body) */
  --fs-display: 56px;  --lh-display: 1.04;
  --fs-h1:      40px;  --lh-h1:      1.10;
  --fs-h2:      28px;  --lh-h2:      1.18;
  --fs-h3:      20px;  --lh-h3:      1.25;
  --fs-body:    15px;  --lh-body:    1.55;
  --fs-small:   13px;  --lh-small:   1.45;
  --fs-micro:   11px;  --lh-micro:   1.30;  /* eyebrows, footnotes, axis */
  --fs-figure:  34px;                        /* KPI numbers */

  /* Spacing — 4px base */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px;

  /* Radii */
  --r-sm:4px; --r-md:6px; --r-lg:10px; --r-pill:999px;

  /* Shadows — hairline first, shadow second */
  --shadow-flat: 0 0 0 1px var(--rule);
  --shadow-card: 0 1px 2px rgba(26,24,20,.05), 0 0 0 1px var(--rule);
  --shadow-pop:  0 12px 40px rgba(26,24,20,.16), 0 0 0 1px var(--rule);

  /* Layout */
  --rail-w: 236px;
  --container: 1320px;
  --gutter: 32px;
  --nav-h: 60px;

  /* Z */
  --z-nav:100; --z-rail:90; --z-drawer:200; --z-palette:300; --z-toast:400;

  /* Motion */
  --dur-fast:120ms; --dur-mid:200ms; --dur-slow:320ms;
  --ease: cubic-bezier(.2,.6,.25,1);
}

/* Derived values — never override a DESIGN token, only compose from them. */
:root {
  --zebra:      #FBFAF7;              /* --surface-2 at 40% over --surface   */
  --scrim:      rgba(26,24,20,.34);
  --rail-gap:   var(--s-7);           /* rail -> content column separation   */
  --kpi-figure: clamp(26px, 2.1vw, var(--fs-figure));
  --tap:        40px;                 /* minimum comfortable hit target      */
}

/* ==========================================================================
   2. Reset and base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;               /* never a horizontal page scrollbar */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding-top: var(--nav-h);
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4, h5, h6, p, dl, dd, figure, blockquote, pre { margin: 0; }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  color: var(--ink);
  letter-spacing: -0.012em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}
button { background: none; border: 0; padding: 0; cursor: pointer; }

img, svg, canvas { display: block; max-width: 100%; }
svg { flex: none; }

table { border-collapse: separate; border-spacing: 0; }

kbd {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: 1;
  color: var(--ink-3);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 3px 5px;
  white-space: nowrap;
}

code, samp { font-family: var(--mono); font-size: .92em; }

hr { border: 0; border-top: 1px solid var(--rule); margin: var(--s-6) 0; }

::selection { background: var(--accent-soft); color: var(--ink); }

[hidden] { display: none !important; }

:target { scroll-margin-top: calc(var(--nav-h) + var(--s-5)); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* ==========================================================================
   3. Utilities
   ========================================================================== */

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed;
  top: var(--s-2);
  left: var(--s-2);
  z-index: calc(var(--z-toast) + 1);
  transform: translateY(calc(-100% - var(--s-4)));
  background: var(--ink);
  color: var(--paper);
  font-size: var(--fs-small);
  font-weight: 500;
  padding: 10px 16px;
  border-radius: var(--r-md);
  transition: transform var(--dur-fast) var(--ease);
}
.skip-link:focus { transform: none; outline-offset: 3px; box-shadow: var(--shadow-pop); }

.num,
.mono {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.num { text-align: right; }

.dim  { color: var(--ink-3); }
.note { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink-3); }

.is-hidden { display: none !important; }

.stack   { display: flex; flex-direction: column; gap: var(--s-4); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.split   { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-5); }

/* 12-column grid (DESIGN §3) */
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-5);
}
.span-3  { grid-column: span 3; min-width: 0; }
.span-4  { grid-column: span 4; min-width: 0; }
.span-6  { grid-column: span 6; min-width: 0; }
.span-8  { grid-column: span 8; min-width: 0; }
.span-12 { grid-column: span 12; min-width: 0; }

.grid--2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); }
.grid--3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5); }
.grid--4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5); }

/* ==========================================================================
   4. Top navigation (fixed, 60px)
   ========================================================================== */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-nav);
  height: var(--nav-h);
  background: rgba(250, 248, 244, .88);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--rule);
}

.nav__inner {
  height: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--s-5);
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex: none;
  color: var(--ink);
  border-radius: var(--r-sm);
}
.nav__mark { color: var(--accent); }
.nav__word {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 20px;
  line-height: 1;
  letter-spacing: -0.015em;
  white-space: nowrap;
}
.nav__word em { font-style: italic; color: var(--ink-2); margin-left: 3px; }

.nav__links {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 20px), transparent 100%);
}
.nav__links::-webkit-scrollbar { display: none; }

.nav__link {
  position: relative;
  flex: none;
  padding: 8px 9px;
  border-radius: var(--r-sm);
  font-size: var(--fs-small);
  line-height: 1;
  color: var(--ink-3);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.nav__link:hover { color: var(--ink); background: var(--surface-2); }
.nav__link.is-active { color: var(--ink); font-weight: 500; }
.nav__link.is-active::after {
  content: "";
  position: absolute;
  left: 9px; right: 9px;
  bottom: -10px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
}

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: none;
  margin-left: auto;
}

.nav__search {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink-3);
  font-size: var(--fs-small);
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav__search:hover { border-color: var(--ink-4); color: var(--ink-2); }
.nav__search span { white-space: nowrap; }
.nav__kbd {
  font-size: 10.5px;
  padding: 2px 5px;
  background: var(--surface-2);
  border-color: var(--rule);
  color: var(--ink-3);
}

.nav__menu {
  display: none;
  width: 34px; height: 34px;
  align-items: center; justify-content: center;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink-2);
}
.nav__menu:hover { background: var(--surface-2); color: var(--ink); }

/* ==========================================================================
   5. Shell, rail, main
   ========================================================================== */

.shell {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  column-gap: var(--rail-gap);
  align-items: start;
}

.rail {
  position: sticky;
  top: var(--nav-h);
  align-self: start;
  height: calc(100vh - var(--nav-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-6) var(--s-4) var(--s-6) 0;
  border-right: 1px solid var(--rule);
  scrollbar-width: thin;
}

.rail__heading {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 0 var(--s-3) var(--s-3);
}
.rail__heading--ref { margin-top: var(--s-6); }

.rail__list { display: flex; flex-direction: column; gap: 1px; }

.rail__item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s-2);
  padding: 9px var(--s-3);
  border-left: 2px solid transparent;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.rail__item:hover { background: var(--surface-2); }
.rail__item.is-active {
  background: var(--surface);
  border-left-color: var(--accent);
  box-shadow: var(--shadow-flat);
}

.rail__num {
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.4;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.rail__item.is-active .rail__num { color: var(--accent-ink); }

.rail__text { display: block; min-width: 0; }
.rail__name {
  display: block;
  font-size: 14px;
  line-height: 1.25;
  color: var(--ink-2);
  font-weight: 500;
}
.rail__item.is-active .rail__name { color: var(--ink); }
.rail__sub {
  display: block;
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  color: var(--ink-3);
  margin-top: 3px;
}

.rail__foot {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  margin-top: var(--s-6);
  padding: var(--s-4) var(--s-3) 0;
  border-top: 1px solid var(--rule);
  font-size: var(--fs-micro);
  line-height: 1.5;
  color: var(--ink-3);
}
.rail__pulse {
  position: relative;
  flex: none;
  width: 7px; height: 7px;
  margin-top: 4px;
  border-radius: 50%;
  background: var(--good);
}
.rail__pulse::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid var(--good);
  animation: gd-pulse 2.6s ease-out infinite;
}
@keyframes gd-pulse {
  0%   { transform: scale(.5); opacity: .7; }
  100% { transform: scale(1.4); opacity: 0; }
}

.rail__scrim {
  position: fixed;
  inset: var(--nav-h) 0 0 0;
  z-index: calc(var(--z-rail) - 1);
  background: var(--scrim);
  animation: gd-fade var(--dur-mid) var(--ease);
}

.main {
  min-width: 0;
  padding: var(--s-6) 0 0;
}
.main:focus { outline: none; }

.view { min-height: 40vh; }

/* ==========================================================================
   6. Section rhythm
   ========================================================================== */

.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.eyebrow__dot {
  width: 6px; height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
}

.section { padding-top: 0; }
.section + .section { margin-top: var(--s-9); }
.view > .section:first-child { margin-top: var(--s-2); }

.section__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  /* The meta stamp reads as a masthead detail beside the eyebrow, not as a
     block stranded halfway down a long standfirst. */
  align-items: start;
  gap: var(--s-5);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--rule-strong);
  margin-bottom: var(--s-6);
}
.section__head > :only-child { grid-column: 1 / -1; }

.section__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(28px, 3.2vw, var(--fs-h1));
  line-height: var(--lh-h1);
  letter-spacing: -0.018em;
  color: var(--ink);
  margin-top: var(--s-3);
}

.section__standfirst {
  max-width: 68ch;
  margin-top: var(--s-3);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* Standfirst continuation: the second and later sentences of a long summary,
   set one step down so the opening sentence still carries the section. */
.section__standfirst--rest {
  margin-top: var(--s-2);
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--ink-3);
}
.section__lede {
  max-width: 68ch;
  margin-top: var(--s-3);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
}

.section__meta {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--ink-3);
  text-align: right;
  white-space: nowrap;
  line-height: 1.65;
  padding-top: 2px;
}
.section__aside { font-size: var(--fs-small); color: var(--ink-3); }

/* Sub-headings inside a rendered section */
.h2, .view h2:not(.section__title):not(.panel__title) {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  margin-bottom: var(--s-4);
}
.h3, .view h3:not(.panel__title):not(.method-card__name):not(.timeline__title):not(.card__title) {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
}

/* Every block heading inside a rendered section opens a new movement, so the
   rhythm above one is the same wherever it appears. */
.section > .subhead { margin-top: var(--s-8); }

.subhead {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s-4);
}

/* ==========================================================================
   7. Hero
   ========================================================================== */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--s-7);
  padding: var(--s-6) 0 var(--s-8);
  border-bottom: 1px solid var(--rule-strong);
  margin-bottom: var(--s-8);
}

.hero__copy { min-width: 0; }

.hero__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(34px, 3.5vw, var(--fs-display));
  line-height: var(--lh-display);
  letter-spacing: -0.024em;
  color: var(--ink);
  margin-top: var(--s-4);
  text-wrap: balance;
}
.hero__title em { font-style: italic; color: var(--accent-ink); }

.hero__standfirst {
  max-width: 56ch;
  margin-top: var(--s-5);
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--ink-2);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-5);
  margin-top: var(--s-6);
}

.hero__facts {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--s-5);
  margin-top: var(--s-7);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}
.hero__facts:empty { display: none; }
.hero__facts > div,
.hero__facts .hero__fact { min-width: 0; }
.hero__facts > * + * { border-left: 1px solid var(--rule); padding-left: var(--s-5); }
.hero__facts dt {
  font-size: var(--fs-micro);
  line-height: 1.4;
  letter-spacing: .04em;
  color: var(--ink-3);
  min-height: 2.8em;
}
.hero__facts dd {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 5px;
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 26px;
  line-height: 1.14;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-top: 6px;
  font-variant-numeric: tabular-nums lining-nums;
}
.hero__facts dd small,
.hero__facts dd .unit {
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.35;
  letter-spacing: 0;
  color: var(--ink-3);
  white-space: nowrap;
}

.hero__figure { min-width: 0; margin: 0; }

.hero__canvas {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;          /* explicit: no reflow when Three.js mounts */
  max-height: 520px;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  background:
    radial-gradient(72% 66% at 50% 46%, #FFFFFF 0%, rgba(255,255,255,0) 100%),
    var(--surface-2);
}
.hero__canvas canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

.hero__legend:empty { display: none; }
.hero__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  margin-top: var(--s-3);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink-3);
}
.hero__key {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
}
.hero__key b, .hero__key strong,
.hero__key-name { color: var(--ink-2); font-weight: 500; }
.hero__key-value { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--ink-2); }
.hero__key-sub { color: var(--ink-3); }
.hero__swatch {
  width: 8px; height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--ink-4);
}
.hero__swatch--teacher { background: var(--ink-4); }
.hero__swatch--signal  { background: var(--accent); }
.hero__swatch--student { background: var(--cat-2); }

/* ==========================================================================
   8. Buttons, chips, segmented control, fields
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  height: 36px;
  padding: 0 15px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.btn--primary { background: var(--ink); color: var(--paper); }
.btn--primary:hover { background: #2E2A24; }
.btn--primary:active { background: #100F0C; }

.btn--ghost {
  border-color: var(--rule-strong);
  background: var(--surface);
  color: var(--ink-2);
}
.btn--ghost:hover { background: var(--surface-2); color: var(--ink); border-color: var(--ink-4); }

.btn--link {
  height: auto;
  padding: 0;
  color: var(--accent-ink);
  border-radius: 2px;
  border-bottom: 1px solid transparent;
}
.btn--link::after { content: "→"; font-family: var(--sans); transition: transform var(--dur-fast) var(--ease); }
.btn--link:hover { border-bottom-color: currentColor; }
.btn--link:hover::after { transform: translateX(2px); }

.btn--sm { height: 30px; padding: 0 11px; font-size: 12.5px; }
.btn--icon { width: 34px; height: 34px; padding: 0; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* Chips ------------------------------------------------------------------ */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-2);
  font-size: 12.5px;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.chip:hover { border-color: var(--ink-4); color: var(--ink); }
.chip[aria-pressed="true"],
.chip.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 500;
}
.chip__count {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.chip[aria-pressed="true"] .chip__count,
.chip.is-active .chip__count { color: var(--accent-ink); opacity: .75; }
.chip__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-4); flex: none; }

/* Segmented control ------------------------------------------------------ */

.seg {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--surface-2);
  max-width: 100%;
  /* As a flex item it would otherwise refuse to shrink below its content and
     push its last tab out past the panel edge on a narrow screen. */
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.seg::-webkit-scrollbar { display: none; }

.seg__btn {
  flex: none;
  padding: 6px 12px;
  border-radius: var(--r-sm);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--ink-3);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.seg__btn:hover { color: var(--ink); }
.seg__btn[aria-selected="true"],
.seg__btn.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}

/* Fields ----------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field__label {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field__input, .select, input[type="search"], input[type="text"]:not(.palette__input), select {
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-small);
  min-width: 0;
}
.field__input::placeholder, input::placeholder { color: var(--ink-4); }
.field__input:hover, .select:hover { border-color: var(--ink-4); }

/* ==========================================================================
   9. KPI tiles
   ========================================================================== */

.kpi-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-3);
  margin-bottom: var(--s-6);
}

.kpi {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-width: 0;
  padding: var(--s-4) var(--s-4) var(--s-3);
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

.kpi__label {
  font-size: var(--fs-small);
  line-height: 1.35;
  color: var(--ink-3);
  overflow-wrap: break-word;
}

.kpi__figure,
.kpi__value {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--kpi-figure);
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  /* Figures must never be clipped: a truncated number is a wrong number.
     Long values wrap and, past a length, step down a size instead. */
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.kpi__figure:has(.kpi__unit) { display: block; }
.kpi[data-len="long"] .kpi__figure,
.kpi[data-len="long"] .kpi__value { font-size: calc(var(--kpi-figure) * 0.76); }
.kpi[data-len="xlong"] .kpi__figure,
.kpi[data-len="xlong"] .kpi__value { font-size: calc(var(--kpi-figure) * 0.6); letter-spacing: -0.02em; }

.kpi__unit {
  font-family: var(--sans);
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-3);
  margin-left: 5px;
  white-space: nowrap;
}

.kpi__delta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: fit-content;
  max-width: 100%;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--ink-2);
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}
.kpi__delta--up,   .kpi__delta--good { background: var(--good-soft); color: var(--good); }
.kpi__delta--down, .kpi__delta--bad  { background: var(--bad-soft);  color: var(--bad); }
.kpi__delta--warn { background: var(--warn-soft); color: var(--warn); }
.kpi__delta--flat { background: var(--surface-2); color: var(--ink-3); }
.kpi__delta--up::before   { content: "\2191"; }
.kpi__delta--down::before { content: "\2193"; }
.kpi__delta--flat::before { content: "\2192"; }

.kpi__source,
.kpi__note {
  font-size: var(--fs-micro);
  line-height: 1.4;
  color: var(--ink-3);
  margin-top: auto;
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
}
.kpi__source a { color: var(--ink-3); border-bottom: 1px solid var(--rule-strong); }
.kpi__source a:hover { color: var(--accent-ink); border-color: var(--accent); }

/* ==========================================================================
   10. Panels and charts
   ========================================================================== */

.panel {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;               /* keeps table scroll inside the panel */
  min-width: 0;
}
.panel + .panel { margin-top: var(--s-5); }

.panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.panel__head > .seg,
.panel__head > .panel__tools { margin-left: auto; }

.panel__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: 21px;
  line-height: 1.25;
  letter-spacing: -0.012em;
  color: var(--ink);
  min-width: 0;
  flex: 1 1 320px;
}
.panel__sub {
  flex-basis: 100%;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-3);
  margin-top: -4px;
  max-width: 78ch;
}
.panel__unit {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
  margin-left: auto;
}
/* min-width:0 so a long segmented control scrolls inside itself instead of
   stretching the head past the panel edge. */
.panel__tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); min-width: 0; max-width: 100%; }
.panel__head > * { min-width: 0; }

.panel__body { padding: var(--s-5); min-width: 0; }
.panel__body--flush { padding: 0; }

.panel__note,
.panel__sources,
.panel__foot {
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--rule);
  background: color-mix(in srgb, var(--surface-2) 45%, var(--surface));
  font-size: var(--fs-micro);
  line-height: 1.5;
  color: var(--ink-3);
}
.panel__note + .panel__sources { border-top: 1px solid var(--rule); }
.panel__sources a, .panel__note a {
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule-strong);
}
.panel__sources a:hover, .panel__note a:hover { color: var(--accent-ink); border-color: var(--accent); }
.panel__sources ol, .panel__sources ul { display: flex; flex-wrap: wrap; gap: 4px var(--s-3); }

.chart {
  width: 100%;
  height: 400px;
  min-width: 0;
}
.chart--short { height: 280px; }
.chart--tall  { height: 520px; }
.panel__chart { width: 100%; height: 400px; min-width: 0; }

/* A run of panels inside one section. */
.panel-stack { display: grid; gap: var(--s-5); }
.panel-stack + .panel-stack { margin-top: var(--s-5); }
.panel-stack--live { margin-top: var(--s-5); }

/* One tab pane of a segmented chart panel; only the selected pane is shown. */
.panel__pane { min-width: 0; }
.panel__pane[hidden] { display: none !important; }

/* Direct-label legend beneath a chart (DESIGN §6: legends only when four or
   more series overlap). */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin: 0;
}
.legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  color: var(--ink-2);
}
.legend__dot {
  width: 9px; height: 9px;
  flex: none;
  border-radius: 50%;
  display: inline-block;
}

/* ==========================================================================
   11. Tables
   ========================================================================== */

.table-wrap {
  position: relative;
  max-height: min(70vh, 660px);
  overflow: auto;                 /* horizontal scroll stays inside the panel */
  overscroll-behavior-x: contain;
  background:
    linear-gradient(to right, var(--surface) 40%, rgba(255,255,255,0)) 0 0 / 32px 100% no-repeat local,
    linear-gradient(to left,  var(--surface) 40%, rgba(255,255,255,0)) 100% 0 / 32px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,   rgba(26,24,20,.16), rgba(26,24,20,0)) 0 0 / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(26,24,20,.16), rgba(26,24,20,0)) 100% 0 / 14px 100% no-repeat scroll,
    var(--surface);
}
.table-wrap--auto { max-height: none; }

.table {
  width: 100%;
  min-width: 100%;
  font-size: 13.5px;
  background: transparent;
  table-layout: auto;
}
.table caption {
  caption-side: top;
  position: sticky;
  left: 0;
  text-align: left;
  padding: var(--s-3) var(--s-5) var(--s-4);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-3);
}
.table__caption {
  padding: var(--s-3) var(--s-5) var(--s-4);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-3);
  max-width: 88ch;
}

.table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--rule-strong);
  text-align: left;
  vertical-align: bottom;
  font-family: var(--sans);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 11px var(--s-3);
  white-space: nowrap;
}
.table thead th:first-child { padding-left: var(--s-5); }
.table thead th:last-child  { padding-right: var(--s-5); }

.table th .th__unit,
.table th small {
  display: block;
  flex: 0 0 100%;
  order: 2;
  font-family: var(--mono);
  font-size: 9.5px;
  line-height: 1.4;
  letter-spacing: .04em;
  text-transform: none;
  color: var(--ink-4);
  font-weight: 400;
  margin-top: 1px;
}

.table__sort,
.table th button {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 6px;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
  border-radius: 2px;
  text-align: inherit;
}
.table__sort::after,
.table th button::after {
  content: "";
  order: 1;
  width: 0; height: 0;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  border-top: 5px solid var(--ink-4);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.table th:hover button::after { opacity: .55; }
.table th[aria-sort="ascending"]  button,
.table th[aria-sort="descending"] button { color: var(--ink); }
.table th[aria-sort="ascending"]  button::after { opacity: 1; border-top-color: var(--accent); transform: rotate(180deg); }
.table th[aria-sort="descending"] button::after { opacity: 1; border-top-color: var(--accent); }
.table th[aria-sort="ascending"], .table th[aria-sort="descending"] { color: var(--ink-2); }

.table td {
  padding: 11px var(--s-3);
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  color: var(--ink-2);
  line-height: 1.45;
}
.table td:first-child { padding-left: var(--s-5); color: var(--ink); font-weight: 500; }
.table th:first-child, .table td:first-child { min-width: 180px; }
.table td:last-child  { padding-right: var(--s-5); }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }

.table td small,
.table .cell__sub {
  display: block;
  font-size: var(--fs-micro);
  line-height: 1.35;
  font-weight: 400;
  color: var(--ink-3);
  margin-top: 2px;
}

.table th.num, .table td.num,
.table th[data-type="number"], .table td[data-type="number"] {
  text-align: right;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  white-space: nowrap;
  width: 1%;                       /* shrink to content; text columns take the rest */
  min-width: 0;
}
.table th.num, .table th[data-type="number"] { font-family: var(--sans); }
.table th.num button, .table th[data-type="number"] button { justify-content: flex-end; }
.table th.num .th__unit, .table th[data-type="number"] .th__unit { text-align: right; }
.table td.num { color: var(--ink); }

.table--zebra tbody tr:nth-child(even) td { background: var(--zebra); }
.table--zebra tbody tr:nth-child(even):hover td { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }

.table td.dim { color: var(--ink-3); font-weight: 400; }
.table a { border-bottom: 1px solid var(--rule-strong); }
.table a:hover { color: var(--accent-ink); border-color: var(--accent); }

.table__empty td {
  text-align: center;
  color: var(--ink-3);
  padding: var(--s-8) var(--s-5);
  font-size: var(--fs-small);
}

.table__source,
.table__foot {
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--rule);
  background: color-mix(in srgb, var(--surface-2) 45%, var(--surface));
  font-size: var(--fs-micro);
  line-height: 1.5;
  color: var(--ink-3);
}

/* Row count shown in the caption once a filter chip narrows a table. */
.table__count {
  display: inline-block;
  margin-left: var(--s-2);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* Winning cell in the compare builder. Colour is never the only signal: the
   column header states which direction is better. */
.table--compare td.is-best { color: var(--accent-ink); font-weight: 600; }

/* in-cell magnitude bar */
.cell-bar { display: inline-flex; align-items: center; gap: var(--s-2); justify-content: flex-end; }
.cell-bar__track { width: 64px; height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; flex: none; }
.cell-bar__fill  { display: block; height: 100%; background: var(--accent); border-radius: 2px; }

/* ==========================================================================
   12. Cards, method cards, badges, callouts
   ========================================================================== */

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4);
}

.card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-width: 0;
  padding: var(--s-5);
  text-align: left;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
a.card:hover, button.card:hover {
  box-shadow: 0 4px 14px rgba(26,24,20,.07), 0 0 0 1px var(--rule-strong);
}
.card__eyebrow {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.card__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 400;
  color: var(--ink);
}
.card__desc { font-size: var(--fs-small); line-height: 1.5; color: var(--ink-2); flex: 1; }
.card__more { font-size: var(--fs-small); font-weight: 500; color: var(--accent-ink); margin-top: var(--s-2); }
.card__more::after { content: " →"; }

/* Method cards ----------------------------------------------------------- */

.method-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4);
}

.method-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  width: 100%;
  min-width: 0;
  min-height: 220px;
  padding: var(--s-5);
  text-align: left;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: box-shadow var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.method-card:hover {
  background: #FFFDFA;
  box-shadow: 0 4px 14px rgba(26,24,20,.08), 0 0 0 1px var(--rule-strong);
}

.method-card__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }

.method-card__family {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
  min-width: 0;
}
.method-card__family i,
.method-card__family .chip__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--cat-8); flex: none; }

.method-card__name {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.method-card__desc { font-size: var(--fs-small); line-height: 1.5; color: var(--ink-2); flex: 1; }
.method-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  padding-top: var(--s-3);
  border-top: 1px solid var(--rule);
}

.dots { display: inline-flex; gap: 3px; flex: none; }
.dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--surface-3); display: block; }
.dots i.on, .dots i.is-on { background: var(--ink-2); }

/* Family hues (stable across the site) */
.fam--logit,   .cat--logit   { --fam: var(--cat-1); }
.fam--feature, .cat--feature { --fam: var(--cat-2); }
.fam--data,    .cat--data    { --fam: var(--cat-3); }
.fam--relation,.cat--relation{ --fam: var(--cat-4); }
.fam--self,    .cat--self    { --fam: var(--cat-5); }
.fam--other,   .cat--other   { --fam: var(--cat-8); }
.method-card__family i { background: var(--fam, var(--cat-8)); }

.method-card__year {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.method-card__difficulty { font-size: var(--fs-micro); color: var(--ink-3); }
.method-card__badges { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }

/* Library filter bar ----------------------------------------------------- */

/* Not sticky: three rows of chips would pin roughly a third of the viewport
   and the grid would scroll visibly under its edge. */
.lib-controls {
  padding: 0 0 var(--s-4);
  border-bottom: 1px solid var(--rule);
  margin: 0 0 var(--s-5);
}
.lib-controls .field { max-width: 420px; }
.lib-filters { display: grid; gap: var(--s-2); margin-top: var(--s-4); }
.lib-filter { display: flex; gap: var(--s-4); align-items: baseline; flex-wrap: wrap; }
.lib-filter__label {
  flex: 0 0 104px;
  padding-top: 7px;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: 1.3;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.lib-chips { display: flex; gap: var(--s-2); flex-wrap: wrap; flex: 1 1 auto; margin: 0; }
.lib-chips .chip__dot { background: var(--fam, var(--ink-4)); }
.lib-count {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-3);
  margin: var(--s-4) 0 0;
}
.lib-count strong { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.lib-count__sep { color: var(--ink-4); padding: 0 7px; }
.lib-reset {
  font-size: var(--fs-small);
  line-height: 1.5;
  font-weight: 500;
  color: var(--accent-ink);
  border-bottom: 1px solid var(--accent-soft);
}
.lib-reset:hover { border-bottom-color: var(--accent); }
.lib-note { margin-top: var(--s-6); font-size: var(--fs-micro); line-height: 1.5; color: var(--ink-3); }
.lib-empty-actions { margin-top: var(--s-3); }

/* Badges ----------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px;
  border-radius: var(--r-sm);
  font-family: var(--sans);
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  background: var(--surface-2);
  color: var(--ink-2);
  white-space: nowrap;
}
.badge--good    { background: var(--good-soft); color: var(--good); }
.badge--bad     { background: var(--bad-soft);  color: var(--bad); }
.badge--warn    { background: var(--warn-soft); color: var(--warn); }
.badge--info    { background: var(--info-soft); color: var(--info); }
.badge--accent  { background: var(--accent-soft); color: var(--accent-ink); }
.badge--neutral { background: var(--surface-2); color: var(--ink-3); }

/* Callouts and quotes ---------------------------------------------------- */

.callout {
  background: var(--surface-2);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  padding: var(--s-4) var(--s-5);
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink-2);
}
.callout p + p { margin-top: var(--s-3); }
.callout__title {
  font-family: var(--sans);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s-2);
}
.callout--bad  { background: var(--bad-soft);  border-left-color: var(--bad);  color: #7A241C; }
.callout--good { background: var(--good-soft); border-left-color: var(--good); }
.callout--warn { background: var(--warn-soft); border-left-color: var(--warn); }
.callout--info { background: var(--info-soft); border-left-color: var(--info); }
.callout--bad .callout__title { color: var(--bad); }

.quote {
  background: var(--surface-2);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  padding: var(--s-5);
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 19px;
  line-height: 1.45;
  color: var(--ink);
}
.quote__source {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--sans);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--ink-3);
}

/* Findings --------------------------------------------------------------- */

.findings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5) var(--s-7);
}
.finding {
  min-width: 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule-strong);
}
.finding__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  line-height: 1.25;
  font-weight: 400;
  color: var(--ink);
}
.finding__detail { font-size: var(--fs-small); line-height: 1.55; color: var(--ink-2); margin-top: var(--s-2); }
.finding__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-top: var(--s-3);
  font-size: var(--fs-micro); color: var(--ink-3);
}

/* Standfirst line under a .subhead block heading. */
.note--lede {
  margin: calc(-1 * var(--s-2)) 0 var(--s-4);
  max-width: 78ch;
  line-height: 1.55;
}

/* Long-form explanatory copy (methodology, panel commentary). */
.prose { display: grid; gap: var(--s-6); max-width: 74ch; }
.prose__block > p { margin-top: var(--s-3); }
.prose__block > p:first-of-type { margin-top: var(--s-2); }
.prose__head {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 400;
  color: var(--ink);
}
.prose p { font-size: var(--fs-body); line-height: 1.62; color: var(--ink-2); }
.prose em { font-style: italic; color: var(--ink); }

/* Sources and footnotes -------------------------------------------------- */

.footnote {
  font-family: var(--mono);
  font-size: 9.5px;
  line-height: 0;
  vertical-align: 5px;
  margin-left: 2px;
  color: var(--accent-ink);
}
.footnote a { color: inherit; }
.footnote a:hover { text-decoration: underline; }
.footnote__sep { color: var(--ink-4); }

.sources { counter-reset: src; display: grid; gap: var(--s-2); }
.sources li, .source {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: var(--s-2);
  padding: var(--s-2) 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-small);
  line-height: 1.45;
}
.sources li::before, .source::before {
  counter-increment: src;
  content: counter(src);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}
.source__body { display: block; min-width: 0; }
.source__title { display: block; color: var(--ink); line-height: 1.4; }
.source__title a { border-bottom: 1px solid var(--rule-strong); }
.source__title a:hover { color: var(--accent-ink); border-color: var(--accent); }
.source__meta { display: block; font-size: var(--fs-micro); color: var(--ink-3); margin-top: 2px; }

/* Glossary --------------------------------------------------------------- */

.glossary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4) var(--s-7);
}
.glossary > div { min-width: 0; padding-top: var(--s-3); border-top: 1px solid var(--rule); }
.glossary dt {
  font-family: var(--sans);
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink);
}
.glossary dd { font-size: var(--fs-small); line-height: 1.5; color: var(--ink-2); margin-top: 4px; }

/* Live signals ----------------------------------------------------------- */

.signals { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5); }
.signal { min-width: 0; padding-top: var(--s-3); border-top: 1px solid var(--rule); }
.signal__label { font-size: var(--fs-micro); letter-spacing: .04em; color: var(--ink-3); }
.signal__figure {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 24px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-top: 4px;
  font-variant-numeric: tabular-nums lining-nums;
}

.newslist { display: grid; gap: var(--s-3); }
.newslist li { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: var(--s-3); padding-bottom: var(--s-3); border-bottom: 1px solid var(--rule); font-size: var(--fs-small); line-height: 1.45; }
.newslist time { font-family: var(--mono); font-size: var(--fs-micro); color: var(--ink-3); font-variant-numeric: tabular-nums; padding-top: 2px; }
.newslist a { color: var(--ink); border-bottom: 1px solid var(--rule); }
.newslist a:hover { color: var(--accent-ink); border-color: var(--accent); }

/* Empty state ------------------------------------------------------------ */

.empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-2);
  padding: var(--s-7) var(--s-6);
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-flat);
  border-left: 2px solid var(--rule-strong);
}
.empty__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--ink);
}
.empty__text { font-size: var(--fs-small); line-height: 1.55; color: var(--ink-3); max-width: 62ch; }

/* ==========================================================================
   13. Timeline
   ========================================================================== */

.timeline__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-5);
  border-bottom: 1px solid var(--rule);
  font-size: 12.5px;
  color: var(--ink-3);
}
/* Filter chips + sort order above a timeline. */
.tl-tools { margin-bottom: var(--s-5); align-items: center; }
.tl-tools .chips { margin-bottom: 0; }

.timeline__legend span { display: inline-flex; align-items: center; gap: 7px; }
.timeline__legend i { width: 8px; height: 8px; border-radius: 50%; background: var(--cat, var(--ink-4)); display: block; }

.timeline { display: block; }

.timeline__item {
  position: relative;
  display: grid;
  grid-template-columns: 62px 20px minmax(0, 1fr);
  column-gap: var(--s-3);
  padding-bottom: var(--s-6);
}
.timeline__item::before {
  content: "";
  position: absolute;
  left: 84px;
  top: 12px;
  bottom: 0;
  width: 1px;
  background: var(--rule);
}
.timeline__item:last-child::before { display: none; }

.timeline__year {
  grid-column: 1;
  font-family: var(--mono);
  font-size: var(--fs-small);
  line-height: 1.4;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  text-align: right;
  padding-top: 1px;
}

.timeline__marker { grid-column: 2; justify-self: center; padding-top: 5px; }
.timeline__dot {
  grid-column: 2;
  justify-self: center;
  align-self: start;
  width: 9px; height: 9px;
  margin-top: 5px;
  border-radius: 50%;
  background: var(--cat, var(--ink-3));
  box-shadow: 0 0 0 3px var(--paper);
  display: block;
}
.timeline__marker .timeline__dot { margin-top: 0; }

.timeline__body { grid-column: 3; min-width: 0; }
.timeline__date {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .05em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.timeline__cat {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--cat, var(--ink-3));
  margin-left: var(--s-3);
}
.timeline__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 19px;
  line-height: 1.25;
  font-weight: 400;
  color: var(--ink);
  margin-top: 5px;
}
.timeline__detail { font-size: var(--fs-small); line-height: 1.55; color: var(--ink-2); margin-top: 6px; max-width: 76ch; }
.timeline__source {
  display: inline-block;
  margin-top: var(--s-2);
  font-size: var(--fs-micro);
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule-strong);
}
.timeline__source:hover { color: var(--accent-ink); border-color: var(--accent); }

.cat--research { --cat: var(--cat-2); }
.cat--product  { --cat: var(--cat-3); }
.cat--market   { --cat: var(--cat-4); }
.cat--policy   { --cat: var(--cat-5); }
.cat--legal    { --cat: var(--cat-6); }
.cat--company  { --cat: var(--cat-1); }

/* ==========================================================================
   14. Drawer
   ========================================================================== */

.drawer { position: fixed; inset: 0; z-index: var(--z-drawer); }

.drawer__scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease);
}
.drawer.is-open .drawer__scrim { opacity: 1; }

.drawer__panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(560px, 100%);
  display: flex;
  flex-direction: column;
  background: var(--paper);
  box-shadow: var(--shadow-pop);
  border-left: 1px solid var(--rule);
  opacity: 0;
  transform: translateX(24px);
  transition: transform var(--dur-mid) var(--ease), opacity var(--dur-mid) var(--ease);
}
.drawer.is-open .drawer__panel { opacity: 1; transform: none; }

.drawer__close {
  position: absolute;
  top: var(--s-3); right: var(--s-3);
  z-index: 2;
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  background: var(--paper);
  color: var(--ink-3);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.drawer__close:hover { background: var(--surface-2); color: var(--ink); }

.drawer__body {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-7) var(--s-6) var(--s-8);
}

.drawer__body h2 {
  font-size: clamp(26px, 4.4vw, 32px);
  line-height: 1.14;
  letter-spacing: -0.02em;
  margin-top: var(--s-2);
}
.drawer__body h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); margin-top: var(--s-5); }
.drawer__body h4,
.drawer__section {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: var(--s-6) 0 var(--s-3);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}
.drawer__body p { font-size: 14.5px; line-height: 1.6; color: var(--ink-2); }
.drawer__body p + p { margin-top: var(--s-3); }
.drawer__body ul, .drawer__body ol { display: grid; gap: 6px; padding-left: var(--s-4); }
.drawer__body li { list-style: disc; font-size: 14.5px; line-height: 1.55; color: var(--ink-2); }
.drawer__body li::marker { color: var(--accent); }
.drawer__body a { color: var(--ink); border-bottom: 1px solid var(--rule-strong); }
.drawer__body a:hover { color: var(--accent-ink); border-color: var(--accent); }

.drawer__eyebrow {
  display: flex; align-items: center; gap: var(--s-3);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.drawer__lede { font-size: 15.5px !important; line-height: 1.6; color: var(--ink-2); margin-top: var(--s-4); }

.formula {
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-flat);
  padding: var(--s-5) var(--s-4);
  margin-top: var(--s-3);
  overflow-x: auto;
  font-size: 15px;
}
.formula .katex-display { margin: 0; }
.formula__gloss { font-size: var(--fs-small) !important; color: var(--ink-3) !important; margin-top: var(--s-3); }

.proscons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); margin-top: var(--s-3); }
.proscons__col { min-width: 0; }
.proscons__col h5,
.proscons__col > .subhead {
  font-family: var(--sans);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  margin-bottom: var(--s-2);
}
.proscons__col--pro h5, .proscons__col--pro > .subhead { color: var(--good); }
.proscons__col--con h5, .proscons__col--con > .subhead { color: var(--bad); }
.proscons__col li { font-size: 13.5px; }

.related { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.related a, .related button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px;
  border-radius: var(--r-pill);
  background: var(--surface);
  box-shadow: var(--shadow-flat);
  font-size: 12.5px;
  color: var(--ink-2);
  border-bottom: 0 !important;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.related a:hover, .related button:hover { background: var(--accent-soft); color: var(--accent-ink); }

/* Method drawer body (library.js) ---------------------------------------- */

.mth__badges { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: var(--s-4); }

.mth__prose > .mth-h:first-child { margin-top: 0; }
.mth__prose .mth-h {
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.35;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: var(--s-5) 0 var(--s-2);
  padding: 0;
  border: 0;
}
.mth__prose .mth-list { margin: var(--s-2) 0 var(--s-3); }
.mth__prose ol.mth-list > li { list-style: decimal; }
.mth__prose p + .mth-h { margin-top: var(--s-5); }
.mth-code {
  font-family: var(--mono);
  font-size: .88em;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 1px 4px;
  color: var(--ink);
}

.mth__pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-3); }
.mth__pill {
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--ink-2);
  background: var(--surface-2);
  border-radius: var(--r-pill);
  padding: 6px 11px;
}
.mth__host {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
  white-space: nowrap;
}
.mth__missing {
  font-size: 12.5px;
  color: var(--ink-3);
  padding: 6px 11px;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--r-pill);
}

.mth__formula-wrap { position: relative; }
.mth__formula-wrap.is-scrollable::after {
  content: "";
  position: absolute;
  top: 1px; right: 1px; bottom: 1px;
  width: 32px;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(255,255,255,0), var(--surface) 78%);
}
.mth__formula-fallback {
  font-family: var(--mono);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-2);
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
}

/* ==========================================================================
   15. Command palette
   ========================================================================== */

.palette { position: fixed; inset: 0; z-index: var(--z-palette); }
.palette__scrim { position: absolute; inset: 0; background: var(--scrim); animation: gd-fade var(--dur-fast) var(--ease); }

.palette__panel {
  position: absolute;
  top: 12vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(640px, calc(100vw - var(--s-6)));
  max-height: 76vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
  animation: gd-rise var(--dur-mid) var(--ease);
}

.palette__input {
  flex: none;
  width: 100%;
  height: 54px;
  padding: 0 var(--s-5);
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  background: var(--paper);
  color: var(--ink);
  font-size: 16px;
  outline: none;
}
.palette__input::placeholder { color: var(--ink-4); }
.palette__input:focus-visible { outline: none; box-shadow: inset 0 -2px 0 var(--accent); }

.palette__list {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-2);
  min-height: 0;
}

.palette__group {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: var(--s-3) var(--s-3) var(--s-2);
}

.palette__item,
.palette__list li[role="option"] {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 9px var(--s-3);
  border-radius: var(--r-md);
  font-size: 14px;
  line-height: 1.35;
  color: var(--ink-2);
  cursor: pointer;
}
.palette__item[aria-selected="true"],
.palette__list li[role="option"][aria-selected="true"],
.palette__item.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
.palette__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette__label small { display: block; font-size: var(--fs-micro); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Matched characters inside a result label. */
.palette__hit { background: none; color: var(--accent-ink); font-weight: 600; }
/* see section 24: the match highlight is a tint, not a colour shift */
.palette__count { margin-left: auto; font-family: var(--mono); font-size: var(--fs-micro); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.palette__type {
  flex: none;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 3px 6px;
}

.palette__hint {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--rule);
  background: var(--surface-2);
  font-size: var(--fs-micro);
  color: var(--ink-3);
}
.palette__hint kbd { background: var(--paper); }

.palette__empty { padding: var(--s-7) var(--s-5); text-align: center; font-size: var(--fs-small); color: var(--ink-3); }

/* ==========================================================================
   16. Skeletons
   ========================================================================== */

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--r-md);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.78) 50%, rgba(255,255,255,0) 100%);
  animation: gd-shimmer 1.2s infinite;
}
@keyframes gd-shimmer { 100% { transform: translateX(100%); } }

.skeleton--text  { height: 12px; border-radius: 3px; }
.skeleton--chart { height: 400px; border-radius: var(--r-lg); }

.skeleton--page {
  min-height: 540px;
  background-color: transparent;
  border-radius: 0;
  background-image:
    linear-gradient(var(--surface-2), var(--surface-2)),
    linear-gradient(var(--surface-2), var(--surface-2)),
    linear-gradient(var(--surface-2), var(--surface-2)),
    linear-gradient(var(--surface), var(--surface)),
    linear-gradient(var(--surface), var(--surface));
  background-repeat: no-repeat;
  background-size:
    min(340px, 70%) 30px,
    min(620px, 96%) 12px,
    min(470px, 82%) 12px,
    100% 132px,
    100% 340px;
  background-position:
    0 4px,
    0 52px,
    0 76px,
    0 116px,
    0 272px;
}

/* ==========================================================================
   17. Footer
   ========================================================================== */

.foot {
  margin-top: var(--s-9);
  padding: var(--s-7) 0 var(--s-8);
  border-top: 1px solid var(--ink);
}
.foot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-7);
}
.foot__word {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.foot__word em { font-style: italic; color: var(--ink-2); margin-left: 3px; }
.foot__col { min-width: 0; }
.foot__head {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s-3);
}
.foot__note {
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--ink-3);
  margin-top: var(--s-3);
  max-width: 52ch;
}
.foot__col .foot__note { margin-top: 0; }
.foot__note a { color: var(--ink-2); border-bottom: 1px solid var(--rule-strong); }
.foot__note a:hover { color: var(--accent-ink); border-color: var(--accent); }

/* ==========================================================================
   18. Animations
   ========================================================================== */

@keyframes gd-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes gd-rise { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ==========================================================================
   19. Responsive
   ========================================================================== */

/* --- 1440 and up: full six-across figure row ---------------------------- */
@media (min-width: 1440px) {
  .kpi-row { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* --- 1024 to 1439 ------------------------------------------------------- */
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .kpi-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* A short row should fill its width rather than leave empty tracks: a section
   with three stats reads as three wide tiles, not three narrow ones stranded
   on the left. Caps at the breakpoint's own column count above. */
@media (min-width: 1024px) {
  .kpi-row:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpi-row:has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1440px) {
  .kpi-row:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .kpi-row:has(> :nth-child(5):last-child) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Reserve label height so figures share a baseline across a multi-up row. */
/* Reserve a common label block so the figures line up across a row; labels
   longer than this grow the tile rather than clip, which keeps the number
   honest at the cost of a slightly taller row. */
@media (min-width: 1440px) { .kpi__label { min-height: 5.4em; } }
@media (min-width: 768px) and (max-width: 1439.98px) { .kpi__label { min-height: 4.05em; } }

@media (max-width: 1279.98px) {
  :root { --rail-gap: var(--s-6); }
  .nav__search span, .nav__kbd { display: none; }
  .nav__search { width: 34px; padding: 0; justify-content: center; }
  .nav__inner { gap: var(--s-3); }
  .nav__link { font-size: 12.5px; padding: 8px 6px; }
  .nav__link.is-active::after { left: 6px; right: 6px; }

  /* The copy column is too narrow for three figures side by side. */
  .hero__facts {
    grid-auto-flow: row;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-3);
  }
  .hero__facts > * + * { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule); padding-top: var(--s-3); }
  .hero__facts > div, .hero__facts .hero__fact { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
  .hero__facts dt { min-height: 0; }
  .hero__facts dd { margin-top: 0; font-size: 23px; justify-content: flex-end; text-align: right; }
}

/* The copy column runs tall here, so a 4:3 figure leaves a hole beside it.
   A square canvas closes most of the gap without turning the scene portrait. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .hero { gap: var(--s-6); }
  .hero__canvas { aspect-ratio: 1 / 1; max-height: 560px; }
}

/* --- below 1024: rail becomes an off-canvas sheet ----------------------- */
@media (max-width: 1023.98px) {
  .shell { grid-template-columns: minmax(0, 1fr); }

  .rail {
    position: fixed;
    top: var(--nav-h);
    left: 0;
    bottom: 0;
    z-index: var(--z-rail);
    width: min(296px, 84vw);
    height: auto;
    padding: var(--s-5) var(--s-4) var(--s-6);
    background: var(--paper);
    border-right: 1px solid var(--rule-strong);
    box-shadow: 12px 0 40px rgba(26,24,20,.14);
    transform: translateX(-101%);
    transition: transform var(--dur-mid) var(--ease);
    visibility: hidden;
  }
  .rail.is-open { transform: none; visibility: visible; }

  /* Below 1024 the rail sheet is the navigation; nine links cannot fit here
     without truncating, so the menu button replaces them. */
  .nav__links { display: none; }
  .nav__menu { display: inline-flex; }

  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-6);
    padding-bottom: var(--s-7);
    margin-bottom: var(--s-7);
  }
  .hero__canvas { aspect-ratio: 16 / 9; }

  .card-grid, .method-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .signals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .span-8, .span-4, .span-6, .span-3 { grid-column: span 12; }
  .foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); }
}

/* --- below 768: nav links collapse, tighter rhythm ---------------------- */
@media (max-width: 767.98px) {
  :root { --gutter: 20px; --nav-h: 56px; }

  .nav__inner { gap: var(--s-3); }
  .nav__word { font-size: 18px; }

  .main { padding-top: var(--s-5); }
  .section + .section { margin-top: var(--s-7); }
  .section__head { grid-template-columns: minmax(0, 1fr); gap: var(--s-2); margin-bottom: var(--s-5); }
  .section__meta { text-align: left; }
  .section__standfirst { font-size: 15px; }

  .hero { padding: var(--s-4) 0 var(--s-6); margin-bottom: var(--s-6); }
  .hero__standfirst { font-size: 15.5px; }
  .hero__actions { gap: var(--s-4); }
  .hero__facts { margin-top: var(--s-6); }

  .findings, .glossary, .proscons { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .card-grid, .method-grid { grid-template-columns: minmax(0, 1fr); }
  .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }

  .panel__head { padding: var(--s-4); }
  .panel__body { padding: var(--s-4); }
  .panel__note, .panel__sources, .panel__foot, .table__source, .table__foot { padding: var(--s-3) var(--s-4); }
  .panel__unit { margin-left: 0; }
  .chart, .panel__chart { height: 320px; }
  .chart--tall { height: 420px; }

  .table thead th:first-child, .table td:first-child { padding-left: var(--s-4); }
  .table thead th:last-child,  .table td:last-child  { padding-right: var(--s-4); }
  .table-wrap { max-height: min(64vh, 520px); }

  .timeline__item { grid-template-columns: 18px minmax(0, 1fr); column-gap: var(--s-3); padding-bottom: var(--s-5); }
  .timeline__item::before { left: 8px; }
  .timeline__year {
    grid-column: 1 / -1;
    text-align: left;
    padding: 0 0 var(--s-2) 0;
    font-size: var(--fs-micro);
    letter-spacing: .12em;
  }
  .timeline__marker, .timeline__dot { grid-column: 1; justify-self: start; }
  .timeline__body { grid-column: 2; }

  .drawer__panel { width: 100%; border-left: 0; }
  .drawer__body { padding: var(--s-6) var(--s-5) var(--s-7); }

  .palette__panel { top: 6vh; width: calc(100vw - var(--s-4)); max-height: 84vh; }

  .foot { margin-top: var(--s-7); padding-top: var(--s-6); }
  .foot__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-5); }
  .newslist li { grid-template-columns: minmax(0, 1fr); gap: 2px; }

  .lib-controls .field { max-width: none; }
  .lib-filter__label { flex-basis: 100%; padding-top: 0; }

  .drawer__body .formula .katex { font-size: 1.05em; }

  .prose { gap: var(--s-5); }
}

/* --- below 480: single-column figures ----------------------------------- */
@media (max-width: 479.98px) {
  :root { --gutter: 16px; --kpi-figure: 30px; }

  .kpi-row { grid-template-columns: minmax(0, 1fr); }
  .kpi__label { min-height: 0; }

  .hero__title { font-size: clamp(31px, 8.6vw, 40px); }
  .hero__facts dd { font-size: 21px; }
  .hero__canvas { aspect-ratio: 4 / 3; }

  .btn { padding: 0 12px; }
  .nav__actions { gap: 6px; }
  .nav__word { font-size: 17px; }

  .signals { grid-template-columns: minmax(0, 1fr); }
  .sources li, .source { grid-template-columns: 20px minmax(0, 1fr); }
}

/* ==========================================================================
   20. Reduced motion — kill every transition, animation and shimmer
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }

  .skeleton::after { display: none; }
  .rail__pulse::after { display: none; }
  .drawer__panel { transform: none; }
  .btn--link:hover::after { transform: none; }
}

/* ==========================================================================
   21. Forced colours / high contrast
   ========================================================================== */

@media (forced-colors: active) {
  .kpi, .panel, .card, .method-card, .empty { border: 1px solid CanvasText; }
  .chip[aria-pressed="true"], .seg__btn[aria-selected="true"] { forced-color-adjust: none; }
}

/* ==========================================================================
   22. Cross-cutting fixes: cited-source highlight, chart data tables
   Additive block. Nothing above is modified.
   ========================================================================== */

/* A footnote scrolls its source row into view rather than writing to the hash
   (which the router owns), so the row itself has to say "this one". */
.source.is-cited {
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding-left: var(--s-2);
  transition: background var(--dur-slow) var(--ease);
}
.source.is-cited::before { color: var(--accent); }
.source:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.footnote a { text-decoration: none; }

/* The text alternative under every chart (DESIGN §8: no fact is vision-only). */
.chart-data { margin-top: var(--s-4); border-top: 1px solid var(--rule); }
.chart-data__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--s-3);
  padding: 3px 0;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  cursor: pointer;
  list-style: none;
  width: fit-content;
}
.chart-data__toggle::-webkit-details-marker { display: none; }
.chart-data__toggle::before {
  content: "";
  width: 0; height: 0;
  border-left: 5px solid var(--ink-4);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform var(--dur-fast) var(--ease);
}
.chart-data[open] > .chart-data__toggle::before { transform: rotate(90deg); }
.chart-data__toggle:hover { color: var(--ink); }
.chart-data__toggle:hover::before { border-left-color: var(--accent); }
.chart-data__cap {
  font-size: var(--fs-micro);
  line-height: 1.45;
  color: var(--ink-3);
  margin: var(--s-2) 0 var(--s-2);
}
.chart-data .table-wrap { max-height: 320px; border: 1px solid var(--rule); border-radius: var(--r-md); }
.table--data { font-size: 12.5px; }
.table--data th[scope="row"] { font-weight: 500; color: var(--ink); }
.table--data th:first-child, .table--data td:first-child { min-width: 0; padding-left: var(--s-3); }
.table--data td:last-child, .table--data th:last-child { padding-right: var(--s-3); }

/* ==========================================================================
   23. Company, developer and customer perspectives
   Components rendered by assets/js/sections-b.js: company dossiers, costed
   recipes, tool profiles, the buyer's decision guide and its checklist, plus
   the table affordances those three routes need. Additive; nothing above is
   modified.
   ========================================================================== */

/* --- Tables: no nested scroller, a pinned identity column, an export ------ */

/* A 660px inner scroller inside a 20,000px page hides rows behind a wheel that
   scrolls the page instead. Tables run their full length; only a long one is
   capped, and it says how many rows are behind the cap. */
[data-perspective="company"] .table-wrap,
[data-perspective="developer"] .table-wrap,
[data-perspective="customer"] .table-wrap { max-height: none; }
[data-perspective="company"] .chart-data .table-wrap,
[data-perspective="developer"] .chart-data .table-wrap,
[data-perspective="customer"] .chart-data .table-wrap { max-height: 320px; }

.table-wrap.is-capped { max-height: 620px; }
.table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.table__more {
  display: block;
  width: calc(100% - var(--s-5) * 2);
  margin: var(--s-3) var(--s-5) 0;
  font-size: var(--fs-small);
}

.table__csv {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule-strong);
}
.table__csv:hover { color: var(--accent-ink); border-color: var(--accent); }
.panel__unit + .table__csv { margin-left: var(--s-3); }

/* The row label has to survive horizontal scrolling, or the numbers belong to
   nobody. */
.table--pin1 tbody th:first-child,
.table--pin1 tbody td:first-child,
.table--pin1 thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  box-shadow: 1px 0 0 var(--rule);
}
.table--pin1 thead th:first-child { z-index: 3; }
.table--zebra.table--pin1 tbody tr:nth-child(even) td:first-child { background: #F7F4EE; }

.table--rowlink tbody tr { cursor: pointer; }
.table--rowlink tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.table--rowlink tbody tr:hover td:first-child { color: var(--accent-ink); }

/* A model chip in the decision guide points at its row in the master table. */
.table tbody tr.is-cited td { background: var(--accent-soft); }
.table tbody tr.is-cited td:first-child { box-shadow: inset 2px 0 0 var(--accent); }

/* The header's count list is the page's natural in-page navigation. */
.meta__jump {
  font: inherit;
  color: inherit;
  border-bottom: 1px solid var(--rule-strong);
  cursor: pointer;
}
.meta__jump:hover { color: var(--accent-ink); border-color: var(--accent); }

/* --- Company dossiers ---------------------------------------------------- */

.dossiers { display: grid; gap: var(--s-6); }
.dossiers__label {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s-3);
}
.dossiers__label .dim { text-transform: none; letter-spacing: 0; }

.dossier-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--s-3);
}

.dossier {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--s-4);
  text-align: left;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.dossier:hover { box-shadow: var(--shadow-pop); transform: translateY(-1px); }
.dossier__top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-2); }
.dossier__name {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: 17px;
  line-height: 1.2;
  color: var(--ink);
}
.dossier__hq { font-size: var(--fs-micro); color: var(--ink-3); }
.dossier__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px var(--s-3);
  margin-top: auto;
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
}

.badge--stance.is-restrictive { background: var(--bad-soft); color: var(--bad); }
.badge--stance.is-permissive { background: var(--good-soft); color: var(--good); }
.badge--stance.is-mixed { background: var(--warn-soft); color: var(--warn); }

.dossier__events { display: grid; gap: var(--s-3); padding-left: 0; }
.dossier__events .dossier__event {
  list-style: none;
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr);
  gap: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
}
.dossier__event time {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
}

/* --- Developer: costed recipes ------------------------------------------- */

.recipes { display: grid; gap: var(--s-5); }
.recipe__head { align-items: flex-start; }
.recipe__n {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--accent);
  margin-right: var(--s-3);
  vertical-align: 4px;
}
.recipe__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-4);
  border-bottom: 1px solid var(--rule);
}
.recipe__stats dt {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 3px;
}
.recipe__stats dd { font-size: var(--fs-small); line-height: 1.5; color: var(--ink); }
.recipe__steps { display: grid; gap: var(--s-3); counter-reset: step; }
.recipe__steps li {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: var(--s-2);
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink-2);
}
.recipe__steps li::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
  padding-top: 4px;
}

/* --- Developer: tool profiles -------------------------------------------- */

.tools { display: grid; gap: var(--s-6); }
.tools__label {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s-2);
}
.tools__label .dim { text-transform: none; letter-spacing: 0; }

.tool {
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-flat);
  margin-bottom: var(--s-2);
}
.tool[open] { box-shadow: var(--shadow-card); }
.tool__summary {
  display: grid;
  grid-template-columns: minmax(180px, 22%) minmax(0, 1fr);
  gap: 2px var(--s-4);
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  list-style: none;
}
.tool__summary::-webkit-details-marker { display: none; }
.tool__summary:hover .tool__name { color: var(--accent-ink); }
.tool__name { font-weight: 600; font-size: var(--fs-small); color: var(--ink); }
.tool__one { font-size: var(--fs-small); line-height: 1.5; color: var(--ink-2); }
.tool__meta {
  grid-column: 2;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
}
.tool__detail { padding: 0 var(--s-4) var(--s-4); border-top: 1px solid var(--rule); }
.tool__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s-4);
  margin-top: var(--s-3);
}
.tool__coltitle {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: var(--s-3) 0 var(--s-2);
}
.tool__col ul, .tool__list { display: grid; gap: 5px; }
.tool__col li, .tool__list li {
  position: relative;
  padding-left: var(--s-4);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-2);
}
.tool__col li::before, .tool__list li::before {
  content: "\2014";
  position: absolute;
  left: 0;
  color: var(--ink-4);
}
.tool__col--pro li::before { content: "+"; color: var(--good); }
.tool__col--con li::before { content: "\2212"; color: var(--bad); }
.tool__chips { display: flex; flex-wrap: wrap; gap: 5px; }
.tool__chips .badge { text-transform: none; letter-spacing: 0; font-weight: 400; }
.tool__link { margin-top: var(--s-3); font-size: var(--fs-small); }

/* --- Customer: decision guide and checklist ------------------------------ */

.guide {
  display: grid;
  gap: 0;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.guide__row {
  display: grid;
  grid-template-columns: 34px minmax(220px, 30%) minmax(0, 1fr);
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.guide__row:last-child { border-bottom: 0; }
.guide__row:nth-child(even) { background: color-mix(in srgb, var(--surface-2) 45%, var(--surface)); }
.guide__n { font-family: var(--mono); font-size: var(--fs-micro); color: var(--ink-4); padding-top: 5px; }
.guide__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.3;
  color: var(--ink);
}
.guide__rec {
  margin-top: 6px;
  font-size: var(--fs-small);
  line-height: 1.5;
  font-weight: 600;
  color: var(--accent-ink);
}
.guide__why p { font-size: var(--fs-small); line-height: 1.6; color: var(--ink-2); }
.guide__models { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-3); }
.chip--model { font-family: var(--mono); font-size: var(--fs-micro); }

.checklist { display: grid; gap: var(--s-2); counter-reset: chk; }
.checklist__item {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-flat);
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink-2);
}
.checklist__item::before {
  counter-increment: chk;
  content: counter(chk, decimal-leading-zero);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--accent);
  padding-top: 4px;
}

@media (max-width: 767.98px) {
  .guide__row { grid-template-columns: 26px minmax(0, 1fr); }
  .guide__why { grid-column: 2; }
  .tool__summary { grid-template-columns: minmax(0, 1fr); }
  .tool__meta { grid-column: 1; }
  .dossier__events .dossier__event { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* ==========================================================================
   24. Legibility corrections
   The muted token measured 3.89:1 on the paper ground at 11px, below the 4.5:1
   AA floor, and it carries the page's caveats: method notes, table headers,
   source lines and captions. DESIGN.md already specifies that the lightest
   permitted text clears 4.6:1, so the token is corrected to meet its own rule
   (5.96:1 on paper, 5.56:1 on the zebra fill) rather than the rule relaxed.
   ========================================================================== */

:root { --ink-3: #655F55; }

/* Column-unit labels were 9.5px in the disabled tint. */
.table th .th__unit,
.table th small { font-size: 10.5px; color: var(--ink-3); }

/* A footnote marker is a link: it needs a readable size and a hit area. */
.footnote { font-size: 11px; vertical-align: 4px; }
.footnote a { display: inline-block; padding: 2px 3px; margin: -2px 0; }

/* The live row count sat in monospace in the middle of a serif sentence. */
.table__caption .table__count { font-family: var(--sans); letter-spacing: 0; }

/* Eight figures wrap 6 + 2 on a six-column grid, leaving four empty cells; at
   four across they fill two clean rows. */
@media (min-width: 1440px) {
  .kpi-row[data-n="7"],
  .kpi-row[data-n="8"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* An arrow reads as a change indicator. Only a signed or directional delta
   gets one; a specification ("512 H800s x 80 hours") is neutral. */
.kpi__delta--flat::before { content: none; }

/* ==========================================================================
   24. Overview shell fixes
   Additive block for the front page, the global chrome and the event lists.
   Nothing above is modified.
   ========================================================================== */

/* --- Front-page figure row ------------------------------------------------
   Six tiles across 1440 gave each 152px against a 430px height, so every label
   wrapped to three or four lines and the source hostnames broke mid-token.
   Three across two rows gives each tile about 310px, which is a two-line label
   and an unbroken attribution. */
@media (min-width: 1024px) {
  .kpi-row--lede { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
  /* One reserved label block, so all six numerals sit on one baseline. */
  .kpi-row--lede .kpi__label { min-height: 2.7em; }
}
/* Attribution lines are publisher names here, but a long one must still wrap
   between words rather than through the middle of a domain. */
.kpi-row--lede .kpi__source { overflow-wrap: break-word; word-break: normal; }
/* WCAG 2.2 Target Size (Minimum): a 15px-tall link in a stack of them is not a
   target. Padding rather than font size, so the rhythm of the tile is intact. */
.kpi__source a,
.timeline__source,
.timeline__from {
  display: inline-block;
  padding-block: 5px;
  min-height: 24px;
}

/* --- Latest events -------------------------------------------------------
   The text column wrapped at ~640px inside a 972px column, leaving a third of
   the width empty down the whole list. The right of each row now carries the
   provenance: who reported it, and which section holds the full account. */
@media (min-width: 900px) {
  .timeline--wide .timeline__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 172px;
    column-gap: var(--s-6);
    align-items: start;
  }
  .timeline--wide .timeline__detail { max-width: none; }
}
.timeline__side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding-top: 2px;
}
.timeline__from {
  font-size: var(--fs-micro);
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule);
}
.timeline__from:hover { color: var(--accent-ink); border-color: var(--accent); }
/* An announced-but-not-yet-in-force date is drawn hollow, so it never reads as
   something that has already happened. */
.timeline__item--ahead .timeline__dot {
  background: var(--paper);
  box-shadow: 0 0 0 2px var(--cat, var(--ink-3)), 0 0 0 5px var(--paper);
}

/* --- Segmented control at narrow widths ----------------------------------
   The strip scrolls, but nothing said so: the third tab was invisible with no
   affordance. A right-edge fade appears only while there is more to scroll to. */
@media (max-width: 767.98px) {
  .panel__tools .seg:has(> :nth-child(3)) {
    scroll-snap-type: x proximity;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
  }
  .panel__tools .seg__btn { scroll-snap-align: start; }
}

/* ==========================================================================
   25. Academic, financial and political perspectives
   Additive block: the in-page index, the figure row's unit slot, the tables
   that stopped clipping, the tick matrix, the row-detail drawer, and the
   panels built for the datasets those three files carry. Nothing above is
   modified.
   ========================================================================== */

/* --- In-page index -------------------------------------------------------- */
/* The left rail moves between routes. A 20,000px route needs a way to move
   inside itself, which is the bar OWID puts under its own title. */

.pagenav {
  position: sticky;
  top: calc(var(--nav-h) + 0px);
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2) var(--s-4);
  margin: 0 0 var(--s-6);
  padding: var(--s-3) var(--s-4);
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(6px);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.pagenav__label {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pagenav__link {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-size: var(--fs-small);
  color: var(--ink-2);
  border-bottom: 1px solid transparent;
}
.pagenav__link:hover { color: var(--accent-ink); border-bottom-color: var(--accent); }
.pagenav__n {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.subhead:focus-visible,
.section [id^="sec-"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* --- Figure row ----------------------------------------------------------- */
/* Every tile carries its unit in the same slot beneath the numeral, so a bare
   "900" cannot read as a different kind of quantity from "42 x". */

.kpi__unit-line {
  font-family: var(--sans);
  font-size: var(--fs-small);
  line-height: 1.3;
  color: var(--ink-3);
  min-height: 1.3em;
  margin-top: -2px;
}
.kpi__delta {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  white-space: normal;
  background: var(--surface-2);
  color: var(--ink-2);
}
/* Tint means a signed change and nothing else. A hardware specification in a
   green pill reads as a favourable result, which it is not. */
.kpi__delta--flat { background: var(--surface-2); color: var(--ink-2); }
.kpi__delta--up   { background: var(--good-soft); color: var(--good); }
.kpi__delta--down { background: var(--bad-soft);  color: var(--bad); }
.kpi__source { word-break: break-word; }

/* --- Tables --------------------------------------------------------------- */
/* The height cap sliced the last visible row through its glyphs, with no fade,
   no scrollbar and no "5 more rows" hint: it read as broken rather than as
   scrollable. These tables are 6 to 63 rows on a page that is already long. */

.table-wrap { max-height: none; }
.chart-data .table-wrap { max-height: 320px; }
.table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.table-wrap--sticky { scrollbar-gutter: stable; }

/* Row identity survives a sideways scroll. */
@media (min-width: 600px) {
  .table--matrix th[scope="row"],
  .table-wrap--sticky .table > tbody > tr > td:first-child,
  .table-wrap--sticky .table > thead > tr > th:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
  }
  .table-wrap--sticky .table > thead > tr > th:first-child { z-index: 3; }
  .table--zebra > tbody > tr:nth-child(even) > td:first-child { background: var(--surface-2); }
  .table-wrap--sticky .table > tbody > tr > td:first-child::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: -1px;
    width: 6px;
    background: linear-gradient(to right, rgba(26,24,20,.07), rgba(26,24,20,0));
    pointer-events: none;
  }
}

/* A reference marker inside a right-aligned numeric cell pushed the digits off
   the column's alignment: 25,899¹ and 3,209⁵⁴ ended at different x. */
.cell-ref {
  display: inline-block;
  width: 2.4ch;
  text-align: left;
  margin-right: -2.4ch;
  position: relative;
  left: 4px;
}
.cell-sub {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-micro);
  line-height: 1.4;
  color: var(--ink-3);
  max-width: 46ch;
}

.row--open { cursor: pointer; }
.row--open:hover > td { background: var(--surface-2); }
.row--open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* --- Tick matrix ---------------------------------------------------------- */
/* Four independent yes/no instruments read across a row and down a column.
   They are never summed: a jurisdiction with three of them does not have
   three times anything, and an empty row is a finding, not missing data. */

.table--matrix th { white-space: normal; vertical-align: bottom; }
.table--matrix thead th:not(:first-child) .table__sort { max-width: 15ch; text-align: left; }
.table--matrix td:not(:first-child) { white-space: nowrap; }
.tick {
  display: inline-block;
  width: 11px; height: 11px;
  margin-right: 7px;
  border-radius: 50%;
  vertical-align: -1px;
}
.tick--on  { background: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.tick--off { background: transparent; box-shadow: inset 0 0 0 1.5px var(--rule-strong); }

/* --- Sources -------------------------------------------------------------- */
/* A hundred identical rows in one column ran to a fifth of the page. Grouped by
   kind, set in columns, and opened rather than scrolled past — a citation still
   opens the disclosure before it scrolls, so nothing is ever unreachable. */

.sources-wrap { margin-top: calc(var(--s-4) * -1); }
.sources__toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: var(--s-2) 0;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  list-style: none;
  width: fit-content;
}
.sources__toggle::-webkit-details-marker { display: none; }
.sources__toggle::before {
  content: "";
  width: 0; height: 0;
  border-left: 5px solid var(--ink-3);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform var(--dur-fast) var(--ease);
}
.sources-wrap[open] > .sources__toggle::before { transform: rotate(90deg); }
.sources__toggle:hover { color: var(--accent-ink); }
.sources__cols { margin-top: var(--s-4); display: grid; gap: var(--s-6); }
@media (min-width: 1024px) { .sources__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1440px) { .sources__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.sources__group { min-width: 0; break-inside: avoid; }
.sources__kind {
  font-family: var(--sans);
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink);
  padding-bottom: var(--s-2);
  margin-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
}

/* --- Assumptions panel ---------------------------------------------------- */

.assumptions { display: grid; gap: var(--s-3); }
.assumptions > div {
  display: grid;
  grid-template-columns: minmax(0, 13em) minmax(0, 1fr);
  gap: var(--s-2) var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
}
.assumptions dt { font-size: var(--fs-small); color: var(--ink); font-weight: 500; }
.assumptions dd { font-size: var(--fs-small); line-height: var(--lh-body); color: var(--ink-2); }
.assumptions__head {
  margin: var(--s-5) 0 var(--s-3);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.ticklist { display: grid; gap: var(--s-2); }
.ticklist li {
  position: relative;
  padding-left: var(--s-4);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}
.ticklist li::before {
  content: "";
  position: absolute;
  left: 0; top: .55em;
  width: 6px; height: 6px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--rule-strong);
}
@media (max-width: 599.98px) {
  .assumptions > div { grid-template-columns: minmax(0, 1fr); }
}

/* --- Quotes and signals in a panel body ----------------------------------- */

.panel__body > .quote + .quote { margin-top: var(--s-4); }
.panel__body > .quote cite {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--sans);
  font-style: normal;
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--ink-3);
}
.signal__note {
  margin-top: var(--s-2);
  font-size: var(--fs-micro);
  line-height: 1.4;
  color: var(--ink-3);
}

/* --- Row-detail drawer ---------------------------------------------------- */

.detail__meta {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--ink-3);
  margin-bottom: var(--s-2);
}
.detail__title {
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--ink);
  margin-bottom: var(--s-5);
}
.detail__block + .detail__block { margin-top: var(--s-5); }
.detail__block h4 {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s-2);
}
.detail__block p { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--ink-2); }
.detail__source {
  margin-top: var(--s-6);
  padding-top: var(--s-3);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-small);
}
.detail__source a { color: var(--accent-ink); border-bottom: 1px solid var(--accent); }

/* --- Narrow widths -------------------------------------------------------- */

@media (max-width: 767.98px) {
  .pagenav {
    position: static;
    gap: var(--s-2) var(--s-3);
    padding: var(--s-3) 0;
  }
  .pagenav__label { flex: 0 0 100%; }
  /* A phone cannot show a row label and its value at the same time on a
     seven-column table; the first column is pinned so it can. */
  .table-wrap--sticky .table > tbody > tr > td:first-child,
  .table-wrap--sticky .table > thead > tr > th:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
    max-width: 40vw;
  }
  .table-wrap--sticky .table > thead > tr > th:first-child { z-index: 3; }
  .table-wrap--sticky .table > tbody > tr > td:first-child {
    box-shadow: 6px 0 6px -6px rgba(26,24,20,.22);
  }
  .cell-sub { display: none; }
}

/* ==========================================================================
   25. Library, timeline record and comparison builder
   Additive block. Nothing above is modified; every rule here is either a new
   component or an intentional override of an earlier one, noted where it is.
   ========================================================================== */

/* --- Family hues ----------------------------------------------------------
   Eleven families, eleven hues. The old five-hue regex map painted
   attention-based, feature-based and compression-composed the same blue, so
   the key asserted a kinship the page's own copy denies. The family name is
   always printed beside its dot, so colour supports the label and never
   carries the fact alone. */
.fam--1  { --fam: #B5451B; }
.fam--2  { --fam: #1F6A99; }
.fam--3  { --fam: #2E7D53; }
.fam--4  { --fam: #9A6C10; }
.fam--5  { --fam: #6B4FA8; }
.fam--6  { --fam: #A8324E; }
.fam--7  { --fam: #3F6470; }
.fam--8  { --fam: #7A6A57; }
.fam--9  { --fam: #0F6B63; }
.fam--10 { --fam: #8E3A6B; }
.fam--11 { --fam: #556B0F; }
.lib-chips .chip__dot { background: var(--fam, var(--ink-4)); }

/* --- Method cards ---------------------------------------------------------
   The card is an <article> with a real <h3>, so the library can be navigated
   by heading; the name is the button and its hit area covers the whole card. */
.method-grid { align-items: start; gap: var(--s-5); }
.method-card { position: relative; min-height: 0; }
.method-card__name { margin: 0; }
.method-card__open {
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.method-card__open::after { content: ""; position: absolute; inset: 0; border-radius: var(--r-lg); }
.method-card:has(.method-card__open:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.method-card__open:focus-visible { outline: none; }
/* Three lines for every card, so a row of cards is one height and the grid
   keeps its rhythm. The full description is in the drawer. */
.method-card__desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.method-card__foot { margin-top: auto; }

/* --- Library controls ---------------------------------------------------- */
.lib-controls__top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
}
.lib-controls__top .field { flex: 1 1 260px; max-width: 420px; }
.field--sm { flex: 0 0 auto; }
.field--sm .field__input { min-width: 190px; }
.lib-controls__top .seg { margin-left: auto; }
.lib-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3) var(--s-5);
  margin-top: var(--s-4);
}
.lib-bar .lib-count { margin: 0; }

/* --- Table view ---------------------------------------------------------- */
.table--lib { font-size: 13.5px; }
.table--lib th[scope="row"] { font-weight: 500; }
.table--lib .lib-row {
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid var(--rule-strong);
}
.table--lib .lib-row:hover { color: var(--accent-ink); border-color: var(--accent); }
.table--lib .method-card__family { letter-spacing: .06em; }
.table--lib tbody tr { cursor: pointer; }

/* --- Attribute badges -----------------------------------------------------
   Teacher access is a constraint, not a grade: green for white-box and amber
   for black-box asserted a preference the page explicitly contradicts. One
   hue family, three tints, all above 4.5:1. */
.badge--attr { background: var(--surface-2); color: var(--ink-2); }
.badge--attr.attr--white-box  { background: #EEEBE3; }
.badge--attr.attr--black-box  { background: #E4DFD5; }
.badge--attr.attr--teacherless { background: #F3F0EA; }
/* An audience badge names another section of the compendium, so it is made
   the link to it. */
.badge--route { background: var(--surface-2); color: var(--ink-2); border-bottom: 0; }
.badge--route:hover { background: var(--accent-soft); color: var(--accent-ink); }

/* --- Method drawer --------------------------------------------------------
   Section labels moved from h4 to h3 so the drawer runs h2 to h3 to h4 with no
   skipped level; these rules keep their mono-label appearance. */
.drawer__body .drawer__section {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: var(--s-6) 0 var(--s-3);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}
.proscons__col h4 {
  font-family: var(--sans);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  margin: 0 0 var(--s-2);
  padding: 0;
  border: 0;
}
.proscons__col--pro h4 { color: var(--good); }
.proscons__col--con h4 { color: var(--bad); }
.drawer__body .mth__prose .mth-h { border: 0; padding: 0; }

/* A long objective scrolls sideways. It used to do so silently: no scrollbar,
   no fade, nothing to drag. Now the scrollbar is always drawn, the fade marks
   the cut, and a line of copy says which way to go. */
.formula {
  scrollbar-width: thin;
  scrollbar-color: var(--rule-strong) transparent;
  overscroll-behavior-x: contain;
}
.formula::-webkit-scrollbar { height: 8px; }
.formula::-webkit-scrollbar-thumb { background: var(--rule-strong); border-radius: 4px; }
.mth__formula-wrap.is-scrollable .formula { padding-bottom: var(--s-3); }
.mth__formula-hint {
  font-size: var(--fs-micro) !important;
  line-height: 1.45;
  color: var(--ink-3) !important;
  margin-top: var(--s-2);
}
.drawer__eyebrow .method-card__family { color: var(--ink-3); }

/* --- The record: years as groups -----------------------------------------
   A hundred and thirty rows of one weight have no structure a reader can
   hold. Each year is a group whose heading stays on screen while its events
   pass, and Compact folds the detail line away for scanning. */
.timeline__group { display: block; margin-bottom: var(--s-5); }
.timeline__group[hidden] { display: none; }
.timeline__yearhead {
  position: sticky;
  top: calc(var(--nav-h) + 2px);
  z-index: 3;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  padding: 6px 0 7px;
  margin-bottom: var(--s-4);
  background: var(--paper);
  border-bottom: 1px solid var(--rule-strong);
  font-family: var(--mono);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.timeline__yearn { font-size: var(--fs-micro); color: var(--ink-3); letter-spacing: .04em; }
.timeline__events { display: block; }
/* Scoped to the grouped record, so the flat event list on the front page
   keeps the layout it was built for. */
.timeline__group .timeline__item {
  grid-template-columns: 20px minmax(0, 1fr);
  padding-bottom: var(--s-5);
}
.timeline__group .timeline__dot  { grid-column: 1; }
.timeline__group .timeline__body { grid-column: 2; }
.timeline__group .timeline__item::before { left: 9px; }
.timeline__meta { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.timeline__meta .timeline__cat { margin-left: 0; }
.timeline__group .timeline__item:hover .timeline__title { color: var(--accent-ink); }
.tl-wrap.is-compact .timeline__detail { display: none; }
.tl-wrap.is-compact .timeline__title { font-size: 16px; margin-top: 2px; }
.tl-wrap.is-compact .timeline__item { padding-bottom: var(--s-4); }
.tl-tools__right { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }

/* An active category chip is filled in its own category colour, not in the
   global accent: three colours on one 100px control read as a fault. */
.chip[data-tl-filter] .chip__dot { background: var(--cat, var(--ink-4)); }
.chip[data-tl-filter][aria-pressed="true"] {
  background: color-mix(in srgb, var(--cat, var(--accent)) 12%, var(--surface));
  border-color: var(--cat, var(--accent));
  color: var(--ink);
}

/* --- Comparison builder --------------------------------------------------- */
.cmp-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-4);
  margin: var(--s-4) 0;
}
.cmp-controls .field { flex: 0 1 300px; }
.chips--sm .chip { font-size: 12.5px; }
.cmp-presets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  padding: var(--s-3) 0 0;
}
.cmp-presets__label {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cmp-presets .chips { margin: 0; }
.cmp-chips { display: grid; gap: var(--s-3); }
.cmp-chips.is-capped {
  max-height: 232px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
}
.cmp-group { display: grid; gap: 6px; }
.cmp-group__head {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cmp-group .chips { margin: 0; }
.cmp-more { margin-top: var(--s-3); }
.cmp-status {
  min-height: 1.4em;
  margin: var(--s-3) 0 0;
  font-size: var(--fs-small);
  color: var(--ink-2);
}
/* The cap on four models used to be enforced with the disabled attribute,
   which removed seventy chips from the tab order and looked identical to an
   enabled one. The chip stays focusable and says what it is. */
.chip.is-disabled { opacity: .45; }
.chip.is-disabled:hover { background: var(--surface); }
.btn--sm { padding: 5px 11px; font-size: var(--fs-small); }

/* Four columns have to fit: the license string used to force one column to
   425px and push two of the four models off the right edge. */
.table--compare { table-layout: fixed; width: 100%; }
.table--compare th:first-child,
.table--compare td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  width: 190px;
  min-width: 190px;
  background: var(--surface);
}
.table--compare thead th:first-child { z-index: 4; }
.table--compare th, .table--compare td { white-space: normal; overflow-wrap: break-word; }
.table--compare thead th { vertical-align: top; }
.table--compare tbody tr.is-empty th,
.table--compare tbody tr.is-empty td { color: var(--ink-4); }
.table--compare tbody tr.is-derived td.num { color: var(--ink); }
.table--compare tbody tr.is-derived { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
/* The first column is sticky, so it paints its own background and would leave
   the derived rows striped. */
.table--compare tbody tr.is-derived th:first-child {
  background: color-mix(in srgb, var(--surface-2) 45%, var(--surface));
}
.cell__sub--warn { color: var(--warn) !important; }
/* 9.5px at 2.3:1 was the least legible text on the site. */
.table th small { font-size: 11px; color: var(--ink-3); }

/* --- Narrow widths -------------------------------------------------------- */
@media (max-width: 767.98px) {
  /* WCAG 2.5.8: a 30px pill is not a touch target. */
  .lib-chips .chip, .chips .chip { min-height: 40px; padding-block: 9px; }
  .lib-controls__top { gap: var(--s-3); }
  .lib-controls__top .seg { margin-left: 0; }
  .lib-filter { gap: var(--s-2); }
  .lib-filter__label { flex-basis: 100%; padding-top: 0; }
  /* The count and the reset stay reachable while the grid scrolls past. */
  .lib-bar {
    position: sticky;
    top: var(--nav-h);
    z-index: 4;
    padding: var(--s-2) 0;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
  }
  .timeline__yearhead { top: var(--nav-h); }
  .cmp-controls .field { flex: 1 1 100%; }
  .table--compare th:first-child,
  .table--compare td:first-child { width: 132px; min-width: 132px; }
}

/* The comparison table scrolls sideways and is reachable from the keyboard. */
.table-wrap { scrollbar-width: thin; }
.table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* A footnote or an in-page jump must not land under the fixed header. */
html { scroll-padding-top: 76px; }

/* Column widths are shared out by content length (sections-b.js); the header
   labels wrap rather than clip once the layout is fixed. */
.table--balanced thead th,
.table--balanced .table__sort { white-space: normal; }
.table--balanced .table__sort { text-align: left; }
.table--balanced th.num .table__sort,
.table--balanced th[data-type="number"] .table__sort { text-align: right; }

/* --- Command palette -----------------------------------------------------
   A dark-red colour shift on body text was very hard to pick out of a list.
   A tint reads as a highlighter at a glance, which is what it is for. */
.palette__hit {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 600;
  border-radius: 2px;
  padding: 0 1px;
  margin: 0 -1px;
}

/* The standfirst continuation carries six citable claims and is the first
   body text on the page; it belongs at body contrast, not in the muted tier
   reserved for captions. */
.section__standfirst--rest { color: var(--ink-2); font-size: 15px; }
.section__standfirst--rest + .section__standfirst--rest { margin-top: var(--s-3); }

/* A row header is a label, not a heading in the middle of a table: left, at
   body weight, on the same rhythm as the cells beside it. */
.table tbody th[scope="row"] {
  text-align: left;
  font-weight: 500;
  color: var(--ink);
  padding: 11px var(--s-3);
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  line-height: 1.45;
}
.table tbody th[scope="row"]:first-child { padding-left: var(--s-5); }
.table tbody tr:last-child th[scope="row"] { border-bottom: 0; }
.table td.is-zero { color: var(--ink-4); }

/* A wrapping signal label pushed its figure down out of the row's baseline. */
.signal__label { min-height: 2.6em; }

/* The pinned first cell paints its own background, so it has to carry the
   zebra fill too or the row splits in two down the pin. */
.table--zebra > tbody > tr:nth-child(even) > td:first-child,
.table-wrap--sticky .table--zebra > tbody > tr:nth-child(even) > td:first-child {
  background: var(--surface-2);
}

/* Source attributions sit in stacks of a dozen on a phone; a 15px line is not
   a target (WCAG 2.2 Target Size, Minimum). Padding, not type size, so the
   typographic rhythm of the panel foot is unchanged. */
.panel__sources a,
.hero .btn--link {
  display: inline-block;
  padding-block: 5px;
  min-height: 24px;
}
.newslist a { padding-block: 4px; }
.nav__brand { min-height: 24px; }

/* One tablist per panel, above the panes rather than repeated inside each. */
.panel__tabs {
  display: flex;
  padding: var(--s-3) var(--s-5) 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.panel__tabs::-webkit-scrollbar { display: none; }
.panel__tabs .seg { flex: 0 0 auto; }
.panel__tabs + .panel__pane > .panel__head { border-top: 0; }

/* --- Key findings: a way in ----------------------------------------------- */
/* Ten cards of identical weight are a wall. The list is numbered and the two
   findings the file leads with take the full measure. */

.finding { position: relative; }
.finding__n {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  color: var(--ink-4);
  margin-bottom: var(--s-2);
}
@media (min-width: 1024px) {
  .finding--lead { grid-column: 1 / -1; }
  .finding--lead .finding__title { font-size: 25px; line-height: 1.2; max-width: 34ch; }
  .finding--lead .finding__detail { font-size: var(--fs-body); max-width: 78ch; }
  .finding--lead .finding__n { color: var(--accent); }
}

/* A four-position ordinal, stated as a meter beside the wording it reads. */
.meter { display: inline-flex; gap: 2px; margin-right: 7px; vertical-align: 1px; }
.meter__seg {
  width: 5px; height: 11px;
  border-radius: 1px;
  box-shadow: inset 0 0 0 1px var(--rule-strong);
}
.meter__seg.is-on { background: var(--accent); box-shadow: none; }

.chart-data__csv { margin-left: var(--s-3); font-size: var(--fs-micro); }

/* The palette scrolls; the cut edge now reads as one. */
.palette__list { box-shadow: inset 0 -14px 12px -12px rgba(26, 24, 20, .10); }

/* Tabular figures inside a sentence open a gap after every full stop
   ("9. 4x the 38 seen in all of 2025"); the pill is prose, not a column. */
.kpi__delta { font-variant-numeric: normal; }

/* A wide evidence table on a phone: the year column stays put, so a figure is
   never read against the wrong row. Scoped to the two reference routes rather
   than applied to every table on the site. */
@media (max-width: 767.98px) {
  [data-perspective="timeline"] .table thead th:first-child,
  [data-perspective="library"]  .table thead th:first-child,
  [data-perspective="timeline"] .table tbody td:first-child,
  [data-perspective="library"]  .table tbody td:first-child,
  [data-perspective="timeline"] .table tbody th[scope="row"]:first-child,
  [data-perspective="library"]  .table tbody th[scope="row"]:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--rule);
  }
  [data-perspective="timeline"] .table thead th:first-child,
  [data-perspective="library"]  .table thead th:first-child { z-index: 3; }
  [data-perspective="timeline"] .table--zebra tbody tr:nth-child(even) td:first-child,
  [data-perspective="library"]  .table--zebra tbody tr:nth-child(even) td:first-child {
    background: var(--zebra);
  }
}

/* Direction of merit, at body size beside the row label. */
.dirmark { color: var(--ink-3); margin-right: 5px; font-family: var(--mono); }

/* A jump target has to clear the fixed nav and the sticky index above it. */
.section [id^="sec-"],
.section .subhead[id] { scroll-margin-top: calc(var(--nav-h) + 68px); }
@media (max-width: 767.98px) {
  .section [id^="sec-"],
  .section .subhead[id] { scroll-margin-top: calc(var(--nav-h) + 12px); }
}

/* The number beside a source is its footnote number, which is set per row
   (counter-set above), so the counter must not also be incremented. */
.sources__cols .source::before { counter-increment: none; }

/* A source line was carrying two link treatments side by side: the domain
   underlined in grey and the reference marker underlined in rust. The marker
   is a superscript numeral, not a second link to the same place. */
.footnote a.footnote__ref { border-bottom: 0; text-decoration: none; }
.footnote a.footnote__ref:hover { color: var(--accent); text-decoration: underline; }

/* ---------------------------------------------------------------------------
   26. Integration pass
   Fixes that only surfaced once every route's components sat on one stylesheet.
   Nothing above this line is modified.
   --------------------------------------------------------------------------- */

/* A technique chip can carry a whole sentence ("Standardized benchmarks (MMLU,
   HellaSwag, ...)"), which at 390px ran 450px wide and was clipped by an
   ancestor rather than wrapped. A chip is a label, not a line. */
.tool__chips .badge,
.dossier__facts .badge {
  white-space: normal;
  max-width: 100%;
  text-align: left;
}

/* Tap targets. WCAG 2.5.8 wants 24px on a pointer-coarse screen; these controls
   are all set in micro type, so they measured 17-22px tall. Inline links inside
   running prose are exempt (they are inline text) and are left alone. */
@media (max-width: 767px) {
  .pagenav__link,
  .meta__jump,
  .chart-data__toggle,
  .chart-data__csv,
  .table__csv,
  .table__sort,
  .sources__toggle,
  .lib-bar .btn--link,
  a.badge--route {
    min-height: 24px;
  }
  .table__sort,
  .chart-data__toggle,
  .sources__toggle,
  .pagenav__link,
  a.badge--route {
    display: inline-flex;
    align-items: center;
  }
  .chart-data__csv,
  .table__csv,
  .meta__jump,
  .lib-bar .btn--link {
    display: inline-flex;
    align-items: center;
  }
}

/* DESIGN.md calls the badges a "footer row"; align-items:start let each card
   stop at its own text, so a row of three cards ended at three heights and the
   badges never lined up. The card is already a column flexbox with a growing
   description, so stretching the row is all the footer needs. */
.method-grid { align-items: stretch; }

/* ==========================================================================
   Chart controls and chart-specific rules
   Appended for the chart pass: the panel tablist had no overflow affordance at
   phone widths, and a legend swatch now has to be able to encode line weight.
   ========================================================================== */

/* The chart-view tablist is a scroller, but at 390px it was hard-clipped at
   the card edge — "Frontier vs small | Fixed capability | DeepSee" — so the
   third view read as unavailable. The strip now shrinks inside its own border
   and fades at the right while there is more than two tabs to reach, which is
   the same affordance the filter segs already use. */
@media (max-width: 767.98px) {
  .panel__tabs .seg { flex: 0 1 auto; }
  .panel__tabs .seg:has(> :nth-child(4)) {
    scroll-snap-type: x proximity;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
  }
  .panel__tabs .seg__btn { scroll-snap-align: start; }
}

/* On a 390px screen three chart views fit outright once the tabs stop being
   sized for a mouse; a strip that does not overflow needs no affordance. */
@media (max-width: 479.98px) {
  .panel__tabs { padding-inline: var(--s-4); }
  .panel__tabs .seg__btn { padding: 6px 8px; font-size: 11.5px; }
}

/* Chart controls sat in three different places across one section: on the
   title row in the dumbbell and price-register panels, and on a row of their
   own below a wrapped legend in the fixed-capability panel, with the scale
   toggle at the far left there and the far right elsewhere. The tools block
   now always takes its own row under the title, right-aligned, so the same
   control is in the same place in every panel on the page. */
@media (min-width: 768px) {
  .panel__head > .panel__tools {
    flex: 1 1 100%;
    justify-content: flex-end;
    margin-left: 0;
  }
}

/* A key for a chart that separates two series by line weight has to show the
   weight: a dot cannot say which of two same-hue lines is which. */
.legend__dot--rule {
  width: 15px;
  height: 3px;
  border-radius: 1px;
}

/* ---------------------------------------------------------------------------
   27. Reading pass
   Table overflow, the in-page index, section rules and figure alignment, from
   a blind read of every route at 1440 and at 390. Nothing above is modified.
   --------------------------------------------------------------------------- */

/* --- Wide tables ---------------------------------------------------------
   A table wider than its card was hard-clipped: "SMALL IN" was sliced to
   "SMAL" and the whole "SMALL OUT" column was unreachable, with no scrollbar,
   no fade and nothing to say a column was missing. Two fixes, in order:
   first make the table fit (header labels wrap instead of forcing a nowrap
   width), then make what still overflows visibly scrollable. */

.table thead th,
.table thead .table__sort {
  white-space: normal;
  overflow-wrap: normal;      /* wrap between words, never inside one */
  word-break: normal;
  hyphens: none;
}
/* Two lines is a header; four is a paragraph standing on its column. */
.table thead th { max-width: 22ch; }
.table thead th:first-child { max-width: none; }
/* A numeric column's header and its unit line share the data's optical axis. */
.table th.num .table__sort,
.table th[data-type="number"] .table__sort { text-align: right; }
.table th.num small,
.table th[data-type="number"] small { text-align: right; }

.table-scroll { position: relative; }

/* The fade is painted over the card, not inside the scroller, so it does not
   scroll away with the content. It appears only on the side that has more. */
.table-scroll::before,
.table-scroll::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 34px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease);
  z-index: 4;
}
.table-scroll::before {
  left: 0;
  background: linear-gradient(to right, var(--surface) 18%, rgba(255, 255, 255, 0));
}
.table-scroll::after {
  right: 0;
  background: linear-gradient(to left, var(--surface) 18%, rgba(255, 255, 255, 0));
  box-shadow: inset -1px 0 0 var(--rule-strong);
}
.table-scroll[data-x="start"]::after,
.table-scroll[data-x="both"]::after,
.table-scroll[data-x="both"]::before,
.table-scroll[data-x="end"]::before { opacity: 1; }

/* Said in words as well as in a gradient: a fade alone does not name what is
   past the edge, and it is invisible to a screen reader. */
.table-scroll__hint {
  display: none;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  padding: 0 var(--s-5) var(--s-2);
}
.table-scroll[data-x="start"] .table-scroll__hint,
.table-scroll[data-x="both"] .table-scroll__hint,
.table-scroll[data-x="end"] .table-scroll__hint { display: block; }

/* A scrollbar that only appears while the pointer moves is not an affordance
   on a page a reader scrolls past in two seconds. This one is always drawn,
   in the page's own ink. */
/* Chromium ignores the ::-webkit-scrollbar pseudo-elements on any element that
   also sets scrollbar-width or scrollbar-color, and an earlier rule set
   scrollbar-width: thin — which is why these containers were drawing an
   overlay scrollbar that vanishes the moment the pointer stops. */
.table-wrap { scrollbar-width: auto; scrollbar-color: auto; }
.table-wrap::-webkit-scrollbar { height: 10px; width: 10px; }
.table-wrap::-webkit-scrollbar-track { background: var(--surface-2); border-radius: var(--r-pill); }
.table-wrap::-webkit-scrollbar-thumb {
  background: var(--rule-strong);
  border-radius: var(--r-pill);
  border: 2px solid var(--surface-2);
}
.table-wrap::-webkit-scrollbar-thumb:hover { background: var(--ink-4); }

/* The "show all rows" button now sits inside the scroller; it stays a block
   on the card, not a cell in the table. */
.table-scroll > .table__more { margin: var(--s-3) var(--s-5) var(--s-4); }

/* A value and its footnote marker are one token: left to break, the marker
   dropped to a line of its own and made that row 20px taller than its
   neighbours, which broke the zebra rhythm. */
.cell-val { white-space: nowrap; }
.table td.txt .cell-val { white-space: normal; }
.table td.txt .cell-val > .footnote { white-space: nowrap; }
.cell-null { color: var(--ink-4); }

/* A filter row belongs to the data under it, so it starts on the same edge as
   the title, the caption and the first column. Chart controls stay right. */
@media (min-width: 768px) {
  .panel__head > .panel__tools:has(> .chips) {
    justify-content: flex-start;
  }
}

/* --- Section rules -------------------------------------------------------
   ".h2, .view h2:not(...)" was winning over ".subhead" on specificity, so every
   block label rendered at 28px in wide-tracked uppercase mono - eight per page,
   each carrying more visual mass than the 40px serif H1 above it, and set in
   the least readable arrangement available. Restored to the eyebrow it is. */
.view h2.subhead:not(.panel__title) {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--s-2);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.subhead__n { color: var(--ink-4); font-variant-numeric: tabular-nums; }
.subhead__sep { color: var(--ink-4); }

/* --- In-page index -------------------------------------------------------
   Eleven destinations, no current state: the bar said where you could go and
   never where you were. */
.pagenav__links { display: contents; }
.pagenav__link.is-current {
  color: var(--ink);
  font-weight: 500;
  border-bottom-color: var(--accent);
}
.pagenav__link.is-current .pagenav__n { color: var(--accent-ink); }

/* Back to the top of a 25,000px route. Fixed to the viewport, not added to
   the sticky stack, and it appears only once there is something to come back
   from. */
.totop {
  position: fixed;
  right: var(--s-5);
  bottom: var(--s-5);
  z-index: var(--z-rail);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--surface);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
.totop:hover { color: var(--accent-ink); box-shadow: var(--shadow-pop); }

/* The header rule ran the full 1440 while this one stopped at the content
   column, leaving a ragged stacked edge at the top of every screen. */
.pagenav { border-top: 0; }

/* --- Global nav ----------------------------------------------------------
   The active item was set in a heavier face, which changed the row's metrics
   and shifted every link (and the wordmark) sideways on every route change.
   One weight for all of them; the current page is marked in ink and rule. */
.nav__link,
.nav__link[aria-current="page"] { font-weight: 500; }

/* --- Findings ------------------------------------------------------------
   A two-column grid row-aligns its cells, so a short finding left ~180px of
   hole before the next row while the column beside it ran on. Columns pack the
   entries instead, and the two leads span both. */
@media (min-width: 900px) {
  .findings {
    display: block;
    columns: 2;
    column-gap: var(--s-7);
  }
  .finding {
    break-inside: avoid;
    margin-bottom: var(--s-5);
  }
  .finding--lead {
    column-span: all;
    break-after: avoid;
  }
}

/* --- Figure cards --------------------------------------------------------
   "margin-top: auto" on both the note and the source split the card's free
   space between them, so the divider rules across one row landed at three
   different heights. One auto margin: the note-and-source block hangs from the
   bottom of the card and every rule in the row lines up. */
.kpi > .kpi__note {
  margin-top: auto;
  min-height: 4.2em;
  border-top: 0;
  padding-top: 0;
}
.kpi__foot {
  margin-top: auto;
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
}
.kpi:has(> .kpi__note) > .kpi__foot { margin-top: var(--s-3); }
.kpi__foot > .kpi__source { margin-top: 0; padding-top: 0; border-top: 0; }
.kpi__foot > .kpi__source + .kpi__source { margin-top: var(--s-1); }

/* --- Method cards --------------------------------------------------------
   "-webkit-line-clamp" is dropped on a flex item (the description is one), so
   the ellipsis was drawn at line three and a fourth line still painted, sliced
   through its letterforms by the rule below. A hard three-line box instead:
   every card clamps at the same place whether or not the clamp applies. */
.method-card__desc {
  flex: 0 0 auto;
  min-height: calc(1.5em * 3);
  max-height: calc(1.5em * 3);
  overflow: hidden;
}

/* --- Footnote runs -------------------------------------------------------
   Each marker carried 3px of padding on each side, so a run of three read as
   "39 , 17 , 1" - separators adrift on the baseline between raised numerals. */
.footnote a { padding: 3px 1px; }
.footnote__sep { margin: 0 -1px; }

/* --- Sources -------------------------------------------------------------
   Three entries stand above the disclosure, so a heading that advertises 65
   sources is not sitting on a closed box. */
.sources--peek {
  margin-bottom: var(--s-4);
  padding-left: var(--s-5);
}
.sources--peek .source::before { counter-increment: none; }

/* --- Footer --------------------------------------------------------------
   The serif wordmark sat ~5px below the mono column labels it opens the row
   with, so the three columns started on three different lines. */
.foot__grid { align-items: baseline; }

@media (max-width: 767.98px) {
  /* Adjacent header labels touched with no gutter at 390px, reading as one
     run-on string, and the fade is the only thing saying a column is hidden. */
  .table thead th { max-width: 16ch; padding-inline: var(--s-2); }
  .table th:first-child, .table td:first-child { min-width: 140px; }
  .table-scroll::before,
  .table-scroll::after { width: 24px; }
  .table-scroll__hint { padding-inline: var(--s-4); }

  .kpi > .kpi__note { min-height: 0; }
}
