/* One stylesheet for every page. Tokens first, then base type, layout, components and motion.
   The living reference is /styleguide.html: copy markup from there. Pages add only what is theirs. */

/* Geist and Geist Mono, SIL Open Font License 1.1, self-hosted so the site works offline. */
@font-face { font-family: "Geist"; font-weight: 100 900; font-display: swap; src: url(/vendor/fonts/geist-latin-wght-normal.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Geist"; font-weight: 100 900; font-display: swap; src: url(/vendor/fonts/geist-latin-ext-wght-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Geist Mono"; font-weight: 100 900; font-display: swap; src: url(/vendor/fonts/geist-mono-latin-wght-normal.woff2) format("woff2"); }
/* Headline figures only: the comma comes from the sans, so a big mono number reads "1,286" and not "1 , 286". */
@font-face { font-family: "Geist Comma"; font-weight: 100 900; font-display: swap; src: url(/vendor/fonts/geist-latin-wght-normal.woff2) format("woff2"); unicode-range: U+2C, U+2E; } /* the comma and the full stop: in mono both leave a gap inside a large figure */

:root {
  color-scheme: light;
  /* Colour roles. The palette is Pinterest's: white, near-black and grey from its public design system Gestalt
     (github.com/pinterest/gestalt, packages/gestalt-design-tokens/tokens/classic/base-color.json), with Pinterest Red for primary actions.
     Red belongs to the interface (primary actions, where you are, focus); it is never a data mark. Colour in data keeps its fixed meaning:
     blue rose, amber fell, grey no clear change. Values are plain colours (scripts read them), so the dark set is written out twice below:
     once for the system setting, once for the data-theme override. */
  --page: #ffffff;      /* the page. Gestalt white (mochimalist 0) */
  --surface: #ffffff;   /* raised things: cards, inputs, menus */
  --sunk: #f1f1f1;      /* wells, hover fills, skeletons. Gestalt grey roboflow 100 */
  --ink: #111111;       /* text. Gestalt black (cosmicore 900) */
  --ink2: #4a4a4a;      /* secondary text. roboflow 600 */
  --muted: #767676;     /* quiet text and "no clear change" marks. roboflow 500, Gestalt's subtle text: 4.5 to 1 on the page */
  --grid: #e9e9e9;      /* hairlines inside data. roboflow 200 */
  --axis: #cdcdcd;      /* control borders, axes. roboflow 300 */
  --line: rgb(17 17 17 / .10); /* hairlines between things */
  --brand: #e60023;        /* Pinterest Red (pushpin 450): primary actions, the reading line, focus, the guided tour */
  --brand-ink: #ffffff;    /* text on the red: 4.8 to 1 */
  --brand-hover: #cc0000;  /* the red under the pointer. pushpin 500 */
  --brand-strong: #b60000; /* the red pressed, and the fill behind small numerals. pushpin 600 */
  --brand-text: #cc0000;   /* red as small text or a fine mark on the page. pushpin 500 */
  --brand-wash: #ffebeb;   /* the pale red behind the current page in the navigation. pushpin 50 */
  --focus-mark: #e60023;   /* the one red subject in a picture: a focal mark that carries no direction. Never beside blue or amber direction marks, never a status. Always with a second cue (fill against hollow, size, place or a label) */
  --s1: #3f87d6;        /* data: a metric rose. A softened blue on Gestalt's skycicle hue, so the red stays the only fully saturated colour on a light page */
  --s2: #bf922e;        /* data: a metric fell. A softened amber on Gestalt's caramellow hue: 2.8 to 1 on white, so marks always carry a label or sit beside a table; colour-blind separation from the red 9.2 */
  --s3: #22a098;        /* data: a third series, never direction. A softened teal on Gestalt's spabattical hue */
  --wash: #d7edff;      /* data: pale end of the blue ramp. skycicle 100 */
  --ramp-hi: #3f87d6;   /* data: strong end of the allocation ramp. On dark it runs lighter than --s1, so the low end can still clear 3:1 against the card */
  --ramp-lo: #cdcdcd;   /* data: the no-clear-change end of the direction ramp on the map. On dark it sits nearer the card, so a weak rise or fall is a dim blue or amber and not a grey mix */
  --ramp-floor: 0;      /* how far along the direction ramp the weakest clear change starts. On dark it starts a third of the way in, so a small rise or fall is plainly blue or amber */
  --dot-o: .9;         /* opacity of the dots in a dot plot. On dark the dots are solid: a see-through amber over black turns brown */
  --up: var(--s1); --down: var(--s2); --band: var(--grid);
  --ctl: #767676;       /* the edge of a control: 4.5 to 1 against the surface. roboflow 500, Gestalt's default border */
  --shade-1: rgb(17 17 17 / .04); --shade-2: rgb(17 17 17 / .14);
  --scrim: rgb(17 17 17 / .5);   /* the dimmed page behind the guided tour */

  /* Decorative only. Gestalt 50 washes, 100/200 tints and 700/800 text.
     Never use these inside a chart, for a status, or as a classification key.
     Dark washes blend 20% Gestalt 900 into --surface; dark mids blend 35% light mid into --surface. */
  --decor-rose-wash: #ffebf1; --decor-rose-mid: #ffbed2; --decor-rose-ink: #82053e;
  --decor-plum-wash: #f0edff; --decor-plum-mid: #d5c7ff; --decor-plum-ink: #550aa9;
  --decor-sage-wash: #e3fae1; --decor-sage-mid: #c3f9c2; --decor-sage-ink: #00422c;
  --decor-peach-wash: #fff0db; --decor-peach-mid: #ffe4c1; --decor-peach-ink: #842000;
  --decor-red-wash: #ffebeb; --decor-red-mid: #fcbbbb; --decor-red-ink: #9b0000;
  --section-band: #f6f6f3; /* warm greige, sampled direction from the supplied homepage references */
  --secondary: #e9e9e4; /* warm grey secondary pills; not a data token */
  --chip-sage: #dce8d6; --chip-sage-ink: #254329;
  --chip-blush: #f5dce5; --chip-blush-ink: #6e2948;
  --chip-peach: #f6dfcc; --chip-peach-ink: #693c25;
  --chip-plum: #e8dff1; --chip-plum-ink: #503064;
  --hue-wash: var(--decor-rose-wash); --hue-mid: var(--decor-rose-mid); --hue-ink: var(--decor-rose-ink);

  /* Type. One sans, one mono for numbers. Sizes are fluid between a 380px and a 1440px screen. */
  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --t-display: clamp(2.5rem, 1.42rem + 4.5vw, 5rem);       /* 40 to 80: one per page, the page title of a story page */
  --t-h1: clamp(2rem, 1.55rem + 1.9vw, 3.125rem);          /* 32 to 50: page titles */
  --t-h2: clamp(1.375rem, 1.2rem + .75vw, 1.875rem);       /* 22 to 30: section headings */
  --t-h3: 1.0625rem;                                       /* 17: headings inside a section */
  --t-lede: clamp(1.125rem, 1.05rem + .32vw, 1.3125rem);   /* 18 to 21: the one sentence under a title */
  --t-body: .9375rem;                                      /* 15: default text */
  --t-prose: 1.0625rem;                                    /* 17: running text on a story page */
  --t-small: .875rem;                                      /* 14: notes, captions, table cells. Was 13; two design reviews called the reading text too small */
  --t-micro: .8125rem;                                     /* 13: labels, axis text. Was 12; a design review found too much of the site sat at the floor */
  --t-figure: clamp(2.25rem, 1.6rem + 2.7vw, 3.75rem);     /* 36 to 60: a headline number */

  /* Space. Use these steps and nothing between them. */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 72px; --sp-9: 112px;
  --gutter: clamp(16px, 4vw, 40px);                        /* page side padding */
  --gap-sec: clamp(72px, 11vw, 168px);                     /* between sections of a story page */
  --gap-sec-tool: clamp(40px, 5vw, 64px);                  /* between sections of a tool page */
  --nav-h: 60px;

  /* Radius. Things you press are pills, content cards are pin-like 20px, small things inside those are 8px. */
  --r-ctl: 999px; --r: 20px; --r-s: 8px; --r-mark: 4px;

  /* Elevation. Flat by default. e1 for a surface on the page, e2 only for things that float above it. */
  --e1: 0 0 0 1px var(--line);
  --e2: 0 0 0 1px var(--line), 0 2px 4px var(--shade-1), 0 16px 40px -12px var(--shade-2);

  /* Motion. Short for feedback, long for entrances. One ease out, one ease in-out. */
  --d-1: 120ms; --d-2: 240ms; --d-3: 520ms; --d-4: 900ms;
  --ease-out: cubic-bezier(.16, 1, .3, 1); --ease-inout: cubic-bezier(.65, 0, .35, 1);
}
/* Dark: Gestalt's dark surfaces (cosmicore 900, roboflow 800 and 700), white text, roboflow 400 for quiet text. The red stays; red as small text steps to pushpin 300. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; --page: #111111; --surface: #191919; --sunk: #2b2b2b; --ink: #ffffff; --ink2: #cdcdcd; --muted: #a5a5a5; --grid: #2b2b2b; --axis: #4a4a4a; --line: rgb(255 255 255 / .11); --brand: #e60023; --brand-ink: #ffffff; --brand-hover: #cc0000; --brand-strong: #b60000; --brand-text: #f47171; --brand-wash: #2b2b2b; --focus-mark: #e60023; --ramp-lo: #3d3d3d; --ramp-floor: .34; --dot-o: 1; --s1: #5b93d6; --s2: #c08a00; --s3: #009990; --wash: #0074e8; --ramp-hi: #abdbff; --ctl: #767676; --shade-1: rgb(0 0 0 / .3); --shade-2: rgb(0 0 0 / .6); --scrim: rgb(0 0 0 / .66); --decor-rose-wash: #28141e; --decor-rose-mid: #6a535a; --decor-rose-ink: #ffbed2; --decor-plum-wash: #1d1428; --decor-plum-mid: #5b566a; --decor-plum-ink: #d5c7ff; --decor-sage-wash: #141c19; --decor-sage-mid: #546754; --decor-sage-ink: #c3f9c2; --decor-peach-wash: #281714; --decor-peach-mid: #6a6054; --decor-peach-ink: #ffe4c1; --decor-red-wash: #281414; --decor-red-mid: #685252; --decor-red-ink: #fcbbbb; --section-band: #24231f; --secondary: #33322e; --chip-sage: #26362b; --chip-sage-ink: #dce8d6; --chip-blush: #422b35; --chip-blush-ink: #f5dce5; --chip-peach: #413126; --chip-peach-ink: #f6dfcc; --chip-plum: #342a40; --chip-plum-ink: #e8dff1; } }
:root[data-theme="dark"] { color-scheme: dark; --page: #111111; --surface: #191919; --sunk: #2b2b2b; --ink: #ffffff; --ink2: #cdcdcd; --muted: #a5a5a5; --grid: #2b2b2b; --axis: #4a4a4a; --line: rgb(255 255 255 / .11); --brand: #e60023; --brand-ink: #ffffff; --brand-hover: #cc0000; --brand-strong: #b60000; --brand-text: #f47171; --brand-wash: #2b2b2b; --focus-mark: #e60023; --ramp-lo: #3d3d3d; --ramp-floor: .34; --dot-o: 1; --s1: #5b93d6; --s2: #c08a00; --s3: #009990; --wash: #0074e8; --ramp-hi: #abdbff; --ctl: #767676; --shade-1: rgb(0 0 0 / .3); --shade-2: rgb(0 0 0 / .6); --scrim: rgb(0 0 0 / .66); --decor-rose-wash: #28141e; --decor-rose-mid: #6a535a; --decor-rose-ink: #ffbed2; --decor-plum-wash: #1d1428; --decor-plum-mid: #5b566a; --decor-plum-ink: #d5c7ff; --decor-sage-wash: #141c19; --decor-sage-mid: #546754; --decor-sage-ink: #c3f9c2; --decor-peach-wash: #281714; --decor-peach-mid: #6a6054; --decor-peach-ink: #ffe4c1; --decor-red-wash: #281414; --decor-red-mid: #685252; --decor-red-ink: #fcbbbb; --section-band: #24231f; --secondary: #33322e; --chip-sage: #26362b; --chip-sage-ink: #dce8d6; --chip-blush: #422b35; --chip-blush-ink: #f5dce5; --chip-peach: #413126; --chip-peach-ink: #f6dfcc; --chip-plum: #342a40; --chip-plum-ink: #e8dff1; }

/* Page identity. app.js chooses one hue from the path, including future /bets.html.
   These aliases are for interface decoration only; all data tokens above remain independent. */
:root[data-hue="rose"] { --hue-wash: var(--decor-rose-wash); --hue-mid: var(--decor-rose-mid); --hue-ink: var(--decor-rose-ink); }
:root[data-hue="plum"] { --hue-wash: var(--decor-plum-wash); --hue-mid: var(--decor-plum-mid); --hue-ink: var(--decor-plum-ink); }
:root[data-hue="sage"] { --hue-wash: var(--decor-sage-wash); --hue-mid: var(--decor-sage-mid); --hue-ink: var(--decor-sage-ink); }
:root[data-hue="peach"] { --hue-wash: var(--decor-peach-wash); --hue-mid: var(--decor-peach-mid); --hue-ink: var(--decor-peach-ink); }
:root[data-hue="red"] { --hue-wash: var(--decor-red-wash); --hue-mid: var(--decor-red-mid); --hue-ink: var(--decor-red-ink); }

/* Base */
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 16px); -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--page); color: var(--ink); font: 400 var(--t-body)/1.55 var(--sans); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overflow-x: clip; }
a { color: var(--ink); text-decoration-color: var(--axis); text-decoration-thickness: 1px; text-underline-offset: 3px; transition: text-decoration-color var(--d-2); }
a:hover { text-decoration-color: var(--brand); }
h1, h2, h3, h4 { text-wrap: balance; }
h1 { font-size: var(--t-h1); line-height: 1.05; letter-spacing: -.04em; margin: 0; font-weight: 750; }
h2 { font-size: var(--t-h2); line-height: 1.15; letter-spacing: -.035em; margin: 0 0 var(--sp-2); font-weight: 700; }
h3 { font-size: var(--t-h3); line-height: 1.3; letter-spacing: -.01em; margin: 0; font-weight: 600; }
h4 { font-size: var(--t-body); margin: 0; font-weight: 600; }
p { margin: var(--sp-2) 0; max-width: 68ch; text-wrap: pretty; }
.display { font-size: var(--t-display); line-height: 1; letter-spacing: -.045em; font-weight: 750; }
.lede { font-size: var(--t-lede); line-height: 1.45; color: var(--ink2); max-width: 56ch; letter-spacing: -.01em; }
.prose { font-size: var(--t-prose); line-height: 1.65; max-width: 62ch; }
.prose p { max-width: none; margin: 0 0 1em; }
.muted, .note { color: var(--ink2); }
.small { font-size: var(--t-small); }
.kicker { font: 500 var(--t-micro)/1.2 var(--mono); color: var(--ink2); letter-spacing: .02em; margin: 0 0 var(--sp-3); } /* at most one in three sections */
code, kbd, .mono { font-family: var(--mono); font-size: max(.92em, 13px); } /* never under the 13px floor */
code { background: var(--sunk); padding: 1px 6px; border-radius: var(--r-mark); }
pre { font: var(--t-small)/1.6 var(--mono); background: var(--sunk); border-radius: var(--r-s); padding: var(--sp-4); margin: var(--sp-3) 0; overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
pre code { background: none; padding: 0; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: var(--r-mark); }
::selection { background: var(--brand); color: var(--brand-ink); }
hr, .rule { border: 0; border-top: 1px solid var(--line); margin: var(--sp-7) 0; }

/* Top bar: one line on a desktop, a menu below 1280px (the same width is in app.js as NAV_WIDE). The <nav> is a native popover on small screens. */
.top { position: sticky; top: 0; z-index: 5; background: color-mix(in srgb, var(--page) 97%, transparent); backdrop-filter: blur(14px) saturate(1.4); -webkit-backdrop-filter: blur(14px) saturate(1.4); border-bottom: 1px solid var(--line); view-transition-name: top; }
body:not(:has(> .top))::before { content: ""; display: block; height: calc(var(--nav-h) + 1px); } .no-app body::before { display: none; } /* app.js inserts the header: hold its place until it does, so the page does not step down */
.top > div { max-width: 1440px; margin: 0 auto; padding: 0 var(--gutter); height: var(--nav-h); display: flex; align-items: center; justify-content: space-between; gap: var(--sp-5); }
.top b { font-size: var(--t-body); font-weight: 600; letter-spacing: -.02em; white-space: nowrap; }
.top b a { color: inherit; text-decoration: none; }
.top nav a { color: var(--ink2); text-decoration: none; padding: 6px 11px; border-radius: var(--r-ctl); white-space: nowrap; font-size: .875rem; transition: background var(--d-2), color var(--d-2); }
.top nav a:hover { background: var(--sunk); color: var(--ink); }
.top nav a[aria-current] { color: var(--hue-ink); font-weight: 600; background: var(--hue-wash); box-shadow: inset 0 -2px 0 var(--hue-mid); }
.top nav i { font: 500 var(--t-micro) var(--mono); color: var(--muted); }
.top .menu-btn { display: none; }
@media (min-width: 1280px) {
  .top nav { all: unset; display: flex; align-items: center; min-width: 0; }
  .top nav a { padding-inline: 8px; }
  .top .tour-btn { margin-left: var(--sp-4); min-height: 32px; padding: 4px 14px; }
  .top nav span { display: flex; gap: 2px; }
  .top nav span + span { margin-left: var(--sp-3); padding-left: var(--sp-3); border-left: 1px solid var(--line); }
  .top nav i { display: none; }
}
@media (max-width: 1279.9px) {
  .top .menu-btn { display: inline-flex; }
  .top nav { position: fixed; inset: calc(var(--nav-h) + 8px) 12px auto auto; width: min(320px, calc(100vw - 24px)); max-height: calc(100dvh - var(--nav-h) - 24px); margin: 0; padding: var(--sp-3); border: 0; border-radius: var(--r); background: var(--surface); color: var(--ink); box-shadow: var(--e2); overflow-y: auto; }
  .top nav:popover-open { display: grid; gap: var(--sp-3); animation: pop var(--d-2) var(--ease-out); }
  .top nav::backdrop { background: color-mix(in srgb, var(--page) 55%, transparent); }
  .top nav span { display: grid; gap: 2px; }
  .top nav span + span { border-top: 1px solid var(--line); padding-top: var(--sp-3); }
  .top nav i { font-style: normal; padding: 2px 11px 4px; }
  .top nav a { padding: 9px 11px; font-size: var(--t-body); border-radius: var(--r-s); }
  .top .tour-btn { justify-self: start; margin: 0 0 var(--sp-1) var(--sp-1); }
}
@keyframes pop { from { opacity: 0; transform: translateY(-6px) scale(.98); } }

/* Page shells. .page is the default; add .story for a narrow, airy reading page or .tool for a wide, dense working page. */
.page { max-width: 1120px; margin: 0 auto; padding: var(--sp-7) var(--gutter) var(--sp-9); }
.page.story { max-width: 1280px; padding-top: clamp(48px, 8vw, 112px); }
.page.tool { max-width: 1280px; padding-top: var(--sp-6); } /* one left edge for every page */
.wrap { max-width: 1280px; margin-inline: auto; padding-inline: var(--gutter); } /* a centred column inside a full-width band */
.sec { margin-top: var(--gap-sec-tool); }
.story .sec, .sec.airy { margin-top: var(--gap-sec); }
.sec > h2 + p { margin-top: 0; }
.sec-head { max-width: 46rem; margin-bottom: var(--sp-6); }
.sec-head h2 { margin-bottom: var(--sp-3); }
.sec-head p { color: var(--ink2); font-size: var(--t-prose); line-height: 1.55; margin: 0; max-width: 58ch; }
.story .sec-head { margin-bottom: var(--sp-7); }
.story .sec-head h2 { font-size: var(--t-h1); letter-spacing: -.035em; line-height: 1.05; }
.grid { display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); gap: var(--gap, var(--sp-5)); }
.grid.auto { grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min, 240px)), 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(24px, 5vw, 72px); align-items: start; }
.split.flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.row { display: flex; gap: var(--sp-3); align-items: end; flex-wrap: wrap; }
.stack { display: grid; gap: var(--gap, var(--sp-4)); align-content: start; }
@media (max-width: 900px) { .grid:not(.auto) { grid-template-columns: repeat(min(var(--cols, 3), 2), minmax(0, 1fr)); } .split, .split.flip { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 560px) { .grid:not(.auto):not(.keep) { grid-template-columns: minmax(0, 1fr); } }

/* Cards. Use one only when the thing is a separate object you can act on or that floats; otherwise use space and a hairline. */
.card { background: var(--surface); box-shadow: var(--e1); border-radius: var(--r); padding: var(--sp-5); overflow-x: auto; }
.card + .card { margin-top: var(--sp-3); }
.card.lift { box-shadow: var(--e2); }
.banner { border-radius: var(--r-s); padding: var(--sp-3) var(--sp-4); margin: 0 0 var(--sp-5); background: var(--sunk); box-shadow: inset 3px 0 0 var(--ink); max-width: none; }

/* Controls. Everything you press is a pill. */
button, select, input, textarea { font: inherit; color: inherit; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); min-height: 36px; padding: 6px 16px; border-radius: var(--r-ctl); border: 1px solid transparent; background: var(--secondary); color: var(--ink); cursor: pointer; white-space: nowrap; text-decoration: none; font-weight: 600; font-size: .875rem; transition: transform var(--d-1) var(--ease-out), background var(--d-2), border-color var(--d-2), opacity var(--d-2); }
.btn:hover { background: var(--axis); }
.btn:active { transform: scale(.97); }
.btn.pri { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); min-width: 84px; }
.btn.pri:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.btn.pri:active { background: var(--brand-strong); border-color: var(--brand-strong); }
.btn.big { min-height: 48px; padding: 10px 24px; font-size: var(--t-body); }
.btn.quiet { border-color: transparent; background: none; }
.btn.quiet:hover { background: var(--sunk); border-color: transparent; }
.btn:disabled { opacity: .4; cursor: default; transform: none; }
select, input[type=number], input[type=search], input[type=text], textarea { min-height: 36px; padding: 6px 14px; border-radius: var(--r-ctl); border: 1px solid var(--ctl); background: var(--surface); transition: border-color var(--d-2); }
textarea { border-radius: var(--r-s); }
select:hover, input:hover, textarea:hover { border-color: var(--ink); }
select { appearance: none; padding-right: 34px; background-image: linear-gradient(45deg, transparent 50%, var(--ink2) 50%), linear-gradient(135deg, var(--ink2) 50%, transparent 50%); background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%; background-size: 5px 5px; background-repeat: no-repeat; cursor: pointer; text-overflow: ellipsis; }
::placeholder { color: var(--muted); opacity: 1; }
label.f { display: grid; gap: var(--sp-1); font-size: var(--t-micro); color: var(--ink2); font-weight: 500; }
.seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--r-ctl); background: var(--sunk); }
.seg button { border: 0; background: none; padding: 5px 14px; border-radius: var(--r-ctl); cursor: pointer; font-size: .875rem; color: var(--ink2); transition: background var(--d-2), color var(--d-2), transform var(--d-1); }
.seg button:hover { color: var(--ink); }
.seg button:active { transform: scale(.96); }
.seg button[aria-pressed=true] { background: var(--surface); color: var(--ink); font-weight: 550; box-shadow: var(--e1); }
input[type=range] { accent-color: var(--ink); }
input[type=checkbox], input[type=radio] { accent-color: var(--ink); }
.chip { display: inline-block; padding: 3px 10px; border-radius: var(--r-ctl); font-size: var(--t-micro); border: 1px solid transparent; background: var(--secondary); color: var(--ink2); white-space: nowrap; }
.more { display: inline-flex; gap: 6px; font-weight: 550; text-decoration: none; border-bottom: 1px solid var(--axis); padding-bottom: 2px; transition: border-color var(--d-2); }
.more::after { content: "\2192"; transition: transform var(--d-2) var(--ease-out); }
.more:hover { border-color: var(--brand); }
.more:hover::after { transform: translateX(4px); }

