/* ==========================================================================
   Wodonga in Numbers — the family's middle canvas.

   Loaded AFTER foundation.css, never instead of it. The foundation owns the
   masthead, banner, rail, evidence grammar, dark record region and footer;
   this file owns only what sits between the banner and the evidence region.

   WHY THIS FILE EXISTS AT ALL. The curated specification found, independently
   on ten different pages, that this corpus keeps producing the same handful of
   shapes: two official measures that point opposite ways, one period with two
   published values, a full peer distribution rather than a rank, a missing
   stage that has to be drawn rather than greyed, two collections deliberately
   left unreconciled, a recording regime drawn beneath the record, parts that
   do not sum, and a derived relationship carrying its own method. Those are
   not components someone invented for a design system. They are what the
   evidence is. So they are the canvas vocabulary, and a page is an ordered
   list of them.

   RULES INHERITED AND NOT RELAXED:
     - no raw hex; every value is a foundation token or a mix of them;
     - three breakpoints only (640, 900, 1100);
     - state is triple-encoded — colour, line style, and a written word;
     - four text measures, no fifth.

   RULES THIS LAYER ADDS:
     - Data ink is a two-value scale plus one accent. Wodonga is ink, the
       comparator is meta, and the accent marks the one thing a section wants
       you to look at. A third data colour means the figure is doing two jobs.
     - No value exists only on hover. Every figure prints its endpoints, or
       carries an exact-value table beside it.
     - A figure sits directly on the canvas. A bordered panel is for a
       relationship that needs a shared field or a boundary, not for tidiness.
   ========================================================================== */

:root {
  /* Data ink. Derived, not new: the subject in full ink, the comparator at
     meta weight, the accent reserved for the single mark that carries the
     section's finding. */
  --n-ink: var(--fg);
  --n-ink-soft: color-mix(in oklab, var(--fg) 62%, var(--surface));
  --n-comp: var(--meta);
  --n-comp-soft: color-mix(in oklab, var(--meta) 42%, var(--surface));
  --n-mark: var(--accent);
  --n-grid: color-mix(in oklab, var(--fg) 12%, var(--surface));
  --n-wash: color-mix(in oklab, var(--fg) 4%, var(--surface));

  /* Figure heights, so a page's rhythm is set in one place rather than at
     every call site. */
  --n-fig-lede: 340px;
  --n-fig: 260px;
  --n-fig-small: 150px;
}

/* ── section rhythm ───────────────────────────────────────────────────────
   .wf-sec supplies the vertical rhythm and the hairline between sections.
   This adds only the internal composition: an eyebrow that carries the
   finding's own identifier, the claim as a heading, and the figure. */
.n-sec > header { max-width: var(--measure-wide); }
.n-eyebrow {
  display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap;
  font-size: 12px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--space-3);
}
/* The finding identifier is real: it is the curated specification's own id,
   stable across the site and against the readiness matrix. It is set in mono
   because it is a reference, not a word. */
.n-id {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em;
  color: var(--fg-2); border: 1px solid var(--border-soft);
  padding: 2px var(--space-2); border-radius: var(--radius-sm);
}
.n-role { color: var(--meta); }
.n-role::before { content: "\00B7"; margin-right: var(--space-3); }

.n-sec h2 { font-size: clamp(24px, 2.9vw, 34px); letter-spacing: -0.015em; max-width: 34ch; }
.n-sec .n-claim {
  margin-top: var(--space-4); max-width: var(--measure); font-size: clamp(17px, 1.5vw, 19px);
  line-height: 1.55; color: var(--fg-2);
}
.n-sec .n-claim b, .n-sec .n-claim strong { color: var(--fg); font-weight: 500; }

/* The page's opening statement, above the first finding and without a rule
   of its own: it is the subject's purpose, not a section. */
.n-purpose { padding-block: clamp(26px, 3vw, 38px) 0; }
.n-purpose p { max-width: var(--measure-wide); font-size: clamp(18px, 1.8vw, 22px);
  line-height: 1.45; color: var(--fg-2); }

/* The lede opens the page. Its promoted values sit BESIDE the claim rather
   than under it: the defining numbers belong in the first viewport, and a
   claim column plus a value column fills the canvas instead of leaving half
   of it empty. Below 1100 the values fall under the claim, which is the
   ordinary section order. */
