/**
 * Graphics Press CSS  v4.5.0
 * ─────────────────────────────────────────────────────────────────────────────
 * A typographic and data-visualization CSS library derived from the books
 * of Edward Tufte, the cartographic color principles of Eduard Imhof, and
 * the typographic standards of Robert Bringhurst.
 *
 * Primary sources
 *   The Visual Display of Quantitative Information (Tufte, 1983/2001)
 *   Envisioning Information (Tufte, 1990)
 *   Visual Explanations (Tufte, 1997)
 *   Beautiful Evidence (Tufte, 2006)
 *   Cartographic Relief Presentation (Imhof, 1982)
 *   The Elements of Typographic Style (Bringhurst, 3rd ed.)
 *
 * Modern CSS used throughout
 *   @layer          — specificity-safe cascade; consumer overrides require
 *                     no !important and no selector wrestling
 *   oklch()         — perceptually uniform color; categorical palette at
 *                     equal lightness per Imhof's equal-weight principle
 *   clamp()         — fluid type scale; body scales 14px → 16px with viewport
 *   font-variant-numeric — oldstyle figures in prose, tabular lining in tables
 *   position: sticky — sidenotes remain visible while scrolling their section
 *   prefers-reduced-motion — sparkline animation gated correctly
 *   prefers-color-scheme  — dark mode: warm paper inverted, not naive black
 *
 * SVG color note
 *   CSS custom properties inside @layer do not reliably cascade into SVG
 *   element style="" attributes in all browsers. For inline SVG charts:
 *   use hardcoded hex presentation attributes (stroke="#b5322a").
 *   CSS vars work normally on HTML elements. Heat table cells use
 *   precomputed oklch() values set as inline style="background:oklch(...)".
 *
 * MIT License. See LICENSE for details.
 * ─────────────────────────────────────────────────────────────────────────────
 */

/* ── ET Book (Tufte's open-source Bembo digitisation) ───────────────────── */

@font-face {
  font-family: "ET Book";
  src: url("https://edwardtufte.github.io/et-book/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff") format("woff"),
       url("https://edwardtufte.github.io/et-book/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf") format("truetype");
  font-weight: normal; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "ET Book";
  src: url("https://edwardtufte.github.io/et-book/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff") format("woff"),
       url("https://edwardtufte.github.io/et-book/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf") format("truetype");
  font-weight: normal; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "ET Book";
  src: url("https://edwardtufte.github.io/et-book/et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff") format("woff"),
       url("https://edwardtufte.github.io/et-book/et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf") format("truetype");
  font-weight: bold; font-style: normal; font-display: swap;
}

/* ── Layer order ─────────────────────────────────────────────────────────────
   Consumer overrides: write unlayered CSS or add a later named @layer.
   @layer my-theme { :root { --gp-red: oklch(55% 0.18 340); } }          */

@layer gp.reset, gp.tokens, gp.base, gp.layout, gp.components, gp.dataviz, gp.utilities;


/* ═══════════════════════════════════════════════════════════════════════════
   TOKENS  — override any variable at :root to retheme without forking
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.tokens {

  :root {
    color-scheme: light;

    /* Layout ─────────────────────────────────────────────────────── */
    /* Layout ─────────────────────────────────────────────────────── */
    --gp-text-width:   640px;   /* reading column; ~60 chars at 15px */
    --gp-margin-width: 260px;   /* sidenote / margin figure column   */
    --gp-gutter:        48px;   /* gap between text and margin       */

    /* Outer margin: fluid, scales with viewport.
       clamp(floor, preferred, ceiling):
         48px  at ≤600px  — always enough to breathe, never touch the edge
         64px  at 800px   — comfortable on tablet/narrow desktop
         80px  at 1000px  — book-like on typical desktop
         96px  at 1200px+ — generous; Tufte's print outer margin ≈ 15–20% of width

       In print, Tufte's outer margins are roughly 1–1.5 inches on a 9" page
       (~11–17% of page width). 8vw at 1000px = 80px = 8% — screen is less
       generous than print by design, but still clearly intentional.          */
    --gp-outer-margin: clamp(3rem, 8vw, 6rem);

    --gp-page-width: calc(var(--gp-text-width) + var(--gp-gutter) + var(--gp-margin-width));

    /* Typefaces ──────────────────────────────────────────────────── */
    --gp-serif: "ET Book", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
    --gp-sans:  "Gill Sans", "Gill Sans MT", Calibri, Optima, "Trebuchet MS", sans-serif;
    --gp-mono:  "Lucida Console", "Andale Mono", Monaco, Consolas, monospace;

    /* Fluid type scale ───────────────────────────────────────────── */
    --gp-font-size:   clamp(14px, 1vw + 10px, 16px);
    --gp-line-height: clamp(1.58, 1.5 + 0.4vw, 1.68);
    --gp-small:   0.8em;
    --gp-caption: 0.77em;
    --gp-micro:   0.69em;

    /* Spacing ────────────────────────────────────────────────────── */
    --gp-space-xs: 0.25rem;
    --gp-space-sm: 0.5rem;
    --gp-space-md: 1rem;
    --gp-space-lg: 2rem;
    --gp-space-xl: 4rem;

    /* Surface — warm cream, not pure white ───────────────────────── */
    --gp-paper:       oklch(99.4% 0.008 98);   /* ≈ #fffff8  */
    --gp-ink:         oklch(17%   0.004 60);   /* ≈ #111111  */
    --gp-margin-ink:  oklch(43%   0.003 60);   /* ≈ #555555  */
    --gp-ghost-ink:   oklch(69%   0.003 60);   /* ≈ #aaaaaa  */
    --gp-rule:        oklch(62%   0.002 60);   /* ≈ #999999  */
    --gp-light-rule:  oklch(84%   0.005 95);   /* ≈ #d4d4c8  */
    --gp-code-bg:     oklch(95%   0.006 95);   /* ≈ #f0f0e8  */

    /* Categorical palette — all at equal perceptual lightness ───────
       Imhof's equal-weight principle: every series reads the same
       visual weight. Green/ochre ↑ slightly for Helmholtz-Kohlrausch. */
    --gp-red:         oklch(44%  0.14  27);    /* muted crimson  ≈ #b5322a */
    --gp-red-light:   oklch(64%  0.10  27);    /*               ≈ #d98080 */
    --gp-blue:        oklch(44%  0.09 251);    /* slate blue     ≈ #3a5a8c */
    --gp-blue-light:  oklch(64%  0.07 251);    /*               ≈ #90a8c8 */
    --gp-green:       oklch(50%  0.08 149);    /* sage green     ≈ #4a7a50 */
    --gp-green-light: oklch(67%  0.06 149);    /*               ≈ #92b897 */
    --gp-ochre:       oklch(49%  0.10  72);    /* warm ochre     ≈ #8b6914 */
    --gp-ochre-light: oklch(67%  0.08  72);    /*               ≈ #c8a85a */
    --gp-brown:       oklch(42%  0.09  52);    /* warm brown     ≈ #6b4423 */
    --gp-gray-data:   oklch(51%  0.002 60);    /* context gray   ≈ #777777 */

    /* Sequential ramp — uniform lightness steps, single ochre hue ── */
    --gp-seq-1: oklch(95%  0.04  80);
    --gp-seq-2: oklch(82%  0.07  76);
    --gp-seq-3: oklch(68%  0.09  72);
    --gp-seq-4: oklch(55%  0.10  68);
    --gp-seq-5: oklch(42%  0.10  65);

    /* Diverging ramp — blue ← midpoint → red ───────────────────── */
    --gp-div-lo-2: oklch(44%  0.09 251);
    --gp-div-lo-1: oklch(64%  0.07 251);
    --gp-div-mid:  oklch(92%  0.004 95);
    --gp-div-hi-1: oklch(64%  0.10  27);
    --gp-div-hi-2: oklch(44%  0.14  27);

    /* Chart interop palette — semantic aliases for JS charting libs ─ */
    --gp-chart-positive:      var(--gp-green);
    --gp-chart-positive-soft: oklch(from var(--gp-green) 93% 0.03 h / 0.35);
    --gp-chart-negative:      var(--gp-red);
    --gp-chart-negative-soft: oklch(from var(--gp-red) 93% 0.04 h / 0.35);
    --gp-chart-neutral:       var(--gp-gray-data);
    --gp-chart-accent-1:      var(--gp-blue);
    --gp-chart-accent-2:      var(--gp-ochre);
    --gp-chart-accent-3:      var(--gp-blue-light);
    --gp-chart-accent-4:      var(--gp-red-light);
    --gp-chart-grid:          oklch(from var(--gp-light-rule) l c h / 0.7);
    --gp-chart-axis:          var(--gp-margin-ink);
    --gp-chart-zero:          oklch(from var(--gp-rule) l c h / 0.9);
    --gp-chart-surface:       oklch(from var(--gp-paper) calc(l - 0.012) c h);

    /* Animation ──────────────────────────────────────────────────── */
    --gp-ease:     cubic-bezier(0.4, 0, 0.2, 1);
    --gp-ease-out: cubic-bezier(0, 0, 0.2, 1);
  }

  /* Dark mode — prefers-color-scheme ───────────────────────────────
     Warm dark paper (not pure black). Data colors at L=66% to
     maintain contrast and equal weight against dark background.     */
  @media (prefers-color-scheme: dark) {
    :root:not(.light):not([data-theme="light"]) {
      color-scheme: dark;
      --gp-paper:       oklch(17%   0.008  80);
      --gp-ink:         oklch(90%   0.005  85);
      --gp-margin-ink:  oklch(63%   0.005  85);
      --gp-ghost-ink:   oklch(40%   0.004  85);
      --gp-rule:        oklch(35%   0.003  85);
      --gp-light-rule:  oklch(27%   0.005  85);
      --gp-code-bg:     oklch(22%   0.007  80);
      --gp-red:         oklch(66%   0.13  27);
      --gp-red-light:   oklch(76%   0.09  27);
      --gp-blue:        oklch(66%   0.09 251);
      --gp-blue-light:  oklch(76%   0.06 251);
      --gp-green:       oklch(66%   0.08 149);
      --gp-green-light: oklch(76%   0.06 149);
      --gp-ochre:       oklch(66%   0.09  72);
      --gp-ochre-light: oklch(76%   0.07  72);
      --gp-gray-data:   oklch(58%   0.002 60);
      --gp-seq-1: oklch(35%  0.06 72); --gp-seq-2: oklch(47%  0.08 72);
      --gp-seq-3: oklch(59%  0.09 72); --gp-seq-4: oklch(71%  0.09 72);
      --gp-seq-5: oklch(83%  0.07 72);
      --gp-div-lo-2: oklch(66%  0.09 251); --gp-div-lo-1: oklch(76%  0.06 251);
      --gp-div-mid:  oklch(25%  0.004 85);
      --gp-div-hi-1: oklch(76%  0.09  27); --gp-div-hi-2: oklch(66%  0.13  27);
    }
  }

}

/* ── Light mode manual class / attribute ──────────────────────────────────── */

.light,
[data-theme="light"] {
  color-scheme: light;
  --gp-paper:       oklch(99.4% 0.008 98);
  --gp-ink:         oklch(17%   0.004 60);
  --gp-margin-ink:  oklch(43%   0.003 60);
  --gp-ghost-ink:   oklch(69%   0.003 60);
  --gp-rule:        oklch(62%   0.002 60);
  --gp-light-rule:  oklch(84%   0.005 95);
  --gp-code-bg:     oklch(95%   0.006 95);
  --gp-red:         oklch(44%  0.14  27);
  --gp-red-light:   oklch(64%  0.10  27);
  --gp-blue:        oklch(44%  0.09 251);
  --gp-blue-light:  oklch(64%  0.07 251);
  --gp-green:       oklch(50%  0.08 149);
  --gp-green-light: oklch(67%  0.06 149);
  --gp-ochre:       oklch(49%  0.10  72);
  --gp-ochre-light: oklch(67%  0.08  72);
  --gp-gray-data:   oklch(51%   0.002 60);
  --gp-seq-1: oklch(95%  0.04  80);
  --gp-seq-2: oklch(82%  0.07  76);
  --gp-seq-3: oklch(68%  0.09  72);
  --gp-seq-4: oklch(55%  0.10  68);
  --gp-seq-5: oklch(42%  0.10  65);
  --gp-div-lo-2: oklch(44%  0.09 251);
  --gp-div-lo-1: oklch(64%  0.07 251);
  --gp-div-mid:  oklch(92%  0.004 95);
  --gp-div-hi-1: oklch(64%  0.10  27);
  --gp-div-hi-2: oklch(44%  0.14  27);
}

