/* Shared chrome for every page under charts/ -- the four annual charts and
 * powermix, which layers only its canvas/brush rules on top in powermix/style.css.
 *
 * The token block below still has two copies elsewhere: landing.html and
 * sankey_template.html, each of which has to be a single self-contained file. If a
 * token value changes here it changes in those two as well -- and in each of the
 * three it is three blocks, not one: :root, :root[data-theme="dark"], and the
 * prefers-color-scheme fallback at the bottom.
 *
 * Series colours are NOT here: they come from data/charts/<name>.json, written
 * by charts_data.py, so the palette has exactly one source of truth.
 */
:root {
  --surface: #fcfcfb;
  --surface-2: #f4f4f0;
  --ink: #16160f;
  --ink-2: #4a4a42;
  --ink-muted: #75746a;
  --grid: #e1e0d9;
  --axis: #c3c2b7;
  --accent: #2171b5;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --surface: #1a1a19;
  --surface-2: #232321;
  --ink: #f2f1ea;
  --ink-2: #c8c7be;
  --ink-muted: #918f85;
  --grid: #2c2c2a;
  --axis: #383835;
  --accent: #3b8ad4;
  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Any explicit `display` beats the UA [hidden] rule, so .pill[hidden] would still
   render. Restate it with priority rather than avoiding `display` everywhere. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 32px 24px 64px;
  background: var(--surface);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  font-size: calc(15px * var(--fs)); line-height: 1.55;
}
main { max-width: 1180px; margin: 0 auto; }

/* Share links point straight at this page, so it needs its own way back. Two
   levels: /charts/<name>/ -> /. */
.home {
  display: inline-block; margin: 0 0 10px;
  font-size: calc(13px * var(--fs)); color: var(--ink-muted); text-decoration: none;
}
.home:hover, .home:focus-visible { color: var(--accent); }

h1 { font-size: calc(22px * var(--fs)); font-weight: 620; margin: 0 0 6px; letter-spacing: -0.01em; }
.sub { margin: 0 0 22px; color: var(--ink-2); max-width: 68ch; }

/* Presentation mode: one multiplier behind every size on the page, so a chart
   read off a slide is legible from the back of the room. CSS owns the number --
   the JS that has to widen margins and thicken strokes to match reads it back
   with cssVar("--fs"), so 1.4 is written down exactly once per file. Not a theme
   token, so it stays out of the three colour blocks; the only other copy is
   sankey_template.html, which has to be a single self-contained file.
   landing.html has no chart and no toggle, so it has no --fs. */
:root { --fs: 1; }
:root[data-pres="on"] { --fs: 1.4; }

/* One height for every control in a filter row, so the row is flush regardless of
   each control's font-size. Scales with --fs, because a 36px box around 18px text
   is a squashed control. Not a theme token, so it stays out of the colour block
   above -- but the 36px is shared with sankey_template.html and landing.html. */
:root { --control-h: calc(36px * var(--fs)); }

/* ---- filter row: one row, above everything it scopes ---- */
.filters {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 18px;
  padding-bottom: 18px; margin-bottom: 18px;
  border-bottom: 1px solid var(--grid);
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field > span { font-size: calc(12px * var(--fs)); color: var(--ink-muted); letter-spacing: 0.02em; }
select {
  font: inherit; height: var(--control-h); padding: 0 10px; min-width: 160px;
  color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--grid); border-radius: 7px;
}
select.narrow { min-width: 92px; }
.segmented { display: inline-flex; height: var(--control-h); border: 1px solid var(--grid); border-radius: 7px; overflow: hidden; }
.segmented button {
  font: inherit; font-size: calc(13px * var(--fs)); padding: 0 12px; cursor: pointer;
  background: var(--surface-2); color: var(--ink-2);
  border: 0; border-right: 1px solid var(--grid);
}
.segmented button:last-child { border-right: 0; }
.segmented button:hover { background: var(--grid); }
.segmented button.is-active { background: var(--accent); color: #fff; }
/* Controls that do not apply to the current view are disabled in place, not
   hidden: hiding them makes the whole filter row jump on every toggle. */
.field[aria-disabled="true"] { opacity: 0.42; }
.field[aria-disabled="true"] button,
.field[aria-disabled="true"] select,
.field[aria-disabled="true"] input { pointer-events: none; }
.check { display: inline-flex; align-items: center; height: var(--control-h); gap: 7px; font-size: calc(13px * var(--fs)); color: var(--ink-2); }
.ghost {
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-size: calc(13px * var(--fs)); height: var(--control-h); padding: 0 12px; cursor: pointer;
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--grid); border-radius: 7px;
}
.ghost:hover { background: var(--grid); }