.n-lede { padding-top: clamp(24px, 2.6vw, 34px); }
.n-lede h2 { font-size: clamp(26px, 3.4vw, 40px); max-width: 30ch; }
.n-lede .n-claim { font-size: clamp(17px, 1.6vw, 20px); }
@media (min-width: 1100px) {
  .n-lede { display: grid; grid-template-columns: minmax(0, 1fr) minmax(210px, 15rem);
    column-gap: clamp(32px, 4vw, 56px); align-items: start; }
  /* Row one is the claim beside its numbers. Everything after it — and that
     is the defining figure — takes the whole canvas, because the reason it is
     the lede is that it deserves the widest field on the page. */
  .n-lede > header { grid-column: 1; grid-row: 1; }
  .n-lede > .n-values { grid-column: 2; grid-row: 1; margin-top: 0;
    flex-direction: column; gap: clamp(18px, 2.2vw, 26px); padding-top: var(--space-2); }
  .n-lede > .n-values .n-v { font-size: clamp(26px, 2.6vw, 32px); }
  .n-lede > .n-values .n-v-l { max-width: 100%; }
  .n-lede > *:not(header):not(.n-values) { grid-column: 1 / -1; }
}

/* ── promoted values ──────────────────────────────────────────────────────
   A row of the section's own numbers, at the size the finding deserves.
   Not cards: no border, no background, no equal widths. The value leads and
   the label follows it, because the value is what the reader came for. */
.n-values { display: flex; flex-wrap: wrap; gap: var(--space-8) clamp(28px, 4vw, 52px);
  margin-top: clamp(20px, 2.4vw, 28px); }
.n-values > div { min-width: 0; }
.n-v {
  display: block; font-family: var(--font-display); font-weight: 500;
  font-size: clamp(30px, 4.2vw, 46px); line-height: 1.02; letter-spacing: -0.02em;
  color: var(--fg); font-variant-numeric: tabular-nums lining-nums;
}
.n-v-l { display: block; margin-top: var(--space-2); font-size: 13px; line-height: 1.4;
  color: var(--muted); max-width: 24ch; }
.n-v-p { display: block; margin-top: 2px; font-size: 11px; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--meta); }
/* Secondary size, for supporting sections where a 46px figure would outrank
   the page's defining one. */
.n-values--sm .n-v { font-size: clamp(22px, 2.6vw, 30px); }
.n-values--sm { gap: var(--space-6) clamp(22px, 3vw, 38px); }

/* ── evidence on demand ───────────────────────────────────────────────────
   A figure's link to its own evidence sits under the label, at meta weight.
   It is deliberately quiet: the guarantee is that the path exists and can be
   followed, not that every number wears a footnote marker. */
.n-v-e { display: inline-block; margin-top: var(--space-2); font-size: 11px;
  letter-spacing: 0.04em; color: var(--meta); text-decoration: none;
  border-bottom: 1px solid var(--rule); }
.n-v-e:hover, .n-v-e:focus-visible { color: var(--wire); border-bottom-color: var(--wire); }

.n-claims { margin-top: clamp(20px, 2.4vw, 28px); border-top: 1px solid var(--rule);
  padding-top: var(--space-4); }
.n-claims > summary { cursor: pointer; font-size: 13px; color: var(--muted);
  letter-spacing: 0.02em; }
.n-claims > summary:hover, .n-claims > summary:focus-visible { color: var(--fg); }
.n-claims .wf-overflow { margin-top: var(--space-4); }
.n-claim-note { display: block; margin-top: 2px; font-size: 12px; color: var(--meta); }

/* ── figure frame ─────────────────────────────────────────────────────────
   A figure is a block on the canvas, not a card. It has a caption below it
   and, where the visual alone cannot carry the values, an exact-value table
   beside or beneath it. */
/* A figure takes the whole canvas: the browser's default figure margin took
   80px of plotting width on every chart. */
.n-fig { margin: clamp(22px, 2.6vw, 32px) 0 0; }
.n-range-bar[hidden] { display: none; }
.n-fig figcaption, .n-cap {
  margin-top: var(--space-4); max-width: var(--measure); font-size: 14px;
  line-height: 1.55; color: var(--muted);
}
.n-cap b { color: var(--fg-2); font-weight: 500; }
/* The qualification is not a caption. It is the sentence without which the
   figure above it would be read wrongly, so it carries a rule and sits in
   the reading colour, not the caption colour. */
.n-qual {
  margin-top: var(--space-5); max-width: var(--measure); padding-left: var(--space-4);
  border-left: 2px solid var(--st-part); font-size: 14.5px; line-height: 1.6; color: var(--fg-2);
}
.n-qual + .n-qual { margin-top: var(--space-3); }
.n-qual b { color: var(--fg); font-weight: 500; }

/* A panel is a shared field: two things that must be compared inside one
   boundary. It is never used to tidy an ordinary figure. */
.n-panel {
  margin-top: clamp(22px, 2.6vw, 32px); border: 1px solid var(--border-soft);
  background: var(--surface); padding: clamp(18px, 2.2vw, 26px);
}
.n-panel-h { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5); }
.n-panel-h h3 { font-size: var(--text-lg); }
.n-panel-h .n-panel-meta { font-size: 12px; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--meta); }