/* Tables */
table { border-collapse: collapse; width: 100%; font-size: var(--t-small); }
th, td { text-align: right; padding: 10px 12px; vertical-align: middle; }
th:first-child, td:first-child { text-align: left; padding-left: 0; }
td.l, th.l { text-align: left; }
thead th { color: var(--ink2); font-weight: 500; font-size: var(--t-micro); border-bottom: 1px solid var(--axis); vertical-align: bottom; white-space: nowrap; }
tbody tr + tr td { border-top: 1px solid var(--grid); }
tbody tr.grp td { border-top: 0; padding-top: var(--sp-5); font: 500 var(--t-micro) var(--mono); color: var(--ink2); }
.mt td:first-child { min-width: 230px; } /* on a narrow screen the table scrolls sideways inside its card instead of crushing the metric names */
.mt td.l { min-width: 210px; }
td.num, .num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -.02em; }
td .sub { display: block; color: var(--ink2); font-size: var(--t-small); font-weight: 400; }
.table-wrap { overflow-x: auto; }

/* Figures: a headline number with its label. Numbers are always mono and tabular. */
.stat { display: grid; gap: var(--sp-2); align-content: start; }
.stat dt, .stat .k { color: var(--ink2); font-size: var(--t-small); order: 2; }
.stat dd, .stat .v { margin: 0; font: 500 var(--t-figure)/1 "Geist Comma", var(--mono); letter-spacing: -.05em; font-variant-numeric: tabular-nums; }
.stat small { font: 400 var(--t-small)/1.4 var(--sans); letter-spacing: 0; color: var(--ink2); }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: var(--sp-6) var(--sp-7); margin: 0; }