/* Icon-only cycling control: system -> light -> dark -> system. It shows the
   CURRENT preference, not the next one, so the monitor means "following the OS".
   All three SVGs ship in the markup and CSS picks one -- chart.js is a module and
   therefore deferred, so a JS-built icon would leave a hole for a frame.
   Square, because width and height are both --control-h; .ghost's text padding
   would otherwise leave a 14px glyph swimming in a pill. The round .icon-btn
   further down is the info "i" and is not reused. */
.theme-btn, .pres-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--control-h); padding: 0; line-height: 0; color: var(--ink-2);
}
.theme-btn:hover, .pres-btn:hover { background: var(--grid); color: var(--ink); }
.theme-btn:focus-visible, .pres-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The glyphs carry width/height attributes so they are the right size with no
   stylesheet; this only rescales them alongside everything else. */
.theme-btn svg, .pres-btn svg { width: calc(14px * var(--fs)); height: calc(14px * var(--fs)); }
.theme-btn svg { display: none; }
:root[data-theme-pref="system"] .theme-btn .i-system,
:root[data-theme-pref="light"]  .theme-btn .i-light,
:root[data-theme-pref="dark"]   .theme-btn .i-dark { display: block; }
/* No preference attribute at all -- scripts off, or theme-boot.js blocked. The
   monitor is honestly what an unpinned page is doing. */
:root:not([data-theme-pref]) .theme-btn .i-system { display: block; }

/* Presentation mode is two-state, so it is one glyph plus aria-pressed rather
   than the theme's three-icon cycle. The lit state is keyed off the attribute
   theme-boot.js pins pre-paint, not off aria-pressed, so a page loaded from a
   #pres=1 link shows the button already lit -- chart.js is deferred and would
   otherwise leave it dark for a frame. */
:root[data-pres="on"] .pres-btn { background: var(--accent); color: #fff; border-color: var(--accent); }
:root[data-pres="on"] .pres-btn:hover { background: var(--accent); color: #fff; }

/* A capped multi-select rendered as checkboxes: the cap is a palette limit, so
   it has to be visible rather than enforced silently. */
.checkgroup { display: flex; flex-wrap: wrap; gap: 4px 12px; max-width: 520px; }
.checkgroup label { display: inline-flex; align-items: center; gap: 6px; font-size: calc(13px * var(--fs)); color: var(--ink-2); }
.checkgroup input:disabled + span { opacity: 0.4; }

/* ---- chart card ---- */
.card { border: 1px solid var(--grid); border-radius: 12px; padding: 14px 14px 6px; }
.card-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 6px; position: relative; }
.head-right { display: flex; align-items: center; gap: 10px; }
.pill {
  display: inline-block; font-size: calc(12px * var(--fs)); font-weight: 560; padding: 3px 9px;
  border-radius: 999px; background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--grid);
}
.pill-quiet { color: var(--ink-muted); font-weight: 400; }
.range-note { font-size: calc(13px * var(--fs)); color: var(--ink-muted); margin-left: 10px; }
.muted { color: var(--ink-muted); font-size: calc(12px * var(--fs)); }
.note { color: var(--ink-2); font-size: calc(13px * var(--fs)); min-height: 1.2em; margin: 4px 0; }
.error { color: #b3261e; font-size: calc(14px * var(--fs)); }

/* Height is set per page from the data -- a 31-country bar chart cannot share a
   fixed height with a 30-band year chart. */
.plot { position: relative; outline: none; }
.plot:focus-visible { box-shadow: 0 0 0 2px var(--accent); border-radius: 6px; }
.plot svg { display: block; overflow: visible; }
.plot .capture { cursor: crosshair; touch-action: none; fill: transparent; pointer-events: all; }

/* Solid hairlines, one shade off the surface. Never dashed. */
.grid line { stroke: var(--grid); stroke-width: 1; shape-rendering: crispEdges; }
.axis text { fill: var(--ink-muted); font-size: calc(11px * var(--fs)); font-variant-numeric: tabular-nums; }
.axis-outer text { fill: var(--ink-2); font-size: calc(12px * var(--fs)); font-weight: 560; }
.axis-outer line { stroke: var(--grid); stroke-width: 1; shape-rendering: crispEdges; }
.crosshair-line { stroke: var(--ink-2); stroke-width: 1; pointer-events: none; }
.direct-labels text { fill: var(--ink-2); font-size: calc(11px * var(--fs)); font-weight: 560; }
.empty-note text { fill: var(--ink-muted); font-size: calc(11px * var(--fs)); font-style: italic; }

/* A reference line is context, not a category: an ink token and a dash, with its
   own label rather than a legend entry. */
.ref-line { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 5 4; pointer-events: none; }
.ref-label { fill: var(--ink-2); font-size: calc(11px * var(--fs)); font-weight: 560; }

/* ---- info popover: anchored to the card head so opening it shifts no layout ---- */
.icon-btn {
  width: calc(22px * var(--fs)); height: calc(22px * var(--fs)); flex: none; padding: 0; cursor: pointer;
  font-family: Georgia, "Times New Roman", serif;
  font-size: calc(12px * var(--fs)); font-weight: 600; line-height: 1; font-style: italic;
  color: var(--ink-2); background: var(--surface-2);
  border: 1px solid var(--grid); border-radius: 999px;
}
.icon-btn:hover, .icon-btn[aria-expanded="true"] { background: var(--grid); color: var(--ink); }
.info-pop {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 20;
  width: min(400px, calc(100vw - 48px));
  padding: 14px 16px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--grid);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.16);
  font-size: calc(12.5px * var(--fs)); color: var(--ink-2);
}
.info-pop p { margin: 0 0 9px; }
.info-pop p:last-child { margin-bottom: 0; }
.info-pop strong { color: var(--ink); font-weight: 620; }