/* ── plot primitives ──────────────────────────────────────────────────────
   Every plot is server-rendered SVG inside a positioned box that also carries
   the axis labels as real text. Nothing is drawn in canvas, nothing needs a
   client library, and nothing loses its values without JavaScript. */
.n-plot { position: relative; padding-left: 52px; }
.n-fuel { margin-top: var(--space-7); }
.n-fuel-tabs { display: flex; gap: 0; margin-bottom: var(--space-5); border-bottom: 1px solid var(--line); }
.n-fuel-tabs button { appearance: none; border: 0; border-bottom: 3px solid transparent; background: transparent; color: var(--ink-soft); font: inherit; font-weight: 700; padding: .6rem 1rem; cursor: pointer; }
.n-fuel-tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--n-mark); }
.n-fuel-tabs button:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.n-fuel-lane + .n-fuel-lane, .n-fuel-strip { margin-top: var(--space-6); }
.n-fuel-strip { border-top: 1px solid var(--line); padding-top: var(--space-5); }
.n-fuel-markers { display: grid; gap: .45rem; margin: var(--space-5) 0; padding: 0; list-style: none; color: var(--ink-soft); }
.n-fuel-markers b { color: var(--ink); font-size: .78em; letter-spacing: .08em; text-transform: uppercase; }
.n-fuel-gap { margin-top: var(--space-5); }
.n-plot svg { display: block; width: 100%; height: auto; overflow: visible; }
.n-axis { position: absolute; inset: 0 0 0 0; pointer-events: none; }
.n-axis-t { position: absolute; left: 0; right: 0; transform: translateY(50%); }
.n-axis-t i { display: block; border-top: 1px solid var(--n-grid); margin-left: 52px; }
.n-axis-t.is-zero i { border-top-color: color-mix(in oklab, var(--fg) 34%, var(--surface)); }
.n-axis-t b {
  position: absolute; left: 0; bottom: -0.62em; width: 46px; text-align: right;
  font-family: var(--font-mono); font-size: 10px; font-weight: 400; letter-spacing: 0.02em;
  color: var(--meta); font-variant-numeric: tabular-nums;
}
.n-plot-body { position: relative; }
/* x labels are real text under the plot, thinned rather than rotated. */
.n-xlab { display: flex; margin-top: var(--space-2); padding-left: 52px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; color: var(--meta); }
.n-xlab span { flex: 1 1 0; min-width: 0; text-align: center; }
.n-xlab span:first-child { text-align: left; }
.n-xlab span:last-child { text-align: right; }

/* Direct end labels: the value at each end of a line, printed beside it, so a
   two-series figure needs no legend and no hover. */
.n-ends { display: flex; justify-content: space-between; gap: var(--space-4);
  margin-top: var(--space-3); padding-left: 52px; font-size: 12.5px; color: var(--muted);
  flex-wrap: wrap; }
.n-ends b { color: var(--fg); font-weight: 500; font-variant-numeric: tabular-nums; }

/* Series key. Line style as well as colour, because greyscale must work. */
.n-key { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
  margin-top: var(--space-4); font-size: 12.5px; color: var(--muted); }