/* The result tile: one metric, its typical change, its range picture and one sentence. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: var(--sp-3); }
.tile { background: var(--surface); box-shadow: var(--e1); border-radius: var(--r); padding: var(--sp-4) var(--sp-5); min-width: 0; }
.tile h3 { font-size: var(--t-small); font-weight: 500; color: var(--ink2); }
.tile .v { font: 500 2rem/1.1 "Geist Comma", var(--mono); letter-spacing: -.05em; margin: var(--sp-2) 0 2px; font-variant-numeric: tabular-nums; }
.tile .range { margin: var(--sp-3) 0 var(--sp-2); }
.tile p { font-size: var(--t-small); color: var(--ink2); margin: 0; }

/* Small data pieces */
.q { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--axis); color: var(--ink2); font: 500 13px/1 var(--mono); cursor: help; margin-left: 6px; vertical-align: 1px; transition: border-color var(--d-2), color var(--d-2); }
.q:hover, .q:focus-visible { border-color: var(--ink); color: var(--ink); }
.dir { color: var(--muted); font-size: 13px; margin-right: 5px; }
.dir.up { color: var(--s1); } .dir.down { color: var(--s2); } /* blue rose, amber fell: a fall is not always bad */
.range { max-width: 320px; overflow: visible; } .range text { font-size: 13px; } .range:has(text:nth-of-type(2)) { margin-bottom: 16px; } .range:has(text:nth-of-type(2)) text:first-of-type { transform: translateY(1.25em); } /* 13 units: 12px on screen once the picture is 240px wide or more; narrower places raise it. Where the ends carry figures, "no change" takes a row of its own below them, so no label is dropped or overprinted */
.meter { height: 6px; border-radius: 3px; background: var(--grid); overflow: hidden; }
.meter i { display: block; height: 100%; background: var(--ink); border-radius: 3px; transition: width var(--d-2); }
svg { display: block; width: 100%; overflow: visible; }
svg text { fill: var(--ink2); font: 10px var(--sans); font-variant-numeric: tabular-nums; }
.legend { color: var(--ink2); font-size: var(--t-micro); display: flex; gap: var(--sp-2) var(--sp-4); flex-wrap: wrap; align-items: center; }
.sw { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: -1px; }
.sw.ln { height: 2px; width: 14px; border-radius: 1px; vertical-align: 3px; }
svg circle[fill-opacity=".62"] { fill-opacity: var(--dot-o); }
#tip { position: fixed; pointer-events: none; background: var(--ink); color: var(--page); padding: 7px 11px; border-radius: var(--r-s); font-size: var(--t-micro); line-height: 1.45; max-width: 320px; display: none; z-index: 9; box-shadow: var(--e2); }
.skel { background: linear-gradient(100deg, var(--sunk) 40%, color-mix(in srgb, var(--sunk) 50%, var(--surface)) 50%, var(--sunk) 60%) 0 0 / 300% 100%; border-radius: var(--r-s); min-height: 1em; animation: shimmer 1.6s linear infinite; }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* Disclosure. Any <details> opens smoothly where the browser can animate to its natural height. */
:root { interpolate-size: allow-keywords; }
details > summary { cursor: pointer; }
details::details-content { block-size: 0; overflow-y: clip; opacity: 0; transition: block-size var(--d-3) var(--ease-out), opacity var(--d-2), content-visibility var(--d-3) allow-discrete; }
details[open]::details-content { block-size: auto; opacity: 1; }
details.disclosure { border-top: 1px solid var(--line); }
details.disclosure:last-of-type { border-bottom: 1px solid var(--line); }
/* The summary rules are wrapped in :where() so they weigh no more than a bare element: one page class on the summary overrides them. */
:where(details.disclosure) > summary { list-style: none; display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); padding: var(--sp-4) 0; font-weight: 550; }
:where(details.disclosure) > summary::-webkit-details-marker { display: none; }
:where(details.disclosure) > summary::after { content: "+"; font: 400 1.25rem/1 var(--mono); color: var(--ink2); transition: transform var(--d-2) var(--ease-out); }
:where(details.disclosure[open]) > summary::after { transform: rotate(45deg); }
details.disclosure > :not(summary) { margin-top: 0; padding-bottom: var(--sp-4); }