/* ---- legend: rect swatches because the marks are areas ---- */
.legend { display: flex; flex-wrap: wrap; gap: 4px 14px; padding: 12px 2px 10px; }
.legend-item {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: calc(12.5px * var(--fs)); color: var(--ink-2);
  background: none; border: 0; padding: 4px 2px; cursor: pointer; border-radius: 5px;
}
.legend-item:hover { color: var(--ink); }
.legend-item.is-off { opacity: 0.4; text-decoration: line-through; }
.legend-item.is-absent { opacity: 0.35; cursor: default; font-style: italic; }
.swatch { width: calc(12px * var(--fs)); height: calc(12px * var(--fs)); border-radius: 3px; flex: none; }
/* Non-interactive key for an encoding that is not a series (the hatch). */
.legend-key { display: inline-flex; align-items: center; gap: 7px; font-size: calc(12.5px * var(--fs)); color: var(--ink-muted); padding: 4px 2px; }
.legend-key .swatch { border: 1px solid var(--grid); }

/* ---- tooltip: values lead, labels follow ---- */
.tooltip {
  position: absolute; z-index: 10; pointer-events: none;
  min-width: 210px; padding: 9px 11px; border-radius: 9px;
  background: var(--surface); border: 1px solid var(--grid);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.13); font-size: calc(12.5px * var(--fs));
}
.tt-head { font-weight: 620; margin-bottom: 6px; color: var(--ink); }
.tt-sub { color: var(--ink-muted); font-size: calc(11.5px * var(--fs)); margin: -4px 0 6px; }
.tt-row { display: grid; grid-template-columns: 12px 1fr auto; gap: 8px; align-items: center; padding: 1.5px 0; }
.tt-key { height: 2.5px; border-radius: 2px; }
.tt-name { color: var(--ink-muted); }
.tt-val { font-weight: 620; color: var(--ink); font-variant-numeric: tabular-nums; }
.tt-total { border-top: 1px solid var(--grid); margin-top: 5px; padding-top: 5px; }

/* ---- table twin ---- */
.table-wrap { margin-top: 22px; }
.table-wrap summary { cursor: pointer; font-size: calc(14px * var(--fs)); color: var(--ink-2); }
.table-scroll { max-height: 420px; overflow: auto; margin-top: 10px; }
table { border-collapse: collapse; width: 100%; font-size: calc(12.5px * var(--fs)); }
th, td { padding: 5px 9px; border-bottom: 1px solid var(--grid); text-align: left; white-space: nowrap; }
th { position: sticky; top: 0; background: var(--surface); color: var(--ink-muted); font-weight: 560; }
td.num { text-align: right; font-variant-numeric: tabular-nums; }

footer { margin-top: 28px; font-size: calc(13px * var(--fs)); color: var(--ink-2); }
footer p { margin: 0 0 8px; max-width: 82ch; }
a { color: var(--accent); }

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

/* No-JS fallback. theme-boot.js normally pins data-theme before the first paint,
   so this only fires with scripts off -- but it costs nothing and it is what makes
   :not([data-theme="light"]) meaningful: an explicit light choice still wins on a
   dark OS. Same values as the [data-theme="dark"] block above, so when both match
   there is no ordering hazard. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface: #1a1a19; --surface-2: #232321; --ink: #f2f1ea; --ink-2: #c8c7be;
    --ink-muted: #918f85; --grid: #2c2c2a; --axis: #383835; --accent: #3b8ad4;
    color-scheme: dark;
  }
}