.n-key span { display: inline-flex; align-items: center; gap: var(--space-2); }
.n-key i { width: 20px; height: 0; border-top: 2.5px solid var(--n-ink); flex: none; }
.n-key .k-comp i { border-top-color: var(--n-comp); border-top-style: dashed; }
.n-key .k-mark i { border-top-color: var(--n-mark); }
.n-key .k-open i { border-top-style: dashed; border-top-color: var(--muted); }
.n-key b { color: var(--fg-2); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── the locked pair ──────────────────────────────────────────────────────
   The signature form. Two official measures that only mean anything together,
   drawn in one field with one shared caption and no reconciliation. The
   tension line below states what the pair says and explicitly does not
   resolve it. */
.n-pair { display: grid; gap: clamp(20px, 2.4vw, 30px); }
@media (min-width: 900px) { .n-pair.is-side { grid-template-columns: 1fr 1fr; } }
.n-pair-part > h3 { font-size: 14px; font-weight: 500; letter-spacing: 0.02em; color: var(--fg-2); max-width: 34ch; }
.n-pair-part > .n-pair-sub { font-size: 12px; color: var(--meta); margin-top: 2px; }
.n-tension {
  margin-top: clamp(18px, 2vw, 24px); padding-top: var(--space-4);
  border-top: 3px double var(--fg-2); max-width: var(--measure-wide);
  font-size: 15.5px; line-height: 1.6; color: var(--fg-2);
}
.n-tension b { color: var(--fg); font-weight: 500; }

/* ── the dual mark ────────────────────────────────────────────────────────
   One period, two published values, each named to the authority that
   published it. The site does not adjudicate, so neither mark is subordinate:
   the disputed year carries both, joined by a bracket. */
.n-dual { display: flex; flex-wrap: wrap; gap: var(--space-6) clamp(24px, 3vw, 40px); }
.n-dual-m { display: flex; align-items: flex-start; gap: var(--space-3); }
.n-dual-m .n-dual-v { font-family: var(--font-display); font-size: clamp(26px, 3.2vw, 36px);
  line-height: 1; color: var(--fg); font-variant-numeric: tabular-nums; }
.n-dual-m .n-dual-a { font-size: 12.5px; line-height: 1.45; color: var(--muted); max-width: 22ch;
  margin-top: 4px; }
.n-dual-m .n-dual-a b { display: block; color: var(--fg-2); font-weight: 500; }
.n-dual-j { align-self: center; font-family: var(--font-mono); font-size: 12px; color: var(--meta);
  letter-spacing: 0.08em; text-transform: uppercase; }

/* ── peer field ───────────────────────────────────────────────────────────
   The full distribution with the position marked. A rank claim needs its
   field visible, so the field is the figure and the rank is a caption. */
.n-field { position: relative; padding-block: var(--space-6) var(--space-2); }
.n-field-row + .n-field-row { margin-top: clamp(18px, 2.2vw, 26px); }
.n-field-l { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
  font-size: 13px; color: var(--fg-2); margin-bottom: var(--space-2); flex-wrap: wrap; }
.n-field-l b { font-weight: 500; }
.n-field-l span { font-size: 12px; color: var(--meta); }
.n-field-scale { position: relative; height: 46px; }
.n-field-axis { position: absolute; left: 0; right: 0; top: 22px; border-top: 1px solid var(--n-grid); }
.n-field-d { position: absolute; top: 16px; width: 9px; height: 9px; margin-left: -4.5px;
  border-radius: 50%; background: var(--n-comp-soft); }
.n-field-d.is-me { top: 11px; width: 19px; height: 19px; margin-left: -9.5px; background: none;
  border: 3px solid var(--n-mark); }
.n-field-d.is-median { top: 8px; width: 0; height: 25px; margin-left: 0; border-radius: 0;
  border-left: 1px dashed var(--fg-2); background: none; }
.n-field-t { position: absolute; top: 34px; transform: translateX(-50%); white-space: nowrap;
  font-family: var(--font-mono); font-size: 10px; color: var(--meta); }
.n-field-t.is-me { color: var(--accent-active); font-size: 11px; } /* 11px text: base accent is 3.5:1 */

/* ── composition with a visible remainder ────────────────────────────────
   Parts that do not sum, showing the gap rather than absorbing it. The
   remainder is drawn open — a dashed outline, never a filled slice — and it
   is labelled with what it is. */
.n-comp-bar { display: flex; height: 34px; width: 100%; }
.n-comp-p { position: relative; min-width: 2px; background: var(--n-ink-soft); }
.n-comp-p:nth-child(2n) { background: color-mix(in oklab, var(--fg) 44%, var(--surface)); }
.n-comp-p:nth-child(3n) { background: color-mix(in oklab, var(--fg) 30%, var(--surface)); }
.n-comp-p.is-mark { background: var(--n-mark); }
.n-comp-p.is-open { background: none; border: 1.5px dashed var(--muted); }
.n-comp-k { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3) var(--space-6); margin-top: var(--space-4); font-size: 13px; }
.n-comp-k > span { display: flex; align-items: baseline; gap: var(--space-2); color: var(--muted); }
.n-comp-k i { width: 11px; height: 11px; flex: none; background: var(--n-ink-soft);
  transform: translateY(1px); }