/* Keep long data tables inside their card and the top navigation inside the viewport. */
.page > *, .row > * { min-width: 0; }
.people-nav { display: inline-flex; flex-wrap: wrap; gap: 2px; margin: var(--sp-3) 0; padding: 3px; border-radius: var(--r-ctl); background: var(--sunk); }
.people-nav a { padding: 5px 14px; border-radius: var(--r-ctl); color: var(--ink2); text-decoration: none; font-size: .875rem; transition: background var(--d-2), color var(--d-2); }
.people-nav a[aria-current] { background: var(--surface); color: var(--ink); font-weight: 550; box-shadow: var(--e1); }
.people-nav a:hover { color: var(--ink); }

/* The guided tour (app.js, TOUR). The ring sits in the page at the element's place and its shadow dims everything else.
   Neither takes clicks away from the page: the visitor can always use what is under it. */
.tour-ring { position: absolute; z-index: 8; pointer-events: none; border-radius: var(--r); outline: 2px solid var(--brand); box-shadow: 0 0 0 9999px var(--scrim); }
.tour-card { position: fixed; z-index: 10; right: var(--sp-4); bottom: var(--sp-4); width: min(380px, calc(100vw - 2 * var(--sp-4))); max-height: calc(100dvh - var(--nav-h) - 2 * var(--sp-4)); overflow-y: auto; background: var(--surface); color: var(--ink); border-radius: var(--r); box-shadow: var(--e2); padding: var(--sp-5); }
.tour-card:focus-visible { outline-offset: 2px; border-radius: var(--r); }
.tour-card h2 { font-size: var(--t-h3); line-height: 1.3; letter-spacing: -.01em; margin: 0 0 var(--sp-2); }
.tour-card p { margin: 0; font-size: .875rem; line-height: 1.5; color: var(--ink2); max-width: none; }
.tour-card .tour-n { font-size: var(--t-micro); color: var(--muted); margin-bottom: var(--sp-2); }
.tour-card .tour-act { margin-top: var(--sp-3); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-s); background: var(--sunk); color: var(--ink); font-weight: 500; box-shadow: inset 3px 0 0 var(--brand); }
.tour-card .tour-act.done { box-shadow: none; font-weight: 400; color: var(--ink2); }
.tour-btns { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4); }
.tour-btns span { display: flex; gap: var(--sp-2); }
.tour-btns .btn.quiet { margin-left: calc(-1 * var(--sp-3)); padding-inline: var(--sp-3); color: var(--ink2); }
.tour-btns .btn.pri { min-width: 76px; }
.guide-prompt { position: fixed; z-index: 4; left: var(--sp-4); bottom: var(--sp-4); max-width: calc(100vw - 2 * var(--sp-4)); display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4); background: var(--surface); border-radius: var(--r-ctl); box-shadow: var(--e2); font-size: .875rem; }
.guide-prompt p { margin: 0; } .guide-prompt .btn { min-height: 30px; padding: 2px 12px; }
/* Printed, or with scripts off, nothing waits for an animation: every revealed, entered or drawn thing is simply there. */
@media print, (scripting: none) { *, ::before, ::after { animation: none !important; transition: none !important; } [data-reveal], [data-enter], [data-draw] :is([data-line], [data-bar], .rp-bar, .rp-dot), .pop, .w, .hp-late, [data-reveal="rows"] > *, [data-reveal="rows"] > tbody > tr, [data-draw] [data-frame] { opacity: 1 !important; transform: none !important; stroke-dashoffset: 0 !important; } [data-reveal="rule"], [data-reveal="lines"], [data-reveal="rows"] > thead th { clip-path: none !important; } [data-reveal="mark"]::after { transform: none !important; } }
/* The same when the shared script could not load (each page marks that with .no-app). */
.no-app :is([data-reveal], [data-enter], [data-draw] :is([data-line], [data-bar], .rp-bar, .rp-dot), .pop, .w, .hp-late, [data-reveal="rows"] > *, [data-reveal="rows"] > tbody > tr, [data-draw] [data-frame]) { opacity: 1 !important; transform: none !important; stroke-dashoffset: 0 !important; } .no-app :is([data-reveal="rule"], [data-reveal="lines"], [data-reveal="rows"] > thead th) { clip-path: none !important; } .no-app [data-reveal="mark"]::after { transform: none !important; } .no-app *, .no-app ::before, .no-app ::after { animation: none !important; transition: none !important; }
@media print { .top, .tour-ring, .tour-card, .guide-prompt, .read-progress, #tip { display: none !important; } }

/* The range picture and the per-world strip, drawn by rangePlot() and strip() in app.js. */
.rp-bar, .rp-dot { transform-box: fill-box; transform-origin: center; }

/* Motion. Every rule below sits behind prefers-reduced-motion: with motion reduced, things are simply there. */
/* A reading-progress line for long story pages: it shows how far through the page you are. Add <div class="read-progress"></div>. */
.read-progress { display: none; }
@media (prefers-reduced-motion: no-preference) {
  /* Reveal on scroll: add data-reveal to a block shorter than the screen. It rises into place as it enters, tied to the scroll
     position where the browser supports that, and once (class .in, added by app.js) where it does not. */
  /* Reveals are timed, not tied to scroll position: a block that has entered always finishes arriving, wherever scrolling stops. */
  @supports (animation-timeline: scroll()) {
    .read-progress { display: block; position: fixed; z-index: 6; top: 0; left: 0; right: 0; height: 2px; background: var(--brand); transform-origin: 0 50%; animation: grow-x linear both; animation-timeline: scroll(root); }
  }
  .no-sda [data-reveal] { opacity: 0; transform: translateY(36px); transition: opacity var(--d-3) var(--ease-out), transform var(--d-4) var(--ease-out); transition-delay: calc(var(--i, 0) * 50ms); }
  .no-sda [data-reveal].in { opacity: 1; transform: none; }
  /* Stagger: put data-stagger on the parent and its revealed children arrive one after another. */
  [data-stagger] > :nth-child(2) { --i: 1; } [data-stagger] > :nth-child(3) { --i: 2; } [data-stagger] > :nth-child(4) { --i: 3; }
  [data-stagger] > :nth-child(5) { --i: 4; } [data-stagger] > :nth-child(6) { --i: 5; } [data-stagger] > :nth-child(n+7) { --i: 6; }
  /* Enter on load, for the first screen: add data-enter, and --i for order. */
  [data-enter] { animation: enter var(--d-4) var(--ease-out) both; animation-delay: calc(var(--i, 0) * 90ms); }
  /* Swap: children put into a data-swap container fade up, so a changed result reads as changed. */
  [data-swap] > * { animation: enter var(--d-3) var(--ease-out) both; }
  /* The tour card rises in at each stop, so a change of stop reads as a change. */
  .tour-card:not([hidden]) { animation: enter var(--d-3) var(--ease-out) both; }
  .guide-prompt { animation: enter var(--d-4) var(--ease-out) 1.2s both; }
  /* Draw: inside data-draw, charts draw themselves once when they first enter view (class .drawn, added by app.js).
     Lines need pathLength="1" and data-line. Bars need data-bar (grows up) or data-bar="x" (grows right). */
  [data-draw] [data-line] { stroke-dasharray: 1; stroke-dashoffset: 1; }
  [data-draw] [data-bar] { transform-box: fill-box; transform-origin: 50% 100%; transform: scaleY(0); }
  [data-draw] [data-bar="x"] { transform-origin: 0 50%; transform: scaleX(0); }
  [data-draw] .rp-bar { transform: scaleX(0); } [data-draw] .rp-dot { transform: scale(0); }
  [data-draw] :is([data-line], [data-bar], .rp-bar, .rp-dot) { transition: stroke-dashoffset var(--d-4) var(--ease-inout), transform var(--d-4) var(--ease-out); transition-delay: min(calc(var(--i, 0) * 40ms), 400ms); }
  [data-draw] .rp-dot { transition-delay: min(calc(var(--i, 0) * 40ms + 150ms), 550ms); } /* capped: a long list must not leave its last charts empty for seconds */
  [data-draw].drawn :is([data-line], [data-bar], .rp-bar, .rp-dot) { stroke-dashoffset: 0; transform: none; }
  /* Pages cross-fade into each other; the top bar stays put. */
  @view-transition { navigation: auto; }
  body > main, body > .page, body > .shell { view-transition-name: page; }
  ::view-transition-old(page) { animation: vt-out 160ms var(--ease-inout) both; }
  ::view-transition-new(page) { animation: vt-in 420ms var(--ease-out) 80ms both; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 200ms; }
}
@keyframes reveal { from { opacity: 0; transform: translateY(36px); } 35% { opacity: .7; transform: translateY(12px); } 70% { opacity: 1; transform: translateY(2px); } to { opacity: 1; transform: none; } }
@keyframes enter { from { opacity: 0; transform: translateY(16px); } }
@keyframes grow-x { from { transform: scaleX(0); } }
@keyframes vt-out { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(12px); } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, ::before, ::after { transition: none !important; animation: none !important; } ::details-content { transition: none !important; } }