/* ── Dark mode manual class — OUTSIDE @layer so it beats everything ─────────
   Unlayered CSS wins over all @layer rules regardless of specificity.
   Apply .dark to <html> via JavaScript to activate.
   @media prefers-color-scheme still applies when .light class is absent.      */

.dark,
[data-theme="dark"] {
  color-scheme: dark;
  --gp-paper:       oklch(17%   0.008  80);
  --gp-ink:         oklch(90%   0.005  85);
  --gp-margin-ink:  oklch(63%   0.005  85);
  --gp-ghost-ink:   oklch(40%   0.004  85);
  --gp-rule:        oklch(35%   0.003  85);
  --gp-light-rule:  oklch(27%   0.005  85);
  --gp-code-bg:     oklch(22%   0.007  80);
  --gp-red:         oklch(66%   0.13  27);
  --gp-red-light:   oklch(76%   0.09  27);
  --gp-blue:        oklch(66%   0.09 251);
  --gp-blue-light:  oklch(76%   0.06 251);
  --gp-green:       oklch(66%   0.08 149);
  --gp-green-light: oklch(76%   0.06 149);
  --gp-ochre:       oklch(66%   0.09  72);
  --gp-ochre-light: oklch(76%   0.07  72);
  --gp-gray-data:   oklch(58%   0.002 60);
  --gp-seq-1: oklch(35%  0.06 72); --gp-seq-2: oklch(47%  0.08 72);
  --gp-seq-3: oklch(59%  0.09 72); --gp-seq-4: oklch(71%  0.09 72);
  --gp-seq-5: oklch(83%  0.07 72);
  --gp-div-lo-2: oklch(66%  0.09 251); --gp-div-lo-1: oklch(76%  0.06 251);
  --gp-div-mid:  oklch(25%  0.004 85);
  --gp-div-hi-1: oklch(76%  0.09  27); --gp-div-hi-2: oklch(66%  0.13  27);
}

/* ── SVG color tokens — outside @layer so they cascade into SVG style="" attributes ───
   CSS custom properties inside @layer don't reliably resolve in SVG.
   These are defined at brace depth 0 and cascade correctly everywhere.
   Light values match the hardcoded hex in the original Tufte palette.
   Dark values shift:
     Ink/text   → warm near-white for legibility on dark paper
     Neutrals   → inverted: light grays become dark grays
     Data colors → L=66% per the dark mode palette (equal-weight principle)     */

:root {
  /* Structural — ink, axes, labels */
  --svg-ink:        #111111;   /* body text weight lines, axes */
  --svg-margin:     #555555;   /* secondary labels, tick values */
  --svg-mid:        #777777;   /* chart titles, mid-weight annotations */
  --svg-rule-mid:   #999999;   /* medium rules, some axis lines */

  /* Ghost / neutral tracks */
  --svg-ghost:      #aaaaaa;   /* ghost lines, track backgrounds */
  --svg-rule:       #cccccc;   /* light rules, grid lines */
  --svg-light-rule: #d4d4c8;   /* very light rules, track lines */
  --svg-soft:       #dddddd;   /* soft separators */
  --svg-faint:      #eeeeee;   /* barely-there backgrounds */
  --svg-dim:        #888888;   /* ghosted comparison lines */
  --svg-dark-rule:  #333333;   /* stronger rules on some charts */

  /* Data — categorical, equal perceptual lightness */
  --svg-red:        #b5322a;   /* primary highlight / decrease */
  --svg-blue:       #3a5a8c;   /* primary comparison / before */
  --svg-green:      #4a7a50;   /* positive / growth */
  --svg-ochre:      #8b6914;   /* fourth category */
  --svg-blue-light: #90a8c8;   /* muted blue connector (dumbbell UK) */
}

/* Dark mode overrides — same selector as .dark for tokens, brace depth 0 */
.dark,
[data-theme="dark"] {
  --svg-ink:        #e6e0d8;
  --svg-margin:     #a09898;
  --svg-mid:        #8a8480;
  --svg-rule-mid:   #606060;
  --svg-ghost:      #505050;
  --svg-rule:       #404040;
  --svg-light-rule: #383430;
  --svg-soft:       #353030;
  --svg-faint:      #2e2a26;
  --svg-dim:        #585450;
  --svg-dark-rule:  #888480;
  --svg-red:        #e07070;
  --svg-blue:       #7090c8;
  --svg-green:      #70b078;
  --svg-ochre:      #c8a040;
  --svg-blue-light: #7090c8;
}

/* ── Heat table dark mode — darken inline oklch backgrounds ──────────────────
   Inline background:oklch() values are hardcoded for light mode. In dark mode
   the cool end (L≈95%) produces near-white cells with near-white text → unreadable.
   An inset box-shadow overlays a dark wash on the background without affecting
   text color. Text is forced to light. The hue ramp is preserved.             */
.dark .heat-table td.heat,
.dark .heat-table td.heat-div,
[data-theme="dark"] .heat-table td.heat,
[data-theme="dark"] .heat-table td.heat-div { color: oklch(93% 0.005 85) !important; box-shadow: inset 0 0 0 100vmax oklch(17% 0.008 80 / 0.6); }