.n-comp-k .k2 i { background: color-mix(in oklab, var(--fg) 44%, var(--surface)); }
.n-comp-k .k3 i { background: color-mix(in oklab, var(--fg) 30%, var(--surface)); }
.n-comp-k .k-mark i { background: var(--n-mark); }
.n-comp-k .k-open i { background: none; border: 1.5px dashed var(--muted); }
.n-comp-k b { color: var(--fg); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── recording band ───────────────────────────────────────────────────────
   What the source captured, drawn beneath what it says. Three states, each
   with its own fill AND its own word in the key, because a reader must be
   able to tell "recorded" from "not recorded at all" in greyscale. */
.n-band { margin-top: var(--space-5); }
.n-band-row { display: grid; grid-template-columns: minmax(120px, 190px) minmax(0, 1fr);
  align-items: center; gap: var(--space-4); }
.n-band-row + .n-band-row { margin-top: var(--space-2); }
.n-band-l { font-size: 13px; color: var(--fg-2); }
.n-band-track { display: flex; gap: 2px; }
.n-band-c { flex: 1 1 0; height: 22px; position: relative; }
.n-band-c.is-full { background: var(--n-ink-soft); }
.n-band-c.is-part { background: repeating-linear-gradient(135deg,
  var(--n-comp-soft) 0 4px, transparent 4px 8px); border: 1px solid var(--n-comp-soft); }
.n-band-c.is-none { border: 1px dashed color-mix(in oklab, var(--muted) 60%, var(--surface)); }
.n-band-x { display: flex; gap: 2px; margin-top: var(--space-2);
  font-family: var(--font-mono); font-size: 10px; color: var(--meta); }
.n-band-x span { flex: 1 1 0; text-align: center; }
.n-band-key { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
  margin-top: var(--space-4); font-size: 12.5px; color: var(--muted); }
.n-band-key span { display: inline-flex; align-items: center; gap: var(--space-2); }
.n-band-key i { width: 16px; height: 12px; flex: none; }
.n-band-key .kb-full i { background: var(--n-ink-soft); }
.n-band-key .kb-part i { background: repeating-linear-gradient(135deg,
  var(--n-comp-soft) 0 4px, transparent 4px 8px); border: 1px solid var(--n-comp-soft); }
.n-band-key .kb-none i { border: 1px dashed color-mix(in oklab, var(--muted) 60%, var(--surface)); }

/* ── drawn absence ────────────────────────────────────────────────────────
   Missing is labelled, never greyed as zero and never rendered as an error.
   A dashed rule and the word, in the same weight as the figures above it. */
.n-absence {
  margin-top: clamp(22px, 2.6vw, 32px); border: 1.5px dashed color-mix(in oklab, var(--muted) 55%, var(--surface));
  padding: clamp(18px, 2.2vw, 26px); max-width: var(--measure-wide);
}
.n-absence-t { display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: 12px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.n-absence-t::before { content: ""; width: 14px; border-top: 3px dotted currentColor; }
.n-absence h3 { margin-top: var(--space-3); font-size: var(--text-lg); }
.n-absence p { margin-top: var(--space-3); max-width: var(--measure); color: var(--fg-2); font-size: 15px;
  line-height: 1.6; }
.n-absence .n-absence-src { margin-top: var(--space-3); font-size: 13px; color: var(--muted); }

/* ── the open chain ───────────────────────────────────────────────────────
   The waste flow. Evidenced stages carry their quantity; the terminus is an
   open node with no value, because no publisher states one. Drawn as a row
   that wraps rather than a diagram that breaks. */
.n-chain { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--space-2);
  margin-top: clamp(22px, 2.6vw, 32px); }
.n-chain-n { flex: 1 1 150px; min-width: 130px; border: 1px solid var(--border-soft);
  background: var(--surface); padding: var(--space-4); display: flex; flex-direction: column; }
.n-chain-n.is-open { background: none; border-style: dashed;
  border-color: color-mix(in oklab, var(--muted) 55%, var(--surface)); }
.n-chain-s { font-size: 11px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--meta); }
.n-chain-v { margin-top: var(--space-2); font-family: var(--font-display); font-size: var(--text-xl);
  line-height: 1.1; color: var(--fg); font-variant-numeric: tabular-nums; }
.n-chain-n.is-open .n-chain-v { font-family: var(--font-body); font-size: 13px; color: var(--muted);
  font-style: italic; }
.n-chain-d { margin-top: var(--space-2); font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.n-chain-a { align-self: center; color: var(--meta); font-family: var(--font-mono); flex: none; }

/* ── exact-value table ────────────────────────────────────────────────────
   Where a visual alone is insufficient. Uses the foundation table, adds only
   numeric alignment and a collapsed disclosure on narrow screens. */
.n-table-wrap { margin-top: clamp(18px, 2.2vw, 26px); }
.n-table-wrap > summary {
  cursor: pointer; font-size: 12px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); padding-block: var(--space-2);
  min-height: 40px; display: flex; align-items: center; gap: var(--space-2);
}
.n-table-wrap > summary:hover { color: var(--fg); }
.n-table-wrap[open] > summary { color: var(--fg-2); }
.wf-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wf-table th.num { text-align: right; }
.wf-table tr.is-me td { background: var(--n-wash); font-weight: 500; }
.wf-table td.flag { color: var(--muted); font-size: 12.5px; }

/* ── the bridge ───────────────────────────────────────────────────────────
   Deep links into the product that owns the detail. A row of doors, not a
   card grid: the number is the door and the label says what is behind it. */
.n-bridge { display: flex; flex-wrap: wrap; gap: var(--space-6) clamp(24px, 3.4vw, 48px);
  margin-top: clamp(20px, 2.4vw, 28px); }