/* Range bands sit at 45% in light. On dark surfaces that reads as a smudge, so they carry more of the colour. */
:root[data-theme="dark"] .rp-bar { opacity: .75; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rp-bar { opacity: .75; } }

/* Tool pages (map, people, replay) open with the same air above the title as the reading pages. */
.page.tool > .head { padding-top: var(--sp-7); }
/* A chip inside a heading keeps its own tracking: the heading's tight tracking crushed it. */
:is(h1, h2, h3) .chip { letter-spacing: 0; font-weight: 400; }

/* The shared page ending, written by app.js where a page has none of its own. */
.site-foot { margin-top: var(--sp-9); padding-top: var(--sp-5); border-top: 1px solid var(--line); color: var(--ink2); font-size: var(--t-small); }
.site-foot p { max-width: none; margin: 0; }

/* Tool pages carry a title closer to the reading pages' scale, so they read as the same site. */
.page.tool > .head h1 { font-size: clamp(2.5rem, 1.6rem + 2.6vw, 4rem); letter-spacing: -.04em; line-height: 1.02; }

/* A soft band behind the introduction, with no new layout or animation dependencies.
   Pictures keep their own neutral surface; decoration never becomes a data mark. */
.page-intro { position: relative; isolation: isolate; }
.page-intro::before { content: ""; position: absolute; z-index: -1; pointer-events: none; inset: calc(-1 * var(--sp-5)) calc(-1 * min(var(--gutter), var(--sp-5))) auto; height: calc(100% + var(--sp-5)); max-height: 480px; border-radius: var(--r); background: linear-gradient(180deg, var(--hue-wash), var(--page)); }
.scene.page-intro::before { display: none; } /* Home's story column is half the page wide: a wash there reads as a broken box. */
.page-intro :is(figure, svg, canvas), table { background-color: var(--surface); }
.page-intro :is(figure, svg, canvas) { border-radius: var(--r); }
/* Quiet text on a wash needs stronger ink than the grey data-mark token. */
html[data-hue] .page-intro :where(.muted, .note, .source, .st):not(figure *) { color: var(--ink2); }
html[data-hue] .page-intro > :is(.kicker, .eyebrow), html[data-hue] .sec-head > :is(.kicker, .eyebrow), html[data-hue] :is(.sec-head, .sh, .scene, .pick-row) > :is(.n, .no) { color: var(--hue-ink); }
html[data-hue] :is(.scene, .pick-row) > .n { background: var(--hue-wash); border-color: var(--hue-mid); }
/* Explicit opt-in for editorial labels. Evidence, sentiment, status and result chips stay neutral.
   Filter colour names a topic only; selected controls still need a non-colour cue. */