@media (prefers-color-scheme: dark) {
  :root:not(.light):not([data-theme="light"]) .heat-table td.heat,
  :root:not(.light):not([data-theme="light"]) .heat-table td.heat-div { color: oklch(93% 0.005 85) !important; box-shadow: inset 0 0 0 100vmax oklch(17% 0.008 80 / 0.6); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESET
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.reset {
  *, *::before, *::after { box-sizing: border-box; }
  html {
    font-size: var(--gp-font-size);
    background: var(--gp-paper); color: var(--gp-ink);
    transition: background-color 0.25s var(--gp-ease), color 0.25s var(--gp-ease);
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   BASE  — typography, prose, and structural HTML elements
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.base {

  body {
    font-family: var(--gp-serif);
    font-weight: normal;
    line-height: var(--gp-line-height);
    background: var(--gp-paper); color: var(--gp-ink);
    margin: 0; padding: 0;
    counter-reset: sidenote-counter;
    text-align: left;
    hyphens: none; -webkit-hyphens: none;
    font-variant-numeric: oldstyle-nums proportional-nums;
    font-optical-sizing: auto;
    /* Minimum page breathing room — applies even when <article> is absent.
       Ensures text is never flush against the viewport edge regardless of
       how the library is used. The article's own padding adds on top.    */
    min-height: 100dvh;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }

  /* Headings — italic, never bold; hierarchy through size not weight */
  h1 { font-size: clamp(1.7rem, 3vw + 0.8rem, 2.4rem); font-style: italic; font-weight: normal; line-height: 1.18; font-optical-sizing: auto; margin: 0 0 var(--gp-space-sm); max-width: var(--gp-text-width); }
  h2 { font-size: clamp(1rem, 0.8vw + 0.75rem, 1.1rem); font-style: italic; font-weight: normal; margin: var(--gp-space-lg) 0 var(--gp-space-sm); max-width: var(--gp-text-width); }
  h3 { font-size: 1rem; font-style: italic; font-weight: normal; margin: var(--gp-space-md) 0 var(--gp-space-xs); max-width: var(--gp-text-width); }
  h4, h5, h6 { font-size: 0.94rem; font-weight: normal; font-variant: small-caps; letter-spacing: 0.06em; margin: var(--gp-space-md) 0 var(--gp-space-xs); max-width: var(--gp-text-width); }

  .subtitle { font-size: 1.04rem; font-style: italic; margin: calc(-1 * var(--gp-space-xs)) 0 var(--gp-space-lg); color: var(--gp-margin-ink); max-width: var(--gp-text-width); }
  .author   { font-family: var(--gp-sans); font-size: var(--gp-small); letter-spacing: 0.04em; color: var(--gp-margin-ink); margin: calc(-1 * var(--gp-space-md)) 0 var(--gp-space-xl); font-variant-numeric: lining-nums; max-width: var(--gp-text-width); }

  p { margin: 0 0 var(--gp-space-md); max-width: var(--gp-text-width); }
  p + p { margin-top: calc(-1 * var(--gp-space-sm)); text-indent: 1.5em; }
  h1 + p, h2 + p, h3 + p, h4 + p, blockquote + p, figure + p, hr + p { text-indent: 0; }
  p.lead { font-size: 1.06rem; text-indent: 0; }
  p.drop-cap::first-letter { font-size: 3.6em; line-height: 0.72; float: left; padding-right: 0.06em; margin-top: 0.06em; font-style: normal; }

  abbr, .small-caps { font-variant: small-caps; letter-spacing: 0.06em; font-size: 0.9em; }
  em  { font-style: italic; }
  strong { font-weight: bold; }
  sup, sub { font-size: 0.7em; line-height: 0; position: relative; vertical-align: baseline; font-variant-numeric: lining-nums; }
  sup { top: -0.5em; } sub { bottom: -0.25em; }

  a { color: var(--gp-ink); text-decoration: underline; text-decoration-color: var(--gp-light-rule); text-underline-offset: 2px; transition: text-decoration-color 0.15s; }
  a:hover { text-decoration-color: var(--gp-ink); }
  .sidenote a, .marginnote a, figcaption a { color: var(--gp-margin-ink); }

  hr { border: none; margin: var(--gp-space-xl) 0; max-width: var(--gp-text-width); }
  hr::after { content: "· · ·"; display: block; text-align: center; color: var(--gp-light-rule); letter-spacing: 0.5em; }
  .rule-thin { border: none; border-top: 0.5px solid var(--gp-light-rule); margin: var(--gp-space-md) 0; max-width: var(--gp-text-width); }

  /* Numeric OpenType features — tables override body's oldstyle setting */
  table, .lnf { font-variant-numeric: lining-nums tabular-nums; }
  .unit { font-size: 0.82em; color: var(--gp-margin-ink); font-variant-numeric: lining-nums; }
  .datum { font-variant-numeric: lining-nums tabular-nums; font-family: var(--gp-sans); font-size: 0.9em; letter-spacing: -0.01em; }
  .data-label { font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-margin-ink); }
  .source-line { font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-ghost-ink); margin-top: var(--gp-space-xs); max-width: var(--gp-text-width); }
  .source-line::before { content: "Source: "; }

  ul, ol { padding-left: 1.5em; margin: 0 0 var(--gp-space-md); max-width: var(--gp-text-width); }
  li { margin-bottom: var(--gp-space-xs); line-height: var(--gp-line-height); }
  li > ul, li > ol { margin: var(--gp-space-xs) 0; }
  dl { margin: 0 0 var(--gp-space-md); max-width: var(--gp-text-width); }
  dt { font-variant: small-caps; letter-spacing: 0.05em; margin-top: var(--gp-space-sm); }
  dd { margin-left: 1.5em; margin-bottom: var(--gp-space-xs); color: var(--gp-margin-ink); font-size: var(--gp-small); }

  blockquote { font-style: italic; margin: var(--gp-space-md) 0 var(--gp-space-md) 2em; padding: 0; border: none; max-width: calc(var(--gp-text-width) - 2em); }
  blockquote footer, blockquote cite { font-style: normal; font-size: var(--gp-small); color: var(--gp-margin-ink); display: block; margin-top: var(--gp-space-xs); }
  blockquote footer::before { content: "— "; }

  .epigraph { margin: var(--gp-space-xl) 0 var(--gp-space-xl) 5%; max-width: var(--gp-text-width); }
  .epigraph > blockquote { font-style: italic; font-size: 1.04rem; margin: 0; padding: 0; border: none; }
  .epigraph > blockquote footer { font-style: normal; font-size: var(--gp-small); color: var(--gp-margin-ink); display: block; margin-top: var(--gp-space-sm); }

  code, kbd, samp { font-family: var(--gp-mono); font-size: 0.84em; background: var(--gp-code-bg); padding: 0.06em 0.28em; border-radius: 2px; font-variant-numeric: lining-nums; transition: background-color 0.25s; }
  pre { background: var(--gp-code-bg); padding: var(--gp-space-md); overflow-x: auto; margin: var(--gp-space-md) 0; border-left: 2px solid var(--gp-light-rule); max-width: var(--gp-text-width); transition: background-color 0.25s, border-color 0.25s; }
  pre code { background: none; padding: 0; font-size: var(--gp-small); line-height: 1.5; }

  .new-thought { font-variant: small-caps; letter-spacing: 0.08em; }
  .callout { font-size: var(--gp-small); color: var(--gp-margin-ink); font-style: italic; padding-left: 1em; border-left: 1px solid var(--gp-light-rule); margin: var(--gp-space-sm) 0; max-width: var(--gp-text-width); }

  /* data-note: on-demand methodology / source notes */
  details.data-note { font-size: var(--gp-small); color: var(--gp-margin-ink); margin: var(--gp-space-sm) 0; border-left: 1px solid var(--gp-light-rule); padding-left: var(--gp-space-sm); max-width: var(--gp-text-width); }
  details.data-note summary { cursor: pointer; font-family: var(--gp-sans); font-size: var(--gp-micro); letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); list-style: none; padding: var(--gp-space-xs) 0; transition: color 0.15s; user-select: none; }
  details.data-note summary::-webkit-details-marker { display: none; }
  details.data-note summary::before { content: "▸  "; font-size: 0.8em; }
  details.data-note[open] summary::before { content: "▾  "; }
  details.data-note summary:hover { color: var(--gp-margin-ink); }

  .bibliography { margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .bibliography ol, .bibliography ul { padding-left: 0; list-style: none; }
  .bibliography li { font-size: var(--gp-small); padding-left: 2em; text-indent: -2em; margin-bottom: var(--gp-space-sm); color: var(--gp-margin-ink); line-height: 1.5; }
  .bibliography .title { font-style: italic; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   LAYOUT
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.layout {

  article {
    position: relative;
    max-width: var(--gp-page-width);
    margin: 0 auto;
    /* Vertical: generous top/bottom breathing.
       Horizontal: the fluid --gp-outer-margin does the work.
       On wide screens this naturally centers the text column with
       substantial white space on both sides — exactly as intended.      */
    padding: var(--gp-space-xl) var(--gp-outer-margin);
  }
  section { padding-top: var(--gp-space-lg); }

  .running-header {
    font-family: var(--gp-sans); font-size: var(--gp-micro); letter-spacing: 0.12em;
    text-transform: uppercase; color: var(--gp-ghost-ink);
    max-width: var(--gp-page-width);
    display: flex; justify-content: space-between;
    border-bottom: 0.5px solid var(--gp-light-rule);
    padding-bottom: var(--gp-space-sm); margin-bottom: var(--gp-space-xl);
    transition: border-color 0.25s, color 0.25s;
  }

  /* Two-column figure comparison */
  .figure-compare { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gp-space-md); max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; align-items: start; }
  .figure-compare.figure-compare-full { max-width: var(--gp-page-width); }
  .figure-compare figure { margin: 0; max-width: none; }
  .figure-compare figcaption { float: none !important; width: auto !important; margin-right: 0 !important; margin-top: var(--gp-space-xs); }

  /* Before/after columns */
  .compare-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gp-space-lg); max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; border-top: 0.75px solid var(--gp-rule); padding-top: var(--gp-space-md); }
  .compare-wrap.compare-wrap-full { max-width: var(--gp-page-width); }
  .compare-col { font-size: var(--gp-small); }
  .compare-col__header { font-family: var(--gp-sans); font-size: var(--gp-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--gp-margin-ink); margin-bottom: var(--gp-space-sm); padding-bottom: 2px; border-bottom: 0.5px solid var(--gp-light-rule); }
  .compare-col.before { color: var(--gp-margin-ink); }

  /* Pull statistics grid */
  .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--gp-space-md) var(--gp-space-lg); border-top: 1.5px solid var(--gp-ink); padding-top: var(--gp-space-md); margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); transition: border-color 0.25s; }

  /* Evidence layout (Beautiful Evidence pp. 82–97)
     Image + analysis column side by side as a unified analytical object. */
  .evidence { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--gp-space-lg); max-width: var(--gp-page-width); margin: var(--gp-space-lg) 0; align-items: start; }
  .evidence__image { margin: 0; max-width: none; }
  .evidence__image img, .evidence__image svg { max-width: 100%; height: auto; display: block; }
  .evidence__image figcaption { float: none; width: auto; margin-right: 0; margin-top: var(--gp-space-xs); font-size: var(--gp-caption); font-family: var(--gp-sans); color: var(--gp-margin-ink); }
  .evidence__analysis { font-size: var(--gp-small); line-height: 1.6; color: var(--gp-ink); padding-top: 0.1rem; }
  .evidence__analysis p { max-width: none; }
  .evidence__analysis p + p { text-indent: 1.2em; }
  .evidence__caption { grid-column: 1 / -1; font-family: var(--gp-sans); font-size: var(--gp-caption); color: var(--gp-margin-ink); border-top: 0.5px solid var(--gp-light-rule); padding-top: var(--gp-space-xs); margin-top: var(--gp-space-xs); }

  /* Analytical brief framing for dashboard-like narrative pages */
  .brief-header { display: grid; grid-template-columns: minmax(0, 1fr) minmax(12rem, auto); gap: var(--gp-space-md) var(--gp-space-lg); align-items: end; max-width: var(--gp-page-width); margin: var(--gp-space-lg) 0; padding-bottom: var(--gp-space-sm); border-bottom: 0.75px solid var(--gp-rule); }
  .brief-header__meta { margin: 0 0 0.4rem; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .brief-header__title { margin: 0; max-width: none; font-size: clamp(1.5rem, 2vw + 1rem, 2.2rem); }
  .brief-header__dek { margin: 0.45rem 0 0; max-width: 52rem; font-size: var(--gp-small); color: var(--gp-margin-ink); text-indent: 0; }
  .brief-header__stat { text-align: right; align-self: start; min-width: 12rem; max-width: min(24rem, 100%); }
  .brief-header__label { display: block; margin-bottom: 0.2rem; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .brief-header__value { display: block; font-size: clamp(2rem, 3vw + 0.7rem, 3.1rem); line-height: 0.95; color: var(--gp-green); font-style: italic; font-variant-numeric: lining-nums tabular-nums; }
  .brief-header__subvalue { display: block; margin-top: 0.2rem; font-family: var(--gp-sans); font-size: var(--gp-caption); color: var(--gp-margin-ink); }
  .brief-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem 0.7rem; margin-top: 0.45rem; }
  .brief-header__title--identifier { font-family: var(--gp-mono); font-style: normal; line-height: 1.18; overflow-wrap: anywhere; word-break: break-word; }
  .brief-header__title-row { grid-column: 1 / -1; }
  .brief-header__meta-row { display: contents; }
  .brief-backlink { display: inline-block; margin-bottom: var(--gp-space-sm); font-family: var(--gp-sans); font-size: 0.8rem; letter-spacing: 0.04em; color: var(--gp-ghost-ink); text-decoration: none; }
  .brief-backlink:hover { color: var(--gp-ink); }

  /* Narrative slippy-map frame: map, inset key, and supporting summary */
  .gp-map-block { max-width: var(--gp-page-width); margin: var(--gp-space-lg) 0; }
  .gp-map-frame {
    position: relative;
    border: 0.5px solid var(--gp-light-rule);
    background: var(--gp-code-bg);
    min-height: 28rem;
    overflow: hidden;
    box-shadow: 0 10px 30px oklch(from var(--gp-ink) l c h / 0.08);
    transition: border-color 0.25s, background-color 0.25s, box-shadow 0.25s;
  }
  .gp-map { width: 100%; min-height: 28rem; background: oklch(from var(--gp-paper) calc(l - 0.02) c h); }
  .gp-map-panel {
    position: absolute;
    left: var(--gp-space-md);
    top: var(--gp-space-md);
    z-index: 2;
    width: min(19rem, calc(100% - 2rem));
    padding: 0.8rem 0.9rem;
    background: oklch(from var(--gp-paper) l c h / 0.92);
    border: 0.5px solid oklch(from var(--gp-rule) l c h / 0.5);
    backdrop-filter: blur(10px);
  }
  .gp-map-kicker {
    display: block;
    margin-bottom: 0.35rem;
    font-family: var(--gp-sans);
    font-size: var(--gp-micro);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gp-ghost-ink);
  }
  .gp-map-title {
    margin: 0 0 0.45rem;
    font-size: 1rem;
    line-height: 1.3;
    color: var(--gp-ink);
    max-width: none;
  }
  .gp-map-panel p {
    margin: 0;
    max-width: none;
    font-family: var(--gp-sans);
    font-size: var(--gp-small);
    line-height: 1.45;
    color: var(--gp-margin-ink);
    text-indent: 0;
  }
  .gp-map-key {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.9rem;
    margin: 0.7rem 0 0;
    padding: 0;
    list-style: none;
  }
  .gp-map-key li {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    font-family: var(--gp-sans);
    font-size: var(--gp-micro);
    letter-spacing: 0.02em;
    color: var(--gp-margin-ink);
  }
  .gp-map-swatch {
    width: 0.72rem;
    height: 0.72rem;
    border-radius: 999px;
    border: 1px solid oklch(from var(--gp-paper) calc(l - 0.18) c h / 0.55);
    flex: 0 0 auto;
  }
  .gp-map-swatch.red { background: var(--gp-red); }
  .gp-map-swatch.blue { background: var(--gp-blue); }
  .gp-map-swatch.ochre { background: var(--gp-ochre); }
  .gp-map-meta {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
    margin-top: var(--gp-space-sm);
    padding-top: var(--gp-space-sm);
    border-top: 0.5px solid var(--gp-light-rule);
    font-family: var(--gp-sans);
  }
  .gp-map-stat {
    font-size: var(--gp-micro);
    color: var(--gp-ghost-ink);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  .gp-map-stat strong {
    display: block;
    margin-top: 0.12rem;
    font-size: 1rem;
    line-height: 1.2;
    letter-spacing: normal;
    text-transform: none;
    color: var(--gp-ink);
    font-weight: normal;
    font-variant-numeric: lining-nums tabular-nums;
  }
  .gp-map-frame .maplibregl-ctrl-group {
    border-radius: 0;
    box-shadow: none;
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) l c h / 0.9);
  }
  .gp-map-frame .maplibregl-ctrl button .maplibregl-ctrl-icon { filter: grayscale(1); }
  .gp-map-frame .maplibregl-popup-content {
    border-radius: 0;
    padding: 0.55rem 0.65rem;
    font-family: var(--gp-sans);
    font-size: var(--gp-small);
    color: var(--gp-ink);
    background: oklch(from var(--gp-paper) l c h / 0.96);
    box-shadow: 0 6px 20px oklch(from var(--gp-ink) l c h / 0.12);
  }
  .gp-map-frame .maplibregl-popup-tip { border-top-color: oklch(from var(--gp-paper) l c h / 0.96); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENTS  — sidenotes, figures, tables, sparklines
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.components {

  /* ── Sidenotes & Margin Notes ─────────────────────────────────────────────
     The structural innovation of Tufte's books. Notes appear beside the text
     they annotate, not below the page. position:sticky keeps them visible
     while scrolling long sections.

     Sidenote (numbered):
       <label for="sn-1" class="sidenote-toggle sidenote-number"></label>
       <input type="checkbox" id="sn-1" class="sidenote-toggle">
       <span class="sidenote">Content.</span>

     Margin note (unnumbered):
       <label for="mn-1" class="sidenote-toggle">⊕</label>
       <input type="checkbox" id="mn-1" class="sidenote-toggle">
       <span class="marginnote">Content.</span>                           */

  .sidenote-number { counter-increment: sidenote-counter; }
  .sidenote-number::after, .sidenote::before { content: counter(sidenote-counter); font-size: 0.68rem; vertical-align: super; line-height: 0; font-variant-numeric: lining-nums; }
  .sidenote-number::after { color: var(--gp-margin-ink); padding-left: 1px; }
  .sidenote::before       { color: var(--gp-margin-ink); padding-right: 4px; }
  input.sidenote-toggle { display: none; }

  .sidenote, .marginnote {
    float: right; clear: right;
    margin-right: calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)));
    width: var(--gp-margin-width);
    font-size: var(--gp-small); line-height: 1.5;
    color: var(--gp-margin-ink); font-style: normal;
    vertical-align: baseline;
    position: sticky; top: 2rem;
    padding-top: 0.08rem;
    transition: color 0.25s;
  }
  .marginnote img, .marginnote svg { max-width: 100%; height: auto; display: block; margin-bottom: var(--gp-space-xs); }
  .marginnote svg { overflow: visible; }
  .marginnote-label { font-family: var(--gp-sans); font-size: var(--gp-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--gp-ghost-ink); display: block; margin-bottom: 2px; }
  label.sidenote-toggle { display: none; cursor: pointer; }
  label.sidenote-number { display: inline; }

  .section-marker { float: right; clear: right; margin-right: calc(-1 * (var(--gp-margin-width) + var(--gp-gutter))); width: var(--gp-margin-width); font-family: var(--gp-sans); font-size: var(--gp-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--gp-ghost-ink); padding-top: 0.2rem; position: sticky; top: 2rem; }

  /* ── Figures ─────────────────────────────────────────────────────────────
     Three widths:
       <figure>                    — column-width (default)
       <figure class="figure-full"> — spans into margin
       <figure class="figure-margin"> — margin only, floated        */

  figure { max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; padding: 0; }
  figure img, figure svg, figure canvas { max-width: 100%; height: auto; display: block; }
  figure.figure-full { max-width: var(--gp-page-width); }
  figure.figure-margin { float: right; clear: right; margin-right: calc(-1 * (var(--gp-margin-width) + var(--gp-gutter))); width: var(--gp-margin-width); margin-top: 0; margin-bottom: var(--gp-space-md); }

  figcaption { font-size: var(--gp-caption); font-family: var(--gp-sans); font-optical-sizing: auto; line-height: 1.45; color: var(--gp-margin-ink); margin-top: var(--gp-space-xs); transition: color 0.25s; }
  figure:not(.figure-margin):not(.figure-full):not(.evidence__image) figcaption { float: right; clear: right; margin-right: calc(-1 * (var(--gp-margin-width) + var(--gp-gutter))); width: var(--gp-margin-width); margin-top: 0; }
  figure.figure-full figcaption { float: right; width: var(--gp-margin-width); margin-top: var(--gp-space-xs); }
  figure.figure-margin figcaption { float: none; width: auto; font-size: 0.71em; }

  /* ── Tables — Booktabs ───────────────────────────────────────────────────
     Three rules only: top 1.5px, mid 0.75px, bottom 1.5px.
     No vertical lines. Numeric columns right-aligned, tabular figures.
     Set in Gill Sans — exactly as Tufte's books.                     */

  table { max-width: var(--gp-text-width); width: 100%; border-collapse: collapse; font-family: var(--gp-sans); font-size: var(--gp-small); font-variant-numeric: lining-nums tabular-nums; margin: var(--gp-space-lg) 0; line-height: 1.4; transition: color 0.25s; }
  thead { border-top: 1.5px solid var(--gp-ink); border-bottom: 0.75px solid var(--gp-ink); }
  tbody tr:last-child td { border-bottom: 1.5px solid var(--gp-ink); padding-bottom: var(--gp-space-sm); }
  tbody tr.midrule td { border-top: 0.75px solid var(--gp-rule); padding-top: var(--gp-space-sm); }
  tbody tr.midrule-above td { padding-bottom: var(--gp-space-sm); }
  th { font-weight: normal; font-variant: small-caps; letter-spacing: 0.06em; text-align: left; padding: var(--gp-space-xs) var(--gp-space-sm); vertical-align: bottom; }
  td { padding: var(--gp-space-xs) var(--gp-space-sm); vertical-align: top; }
  td.num, th.num { text-align: right; }
  td.neg { color: var(--gp-red); } td.pos { color: var(--gp-green); }
  tr.highlight td { background: var(--gp-code-bg); font-style: italic; }
  .table-dense th, .table-dense td { padding: 2px var(--gp-space-xs); font-size: var(--gp-micro); }
  table.table-full { max-width: var(--gp-page-width); }
  table.table-striped tbody tr:nth-child(even) td { background: oklch(from var(--gp-paper) calc(l - 0.02) c h); }
  caption { font-size: var(--gp-caption); font-family: var(--gp-sans); color: var(--gp-margin-ink); text-align: left; caption-side: top; padding-bottom: var(--gp-space-xs); }

  /* ── Sparklines ──────────────────────────────────────────────────────────
     Word-sized inline charts. Draw animation gated by prefers-reduced-motion. */

  .sparkline { display: inline-block; vertical-align: middle; line-height: 1; position: relative; top: -1px; }
  .sparkline svg { overflow: visible; }

  @media (prefers-reduced-motion: no-preference) {
    .sp-draw { stroke-dasharray: 300; stroke-dashoffset: 300; animation: gp-draw 0.9s var(--gp-ease-out) forwards; }
    @keyframes gp-draw { to { stroke-dashoffset: 0; } }
  }

  /* Sparkline table — Tufte's canonical high-density format (Beautiful Evidence pp. 47–63) */
  table.sparkline-table { font-family: var(--gp-sans); font-size: var(--gp-small); }
  table.sparkline-table .sp-cell { padding-top: 2px; padding-bottom: 2px; }
  table.sparkline-table .sp-cell svg { display: block; overflow: visible; }

  /* ── Small Multiples ──────────────────────────────────────────────────── */

  .small-multiples { max-width: var(--gp-page-width); display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: var(--gp-space-md); margin: var(--gp-space-lg) 0; }
  .small-multiples-3 { grid-template-columns: repeat(3, 1fr); }
  .small-multiples-4 { grid-template-columns: repeat(4, 1fr); }
  .small-multiples-6 { grid-template-columns: repeat(6, 1fr); }
  .small-multiples figure { margin: 0; max-width: none; }
  .small-multiples figure figcaption { float: none !important; width: auto !important; margin-right: 0 !important; margin-top: var(--gp-space-xs); font-size: 0.7em; }
  .small-multiples-xlabel { grid-column: 1 / -1; font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-margin-ink); text-align: center; margin-top: calc(-1 * var(--gp-space-sm)); }

  /* ── Pull statistics ──────────────────────────────────────────────────── */

  .pull-stat { margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .pull-stat__number { font-size: clamp(2.4rem, 4vw + 1rem, 3.5rem); line-height: 1; font-style: italic; font-weight: normal; display: block; font-variant-numeric: lining-nums; }
  .pull-stat__label  { font-family: var(--gp-sans); font-size: var(--gp-small); color: var(--gp-margin-ink); letter-spacing: 0.04em; display: block; margin-top: 0.2em; }
  .pull-stat__context { font-size: var(--gp-small); color: var(--gp-ghost-ink); font-style: italic; display: block; }
  .pull-quote { font-size: clamp(1.2rem, 2vw + 0.6rem, 1.45rem); font-style: italic; line-height: 1.35; margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }

  .metric-strip { max-width: var(--gp-page-width); display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 0; border-top: 0.75px solid var(--gp-rule); border-bottom: 0.75px solid var(--gp-rule); margin: var(--gp-space-md) 0; }
  .metric-strip__item { padding: 0.55rem 0.8rem 0.5rem 0; font-family: var(--gp-sans); }
  .metric-strip__label { display: block; font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .metric-strip__value { display: block; margin-top: 0.14rem; font-size: 1.05rem; color: var(--gp-ink); font-style: italic; font-variant-numeric: lining-nums tabular-nums; }
  .metric-strip__value.green { color: var(--gp-green); }
  .metric-strip__value.red { color: var(--gp-red); }
  .metric-strip__value.blue { color: var(--gp-blue); }

  .tab-nav { max-width: var(--gp-page-width); display: flex; flex-wrap: wrap; gap: 0.1rem 0.9rem; margin: 0 0 var(--gp-space-md); padding: 0 0 var(--gp-space-xs); border-bottom: 0.5px solid var(--gp-light-rule); list-style: none; }
  .tab-nav li { margin: 0; }
  .tab-nav a, .tab-nav button { display: inline-block; padding: 0.32rem 0; border: 0; border-bottom: 1.5px solid transparent; background: none; font-family: var(--gp-sans); font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); text-decoration: none; cursor: pointer; }
  .tab-nav .is-active, .tab-nav a[aria-current="page"], .tab-nav button[aria-selected="true"] { color: var(--gp-ink); border-bottom-color: var(--gp-ink); }
  .tab-nav.tab-nav--filled { gap: 0.25rem 0.55rem; border-bottom-color: var(--gp-rule); }
  .tab-nav.tab-nav--filled a, .tab-nav.tab-nav--filled button { padding: 0.45rem 0.8rem; border-bottom-width: 0; color: var(--gp-margin-ink); }
  .tab-nav.tab-nav--filled .is-active,
  .tab-nav.tab-nav--filled a[aria-current="page"],
  .tab-nav.tab-nav--filled button[aria-selected="true"] { background: var(--gp-ink); color: var(--gp-paper); }

  .analytic-grid { max-width: var(--gp-page-width); display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--gp-space-sm); margin: var(--gp-space-md) 0; }
  .analytic-card { position: relative; min-height: 8.5rem; padding: 0.75rem 0.8rem 0.7rem; border: 0.5px solid var(--gp-light-rule); background: linear-gradient(180deg, oklch(from var(--gp-paper) calc(l - 0.005) c h), oklch(from var(--gp-paper) calc(l - 0.018) c h)); box-shadow: inset 0 1px 0 oklch(from var(--gp-paper) calc(l - 0.001) c h / 0.9); }
  .analytic-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--gp-ghost-ink); }
  .analytic-card.red::before { background: var(--gp-red); }
  .analytic-card.blue::before { background: var(--gp-blue); }
  .analytic-card.green::before { background: var(--gp-green); }
  .analytic-card.ochre::before { background: var(--gp-ochre); }
  .analytic-card__eyebrow { display: block; margin: 0 0 0.25rem; padding-left: 0.35rem; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .analytic-card__title { margin: 0; padding-left: 0.35rem; max-width: none; font-size: 0.98rem; line-height: 1.25; }
  .analytic-card__value { display: block; margin: 0.5rem 0 0.18rem; padding-left: 0.35rem; font-size: 1.35rem; line-height: 1; color: var(--gp-ink); font-style: italic; font-variant-numeric: lining-nums tabular-nums; }
  .analytic-card__meta { display: block; padding-left: 0.35rem; font-family: var(--gp-sans); font-size: var(--gp-caption); color: var(--gp-margin-ink); }

  .algorithm-panel { max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; border: 0.5px solid var(--gp-light-rule); background: var(--gp-code-bg); padding: var(--gp-space-md); }
  .algorithm-panel__title { margin: 0 0 0.55rem; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .algorithm-panel pre { margin: 0; max-width: none; border-left: 0; padding: 0; background: transparent; }

  .activity-timeline { max-width: var(--gp-page-width); margin: var(--gp-space-lg) 0; padding-top: var(--gp-space-xs); border-top: 0.5px solid var(--gp-light-rule); }
  .activity-timeline__header { display: flex; justify-content: space-between; gap: var(--gp-space-sm); margin-bottom: var(--gp-space-sm); font-family: var(--gp-sans); font-size: 0.74rem; color: var(--gp-ghost-ink); }
  .activity-timeline__lane { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: var(--gp-space-sm); margin-bottom: 0.45rem; font-family: var(--gp-sans); font-size: var(--gp-small); }
  .activity-timeline__label { color: var(--gp-margin-ink); text-align: right; white-space: nowrap; }
  .activity-timeline__track { position: relative; height: 0.85rem; background: oklch(from var(--gp-paper) calc(l - 0.05) c h); overflow: hidden; }
  .activity-timeline__span { position: absolute; left: var(--at-start, 0%); width: var(--at-width, 50%); height: 100%; background: var(--gp-ghost-ink); }
  .activity-timeline__span.red { background: var(--gp-red); }
  .activity-timeline__span.blue { background: var(--gp-blue); }
  .activity-timeline__span.green { background: var(--gp-green); }
  .activity-timeline__span.ochre { background: var(--gp-ochre); }
  .activity-timeline__value { color: var(--gp-ghost-ink); font-size: 0.74rem; white-space: nowrap; }

  /* Application shell / analytics UI coverage */
  .gp-app-shell { min-height: 100dvh; display: flex; flex-direction: column; background: var(--gp-paper); color: var(--gp-ink); }
  .gp-app-header { position: sticky; top: 0; z-index: 50; border-bottom: 0.5px solid var(--gp-light-rule); background: oklch(from var(--gp-paper) l c h / 0.94); backdrop-filter: blur(16px); }
  .gp-app-header__inner,
  .gp-app-main,
  .gp-app-footer__inner { width: min(100%, 100rem); margin: 0 auto; padding-left: 1.5rem; padding-right: 1.5rem; }
  .gp-app-header__inner { min-height: 4rem; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
  .gp-app-brand { display: flex; align-items: center; gap: 0.75rem; min-width: 0; font-family: var(--gp-sans); }
  .gp-app-brand__mark { width: 1.7rem; height: 1.7rem; color: var(--gp-ink); flex: 0 0 auto; }
  .gp-app-brand__title { font-size: 1rem; letter-spacing: -0.02em; color: var(--gp-ink); font-weight: 600; white-space: nowrap; }
  .gp-app-brand__meta { font-size: 0.75rem; color: var(--gp-ghost-ink); white-space: nowrap; }
  .gp-app-status { display: inline-flex; align-items: center; gap: 0.4rem; font-family: var(--gp-sans); font-size: 0.78rem; color: var(--gp-margin-ink); white-space: nowrap; }
  .gp-app-status::before { content: ""; width: 0.42rem; height: 0.42rem; border-radius: 999px; background: #79d8b9; box-shadow: 0 0 0 0.2rem oklch(82% 0.06 165 / 0.22); }
  .gp-app-main { flex: 1; width: min(100%, 100rem); padding-top: 1.35rem; padding-bottom: 1.5rem; }
  .gp-app-main--detail { width: min(100%, 86rem); }
  .gp-app-main--detail-wide { width: min(100%, 88rem); }
  .gp-app-frame { border-top: 0.5px solid var(--gp-light-rule); padding-top: 1rem; }
  .gp-app-footer { margin-top: auto; border-top: 0.5px solid var(--gp-light-rule); }
  .gp-app-footer__inner { min-height: 2.85rem; display: flex; align-items: center; justify-content: space-between; gap: 1rem; font-family: var(--gp-sans); font-size: 0.76rem; color: var(--gp-margin-ink); }
  .gp-workspace { width: min(100%, 112rem); }
  .gp-workspace__tabs,
  .gp-workspace__header,
  .gp-workspace__toolbar,
  .gp-workspace__content { max-width: none; }
  .gp-workspace__tabs { margin-bottom: 1rem; }
  .gp-workspace__toolbar { margin-top: 1rem; margin-bottom: 1.15rem; }
  .gp-workspace__toolbar .gp-toolbar__meta { font-size: 0.86rem; }
  .brief-header.gp-workspace__header { grid-template-columns: minmax(0, 1.35fr) minmax(16rem, 0.65fr); gap: 1rem 2rem; }
  .gp-workspace__header .brief-header__title { font-size: clamp(2rem, 1.6vw + 1.45rem, 3rem); line-height: 0.98; }
  .gp-workspace__header .brief-header__meta { font-size: 0.82rem; }
  .gp-workspace__header .brief-header__stat { min-width: 16rem; justify-self: end; width: min(100%, 22rem); margin-left: auto; }
  .gp-workspace__tabs.tab-nav.tab-nav--filled button { font-size: 0.84rem; padding: 0.5rem 0.9rem; }

  .gp-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem; margin: 0.9rem 0 1rem; }
  .gp-toolbar__group { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; }
  .gp-toolbar__meta { margin-left: auto; display: inline-flex; align-items: center; gap: 1rem; font-family: var(--gp-sans); font-size: 0.8rem; color: var(--gp-margin-ink); }

  .gp-btn, .gp-segmented button, .gp-chip {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
    min-height: 2.15rem; padding: 0.45rem 0.85rem;
    border: 0.5px solid var(--gp-light-rule);
    background: transparent; color: var(--gp-margin-ink);
    font-family: var(--gp-sans); font-size: 0.8rem; font-weight: 500;
    letter-spacing: 0.01em; text-decoration: none; cursor: pointer;
    transition: color 0.16s, background-color 0.16s, border-color 0.16s, box-shadow 0.16s;
  }
  .gp-btn:hover, .gp-segmented button:hover, .gp-chip:hover { color: var(--gp-ink); border-color: var(--gp-rule); background: oklch(from var(--gp-paper) calc(l - 0.02) c h); }
  .gp-btn:disabled, .gp-segmented button:disabled, .gp-chip:disabled { opacity: 0.45; cursor: default; }
  .gp-btn--primary, .gp-segmented .is-active { background: var(--gp-ink); border-color: var(--gp-ink); color: var(--gp-paper); }
  .gp-btn--primary:hover, .gp-segmented .is-active:hover { background: oklch(from var(--gp-ink) calc(l + 0.06) c h); border-color: oklch(from var(--gp-ink) calc(l + 0.06) c h); color: var(--gp-paper); }
  .gp-btn--soft { background: oklch(from var(--gp-paper) calc(l - 0.02) c h); }
  .gp-btn--sm, .gp-chip { min-height: 1.95rem; padding: 0.3rem 0.7rem; font-size: 0.78rem; }
  .gp-btn--pill, .gp-chip, .gp-segmented button { border-radius: 999px; }
  .gp-segmented { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; }

  .gp-input {
    min-height: 2.2rem; min-width: min(18rem, 100%);
    padding: 0.48rem 0.8rem; border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.01) c h);
    color: var(--gp-ink); font-family: var(--gp-sans); font-size: 0.86rem;
    outline: none; transition: border-color 0.16s, box-shadow 0.16s, background-color 0.16s;
  }
  .gp-input::placeholder { color: var(--gp-ghost-ink); }
  .gp-input:focus { border-color: var(--gp-rule); box-shadow: 0 0 0 3px oklch(from var(--gp-blue) l c h / 0.08); }

  .gp-badge {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.18rem 0.5rem; border: 0.5px solid var(--gp-light-rule);
    font-family: var(--gp-sans); font-size: 0.68rem; font-weight: 600;
    letter-spacing: 0.06em; text-transform: uppercase; color: var(--gp-margin-ink);
    background: oklch(from var(--gp-paper) calc(l - 0.02) c h);
  }
  .gp-badge::before { content: ""; width: 0.38rem; height: 0.38rem; border-radius: 999px; background: currentColor; opacity: 0.55; }
  .gp-badge--live { color: var(--gp-green); background: oklch(from var(--gp-green) 95% 0.03 h / 0.22); border-color: oklch(from var(--gp-green) 86% 0.03 h / 0.42); }
  .gp-badge--venue-blue { color: var(--gp-blue); }
  .gp-badge--venue-red { color: var(--gp-red); }
  .gp-badge--venue-ochre { color: var(--gp-ochre); }
  .gp-badge--quiet::before { display: none; }

  .gp-panel {
    padding-top: 0;
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.006) c h);
  }
  .gp-panel__header { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem; padding: 0.9rem 1rem; border-bottom: 0.5px solid var(--gp-light-rule); }
  .gp-panel__title { margin: 0; max-width: none; font-size: 0.98rem; line-height: 1.2; font-style: normal; font-family: var(--gp-sans); color: var(--gp-ink); }
  .gp-panel__meta { font-family: var(--gp-sans); font-size: 0.8rem; color: var(--gp-margin-ink); }
  .gp-panel__body { padding: 1rem; }
  .gp-panel__body > :first-child { margin-top: 0; }
  .gp-panel__body > :last-child { margin-bottom: 0; }

  .gp-kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.75rem; margin: 0 0 1rem; }
  .gp-kpi { border: 0.5px solid var(--gp-light-rule); background: oklch(from var(--gp-paper) calc(l - 0.008) c h); padding: 0.8rem 0.9rem; }
  .gp-kpi__label { display: block; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .gp-kpi__value { display: block; margin-top: 0.25rem; font-family: var(--gp-sans); font-size: 1.25rem; line-height: 1.05; color: var(--gp-ink); font-weight: 600; font-variant-numeric: lining-nums tabular-nums; }
  .gp-kpi__sub { display: block; margin-top: 0.2rem; font-family: var(--gp-sans); font-size: 0.8rem; color: var(--gp-margin-ink); }
  .gp-kpi__value.red { color: var(--gp-red); }
  .gp-kpi__value.green { color: var(--gp-green); }
  .gp-kpi__value.blue { color: var(--gp-blue); }

  .gp-data-table { width: 100%; max-width: none; margin: 0; font-size: 0.86rem; line-height: 1.5; }
  .gp-data-table thead { border-top: 0; border-bottom: 0.5px solid var(--gp-light-rule); }
  .gp-data-table thead th { font-size: 0.76rem; color: var(--gp-ghost-ink); letter-spacing: 0.08em; }
  .gp-data-table tbody tr:last-child td { border-bottom: 0; padding-bottom: var(--gp-space-xs); }
  .gp-data-table tbody tr + tr td { border-top: 0.5px solid oklch(from var(--gp-light-rule) l c h / 0.5); }
  .gp-data-table tbody tr:hover td { background: oklch(from var(--gp-paper) calc(l - 0.02) c h); }
  .gp-data-table td { padding-top: 0.55rem; padding-bottom: 0.55rem; }
  .gp-data-table__wrap { overflow: auto; }
  .gp-data-table__wrap.sticky-head thead th { position: sticky; top: 0; z-index: 1; background: oklch(from var(--gp-paper) calc(l - 0.005) c h); }

  .gp-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.9rem; }
  .gp-card {
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.007) c h);
    padding: 1rem;
  }
  .gp-card__eyebrow { display: block; font-family: var(--gp-sans); font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gp-ghost-ink); }
  .gp-card__title { margin: 0.2rem 0 0; max-width: none; font-family: var(--gp-sans); font-size: 1rem; line-height: 1.25; color: var(--gp-ink); }
  .gp-card__meta { margin-top: 0.45rem; font-family: var(--gp-sans); font-size: 0.82rem; color: var(--gp-margin-ink); }

  .gp-progress { position: relative; width: 100%; height: 0.4rem; overflow: hidden; background: oklch(from var(--gp-paper) calc(l - 0.05) c h); }
  .gp-progress__bar { width: var(--gp-progress, 0%); height: 100%; background: var(--gp-ink); }

  .gp-meter {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 7.25rem;
    font-family: var(--gp-sans);
    vertical-align: middle;
  }
  .gp-meter__track {
    position: relative;
    flex: 1 1 auto;
    min-width: 4.5rem;
    height: 0.5rem;
    overflow: hidden;
    background: oklch(from var(--gp-paper) calc(l - 0.05) c h);
  }
  .gp-meter__fill {
    display: block;
    width: var(--gp-meter-value, 0%);
    height: 100%;
    background: var(--gp-meter-color, var(--gp-ink));
  }
  .gp-meter__value {
    min-width: 2.9rem;
    text-align: right;
    font-family: var(--gp-sans);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--gp-ink);
    font-variant-numeric: lining-nums tabular-nums;
  }

  .gp-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem 1rem; font-family: var(--gp-sans); font-size: 0.78rem; color: var(--gp-margin-ink); }
  .gp-legend__item { display: inline-flex; align-items: center; gap: 0.4rem; }
  .gp-legend__swatch { width: 0.62rem; height: 0.62rem; border-radius: 999px; flex: 0 0 auto; background: var(--gp-ghost-ink); }

  .gp-note { font-family: var(--gp-sans); font-size: 0.82rem; color: var(--gp-margin-ink); line-height: 1.55; }

  .gp-chart-frame {
    border: 0.5px solid var(--gp-light-rule);
    background: var(--gp-chart-surface);
    padding: 0.85rem 0.95rem 0.95rem;
  }
  .gp-chart-frame svg { display: block; width: 100%; height: auto; overflow: visible; }
  .gp-chart-axis text,
  .gp-chart-axis-label,
  .gp-chart-value {
    fill: var(--gp-chart-axis);
    color: var(--gp-chart-axis);
    font-family: var(--gp-sans);
    font-size: 0.72rem;
  }
  .gp-chart-axis path,
  .gp-chart-axis line { stroke: var(--gp-chart-grid); }
  .gp-chart-gridline { stroke: var(--gp-chart-grid); stroke-dasharray: 4 3; }
  .gp-chart-zero { stroke: var(--gp-chart-zero); stroke-dasharray: 4 3; }
  .gp-chart-label {
    fill: var(--gp-ink);
    color: var(--gp-ink);
    font-family: var(--gp-sans);
    font-size: 0.76rem;
  }

  .gp-record-list { display: grid; gap: 0; border-top: 1px solid var(--gp-ink); }
  .gp-record {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.9rem 1.2rem;
    width: 100%;
    padding: 1.1rem 0;
    border-bottom: 0.5px solid var(--gp-light-rule);
    background: transparent;
    color: inherit;
    text-align: left;
    text-decoration: none;
    transition: background-color 0.16s, border-color 0.16s, color 0.16s;
  }
  .gp-record:hover { background: oklch(from var(--gp-paper) calc(l - 0.018) c h); }
  .gp-record__title { margin: 0; max-width: none; font-size: 1.08rem; line-height: 1.2; }
  .gp-record__eyebrow,
  .gp-record__meta,
  .gp-record__kicker {
    font-family: var(--gp-sans);
    color: var(--gp-margin-ink);
  }
  .gp-record__eyebrow,
  .gp-record__kicker {
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .gp-record__summary {
    margin: 0.45rem 0 0;
    max-width: 40rem;
    font-size: 0.96rem;
    line-height: 1.55;
    color: var(--gp-margin-ink);
    text-indent: 0;
  }
  .gp-record__meta { display: flex; flex-wrap: wrap; gap: 0.45rem 1rem; margin-top: 0.55rem; font-size: 0.8rem; }
  .gp-record__value { align-self: start; text-align: right; min-width: 8rem; }
  .gp-record__value .datum { display: block; font-size: clamp(1.45rem, 1vw + 1.15rem, 2rem); line-height: 1; }

  .gp-stack-bar {
    display: flex;
    width: 100%;
    height: 0.78rem;
    overflow: hidden;
    background: oklch(from var(--gp-paper) calc(l - 0.05) c h);
  }
  .gp-stack-bar__segment { height: 100%; background: var(--gp-chart-neutral); }

  .gp-rank-list { display: grid; gap: 0.7rem; }
  .gp-rank-card {
    padding: 0.85rem 0.95rem;
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.008) c h);
  }
  .gp-rank-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.3rem;
    font-family: var(--gp-sans);
    font-size: 0.84rem;
  }
  .gp-rank-card__label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    color: var(--gp-ink);
  }
  .gp-rank-card__swatch {
    width: 0.72rem;
    height: 0.72rem;
    border-radius: 0.18rem;
    flex: 0 0 auto;
    background: var(--gp-chart-accent-1);
  }
  .gp-rank-card__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .gp-rank-card__value {
    flex: 0 0 auto;
    font-family: var(--gp-sans);
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--gp-ink);
    font-variant-numeric: lining-nums tabular-nums;
  }
  .gp-rank-list--nested {
    margin-top: 0.45rem;
    margin-left: 1.25rem;
    gap: 0.35rem;
  }
  .gp-rank-row { display: grid; gap: 0.12rem; }
  .gp-rank-row__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    font-family: var(--gp-sans);
    font-size: 0.73rem;
    color: var(--gp-margin-ink);
  }
  .gp-rank-row__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .gp-rank-row__value {
    flex: 0 0 auto;
    font-variant-numeric: lining-nums tabular-nums;
  }

  .gp-spread {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.35rem 2rem;
    align-items: start;
    margin: 0 0 1.5rem;
  }
  .gp-spread--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gp-spread--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .gp-spread__col { min-width: 0; }
  .gp-spread__wide,
  .gp-spread__full { grid-column: 1 / -1; min-width: 0; }
  .gp-spread__rail {
    padding-top: 0.1rem;
    font-family: var(--gp-sans);
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--gp-margin-ink);
  }
  .gp-section-head {
    margin: 0 0 0.65rem;
    padding-top: 0.7rem;
    border-top: 1.5px solid var(--gp-ink);
  }
  .gp-section-head__title {
    margin: 0 0 0.2rem;
    max-width: none;
    font-size: 1.08rem;
    line-height: 1.2;
  }
  .gp-section-head__meta {
    margin: 0;
    max-width: 44rem;
    font-family: var(--gp-sans);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--gp-margin-ink);
    text-indent: 0;
  }

  .gp-link-list { display: grid; gap: 0.5rem; }
  .gp-link-card {
    display: flex; align-items: center; gap: 0.75rem; width: 100%;
    padding: 0.95rem 1rem; border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.005) c h); color: inherit; text-decoration: none;
    transition: background-color 0.16s, border-color 0.16s, color 0.16s;
  }
  .gp-link-card:hover { background: oklch(from var(--gp-paper) calc(l - 0.018) c h); border-color: var(--gp-rule); color: inherit; }
  .gp-link-card__marker { width: 0.72rem; height: 0.72rem; border-radius: 999px; flex: 0 0 auto; opacity: 0.9; }
  .gp-link-card__title { font-family: var(--gp-sans); font-size: 0.92rem; color: var(--gp-ink); }
  .gp-link-card__meta { font-family: var(--gp-sans); font-size: 0.75rem; color: var(--gp-margin-ink); }
  .gp-link-card__trail { margin-left: auto; font-family: var(--gp-sans); font-size: 0.72rem; color: var(--gp-ghost-ink); }

  .gp-state { display: flex; align-items: center; justify-content: center; gap: 0.8rem; min-height: 16rem; font-family: var(--gp-sans); font-size: 0.9rem; color: var(--gp-margin-ink); }
  .gp-state--compact { min-height: 8rem; }
  .gp-spinner { width: 1.6rem; height: 1.6rem; border-radius: 999px; border: 2px solid oklch(from var(--gp-ink) l c h / 0.14); border-top-color: var(--gp-ink); animation: gp-spin 0.85s linear infinite; }
  @keyframes gp-spin { to { transform: rotate(360deg); } }

  .gp-treemap { border: 0.5px solid var(--gp-light-rule); background: var(--gp-chart-surface); overflow: hidden; }
  .gp-treemap__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.7rem 0.9rem;
    border-bottom: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.012) c h);
    font-family: var(--gp-sans);
  }
  .gp-treemap__title { margin: 0; max-width: none; font-size: 0.9rem; line-height: 1.2; color: var(--gp-ink); }
  .gp-treemap__meta { font-size: 0.76rem; color: var(--gp-margin-ink); }
  .gp-treemap__body { padding: 0; }
  .gp-treemap__principles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.75rem 1rem;
    margin: 0.85rem 0 1rem;
    font-family: var(--gp-sans);
  }
  .gp-treemap__principle {
    padding-top: 0.45rem;
    border-top: 0.5px solid var(--gp-light-rule);
  }
  .gp-treemap__principle-title {
    display: block;
    margin-bottom: 0.22rem;
    font-size: 0.73rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gp-ghost-ink);
  }
  .gp-treemap__principle-copy {
    margin: 0;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--gp-margin-ink);
  }
  .gp-treemap__legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.7rem 1rem;
    padding: 0.75rem 0.9rem;
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) calc(l - 0.006) c h);
    font-family: var(--gp-sans);
  }
  .gp-treemap__legend-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    min-width: 0;
  }
  .gp-treemap__legend-note {
    margin-left: auto;
    font-family: var(--gp-sans);
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--gp-margin-ink);
  }
  .gp-treemap__crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.55rem;
    margin-bottom: 0.55rem;
    font-family: var(--gp-sans);
    font-size: 0.78rem;
    color: var(--gp-margin-ink);
  }
  .gp-treemap__crumb {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
  }
  .gp-treemap__separator { opacity: 0.45; }
  .gp-treemap__crumbs .gp-btn { min-height: 1.8rem; }
  .gp-treemap svg { display: block; width: 100%; height: auto; }
  .gp-treemap__tooltip {
    position: fixed;
    z-index: 100;
    pointer-events: none;
    max-width: 25rem;
    padding: 0.7rem 0.85rem;
    border: 0.5px solid var(--gp-light-rule);
    background: oklch(from var(--gp-paper) l c h / 0.95);
    backdrop-filter: blur(10px);
    box-shadow: 0 8px 24px oklch(from var(--gp-ink) l c h / 0.08);
  }
  .gp-treemap__tooltip-eyebrow {
    margin: 0 0 0.25rem;
    font-family: var(--gp-sans);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gp-ghost-ink);
  }
  .gp-treemap__tooltip-title {
    margin: 0;
    font-family: var(--gp-sans);
    font-size: 0.92rem;
    line-height: 1.25;
    color: var(--gp-ink);
  }
  .gp-treemap__tooltip-meta {
    margin: 0.3rem 0 0;
    font-family: var(--gp-sans);
    font-size: 0.76rem;
    color: var(--gp-margin-ink);
  }
  .gp-guidance {
    display: grid;
    gap: 0.9rem;
    margin: 1rem 0 0;
  }
  .gp-guidance__row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 1.4rem;
  }
  .gp-guidance__card {
    padding-top: 0.55rem;
    border-top: 0.5px solid var(--gp-light-rule);
    font-family: var(--gp-sans);
  }
  .gp-guidance__label {
    display: inline-block;
    margin-bottom: 0.3rem;
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .gp-guidance__label--do { color: var(--gp-chart-positive); }
  .gp-guidance__label--dont { color: var(--gp-chart-negative); }
  .gp-guidance__card p {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--gp-margin-ink);
  }
  .gp-guidance__card strong { color: var(--gp-ink); }

  .gp-analytics-shell {
    display: grid;
    gap: 1rem;
    margin: 1rem 0 0;
  }
  .gp-analytics-shell__top {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(13rem, 0.8fr);
    gap: 1rem 1.25rem;
    align-items: start;
  }
  .gp-analytics-shell__kpis {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
  }
  .gp-analytics-shell__kpi {
    padding-top: 0.5rem;
    border-top: 0.5px solid var(--gp-light-rule);
    font-family: var(--gp-sans);
  }
  .gp-analytics-shell__kpi-label {
    display: block;
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gp-ghost-ink);
  }
  .gp-analytics-shell__kpi-value {
    display: block;
    margin-top: 0.18rem;
    font-size: 1.05rem;
    color: var(--gp-ink);
  }
  .gp-analytics-shell__kpi-meta {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.76rem;
    color: var(--gp-margin-ink);
  }
  .gp-analytics-shell__note {
    margin: 0;
    padding-top: 0.5rem;
    border-top: 0.5px solid var(--gp-light-rule);
    font-family: var(--gp-sans);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--gp-margin-ink);
  }
  .gp-analytics-shell__layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1rem 1.25rem;
  }
  .gp-analytics-shell__wide {
    grid-column: 1 / -1;
  }

  /* ── Minimal bar chart ────────────────────────────────────────────────── */

  .bar-chart { list-style: none; padding: 0; margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .bar-chart li { display: grid; grid-template-columns: 160px 1fr auto; align-items: center; gap: var(--gp-space-sm); margin-bottom: var(--gp-space-xs); font-family: var(--gp-sans); font-size: var(--gp-small); }
  .bar-label { text-align: right; color: var(--gp-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .bar { position: relative; height: 1px; background: var(--gp-ghost-ink); }
  .bar::after { content: ""; position: absolute; left: var(--bar-value, 50%); top: -3px; width: 1px; height: 7px; background: var(--gp-ink); }
  .bar-chart.filled .bar { height: 8px; background: none; }
  .bar-chart.filled .bar::before { content: ""; position: absolute; left: 0; top: 0; height: 100%; width: var(--bar-value, 0%); background: var(--gp-gray-data); }
  .bar-chart.filled .bar::after { display: none; }
  .bar-value { color: var(--gp-margin-ink); white-space: nowrap; font-variant-numeric: tabular-nums lining-nums; }
  .bar.red::after,   .bar-chart.filled .bar.red::before   { background: var(--gp-red);   }
  .bar.blue::after,  .bar-chart.filled .bar.blue::before  { background: var(--gp-blue);  }
  .bar.green::after, .bar-chart.filled .bar.green::before { background: var(--gp-green); }
  .bar.ochre::after, .bar-chart.filled .bar.ochre::before { background: var(--gp-ochre); }

  .gp-table-note {
    margin: 0.75rem 0 0;
    font-family: var(--gp-sans);
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--gp-margin-ink);
  }

  /* Font variation: Inter + JetBrains Mono via next/font/google */
  .gp-font-inter,
  [data-gp-font="inter"] {
    --gp-serif: var(--font-inter), "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --gp-sans: var(--font-inter), "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --gp-mono: var(--font-jetbrains-mono), "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    --gp-font-size: clamp(14px, 0.45vw + 12.5px, 16px);
    --gp-line-height: 1.62;
  }

  /* ── Ghosting / emphasis ──────────────────────────────────────────────── */
  .ghost { opacity: 0.22; } .near-ghost { opacity: 0.40; } .focal { opacity: 1; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   DATA VISUALIZATION  — chart-specific components
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.dataviz {

  /* ── Dot Chart (VDQI p. 178) ─────────────────────────────────────────────
     Tufte's replacement for bar charts. Dots encode individual values;
     no wasted ink of bar fills.

     <ul class="dot-chart">
       <li>
         <span class="dc-label">Country A</span>
         <span class="dc-track"><span class="dc-dot" style="--dc-pos:72%"></span></span>
         <span class="dc-value">72</span>
       </li>
     </ul>                                                               */

  .dot-chart { list-style: none; padding: 0; margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .dot-chart li { display: grid; grid-template-columns: 160px 1fr auto; align-items: center; gap: var(--gp-space-sm); margin-bottom: var(--gp-space-xs); font-family: var(--gp-sans); font-size: var(--gp-small); }
  .dc-label { text-align: right; color: var(--gp-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .dc-track { position: relative; height: 1px; background: var(--gp-light-rule); }
  .dc-dot { position: absolute; left: var(--dc-pos, 50%); top: 50%; transform: translate(-50%, -50%); width: 6px; height: 6px; border-radius: 50%; background: var(--gp-ink); transition: background 0.25s; }
  .dc-dot.red   { background: var(--gp-red);   }
  .dc-dot.blue  { background: var(--gp-blue);  }
  .dc-dot.green { background: var(--gp-green); }
  .dc-dot.open  { background: var(--gp-paper); border: 1.5px solid var(--gp-ink); }
  .dc-value { color: var(--gp-margin-ink); font-variant-numeric: tabular-nums lining-nums; }

  /* ── Dumbbell Chart (connected dot plot) ────────────────────────────────
     Before/after: two dots connected by a line. Shows start, end, and
     magnitude of change simultaneously.

     <ul class="dumbbell">
       <li>
         <span class="db-label">Item A</span>
         <span class="db-track" style="--db-l:34%;--db-r:68%">
           <span class="db-dot db-dot--left"  style="--db-l:34%"></span>
           <span class="db-dot db-dot--right" style="--db-r:68%"></span>
         </span>
         <span class="db-value">34 → 68</span>
       </li>
     </ul>                                                               */

  .dumbbell { list-style: none; padding: 0; margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .dumbbell li { display: grid; grid-template-columns: 160px 1fr auto; align-items: center; gap: var(--gp-space-sm); margin-bottom: var(--gp-space-sm); font-family: var(--gp-sans); font-size: var(--gp-small); }
  .db-label { text-align: right; color: var(--gp-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .db-track { position: relative; height: 1px; }
  .db-track::before { content: ""; position: absolute; top: 0; left: var(--db-l, 30%); right: calc(100% - var(--db-r, 70%)); height: 1px; background: var(--gp-ghost-ink); }
  .db-dot { position: absolute; top: 50%; width: 8px; height: 8px; border-radius: 50%; }
  .db-dot--left  { left: var(--db-l, 30%); transform: translate(-50%, -50%); background: var(--gp-blue); }
  .db-dot--right { left: var(--db-r, 70%); transform: translate(-50%, -50%); background: var(--gp-red);  }
  .db-value { color: var(--gp-margin-ink); font-size: var(--gp-micro); white-space: nowrap; font-variant-numeric: lining-nums; }

  /* ── Strip Plot (one-way scatter) ───────────────────────────────────────
     Shows all observations; no invented distribution shapes.

     <ul class="strip-plot">
       <li>
         <span class="sp-label">Group A</span>
         <span class="sp-track">
           <span class="sp-dot" style="--sp-pos:23%"></span>
           <span class="sp-dot" style="--sp-pos:41%"></span>
         </span>
       </li>
     </ul>
     <div class="sp-axis-labels"><span>0</span><span>50</span><span>100</span></div>  */

  .strip-plot { list-style: none; padding: 0; margin: var(--gp-space-lg) 0; max-width: var(--gp-text-width); }
  .strip-plot li { display: grid; grid-template-columns: 160px 1fr; align-items: center; gap: var(--gp-space-sm); margin-bottom: 10px; font-family: var(--gp-sans); font-size: var(--gp-small); }
  .sp-label { text-align: right; color: var(--gp-ink); white-space: nowrap; }
  .sp-track { position: relative; height: 1px; background: var(--gp-light-rule); }
  .sp-dot { position: absolute; left: var(--sp-pos, 50%); top: 50%; transform: translate(-50%, -50%); width: 5px; height: 5px; border-radius: 50%; background: var(--gp-ink); opacity: 0.65; }
  .sp-dot.red   { background: var(--gp-red);   }
  .sp-dot.blue  { background: var(--gp-blue);  }
  .sp-dot.green { background: var(--gp-green); }
  .sp-axis-labels { display: flex; justify-content: space-between; margin-left: calc(160px + var(--gp-space-sm)); font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-margin-ink); margin-top: 4px; font-variant-numeric: lining-nums; }

  /* ── Stem-and-Leaf (VDQI p. 140) ────────────────────────────────────────
     Histogram using the actual data digits. Use a real HTML <table> for
     reliable three-column layout — display:table on divs is inconsistent.

     <table class="stem-leaf">
       <thead>
         <tr>
           <th class="sl-col-left">Group A</th>
           <th class="sl-col-stem">Stem</th>
           <th class="sl-col-right">Group B</th>
         </tr>
       </thead>
       <tbody>
         <tr>
           <td class="sl-col-left">8  5  3</td>
           <td class="sl-col-stem">4</td>
           <td class="sl-col-right">0  2  6</td>
         </tr>
       </tbody>
     </table>
     <p class="sl-unit">Leaf unit = ...</p>                               */

  table.stem-leaf {
    font-family: var(--gp-mono);
    font-size: var(--gp-small);
    font-variant-numeric: lining-nums tabular-nums;
    max-width: var(--gp-text-width);
    margin: var(--gp-space-lg) 0;
    line-height: 1.9;
    border-collapse: collapse;
    width: 100%;
    border: none;
  }
  table.stem-leaf thead { border-bottom: 0.75px solid var(--gp-rule); }
  table.stem-leaf thead th {
    font-family: var(--gp-sans);
    font-size: var(--gp-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gp-ghost-ink);
    font-weight: normal;
    padding-bottom: 3px;
  }
  table.stem-leaf .sl-col-left  { width: 43%; text-align: right; padding-right: 8px; color: var(--gp-blue); }
  table.stem-leaf .sl-col-stem  {
    width: 14%; text-align: center; color: var(--gp-margin-ink);
    border-left: 0.5px solid var(--gp-rule);
    border-right: 0.5px solid var(--gp-rule);
    padding: 0 4px;
  }
  table.stem-leaf thead .sl-col-stem { color: var(--gp-margin-ink); }
  table.stem-leaf .sl-col-right { width: 43%; text-align: left; padding-left: 8px; }
  .sl-unit { font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-ghost-ink); margin-top: var(--gp-space-xs); }

  /* ── Bullet Graph (Beautiful Evidence p. 176) ───────────────────────────
     Tufte's replacement for gauge/speedometer charts.
     RECOMMENDED: implement as inline SVG (see index.html for working example).
     The CSS/HTML approach below uses position:absolute which is fragile.
     SVG approach: three <rect> for qualitative bands, one <rect> for featured
     bar, one <line> for the target tick. Fully reliable across browsers.

     CSS/HTML fallback (may be unreliable in some rendering contexts):
     <div class="bullet-graphs">
       <div class="bullet-graph">
         <span class="bg-label">Revenue</span>
         <div class="bg-track">
           <span class="bg-range bg-range-1" style="width:33%"></span>
           <span class="bg-range bg-range-2" style="width:34%"></span>
           <span class="bg-range bg-range-3" style="width:33%"></span>
           <span class="bg-bar green" style="width:72%"></span>
           <span class="bg-target" style="left:85%"></span>
         </div>
         <span class="bg-value">$72M</span>
       </div>
     </div>
     <div class="bg-axis"><span>Poor</span><span>Satisfactory</span><span>Good</span></div>  */

  .bullet-graphs { max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; display: flex; flex-direction: column; gap: var(--gp-space-md); }
  .bullet-graph { display: grid; grid-template-columns: 140px 1fr auto; align-items: center; gap: var(--gp-space-sm); font-family: var(--gp-sans); font-size: var(--gp-small); }
  .bg-label { text-align: right; color: var(--gp-ink); }
  .bg-track { position: relative; height: 16px; background: transparent; }
  .bg-range { position: absolute; top: 0; height: 100%; display: inline-block; }
  .bg-range-1 { left: 0;   background: var(--gp-ghost-ink); opacity: 0.35; }
  .bg-range-2 { left: 33%; background: var(--gp-ghost-ink); opacity: 0.22; }
  .bg-range-3 { left: 66%; background: var(--gp-ghost-ink); opacity: 0.12; }
  .bg-bar { position: absolute; left: 0; top: 25%; height: 50%; background: var(--gp-ink); z-index: 2; transition: background 0.25s; }
  .bg-bar.red   { background: var(--gp-red);   }
  .bg-bar.blue  { background: var(--gp-blue);  }
  .bg-bar.green { background: var(--gp-green); }
  .bg-target { position: absolute; top: 10%; height: 80%; width: 2px; background: var(--gp-ink); z-index: 3; transform: translateX(-50%); }
  .bg-value { color: var(--gp-margin-ink); font-variant-numeric: tabular-nums lining-nums; }
  .bg-axis { margin-left: calc(140px + var(--gp-space-sm)); display: flex; justify-content: space-between; font-family: var(--gp-sans); font-size: var(--gp-micro); color: var(--gp-ghost-ink); border-top: 0.5px solid var(--gp-light-rule); padding-top: 2px; }

  /* ── Heat Table ──────────────────────────────────────────────────────────
     Cell color encodes magnitude. Data is both visual and label.
     Set background via inline style with precomputed oklch() values.
     Note: calc() inside oklch() is not yet supported; precompute values.

     Ochre sequential ramp guide (val 0.0=cool → 1.0=warm):
       val 0.00 → oklch(95% 0.04 80)   val 0.25 → oklch(82% 0.07 76)
       val 0.50 → oklch(68% 0.09 72)   val 0.75 → oklch(55% 0.10 68)
       val 1.00 → oklch(42% 0.10 65)

     <td class="heat num" style="background:oklch(57% 0.09 72)">27</td>
     Dark cells: add data-dark attribute for automatic light text.       */

  .heat-table td.heat      { color: var(--gp-ink); transition: background 0.2s; text-align: right; }
  .heat-table td.heat[data-dark] { color: oklch(93% 0.005 85); }
  .heat-table td.heat-div  { text-align: right; transition: background 0.2s; }

  /* ── Ranked Table ────────────────────────────────────────────────────────
     Dotted leaders from label to value. Rank numbers recessive.

     <table class="ranked-table">
       <tbody>
         <tr>
           <td class="rank">1</td>
           <td class="rank-label"><span>Entry Name</span></td>
           <td class="num rank-value">42.1%</td>
         </tr>
         <tr class="rank-highlight">...</tr>
       </tbody>
     </table>                                                             */

  table.ranked-table td.rank { color: var(--gp-ghost-ink); text-align: right; padding-right: var(--gp-space-sm); font-variant-numeric: lining-nums tabular-nums; width: 2em; }
  table.ranked-table td.rank-label { background-image: radial-gradient(circle, var(--gp-light-rule) 1px, transparent 1px); background-size: 6px 1px; background-position: 0 0.9em; background-repeat: repeat-x; padding-right: var(--gp-space-sm); }
  table.ranked-table td.rank-label span { background: var(--gp-paper); padding-right: 4px; transition: background 0.25s; }
  table.ranked-table td.rank-value { font-variant-numeric: tabular-nums lining-nums; text-align: right; }
  table.ranked-table tr.rank-highlight td.rank-label span,
  table.ranked-table tr.rank-highlight td.rank-label { font-style: italic; }

  /* ── Timeline ────────────────────────────────────────────────────────────
     Horizontal display of events (dots) and periods (bars).

     <div class="timeline">
       <div class="tl-track">
         <div class="tl-period blue" style="--tl-start:10%;--tl-end:40%">
           <span class="tl-period-label">Period A</span>
         </div>
         <div class="tl-event" style="--tl-pos:25%">
           <span class="tl-event-label">Event B</span>
         </div>
       </div>
       <div class="tl-axis"><span>2010</span><span>2015</span><span>2020</span></div>
     </div>                                                               */

  .timeline { max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; font-family: var(--gp-sans); font-size: var(--gp-small); }
  .tl-track { position: relative; height: 48px; border-bottom: 1px solid var(--gp-ink); }
  .tl-event { position: absolute; left: var(--tl-pos, 50%); bottom: 0; transform: translateX(-50%); display: flex; flex-direction: column-reverse; align-items: center; }
  .tl-event::after { content: ""; display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--gp-ink); }
  .tl-event-label { font-size: var(--gp-micro); color: var(--gp-ink); white-space: nowrap; margin-bottom: 4px; text-align: center; }
  .tl-period { position: absolute; bottom: 4px; left: var(--tl-start, 0%); right: calc(100% - var(--tl-end, 50%)); height: 8px; background: var(--gp-ghost-ink); opacity: 0.4; }
  .tl-period-label { position: absolute; top: -18px; left: 0; font-size: var(--gp-micro); color: var(--gp-margin-ink); white-space: nowrap; }
  .tl-period.red   { background: var(--gp-red);   opacity: 0.5; }
  .tl-period.blue  { background: var(--gp-blue);  opacity: 0.5; }
  .tl-period.green { background: var(--gp-green); opacity: 0.5; }
  .tl-period.ochre { background: var(--gp-ochre); opacity: 0.5; }
  .tl-axis { display: flex; justify-content: space-between; margin-top: 4px; font-size: var(--gp-micro); color: var(--gp-margin-ink); font-variant-numeric: lining-nums; }
  .tl-axis span::before { content: ""; display: block; width: 1px; height: 4px; background: var(--gp-rule); margin: 0 auto 2px; }

  /* ── Slopegraph (VDQI p. 158) ────────────────────────────────────────── */
  .slopegraph-wrap { max-width: var(--gp-text-width); margin: var(--gp-space-lg) 0; }

  /* ── Parallel Coordinates skeleton ──────────────────────────────────────
     CSS classes for SVG parallel coordinates charts.                    */
  .parallel-coords { max-width: var(--gp-page-width); margin: var(--gp-space-lg) 0; overflow-x: auto; }
  .parallel-coords svg { display: block; overflow: visible; }
  .pc-line { fill: none; stroke: var(--gp-ghost-ink); stroke-width: 0.75; opacity: 0.5; }
  .pc-line.highlight { stroke: var(--gp-red); stroke-width: 1.5; opacity: 1; }
  .pc-line.blue-hl   { stroke: var(--gp-blue); stroke-width: 1.5; opacity: 1; }
  .pc-axis { stroke: var(--gp-rule); stroke-width: 0.75; }

  /* ── SVG annotation conventions ──────────────────────────────────────── */
  .ann-line  { stroke: var(--gp-ghost-ink); stroke-width: 0.6; fill: none; }
  .ann-text  { font-family: var(--gp-sans); font-size: 8px; fill: var(--gp-margin-ink); font-style: italic; }
  .ref-band  { fill: var(--gp-ghost-ink); fill-opacity: 0.10; stroke: none; }
  .ref-line  { stroke: var(--gp-rule); stroke-width: 0.75; stroke-dasharray: 2 4; fill: none; }
  .zero-line { stroke: var(--gp-rule); stroke-width: 0.75; stroke-dasharray: 2 4; fill: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   UTILITIES
   ═══════════════════════════════════════════════════════════════════════════ */

@layer gp.utilities {
  .gp-red   { color: var(--gp-red);   } .gp-blue  { color: var(--gp-blue);  }
  .gp-green { color: var(--gp-green); } .gp-ochre { color: var(--gp-ochre); }

  .full-bleed  { max-width: var(--gp-page-width) !important; }
  .align-right { text-align: right; } .align-center { text-align: center; }
  .sans   { font-family: var(--gp-sans); } .mono { font-family: var(--gp-mono); }
  .italic { font-style: italic; }
  .muted  { color: var(--gp-margin-ink); } .very-muted { color: var(--gp-ghost-ink); }
  .small  { font-size: var(--gp-small); } .micro { font-size: var(--gp-micro); }
  .cf::after { content: ""; display: table; clear: both; }

  .mt-sm { margin-top: var(--gp-space-sm); } .mt-md { margin-top: var(--gp-space-md); }
  .mt-lg { margin-top: var(--gp-space-lg); } .mt-xl { margin-top: var(--gp-space-xl); }
  .mb-sm { margin-bottom: var(--gp-space-sm); } .mb-md { margin-bottom: var(--gp-space-md); }
  .mb-lg { margin-bottom: var(--gp-space-lg); } .mb-xl { margin-bottom: var(--gp-space-xl); }

  .seq-1 { color: var(--gp-seq-1); } .seq-2 { color: var(--gp-seq-2); }
  .seq-3 { color: var(--gp-seq-3); } .seq-4 { color: var(--gp-seq-4); }
  .seq-5 { color: var(--gp-seq-5); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE  — outside @layer (wins over all layered rules)
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 960px) {
  /* Reduce vertical rhythm at narrow widths; horizontal uses the fluid token
     which already computes down to ~24px at mobile — no override needed.   */
  article { padding-top: var(--gp-space-lg); padding-bottom: var(--gp-space-lg); }

  label.sidenote-toggle:not(.sidenote-number) { display: inline; cursor: pointer; color: var(--gp-red); font-size: 0.85em; }
  .sidenote, .marginnote {
    display: none; float: none; position: static;
    margin: var(--gp-space-sm) 0; width: 100%;
    background: var(--gp-code-bg);
    padding: var(--gp-space-sm) var(--gp-space-md);
    border-left: 2px solid var(--gp-light-rule);
    font-size: var(--gp-small); color: var(--gp-margin-ink);
  }
  .sidenote-toggle:checked + .sidenote,
  .sidenote-toggle:checked + .marginnote { display: block; }

  figure.figure-margin { float: none; margin-right: 0; width: 100%; }
  figure:not(.figure-margin):not(.figure-full):not(.evidence__image) figcaption { float: none; margin-right: 0; width: 100%; margin-top: var(--gp-space-xs); }
  figure.figure-full, figure.figure-full figcaption { max-width: 100%; float: none; width: 100%; }

  .figure-compare, .compare-wrap, .evidence { grid-template-columns: 1fr; }
  .evidence__caption { grid-column: 1; }
  .brief-header { grid-template-columns: 1fr; }
  .brief-header__stat { text-align: left; min-width: 0; }
  .brief-header.gp-workspace__header { grid-template-columns: 1fr; }
  .gp-workspace__header .brief-header__stat { min-width: 0; }
  .gp-spread, .gp-spread--3, .gp-spread--4 { grid-template-columns: 1fr; }
  .gp-record { grid-template-columns: 1fr; }
  .gp-record__value { text-align: left; min-width: 0; }
  .gp-map-frame, .gp-map { min-height: 24rem; }
  .gp-map-panel { width: min(18rem, calc(100% - 2rem)); }
  .gp-map-meta { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .small-multiples-3, .small-multiples-4 { grid-template-columns: repeat(2, 1fr); }
  .small-multiples-6 { grid-template-columns: repeat(3, 1fr); }
  .running-header { flex-direction: column; }

  .dot-chart li, .dumbbell li, .bar-chart li { grid-template-columns: 100px 1fr auto; }
  .strip-plot li { grid-template-columns: 100px 1fr; }
  .sp-axis-labels { margin-left: calc(100px + var(--gp-space-sm)); }
  .bullet-graph { grid-template-columns: 100px 1fr auto; }
  .bg-axis { margin-left: calc(100px + var(--gp-space-sm)); }
}

@media (max-width: 560px) {
  article { padding-top: var(--gp-space-md); padding-bottom: var(--gp-space-md); }
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .metric-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .activity-timeline__lane { grid-template-columns: 70px 1fr; }
  .activity-timeline__value { grid-column: 2; }
  .brief-header__actions { align-items: flex-start; }
  .gp-record__meta { gap: 0.35rem 0.75rem; }
  .gp-map-frame, .gp-map { min-height: 21rem; }
  .gp-map-panel {
    left: var(--gp-space-sm);
    right: var(--gp-space-sm);
    top: var(--gp-space-sm);
    width: auto;
    padding: 0.7rem 0.75rem;
  }
  .gp-map-meta { grid-template-columns: 1fr; gap: 0.45rem; }
  .dot-chart li, .dumbbell li, .bar-chart li { grid-template-columns: 70px 1fr auto; }
  .strip-plot li { grid-template-columns: 70px 1fr; }
  .sp-axis-labels { margin-left: calc(70px + var(--gp-space-sm)); }
  .bullet-graph { grid-template-columns: 70px 1fr auto; }
  .bg-axis { margin-left: calc(70px + var(--gp-space-sm)); }
  .small-multiples-3, .small-multiples-4, .small-multiples-6 { grid-template-columns: repeat(2, 1fr); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   PRINT
   ═══════════════════════════════════════════════════════════════════════════ */

@media print {
  :root {
    --gp-font-size:    11pt;
    --gp-text-width:   120mm;
    --gp-margin-width:  50mm;
    --gp-gutter:        10mm;
    --gp-outer-margin:   0mm;
  }
  html { color-scheme: light; }
  body { background: white; color: black; }
  article { max-width: none; padding: 0; }
  a { text-decoration: none; color: black; }
  .sidenote, .marginnote {
    display: block !important; float: right; position: static;
    margin-right: calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)));
    width: var(--gp-margin-width); font-size: 8pt;
    background: none; border: none; padding: 0;
  }
  input.sidenote-toggle, label.sidenote-toggle:not(.sidenote-number) { display: none; }
  figure, table { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
}