.n-bridge a { text-decoration: none; display: block; min-width: 0; padding-block: var(--space-1); }
.n-bridge .n-v { font-size: clamp(24px, 2.8vw, 32px); }
.n-bridge a:hover .n-v { color: var(--accent-hover); }
.n-bridge a .n-v-l { text-decoration: underline; text-decoration-color: var(--border-soft); }
.n-bridge a:hover .n-v-l { color: var(--fg-2); text-decoration-color: var(--accent); }

/* Cross-links out of a subject. One line of named destinations; the link text
   names the question the other product answers, never "read more". */
.n-onward { margin-top: clamp(20px, 2.4vw, 28px); display: flex; flex-wrap: wrap;
  gap: var(--space-2) var(--space-5); font-size: 14px; }
.n-onward a { color: var(--fg-2); text-decoration: underline; text-decoration-color: var(--border-soft); }
.n-onward a:hover { color: var(--fg); text-decoration-color: var(--accent); }

/* ── slope ────────────────────────────────────────────────────────────────
   Change between two points across many categories. Only the categories the
   finding names are inked; the rest are the field they move within. */
.n-slope-l { display: flex; justify-content: space-between; padding-left: 52px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.02em; color: var(--meta);
  margin-bottom: var(--space-2); }

/* ── overview ─────────────────────────────────────────────────────────────
   /numbers is a civic snapshot: one heading and six figures, the values doing
   the work. The family navigation under the band moves a reader between the
   subjects, so nothing here is a card, a chart or a teaser. Each figure is
   one link to the section that publishes it (the Home entry pattern in
   foundation.css): the value is the anchor, its ::after covers the entry, the
   ring is drawn round the entry, and feedback is colour only. */
.n-glance-page { padding-block: clamp(40px, 5vw, 72px) clamp(56px, 7vw, 104px); }
/* The page's explanation sits to the right of its illustration
   (publication.css .wf-withplate); the figures below keep the full width. */
.n-glance-head { --plate-w: 280px; align-items: center; }
.n-glance-page h2 { font-size: clamp(26px, 3vw, 36px); letter-spacing: -0.015em; }
.n-glance-lede { margin: var(--space-3) 0 0; max-width: var(--measure);
  font-size: var(--text-lg); line-height: var(--leading-body); color: var(--fg-2); }
.n-glance-page dl { display: grid; grid-template-columns: 1fr; margin: clamp(28px, 3.4vw, 48px) 0 0;
  gap: clamp(28px, 3.6vw, 52px) clamp(28px, 4vw, 64px); }