.chip.soft { background: var(--hue-wash); color: var(--hue-ink); }
.chip.sage { background: var(--chip-sage); color: var(--chip-sage-ink); }
.chip.blush { background: var(--chip-blush); color: var(--chip-blush-ink); }
.chip.peach { background: var(--chip-peach); color: var(--chip-peach-ink); }
.chip.plum { background: var(--chip-plum); color: var(--chip-plum-ink); }
/* Area filters name topics, never evidence strength or direction. Preserve native select affordances. */
html[data-hue] :is(#filters select#area, #filters select#f-area) { background-color: var(--chip-sage); color: var(--chip-sage-ink); border-color: var(--chip-sage-ink); }
/* Cast's compact chips previously used --muted on white; a filled chip needs stronger ink. */
html[data-hue] .p .chip { color: var(--ink2); }
html[data-hue] .p[aria-pressed="true"] .chip { color: var(--ink); }
:is(.btn, input, select, textarea):focus-visible { box-shadow: 0 0 0 6px var(--hue-wash); }
html[data-hue] .page-intro :is(h1, .display) { font-weight: 750; }

/* Reviewed editorial sections only. Paint beyond the content column without changing its width.
   A background layer never clips focus rings or steals pointer events. No data palette aliases change. */
.section-band { position: relative; isolation: isolate; padding-block: var(--sp-7); background: var(--section-band); }
.section-band::before { content: ""; position: absolute; z-index: -1; inset-block: 0; left: calc(50% - 50vw); width: 100vw; background: var(--section-band); pointer-events: none; }
.section-band > .sec-head { margin-inline: auto; text-align: center; }
.section-band > .sec-head :is(h2, p) { margin-inline: auto; }
.section-band > h2 { text-align: center; margin-bottom: var(--sp-5); }
html[data-hue] .section-band :where(.muted, .note, .source, .meta, .cap, .kicker, .no, .n):not(svg *) { color: var(--ink2); }
html[data-hue] .section-band .route p b,
html[data-hue] .section-band .missing .num,
html[data-hue] .section-band .questions li::before,
html[data-hue] .section-band .priorities li::before,
html[data-hue] .section-band #limits li::before,
html[data-hue] .rail a i { color: var(--ink2); }
.section-band :where(.card, .tile, table, figure, svg, canvas) { background-color: var(--surface); }
/* Home already supplies its own shell and inline padding; only the reviewed band overrides that padding. */
main > .wide.section-band { padding-block: var(--sp-8) !important; }
/* The brief's editorial body is offset by a sidebar. Keep its navigation above the full-bleed background layer. */
.brief-layout > .rail { z-index: 1; }
.brief-body > .section-band::before { left: auto; right: calc((min(1280px, 100vw) - 100vw) / 2 - var(--gutter)); }

/* Fixed, quiet image collages. Decoration never animates or appears inside a data figure.
   All images reserve a CSS box as well as carrying their intrinsic 480 x 720 dimensions. */
.hero-collage { display: flex; align-items: center; justify-content: center; gap: var(--sp-3); width: 100%; max-width: 720px; margin: var(--sp-6) auto 0; pointer-events: none; }
.hero-collage > img { display: block; width: 0; flex: 1 1 0; min-width: 0; height: 192px; object-fit: cover; border-radius: 24px; background: var(--secondary); }
.hero-collage > img:nth-child(2n) { height: 224px; }
.hero-collage > img:nth-child(3n) { height: 168px; }
.hero-collage--slim { max-width: 480px; margin-inline: auto 0; gap: var(--sp-2); }
.hero-collage--slim > img { height: 104px; }
.hero-collage--slim > img:nth-child(2n) { height: 120px; }
.hero-collage--slim > img:nth-child(3n) { height: 88px; }
.foot.has-pinboard { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); align-items: center; gap: var(--sp-5) var(--sp-7); }
.foot.has-pinboard > :not(.pinboard):not(.illustration-credit) { grid-column: 1; }
.foot.has-pinboard > .pinboard { grid-column: 2; grid-row: 1; }
.pinboard { width: 100%; max-width: 720px; columns: 4; column-gap: var(--sp-3); pointer-events: none; }
.pinboard:empty { display: none; }
.pinboard > img { display: block; width: 100%; height: 168px; object-fit: cover; break-inside: avoid; margin-bottom: var(--sp-3); border-radius: 24px; background: var(--secondary); }
.pinboard > img:nth-child(4n+2) { height: 128px; }
.pinboard > img:nth-child(4n+3) { height: 208px; }
.pinboard > img:nth-child(4n) { height: 144px; }
.foot .illustration-credit { grid-column: 1 / -1; margin: 0; font-size: var(--t-micro); line-height: 1.5; color: var(--ink2); }
@media (max-width: 800px) {
  .foot.has-pinboard { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
  .foot.has-pinboard > .pinboard { grid-column: 1; grid-row: auto; max-width: none; }
  .foot .illustration-credit { grid-row: auto; }
}
@media (max-width: 560px) {
  .section-band { padding-block: var(--sp-6); }
  .hero-collage, .hero-collage--slim { max-width: none; justify-content: start; margin-top: var(--sp-5); gap: var(--sp-2); }
  .hero-collage > img:nth-child(n), .pinboard > img:nth-child(n) { height: 80px; }
  .hero-collage > img:nth-child(n+4), .pinboard > img:nth-child(n+4) { display: none; }
  .pinboard { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }
  .pinboard > img { margin: 0; }
}
@media print {
  .hero-collage, .pinboard, .page-intro::before, .section-band::before { display: none !important; }
  .foot.has-pinboard { display: block; }
  .section-band { background: none; padding-block: 0; }
}

/* Scroll entrances with meaning. Each is a value of data-reveal (or an attribute inside data-draw), plays once when the block enters view
   (class .in or .drawn, added by app.js), and is simply there with reduced motion, in print, without script, or under .no-app.
   Content a script inserts after the block has arrived is at rest: nothing replays on a re-render. One entrance per block.
   rule:  the element's own rule (a border) and label wipe in from the start, before what follows rises.
   lines: a display-size heading sets line by line, up to three lines.
   mark:  a figure gets a thin underline that grows while data-count counts it. The underline stays: it is the rest state.
   rows:  a table's head wipes in, then its rows arrive in a capped stagger (also for any list of direct children).
   data-frame (with pathLength="1", inside data-draw): a chart's axis draws first; the marks follow. */
[data-reveal="mark"]::after { content: ""; display: block; width: 3rem; max-width: 100%; height: 2px; margin-top: var(--sp-2); background: var(--ink); transform-origin: 0 50%; }
@media (prefers-reduced-motion: no-preference) {
  .no-sda :is([data-reveal="rule"], [data-reveal="lines"], [data-reveal="mark"], [data-reveal="rows"]) { opacity: 1; transform: none; }
  .no-sda [data-reveal="rule"] { clip-path: inset(-1em 100% -1em -1em); transition: clip-path var(--d-3) var(--ease-out); }
  .no-sda [data-reveal="rule"].in { clip-path: inset(-1em); }
  .no-sda [data-reveal="rule"] + [data-reveal] { transition-delay: calc(var(--i, 0) * 50ms + 120ms); }
  .no-sda [data-reveal="lines"] { clip-path: inset(-.2em -.5em 100% -.5em); }
  .no-sda [data-reveal="lines"].in { clip-path: none; animation: set-lines 640ms var(--ease-out); }
  .no-sda [data-reveal="mark"]::after { transform: scaleX(0); transition: transform var(--d-4) var(--ease-inout); }
  .no-sda [data-reveal="mark"].in::after { transform: none; }
  .no-sda [data-reveal="rows"] > thead th { clip-path: inset(-4px 100% -4px -4px); transition: clip-path 360ms var(--ease-out); }
  .no-sda [data-reveal="rows"].in > thead th { clip-path: inset(-4px); }
  .no-sda [data-reveal="rows"] > tbody > tr, .no-sda [data-reveal="rows"] > :not(thead, tbody, tfoot, caption, colgroup) { opacity: 0; transform: translateY(12px); transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out); transition-delay: calc(var(--n, 0) * 40ms + 60ms); }
  .no-sda [data-reveal="rows"].in > tbody > tr, .no-sda [data-reveal="rows"].in > :not(thead, tbody, tfoot, caption, colgroup) { opacity: 1; transform: none; }
  [data-reveal="rows"] > :nth-child(2), [data-reveal="rows"] > tbody > :nth-child(2) { --n: 1; } [data-reveal="rows"] > :nth-child(3), [data-reveal="rows"] > tbody > :nth-child(3) { --n: 2; }
  [data-reveal="rows"] > :nth-child(4), [data-reveal="rows"] > tbody > :nth-child(4) { --n: 3; } [data-reveal="rows"] > :nth-child(5), [data-reveal="rows"] > tbody > :nth-child(5) { --n: 4; }
  [data-reveal="rows"] > :nth-child(6), [data-reveal="rows"] > tbody > :nth-child(6) { --n: 5; } [data-reveal="rows"] > :nth-child(7), [data-reveal="rows"] > tbody > :nth-child(7) { --n: 6; }
  [data-reveal="rows"] > :nth-child(8), [data-reveal="rows"] > tbody > :nth-child(8) { --n: 7; } [data-reveal="rows"] > :nth-child(n+9), [data-reveal="rows"] > tbody > :nth-child(n+9) { --n: 8; } /* capped: the last row starts within 0.4 s */
  [data-draw] [data-frame] { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset var(--d-3) var(--ease-inout); }
  [data-draw].drawn [data-frame] { stroke-dashoffset: 0; }
  [data-draw]:has([data-frame]) :is([data-line], [data-bar], .rp-bar, .rp-dot) { transition-delay: calc(min(calc(var(--i, 0) * 40ms), 400ms) + 260ms); }
}
@keyframes set-lines { 0% { clip-path: inset(-.2em -.5em 100% -.5em); transform: translateY(.3em); } 34% { clip-path: inset(-.2em -.5em max(0px, calc(100% - 1.04lh)) -.5em); } 67% { clip-path: inset(-.2em -.5em max(0px, calc(100% - 2.04lh)) -.5em); } 100% { clip-path: inset(-.2em -.5em -.4em -.5em); transform: none; } }