@media (min-width: 640px) { .n-glance-page dl { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .n-glance-page dl { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.n-glance-page dl > div { position: relative; min-width: 0; }
.n-glance-page dt a { color: inherit; text-decoration: none; }
.n-glance-page dt a::after { content: ""; position: absolute; inset: calc(-1 * var(--space-2)); }
.n-glance-page dt a:focus-visible { box-shadow: none; }
.n-glance-page dt a:focus-visible::after { box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
.n-glance-page dl > div:hover dt a { color: var(--accent-active); }
.n-glance-page dt { font-family: var(--font-display); font-size: clamp(40px, 4.6vw, 60px); line-height: 1;
  letter-spacing: -0.025em; font-variant-numeric: tabular-nums; color: var(--fg); }
.n-glance-page dd { margin: var(--space-3) 0 0; font-size: 15px; line-height: 1.4; color: var(--fg-2); max-width: 26ch; }
.n-glance-page dd span { display: block; margin-top: var(--space-2); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--meta); }

/* ── responsive ───────────────────────────────────────────────────────────
   Recomposition, not compression. Figures keep their axis labels; paired
   fields stack; nothing is dropped for width. */
@media (max-width: 900px) {
  .n-plot { padding-left: 44px; }
  .n-axis-t i { margin-left: 44px; }
  .n-axis-t b { width: 38px; }
  .n-xlab, .n-ends, .n-slope-l { padding-left: 44px; }
  .n-band-row { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
  .n-band-l { font-size: 12.5px; color: var(--muted); }
}
@media (max-width: 640px) {
  .n-plot { padding-left: 38px; }
  .n-axis-t i { margin-left: 38px; }
  .n-axis-t b { width: 32px; font-size: 9px; }
  .n-xlab, .n-ends, .n-slope-l { padding-left: 38px; }
  /* Two a row rather than one. Four promoted values stacked vertically is
     most of a phone screen before the section's figure begins, and the point
     of promoting them is that they are read together. */
  .n-values { display: grid; grid-template-columns: 1fr 1fr;
    gap: var(--space-6) var(--space-6); }
  .n-v { font-size: clamp(22px, 6.2vw, 30px); }
  .n-values--sm .n-v { font-size: clamp(19px, 5.4vw, 26px); }
  .n-glance dl { grid-template-columns: 1fr 1fr; }
  .n-glance dt { font-size: clamp(22px, 6.2vw, 30px); }
  .n-dual { gap: var(--space-5); }
  /* Stacked, the two marks would read as a list unless the word between them
     survives. It is the word that says these are rival figures rather than
     two facts, so it becomes a full-width rule between them instead of
     disappearing. */
  .n-dual-j { flex-basis: 100%; align-self: stretch; text-align: left;
    padding-top: var(--space-4); border-top: 1px solid var(--border-soft); }
  .n-chain-a { display: none; }
  .n-chain-n { flex-basis: 100%; }
  /* A long series prints only its four anchor labels on a phone (both ends
     and two between, chosen by shape.label_anchors); the rest keep their
     place in the row so nothing shifts. */
  .n-xlab span:not(.is-anchor):not(:first-child):not(:last-child) { visibility: hidden; }
  .n-xlab span.is-anchor { white-space: nowrap; }
}

@media print {
  .n-table-wrap[open] > summary { display: none; }
  .n-table-wrap { display: block; }
  .n-sec { break-inside: avoid; }
}

/* ── touch targets ────────────────────────────────────────────────────────
   Two link classes are navigation rather than prose and were landing at 16 to
   22px on a phone: the onward links at the foot of a section, and the finding
   links in the evidence region's readiness table. Inline links inside a
   sentence are left alone — enlarging those would break the line box, and a
   link in a block of text is exempt from the target-size rule for that
   reason. */
@media (max-width: 640px) {
  .n-onward a { display: inline-flex; align-items: center; min-height: 44px; }
  .wf-record .wf-table td a { display: inline-flex; align-items: center;
    min-height: 44px; padding-right: var(--space-3); }
}

/* ------------------------------------------------ nothing may push wider

   A grid or flex child is `min-width: auto` by default, which means it
   refuses to shrink below the intrinsic width of its own content. Two
   places on a Numbers page hit that at 375px: a paired figure, whose plot
   holds an axis wider than a phone, and the source list, whose items are
   full publication titles. Both are the container's problem, not the
   content's — the figure rescales and the title wraps once they are allowed
   to. Mobile here is recomposition, so a page must never scroll sideways. */
.n-pair-part, .n-pair-part .n-fig, .n-pair-part .n-plot { min-width: 0; }
.n-sec .src ul { flex-wrap: wrap; }
.n-sec .src li { min-width: 0; overflow-wrap: break-word; }
/* The publisher and date are held on one line so they read as one credit.
   A publisher name can be longer than a phone is wide, and at that point an
   unbreakable credit costs more than a wrapped one. */
@media (max-width: 640px) { .n-sec .src li span { white-space: normal; } }

/* A paired figure keeps two plots side by side, so each gets roughly half the
   width its full-width sibling would. Below the wide breakpoint the tick
   labels no longer fit that half, and a label row that does not fit is the one
   part of the figure that can be dropped without losing a value: the ends stay
   labelled, the shape stays readable, and every number is still in the exact
   values table under the figure. */
@media (max-width: 900px) {
  .n-pair .n-xlab span:not(:first-child):not(:last-child) { display: none; }
}

/* ── at a glance ──────────────────────────────────────────────────────────
   The orientation strip. It is the first thing under the banner, and it is
   numbers before prose because the page is called Numbers. Every entry is
   restated in context by a section below; nothing lives only here. */
.n-glance {
  padding-block: clamp(22px, 2.6vw, 32px);
  border-bottom: 1px solid var(--rule);
}
.n-glance dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(18px, 2.4vw, 30px);
}
.n-glance dt {
  font-family: var(--font-display);
  font-size: clamp(26px, 3.1vw, 38px);
  line-height: 1.02;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.n-glance dd {
  margin-top: var(--space-2);
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  max-width: 26ch;
}
.n-glance dd span {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--meta);
}
.n-glance a {
  display: inline-block;
  margin-top: var(--space-2);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  border-bottom: 1px solid var(--rule);
}
.n-glance a:hover, .n-glance a:focus-visible { color: var(--wire); border-bottom-color: var(--wire); }

/* ── range control ────────────────────────────────────────────────────────
   Hidden until script reveals it, because every window is already drawn and
   the buttons only choose between them. */
.n-range-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.n-range-bar button {
  min-height: 34px;
  min-width: 46px;
  padding: 4px 12px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--muted);
  background: none;
  border: 1px solid var(--rule);
  border-radius: 2px;
  cursor: pointer;
}
.n-range-bar button:hover, .n-range-bar button:focus-visible { color: var(--fg); border-color: var(--fg-2); }
.n-range-bar button[aria-pressed="true"] {
  color: var(--surface);
  background: var(--fg);
  border-color: var(--fg);
}

/* ── change ladder ────────────────────────────────────────────────────────
   One headline restated under successive adjustments. The bars are the point:
   three percentages in prose hide how much each adjustment removes. */
.n-ladder { margin-top: var(--space-4); }
.n-ladder-row + .n-ladder-row { margin-top: clamp(14px, 1.8vw, 20px); }
.n-ladder-l { font-size: 13px; color: var(--muted); max-width: var(--measure); }
/* Grid, not flex: the bar's width is a percentage, and against a flex
   container that percentage resolves to the whole track — so the value beside
   it was pushed 49px past the canvas on a phone. Against a `1fr` column it
   resolves to the space left after the value has been laid out. */
.n-ladder-track {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.n-ladder-bar {
  height: 16px;
  min-width: 2px;
  max-width: 100%;
  background: var(--n-ink-soft);
  justify-self: start;
}
.n-ladder-row.is-last .n-ladder-bar { background: var(--n-mark); }
.n-ladder-bar.is-neg { background: var(--n-comp-soft); }
.n-ladder-track b {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.1vw, 24px);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.n-ladder-n { margin-top: var(--space-2); font-size: 12px; color: var(--meta); max-width: var(--measure); }

/* ── two-sided flow ───────────────────────────────────────────────────────
   Each side over its own denominator, printed on that side. */
.n-flow { display: grid; gap: clamp(24px, 3vw, 38px); margin-top: var(--space-4); }
@media (min-width: 900px) { .n-flow[data-sides="2"] { grid-template-columns: 1fr 1fr; } }
.n-flow-side > h3 { font-size: 14px; font-weight: 500; letter-spacing: 0.02em; color: var(--fg-2); }
.n-flow-tot { margin-top: var(--space-2); font-size: 13px; color: var(--muted); }
.n-flow-tot b {
  font-family: var(--font-display);
  font-size: clamp(21px, 2.3vw, 26px);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
  margin-right: var(--space-2);
}
.n-flow[data-sides="1"] .n-flow-row { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) auto; }
.n-flow-row {
  display: grid;
  grid-template-columns: minmax(0, 9rem) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.n-flow-l { font-size: 12.5px; color: var(--muted); min-width: 0; }
.n-flow-track { display: block; height: 14px; background: var(--n-wash); }
.n-flow-bar { display: block; height: 100%; background: var(--n-ink-soft); }
.n-flow-bar.is-mark { background: var(--n-mark); }
.n-flow-v { font-size: 12.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.n-flow-v b { margin-left: var(--space-2); color: var(--fg); font-weight: 500; }
@media (max-width: 639px) {
  .n-flow-row { grid-template-columns: minmax(0, 1fr) auto; }
  .n-flow-track { grid-column: 1 / -1; }
}

/* ── small multiples ──────────────────────────────────────────────────────
   Aligned panels on their own scales, because these measures answer different
   questions and one axis would imply they are commensurable. */
.n-mult { display: grid; gap: clamp(20px, 2.4vw, 30px); }
@media (min-width: 900px) {
  .n-mult[data-cols="2"] { grid-template-columns: 1fr 1fr; }
  .n-mult[data-cols="3"] { grid-template-columns: repeat(3, 1fr); }
}
/* A peer distribution needs its own width: at a third of the canvas the
   council labels collide with the median marker. It spans the row instead. */
@media (min-width: 900px) { .n-mult .n-mult-part.is-wide { grid-column: 1 / -1; } }
.n-mult-part > h3 { font-size: 14px; font-weight: 500; letter-spacing: 0.02em; color: var(--fg-2); }
.n-mult-part .n-fig { margin-top: var(--space-4); }

/* ── deeper detail ────────────────────────────────────────────────────────
   Demoted material stays inspectable and stops competing. Closed by default:
   a reader who wants the main proposition should not have to walk past the
   secondary measures to reach the end of the argument. */
.n-deeper {
  margin-top: clamp(30px, 4vw, 52px);
  border-top: 1px solid var(--rule);
  padding-top: clamp(20px, 2.4vw, 28px);
}
.n-deeper > summary {
  cursor: pointer;
  font-family: var(--font-display);
  font-size: clamp(19px, 2vw, 23px);
  color: var(--fg);
  list-style: none;
}
.n-deeper > summary::-webkit-details-marker { display: none; }
.n-deeper > summary::after {
  content: "  \002B";
  font-family: var(--font-mono);
  font-size: 0.8em;
  color: var(--meta);
}
.n-deeper[open] > summary::after { content: "  \2212"; }
.n-deeper > summary:hover, .n-deeper > summary:focus-visible { color: var(--wire); }
.n-deeper-lede { margin-top: var(--space-3); font-size: 14px; color: var(--muted); max-width: var(--measure); }
.n-deeper .n-sec { border-top: 1px solid var(--rule); }
.n-deeper .n-sec h2 { font-size: clamp(19px, 2vw, 23px); }
