/* Electoral Reforms section (REDEEM).
 *
 * Scoped to /electoral-reforms/ and loaded only by that section's templates.
 * Everything here is built from core.css tokens — there are no raw colour
 * literals, because scripts/lint_design_system.py refuses them and because a
 * literal here would drift the moment the brand palette moves.
 *
 * Two structural rules the whole section obeys:
 *
 *   1. REVERSED by owner direction, 2026-09-01. This section used to forbid
 *      JavaScript outright. The signed REDEEM proposal promised the opposite —
 *      "Apache ECharts, configured with keyboard and screen-reader
 *      alternatives and a data table behind every chart" — and the client's
 *      reading of the delivered pages was that they narrate rather than
 *      visualise. The charts are now ECharts islands.
 *
 *      What has NOT changed is the reason the old rule existed. Every island is
 *      progressive enhancement: the server renders the picture first, in CSS
 *      geometry from inline custom properties (style="--w: 40%"), and the
 *      island replaces it only once it has mounted and has data. A 2-vCPU
 *      production host, a mobile-first audience and WCAG 2.2 AA still point the
 *      same way, so a page with JavaScript off loses the tooltip and keeps the
 *      chart. Chart colours live in the Vue component, never here — the design
 *      lint refuses a raw literal in this file and is right to.
 *   2. Every graphic has a table twin in the same <figure>, and every
 *      horizontal graphic collapses to a vertical card list on a phone rather
 *      than growing a sideways scrollbar (1.4.10 Reflow).
 */

/* --- Status palette -------------------------------------------------------
 * Nine roadmap statuses collapse onto the four semantic badge colours plus
 * muted. Colour is never the only signal: every lane and card also carries the
 * status as text (1.4.1).
 */
.rf-s--done { --rf-ink: var(--colour-success); --rf-wash: var(--colour-success-bg); }
.rf-s--active { --rf-ink: var(--colour-info); --rf-wash: var(--colour-info-bg); }
.rf-s--hold { --rf-ink: var(--colour-warning); --rf-wash: var(--colour-warning-bg); }
.rf-s--late { --rf-ink: var(--colour-danger); --rf-wash: var(--colour-danger-bg); }
.rf-s--idle { --rf-ink: var(--colour-text-muted); --rf-wash: var(--colour-bg-subtle); }

/* --- Section sub-navigation ---------------------------------------------- */
.rf-subnav {
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--colour-border);
}

.rf-subnav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rf-subnav a {
  display: block;
  /* 2.5.8 Target Size: legislation.css's .tl-chip is ~22px tall and fails it.
     Do not copy that; 2.75rem clears the 24px minimum with room to spare. */
  min-height: 2.75rem;
  padding: var(--space-3) var(--space-4);
  border-bottom: 3px solid transparent;
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
}

.rf-subnav a:hover { color: var(--colour-text); background: var(--colour-bg-subtle); }
.rf-subnav a.is-active { color: var(--colour-primary); border-bottom-color: var(--colour-primary); }

/* --- Shared figure furniture --------------------------------------------- */
.rf-figure { margin: 0 0 var(--space-6); }

.rf-figure > figcaption {
  margin-bottom: var(--space-3);
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.rf-twin { margin-top: var(--space-4); }

.rf-twin > summary {
  min-height: 2.75rem;
  padding: var(--space-2) 0;
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
}

.rf-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3);
  padding: 0;
  list-style: none;
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
}

.rf-legend li { display: flex; gap: var(--space-2); align-items: center; }

.rf-legend__key {
  display: inline-block;
  width: 1.5rem;
  height: 0.6rem;
  border-radius: var(--radius-sm);
  background: var(--rf-ink, var(--colour-text-muted));
}

.rf-legend__key--over {
  border: 1px solid var(--colour-danger);
  background: repeating-linear-gradient(
    135deg,
    color-mix(in srgb, var(--colour-danger) 26%, transparent) 0 4px,
    transparent 4px 8px
  );
}

/* --- Surface A: the reform window strip ----------------------------------
 * One column per month over the whole electoral cycle. Labels and dots are
 * separate grid children rather than one nested marker, so a label can be
 * wider than its column and overflow harmlessly, and so consecutive markers
 * can sit on opposite sides of the line. That alternation is not decoration:
 * two of these dates are four weeks apart and would otherwise print on top of
 * each other.
 */
.rf-window { padding: var(--space-4) 0; }

.rf-window__grid {
  display: grid;
  grid-template-columns: repeat(var(--months), minmax(0, 1fr));
  grid-template-rows: minmax(4rem, auto) auto minmax(4rem, auto);
  align-items: center;
}

.rf-window__line {
  grid-row: 2;
  grid-column: 1 / -1;
  height: 3px;
  border-radius: var(--radius-pill);
  background: linear-gradient(
    to right,
    var(--colour-secondary) 0 calc(var(--now) * 1%),
    var(--colour-border-strong) calc(var(--now) * 1%) 100%
  );
}

.rf-window__lab {
  grid-column: var(--m);
  justify-self: center;
  width: 8.5rem;
  color: var(--colour-text-light);
  font-size: var(--text-xs);
  line-height: 1.35;
  text-align: center;
}

.rf-window__lab b { display: block; color: var(--colour-text); }
.rf-window__lab--up { grid-row: 1; align-self: end; padding-bottom: var(--space-3); }
.rf-window__lab--down { grid-row: 3; align-self: start; padding-top: var(--space-3); }
.rf-window__lab--start { justify-self: start; text-align: left; }
.rf-window__lab--end { justify-self: end; text-align: right; }

.rf-window__dot {
  grid-row: 2;
  grid-column: var(--m);
  justify-self: center;
  width: 0.85rem;
  height: 0.85rem;
  border: 2px solid var(--colour-bg);
  border-radius: 50%;
  background: var(--colour-secondary);
}

.rf-window__dot--rule {
  width: 0.3rem;
  height: 1.6rem;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--colour-warning);
}

.rf-window__dot--now {
  width: 0.9rem;
  height: 0.8rem;
  border: none;
  border-radius: 0;
  background: var(--colour-primary);
  clip-path: polygon(50% 100%, 0 0, 100% 0);
}

.rf-window__dot--ahead { background: var(--colour-info); }

.rf-window__dot--contested {
  width: 1rem;
  height: 1rem;
  border: 3px solid var(--colour-primary);
  background: var(--colour-bg);
}

.rf-window__notes { margin-top: var(--space-5); display: grid; gap: var(--space-3); }

.rf-window__note {
  padding: var(--space-2) var(--space-4);
  border-left: 3px solid var(--colour-border-strong);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  line-height: 1.6;
}

/* --- The view switcher --------------------------------------------------- */
.rf-views {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-4);
}

.rf-views__label {
  margin-right: var(--space-1);
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.rf-views a {
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-pill);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
}

.rf-views a:hover { border-color: var(--colour-border-strong); background: var(--colour-bg-subtle); }

.rf-views a[aria-current="true"] {
  border-color: var(--colour-primary);
  background: var(--colour-primary);
  color: var(--colour-bg);
}

.rf-views__hint {
  flex-basis: 100%;
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
}

/* --- Surface B, board view ------------------------------------------------ */
.rf-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-4);
  padding: 0;
  list-style: none;
}

.rf-board__col > h3 {
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--colour-border);
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.rf-board__col > h3 .rf-count { color: var(--colour-text-muted); font-weight: 400; }

.rf-board__col ol { display: grid; gap: var(--space-3); padding: 0; list-style: none; }

.rf-card {
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-left: 4px solid var(--rf-ink, var(--colour-border-strong));
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}

.rf-card__title { margin-bottom: var(--space-1); font-size: var(--text-base); font-weight: 700; line-height: 1.35; }
.rf-card__origin { color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-card__meta { margin-top: var(--space-3); color: var(--colour-text-light); font-size: var(--text-sm); line-height: 1.5; }
.rf-card__meta dt { color: var(--colour-text-muted); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; }
.rf-card__meta dd { margin: 0 0 var(--space-2); }
.rf-card__meta dd:last-child { margin-bottom: 0; }
.rf-card__absent { color: var(--colour-text-muted); font-style: italic; }
.rf-card .badge { margin-top: var(--space-3); }

/* --- Surface B, Gantt view ------------------------------------------------
 * One grid per lane: label column, the quarter track, status column. Rules
 * repeat inside each lane's track rather than floating over the whole block,
 * which keeps them exactly aligned without absolute positioning and without
 * display:contents (which drops list semantics in some screen readers).
 */
.rf-gantt { --label-col: minmax(11rem, 15rem); --status-col: minmax(7rem, 10rem); }

.rf-gantt__head,
.rf-gantt__lane {
  display: grid;
  grid-template-columns: var(--label-col) minmax(0, 1fr) var(--status-col);
  gap: var(--space-3);
  align-items: center;
}

.rf-gantt__head { padding-bottom: var(--space-2); border-bottom: 1px solid var(--colour-border); }

.rf-gantt__years {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
}

.rf-gantt__yr {
  grid-column: var(--at) / span var(--span);
  border-left: 1px solid var(--colour-border);
  padding-left: var(--space-1);
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
}

.rf-gantt__theme {
  margin: var(--space-5) 0 var(--space-2);
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.rf-gantt__lanes { padding: 0; list-style: none; }

.rf-gantt__lane { border-bottom: 1px solid var(--colour-border); padding: var(--space-2) 0; }

.rf-gantt__label b { font-size: var(--text-sm); font-weight: 700; line-height: 1.3; }
.rf-gantt__origin { display: block; margin-top: 2px; color: var(--colour-text-muted); font-size: var(--text-xs); }

.rf-gantt__track {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  align-items: center;
  min-height: 2rem;
}

.rf-gantt__rule {
  grid-row: 1;
  grid-column: var(--at);
  align-self: stretch;
  border-left: 1px dashed var(--colour-border-strong);
}

.rf-gantt__rule--now { border-left: 2px solid var(--colour-primary); }
.rf-gantt__rule--cut { border-left: 2px dashed var(--colour-warning); }

.rf-gantt__bar {
  grid-row: 1;
  grid-column: var(--from) / var(--to);
  height: 0.95rem;
  border-radius: var(--radius-sm);
  background: var(--rf-ink, var(--colour-text-muted));
}

/* The overrun tail is the point of this view: it runs from the due date to
   today and grows on its own, every day, with nobody editing anything. It is
   also stated in words inside the track's aria-label, so it is never
   hatch-only. */
.rf-gantt__over {
  grid-row: 1;
  grid-column: var(--from) / var(--to);
  height: 0.95rem;
  border: 1px solid var(--colour-danger);
  border-left: none;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: repeating-linear-gradient(
    135deg,
    color-mix(in srgb, var(--colour-danger) 26%, transparent) 0 4px,
    transparent 4px 8px
  );
}

.rf-gantt__mile {
  grid-row: 1;
  grid-column: var(--at);
  justify-self: center;
  width: 0.6rem;
  height: 0.6rem;
  border: 2px solid var(--colour-bg);
  background: var(--colour-text);
  rotate: 45deg;
}


.rf-gantt__status { font-size: var(--text-xs); text-align: right; }
.rf-gantt__movement { display: block; margin-top: 2px; color: var(--colour-text-muted); }

/* --- Table view ----------------------------------------------------------- */
.rf-table-note { margin-bottom: var(--space-3); color: var(--colour-text-muted); font-size: var(--text-sm); }

/* --- Composition strip ---------------------------------------------------- */
/* THE section's one stat-tile component. It was two: this one (bordered cell,
 * auto-fit grid, a `--rf-ink` rule on top) on the overview, and a flat
 * `.rf-bills__stats` grey strip on roadmap / laws / timeline / participate. The
 * flat one is gone — four numerals in one undivided panel read as a single
 * blob, and on /participate/, where every count is currently 0, it was the
 * loudest and least informative element on the page.
 *
 * The list resets let a `<ul>` use it; a `<div>` ignores them. */
.rf-comp {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin: var(--space-5) 0;
  padding: 0;
  list-style: none;
}

.rf-comp__cell {
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-top: 3px solid var(--rf-ink, var(--colour-border-strong));
  border-radius: var(--radius-md);
  background: var(--colour-bg);
}

.rf-comp__num { font-size: var(--text-3xl); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.rf-comp__lab { display: block; margin-top: var(--space-2); color: var(--colour-text-light); font-size: var(--text-sm); line-height: 1.35; }

/* A count of nothing is still printed in full, at full size — it is simply not
 * shouted. Contrast is presentation; withholding the number would be the gate
 * AGENTS.md 0 forbids. Set from the template, because CSS cannot read a value. */
.rf-comp__cell--zero { border-top-color: var(--colour-border); }
.rf-comp__cell--zero .rf-comp__num { color: var(--colour-text-muted); }


/* --- Phones: every horizontal graphic becomes a vertical list -------------
 * Nothing here grows a sideways scrollbar. The Gantt keeps its DOM and drops
 * its track, so a shared ?view=gantt link opens as readable cards.
 */
@media (max-width: 760px) {
  .rf-window__grid {
    display: grid;
    grid-template-columns: 1.25rem 1fr;
    grid-template-rows: none;
    gap: var(--space-2) var(--space-3);
    align-items: center;
    padding-left: var(--space-2);
    border-left: 2px solid var(--colour-border);
  }

  .rf-window__line { display: none; }

  .rf-window__lab,
  .rf-window__dot {
    grid-row: auto;
    grid-column: auto;
    align-self: center;
    justify-self: center;
    padding: 0;
  }

  .rf-window__lab { width: auto; text-align: left; justify-self: start; }

  .rf-gantt__head { display: none; }

  .rf-gantt__lane {
    grid-template-columns: 1fr;
    gap: var(--space-2);
    padding: var(--space-4) 0;
  }

  .rf-gantt__track { display: none; }
  .rf-gantt__status { text-align: left; }
}

/* --- Print: the view a programme officer takes into a meeting ------------- */
@media print {
  .rf-subnav,
  .rf-views,
  .rf-notice { display: none; }

  .rf-twin[open] > summary { display: none; }
  .rf-gantt__lane { break-inside: avoid; }
}

/* --- Section furniture ----------------------------------------------------

   READING MEASURES ARE OFF SITE-WIDE — owner decision, 2026-08-02, documented
   at core.css:165. `--container-prose` and `--measure-lead` are both `none`,
   so `.page-intro--text`, `.section-intro--text` and `.section__lead` span
   their container everywhere else on the site.

   These three rules opted out of that: two reached for `--measure-lead-len`,
   which core.css:191 says exists for ONE consumer — publicfinance.css needs a
   real length for a `minmax(0, …)` grid track, because `minmax(0, none)` is
   invalid — and the hero lead used a flat 46rem. Measured at a 1920px viewport
   that rendered the standfirst at 558px and the hero lead at 736px inside a
   1728px container, which is the dead space the owner reported on 2026-08-20.
   Consuming `--measure-lead` puts this section back on the site's decision. */
.rf-hero-lead {
  max-width: var(--measure-lead);
  margin-top: var(--space-3);
  font-size: var(--text-base);
  line-height: 1.6;
}

.rf-sec { padding: var(--space-5) 0; }
.rf-sec + .rf-sec { border-top: 1px solid var(--colour-border); }

.rf-sec > h2 {
  margin-bottom: var(--space-2);
  font-size: var(--text-xl);
}

.rf-sec__standfirst {
  max-width: var(--measure-lead);
  margin-bottom: var(--space-4);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  line-height: 1.6;
}

.rf-sec__more {
  margin-top: var(--space-4);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  line-height: 1.6;
}

.rf-gantt__ruletag {
  grid-column: var(--at) / span 3;
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.rf-gantt__ruletag--now { color: var(--colour-primary); }
.rf-gantt__ruletag--cut { color: var(--colour-warning); }

.rf-gantt__head--rules { padding: var(--space-2) 0 0; border-bottom: none; }

/* --- Split layout: the roadmap and its evidence panel ---------------------
 * The panel is opened by a ?open= link rather than a JavaScript drawer, so it
 * is shareable, printable and keyboard-reachable. Below the breakpoint it
 * simply stacks under the graphic — no off-canvas, no focus trap, nothing to
 * get wrong.
 */
.rf-split { display: grid; gap: var(--space-5); }
.rf-split--open { grid-template-columns: minmax(0, 1fr); }

@media (min-width: 1100px) {
  .rf-split--open { grid-template-columns: minmax(0, 1fr) minmax(21rem, 25rem); align-items: start; }
}

.rf-split__main { min-width: 0; }

.rf-panel {
  position: sticky;
  top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-top: 4px solid var(--rf-ink, var(--colour-border-strong));
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}

.rf-panel__bar { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }

.rf-panel__eyebrow {
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.rf-panel__close {
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  font-size: var(--text-sm);
  font-weight: 600;
}

.rf-panel__title { margin: var(--space-2) 0 var(--space-1); font-size: var(--text-lg); line-height: 1.3; }
.rf-panel__origin { color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-panel__summary { margin-top: var(--space-3); font-size: var(--text-sm); line-height: 1.6; }

.rf-panel__facts { margin-top: var(--space-4); font-size: var(--text-sm); }
.rf-panel__facts dt {
  margin-top: var(--space-3);
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.rf-panel__facts dd { margin: 2px 0 0; line-height: 1.5; }

.rf-panel__h {
  margin: var(--space-5) 0 var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--colour-border);
  font-size: var(--text-sm);
}

.rf-panel__list { display: grid; gap: var(--space-3); padding: 0; list-style: none; font-size: var(--text-sm); }
.rf-panel__list li { line-height: 1.45; }
.rf-panel__note { display: block; margin-top: 2px; color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-panel__late { color: var(--colour-danger); font-weight: 700; }
.rf-panel__absent { color: var(--colour-text-muted); font-size: var(--text-sm); font-style: italic; line-height: 1.5; }
.rf-panel__table { margin: 0; }
.rf-panel__table th, .rf-panel__table td { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); }

/* --- Absence, stated rather than left blank ------------------------------- */
.rf-absent { color: var(--colour-text-muted); font-style: italic; }
.rf-late { color: var(--colour-danger); font-weight: 700; }
/* An empty group is INFORMATION, not an error, and it is the commonest state on
 * a scoped page — /participate/ renders three of these at once today. It was
 * 13.6px muted italic with no container, which with a `<strong>` inside came
 * out bold-italic: the house style for "something broke". A dashed panel reads
 * as a deliberate placeholder, and dropping the italic lets the lead sentence
 * carry the weight instead of the slant. The dashed border distinguishes it
 * from a real content card (solid) at a glance.
 *
 * No `max-width` here — see the READING MEASURES note at core.css:165. */
.rf-empty {
  margin: var(--space-3) 0 var(--space-5);
  padding: var(--space-5);
  border: 1px dashed var(--colour-border-strong);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
  color: var(--colour-text-light);
  font-size: var(--text-base);
  line-height: 1.6;
}

/* The first sentence names the subject nothing was found in; the rest explains
 * and offers the way out. Sizing them apart is what makes the panel scannable. */
.rf-empty strong { display: block; margin-bottom: var(--space-2); color: var(--colour-text); font-size: var(--text-lg); }
.rf-empty .btn { margin-top: var(--space-3); }

.rf-filter {
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--colour-info);
  background: var(--colour-info-bg);
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* --- Per-theme composition ------------------------------------------------ */
.rf-themes { display: grid; gap: var(--space-5); padding: 0; list-style: none; }
.rf-themes__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-2); }
.rf-themes__head h3 { font-size: var(--text-base); }
.rf-themes__count { color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-themes .meter__stack { display: flex; height: 0.75rem; overflow: hidden; border-radius: var(--radius-pill); background: var(--colour-bg-subtle); }
.rf-themes .meter__seg { background: var(--rf-ink, var(--colour-text-muted)); }
.rf-themes .meter-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); margin-top: var(--space-2); padding: 0; list-style: none; color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-themes .meter-legend li { display: flex; gap: var(--space-2); align-items: center; }

/* --- What moved recently -------------------------------------------------- */
.rf-recent { display: grid; gap: var(--space-1); padding: 0; list-style: none; }

.rf-recent__item {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  border-left: 3px solid var(--rf-ink, var(--colour-border-strong));
  border-bottom: 1px solid var(--colour-border);
}

.rf-recent__date { color: var(--colour-text-muted); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.rf-recent__body { display: grid; gap: 2px; font-size: var(--text-sm); }
.rf-recent__what { color: var(--colour-text-muted); font-size: var(--text-xs); }

/* --- The pill filter bar, shared by all seven tabs -------------------------

   The pills themselves are `.house-tab` from core/components.css, reused
   unchanged so a reader meets ONE filter control across the site rather than
   two that drift. Only the layout around them lives here: a labelled group,
   groups flowing onto one line, wrapping rather than scrolling.

   `.house-tabs` ships `margin-bottom` and, under 480px, `flex: 1` on every
   pill so two chamber tabs split the width. Both are wrong inside a bar that
   carries four groups and up to ten pills in one of them, so both are undone
   here — and only here, leaving the two-tab pages exactly as they were. */
.rf-filterbar { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5);
  align-items: flex-start; margin: var(--space-4) 0 var(--space-3); }
.rf-filterbar__group { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-1) var(--space-2); min-width: 0; }
.rf-filterbar__label { color: var(--colour-text-muted); font-size: var(--text-xs);
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.rf-filterbar .house-tabs { margin: 0; }
/* `.house-tab` is `white-space: nowrap`, which is right for two chamber tabs
   and wrong here: "Democratic transition and constitutional reform 2002–2009"
   is wider than a 390px phone, and at that width the timeline's era row pushed
   the whole document 97px sideways (measured 2026-08-20). Wrapping inside the
   pill costs nothing on a wide screen — a pill only wraps when it must. */
.rf-filterbar .house-tab { white-space: normal; max-width: 100%; }
.rf-filterbar__hint { color: inherit; opacity: 0.7; font-weight: 400;
  font-variant-numeric: tabular-nums; }
.rf-filterbar__note { margin-top: var(--space-2); }
@media (max-width: 480px) {
  .rf-filterbar { gap: var(--space-3); }
  .rf-filterbar .house-tabs { width: auto; }
  .rf-filterbar .house-tab { flex: 0 1 auto; }
}
@media print { .rf-filterbar { display: none; } }

/* --- People --------------------------------------------------------------- */
.rf-filters { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-end; margin: var(--space-4) 0; }
/* The search half of the bar sits under the pills and stays compact — it is
   one field now that every categorical filter has become a pill. */
.rf-filters--search { align-items: flex-end; margin: 0 0 var(--space-4); }
.rf-filters--search .rf-filters__field { flex: 1 1 18rem; max-width: 32rem; }
.rf-filters__field { display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1); min-width: 0; max-width: 100%; }
.rf-filters__field .field { max-width: 100%; }
.rf-filters__field label { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.rf-filters__clear { align-self: center; font-size: var(--text-sm); }

/* The year range. Two narrow number fields rather than one wide text field:
   a year is four characters, and a 32rem box for four characters reads as an
   invitation to type a sentence. They sit above the search box, because on a
   chronology that starts in 1895 "which years?" is the question a reader
   arrives with and "which words?" is the one they refine with. */
.rf-filters--years { margin: 0 0 var(--space-3); }
.rf-filters--years .rf-filters__field { flex: 0 0 auto; }
.rf-filters--years .field { width: 7rem; }

/* The range the page actually applied, printed because a range given backwards
   is swapped rather than refused, and a silent swap is a lie by omission. */
.rf-years-applied {
  margin: var(--space-3) 0 0;
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  font-weight: 700;
}

.rf-people { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--space-4); padding: 0; list-style: none; }

.rf-people__card {
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
}

.rf-people__name { font-size: var(--text-base); font-weight: 700; line-height: 1.3; }
.rf-people__role { margin-top: 2px; color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-people__latest {
  display: grid;
  gap: var(--space-1);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--colour-border);
  font-size: var(--text-sm);
  line-height: 1.45;
}
.rf-people__latest-label {
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.rf-people__latest time { color: var(--colour-primary); font-size: var(--text-xs); font-weight: 700; }
.rf-people__count { margin-top: var(--space-2); font-size: var(--text-sm); }
.rf-people__link { margin-top: var(--space-2); font-size: var(--text-xs); }

.rf-person__head { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; justify-content: space-between; margin-bottom: var(--space-4); }
.rf-person__count { font-size: var(--text-lg); font-weight: 700; }
.rf-person__bio { max-width: var(--measure-lead); margin-bottom: var(--space-4); line-height: 1.7; }

.rf-timeline { display: grid; gap: var(--space-1); padding: 0; list-style: none; }

.rf-timeline__item {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--colour-border);
}

.rf-timeline__date { color: var(--colour-text-muted); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.rf-timeline__body { display: grid; gap: var(--space-2); justify-items: start; }
.rf-timeline__what { font-size: var(--text-sm); line-height: 1.5; }
.rf-timeline__src { color: var(--colour-text-muted); font-size: var(--text-xs); }

/* --- Target size for STANDALONE links (WCAG 2.2 AA, 2.5.8) -----------------
 *
 * Measured across the 13 section routes on 2026-08-24: 257 interactive targets
 * were under 24px tall. 174 of them are links sitting inside a sentence, and
 * 2.5.8's own Inline exception covers those — "the target is in a sentence, or
 * its size is otherwise constrained by the line-height of non-target text".
 * Padding those would fight the line box and buy no conformance.
 *
 * The other 83 are STANDALONE: the sole content of a cell, a card title, a
 * card action, a source line. Those are real failures, and this is the list of
 * them, by measured height — 15px (`.rf-people__link`, `.rf-timeline__src`),
 * 16px (table cells, `.rf-bills__record-link`, `<dd>`), 19px
 * (`.rf-people__name`, `.rf-card__title`), 22px (`.rf-recent__body`) and 23px
 * (`.rf-connection__node`).
 *
 * `padding-block` on an INLINE element grows the hit box without growing the
 * line box, so every one of these clears 24px with the page geometry untouched
 * — deliberately not `min-height`, which would reflow tables and cards. The
 * section already carries this rule for its tab strip; see the note at the top
 * of `.rf-subnav a` about `.tl-chip` failing the same criterion. */
.rf-people__name > a,
.rf-people__link > a,
.rf-timeline__src > a,
.rf-bills__record-link > a,
.rf-card__title > a,
.rf-recent__body > a,
.rf-connection__node > a,
.page-electoral-reforms .data-table th > a,
.page-electoral-reforms .data-table td > a,
.page-electoral-reforms dd > a:only-child {
  padding-block: var(--space-2);
}

/* --- Visually hidden, but read aloud -------------------------------------- */
.rf-vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Clickable Gantt bars and composition tiles --------------------------- */
a.rf-gantt__track { text-decoration: none; border-radius: var(--radius-sm); }
a.rf-gantt__track:hover { background: var(--colour-bg-subtle); }
a.rf-gantt__track:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }

.rf-gantt__lane.is-open { background: var(--colour-bg-subtle); }
.rf-gantt__lane.is-open .rf-gantt__label a { color: var(--colour-primary); }
.rf-gantt__late { display: block; margin-top: 2px; color: var(--colour-danger); font-weight: 700; }

a.rf-comp__cell { display: block; text-decoration: none; color: inherit; }
a.rf-comp__cell:hover { background: var(--colour-bg-subtle); }
a.rf-comp__cell:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.rf-comp__num { display: block; }
.rf-comp__lab { display: block; }

.rf-legend__key--diamond {
  width: 0.6rem; height: 0.6rem;
  border-radius: 0;
  background: var(--colour-text);
  rotate: 45deg;
}

@media (max-width: 760px) {
  .rf-recent__item { grid-template-columns: 1fr; gap: var(--space-2); }
  .rf-timeline__item { grid-template-columns: 1fr; gap: var(--space-2); }
  .rf-panel { position: static; }
}

/* The evidence table's Bill column carries "Senate Bill No. 29 of 2024", which
   wraps to four lines in a 25rem panel. Let it size to its content and give
   the stage column the slack instead. */
.rf-panel__table td:nth-child(3) a { white-space: nowrap; }
.rf-panel__table { table-layout: auto; }
.rf-panel__table th:nth-child(4), .rf-panel__table td:nth-child(4) { white-space: nowrap; }

/* --- Bills tab ------------------------------------------------------------
 * One card per curated Bill. The card carries the progress stepper from
 * `legislation/_bill_stepper.html` verbatim, so the geometry here is only the
 * frame around it — the steps themselves are that app's markup and CSS,
 * reused rather than reimplemented.
 *
 * The card stacks in source order at every width. A Bill's stage list is
 * vertical by nature, so there is nothing here that could grow a sideways
 * scrollbar (1.4.10 Reflow), and no breakpoint is needed. */
/* The stat strip that used to live here is gone — every tab now uses the one
 * tile component, `.rf-comp`. See the note there. */

.rf-bills { display: grid; gap: var(--space-4); margin: var(--space-4) 0 0; padding: 0; list-style: none; }

.rf-bills__card {
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
}

.rf-bills__ref {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--colour-text-muted);
}
.rf-bills__title { margin-top: 2px; font-size: var(--text-lg); font-weight: 700; line-height: 1.3; }
.rf-bills__meta { margin-top: var(--space-2); font-size: var(--text-sm); }

/* A cross-House row is a finding, not a footnote: the Bill is numbered by one
   House and captured from the other (AGENTS.md 3b). Marked with a rule as well
   as a tint, because colour alone never carries meaning here (1.4.1). */
.rf-bills__warn {
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--colour-warning);
  background: var(--colour-warning-bg);
  font-size: var(--text-xs);
  border-radius: var(--radius-sm);
}

.rf-bills__last { margin-top: var(--space-2); font-size: var(--text-sm); }
.rf-bills__src { color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-bills__commit { margin-top: var(--space-2); font-size: var(--text-sm); }
.rf-bills__dup { margin-top: var(--space-2); font-size: var(--text-xs); color: var(--colour-text-muted); }

/* A GROUP heading — "Open now", "Principal Acts" — one rung below a band
 * heading. Both selectors carry the same declarations on purpose: bare
 * `.rf-bills__h` is (0,1,0) and loses to `.rf-sec > h2` (0,1,1), so an
 * identical `<h2 class="rf-bills__h">` rendered at 18.4px when nested and
 * 30.72px when it happened to be a direct child of `.rf-sec` — measured on
 * /participate/ on 2026-08-24, where "How to submit" was 67% larger than the
 * three group headings above it. `.rf-sec > h2.rf-bills__h` is (0,2,1) and
 * settles it in both positions. Size is a ROLE, never a nesting accident. */
.rf-bills__h,
.rf-sec > h2.rf-bills__h {
  max-width: none;
  margin: var(--space-6) 0 var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--colour-border);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
}
.rf-bills__pending { margin-top: var(--space-3); padding-left: var(--space-5); display: grid; gap: var(--space-2); font-size: var(--text-sm); }

/* A bicameral Bill gets one lane per House. The heading only appears when
   there are two, because on a single-House Bill the reference line above the
   card ("Senate Bill No. 9 of 2024") already says which. */
.rf-bills__lane + .rf-bills__lane { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px dashed var(--colour-border); }
.rf-bills__house { font-size: var(--text-sm); font-weight: 700; letter-spacing: .02em; }
.rf-bills__intro { margin-top: var(--space-2); font-size: var(--text-xs); color: var(--colour-text-muted); }
.rf-bills__assent { margin-top: var(--space-2); font-size: var(--text-sm); display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); }

/* Laws tab. Two tables — principal Acts and subsidiary legislation — because
   they are different things with different dates, and one merged table would
   have to leave the assent column blank on more than half its rows. */
.rf-laws__blurb { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--colour-text-muted); }
.rf-laws__table th[scope="row"] { font-weight: 600; }

/* The principal statutes as questions a citizen is likely to ask.  Each card
   is still the exact Kenya Law link; the visual map changes the entry point,
   not the authority or the complete record beneath it. */
.rf-law-map {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0;
  padding: 0;
  list-style: none;
  counter-reset: law-question;
}
.rf-law-map li { min-width: 0; }
.rf-law-map a {
  display: grid;
  align-content: start;
  gap: var(--space-3);
  min-height: 17rem;
  padding: var(--space-5);
  border: 1px solid var(--colour-border);
  border-top: 5px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
  color: var(--colour-text);
  text-decoration: none !important;
}
.rf-law-map li:nth-child(3n + 2) a { border-top-color: var(--colour-secondary); }
.rf-law-map li:nth-child(3n) a { border-top-color: var(--colour-info); }
.rf-law-map a:hover,
.rf-law-map a:focus-visible { border-color: var(--colour-primary); box-shadow: var(--shadow-md); }
.rf-law-map__step {
  color: var(--colour-secondary);
  font-size: var(--text-xs);
  font-weight: 850;
  letter-spacing: .08em;
}
.rf-law-map strong { font-size: var(--text-xl); line-height: 1.2; text-wrap: balance; }
.rf-law-map__summary { color: var(--colour-text-light); font-size: var(--text-sm); line-height: 1.6; }
.rf-law-map__source {
  align-self: end;
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--colour-border);
  color: var(--colour-primary);
  font-size: var(--text-xs);
  font-weight: 750;
}

.rf-laws__records {
  overflow: clip;
  margin-top: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
}
.rf-laws__records > summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-3);
  align-items: center;
  min-height: 4.75rem;
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  list-style: none;
  font-weight: 800;
}
.rf-laws__records > summary::-webkit-details-marker { display: none; }
.rf-laws__records > summary small { color: var(--colour-text-muted); font-weight: 500; }
.rf-laws__records > summary::after { content: "+"; color: var(--colour-primary); font-size: var(--text-xl); }
.rf-laws__records[open] > summary { background: var(--colour-bg-subtle); }
.rf-laws__records[open] > summary::after { content: "−"; }
.rf-laws__records-body { padding: var(--space-5); border-top: 1px solid var(--colour-border); }

/* ── Participate: one card per invitation ────────────────────────────────────
   The state class is presentation only. Every window renders whatever its
   state — "closed" tones the card down, it never hides it, because a closed
   window is the record of what the public was asked about and when. */
/* The group's count, as a chip rather than a loose grey numeral trailing the
 * heading. `tabular-nums` keeps the chip the same width as counts change, so a
 * column of headings does not shuffle. A zero is still printed in full — it is
 * simply not shouted (AGENTS.md 0: contrast is presentation, hiding is a gate). */
.rf-bills__hn {
  display: inline-block;
  margin-left: var(--space-3);
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--colour-bg-subtle);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  vertical-align: middle;
}

/* An invitation card, DEADLINE FIRST.
 *
 * The date used to be one `<dd>` among eight in an auto-fit facts grid, which
 * made the single most time-critical fact on the page compete with "Channel".
 * It now has its own rail, and the card is a two-column grid: rail, then body.
 *
 * The rail prints an ABSOLUTE date and never a countdown. That is not a style
 * choice — `services/participation.py` states it ("The badge still prints an
 * absolute date; it never emits a relative countdown that could go stale in a
 * cached response") and `test_participation_page.py` asserts the rendered page
 * does not contain "Closes in 11 days". A server-rendered countdown is wrong
 * the moment the response is cached.
 *
 * `--rf-ink` carries the state colour to the rail, the left border and the
 * numerals from ONE declaration per state, using the section's existing status
 * palette. Colour is never the only signal: `.rf-win__state` prints the state
 * as text beside the title. */
.rf-win {
  --rf-ink: var(--colour-border-strong);
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  border: 1px solid var(--colour-border);
  border-left: 4px solid var(--rf-ink);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
}
.rf-win--closing_soon { --rf-ink: var(--colour-primary); }
.rf-win--open { --rf-ink: var(--colour-secondary); }
.rf-win--announced { --rf-ink: var(--colour-info); }
.rf-win--closed { --rf-ink: var(--colour-border); background: var(--colour-lighter); }
.rf-win--cancelled { --rf-ink: var(--colour-border); border-style: dashed; background: var(--colour-lighter); box-shadow: none; }
.rf-win--cancelled .rf-win__title { text-decoration: line-through; }

/* The rail. `tabular-nums` keeps a column of cards' dates in vertical
   alignment, which is what makes a list of deadlines scannable at all. */
.rf-win__when {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding-right: var(--space-4);
  border-right: 1px solid var(--colour-border);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.rf-win__when-day { color: var(--rf-ink); font-size: var(--text-3xl); font-weight: 800; line-height: .95; letter-spacing: -.04em; }
.rf-win__when-mon { color: var(--colour-text); font-size: var(--text-sm); font-weight: 800; text-transform: uppercase; letter-spacing: .08em; }
.rf-win__when-yr { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 700; }
.rf-win__when-lab { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.rf-win__when .rf-absent { font-size: var(--text-xs); line-height: 1.3; }
/* A closed or cancelled deadline is history, not a call to act. */
.rf-win--closed .rf-win__when-day,
.rf-win--cancelled .rf-win__when-day { color: var(--colour-text-muted); }

.rf-win__body { min-width: 0; }
.rf-win__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); }
.rf-win__title { flex: 1 1 20rem; min-width: 0; font-size: var(--text-lg); font-weight: 700; margin: 0; }
.rf-win__state { white-space: nowrap; }

/* The source's own wording for the deadline, verbatim, under the title — the
   rail gives the date its weight, this gives it its provenance and its time. */
.rf-win__deadline { margin: var(--space-2) 0 0; font-size: var(--text-sm); font-weight: 600; }
.rf-win__deadline span { color: var(--colour-text-muted); font-weight: 700; text-transform: uppercase; font-size: var(--text-xs); letter-spacing: .05em; }

.rf-win__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-3);
  margin: var(--space-4) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--colour-border);
}
.rf-win__facts dt { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--colour-text-muted); }
.rf-win__facts dd { margin: 0; font-size: var(--text-sm); font-weight: 600; overflow-wrap: anywhere; text-wrap: balance; }
/* Where to send it is the second thing a reader needs, and an email address is
   the longest value in the grid — so it gets the full width and its own tint
   rather than being squeezed into a 13rem track. */
.rf-win__fact--wide {
  grid-column: 1 / -1;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--colour-bg-subtle);
}
.rf-win__note { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--colour-text-muted); }

/* The scope's own exclusions, shown rather than asserted. Collapsed by default:
   a reader wants the instruments, and an auditor wants the rule. */
.rf-laws__scope { margin: var(--space-4) 0; padding: var(--space-3); border: 1px dashed var(--colour-border); border-radius: var(--radius-md); }
/* `padding-block`, not `display: flex` + `min-height`: a flex `summary` loses
   its `::marker`, and the disclosure triangle is the only affordance saying
   this opens. 8px top and bottom takes the 22px target past 24px (2.5.8). */
.rf-laws__scope > summary { padding-block: var(--space-2); cursor: pointer; font-size: var(--text-sm); font-weight: 600; }

/* ── Timeline: an era ribbon over a dated feed ───────────────────────────────
   The era band is drawn for every era, INCLUDING empty ones: a period of
   Kenya's history we hold nothing for is a gap to show, not to omit. The
   left rail is the spine; each entry hangs off its own date. */
.rf-era { margin: var(--space-6) 0 0; }
.rf-era__band {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--colour-lighter);
  border-left: 4px solid var(--colour-primary);
}
.rf-era__span { font-size: var(--text-sm); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--colour-primary); }
.rf-era__label { flex: 1 1 18rem; margin: 0; font-size: var(--text-lg); font-weight: 700; }
.rf-era__n { font-size: var(--text-xs); color: var(--colour-text-muted); white-space: nowrap; }
.rf-era__blurb { margin: var(--space-2) 0 var(--space-4); font-size: var(--text-sm); color: var(--colour-text-muted); }

.rf-yr { margin-bottom: var(--space-4); }
.rf-yr__label {
  margin: 0 0 var(--space-2);
  font-size: var(--text-base); font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.rf-feed { list-style: none; margin: 0; padding: 0 0 0 var(--space-4); border-left: 2px solid var(--colour-border); }
.rf-feed__item {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--colour-border);
}
.rf-feed__item:last-child { border-bottom: 0; }
.rf-feed__when { font-size: var(--text-xs); font-weight: 700; color: var(--colour-text-muted); font-variant-numeric: tabular-nums; padding-top: .15rem; }
.rf-feed__body { min-width: 0; }
.rf-feed__title { margin: 0; font-size: var(--text-sm); font-weight: 600; text-wrap: pretty; }
.rf-feed__kind { margin-left: var(--space-2); font-weight: 400; }
.rf-feed__detail { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--colour-text-muted); overflow-wrap: anywhere; }

/* The kind is carried by a badge, so the rail tint is a second, quieter cue
   rather than the only one — it must never be the sole carrier of meaning. */
.rf-feed__item--law { box-shadow: inset 3px 0 0 -1px var(--colour-primary); }
.rf-feed__item--bill { box-shadow: inset 3px 0 0 -1px var(--colour-secondary); }
.rf-feed__item--participation { box-shadow: inset 3px 0 0 -1px var(--colour-info); }

@media (max-width: 599px) {
  .rf-feed { padding-left: var(--space-3); }
  .rf-feed__item { grid-template-columns: 1fr; gap: var(--space-1); }
}
/* What kind of date this is — assented, recorded, published by the source. The
   lanes do not all measure the same thing and a bare date would be read as if
   they did. */
.rf-feed__basis { display: block; font-weight: 400; font-size: .68rem; line-height: 1.25; text-transform: uppercase; letter-spacing: .03em; }

/* ── Story-first composition ────────────────────────────────────────────────
   The warehouse remains complete; this layer changes the order in which a
   reader meets it. Strong summaries lead, native disclosures carry method and
   exhaustive sequences, and the same URLs still reach the underlying record. */
.page-electoral-reforms .page-band { min-height: 17rem; display: grid; align-items: center; }
.page-electoral-reforms .page-heading { max-width: 18ch; text-wrap: balance; }
/* No `max-width` on any paragraph in this section — see the READING MEASURES
   block at core.css:165. `--container-prose` and `--measure-lead` are both
   `none` by owner decision (2026-08-02): capped text left ~750px of white space
   at a 1728px container and the owner rejected that on four pages, choosing
   full width and the long lines that come with it. This story-first layer had
   re-added flat caps (54rem here, 54rem on the standfirst, 36rem/48rem/56rem/
   62rem/68ch on eight more), which put the section back in the state the
   decision removed. Re-adding one is a revert of an owner decision — ask first
   (owner re-confirmed 2026-08-24). Heading caps in `ch` stay: those are display
   typography for balanced titles, not reading measures for prose. */
.page-electoral-reforms .rf-hero-lead {
  color: color-mix(in srgb, currentColor 86%, transparent);
  font-size: clamp(var(--text-base), 1.4vw, var(--text-lg));
  line-height: 1.55;
  text-wrap: pretty;
}

.page-electoral-reforms .rf-hero-note {
  margin-top: var(--space-2);
  color: color-mix(in srgb, currentColor 72%, transparent);
  font-size: var(--text-sm);
  line-height: 1.45;
}

.rf-subnav {
  display: flex;
  gap: var(--space-4);
  align-items: stretch;
  margin: var(--space-4) 0 var(--space-5);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.rf-subnav__label {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}
/* Seven tabs and the help link on ONE row, and the tabs stay RIGHT-aligned —
 * owner preference, 2026-08-24.
 *
 * The wrap to two ragged rows on all 13 routes was never caused by the
 * alignment: `justify-content` does not decide whether a flex line breaks, only
 * where the items sit on it. It broke because the `ul` had 678px of a 1216px nav
 * to fit seven tabs in, the rest going to the label and an UNCAPPED help cell.
 * Tightening the per-tab inline padding (--space-3 -> --space-2) and capping the
 * help cell at 12rem is what buys the room; `flex-end` is untouched, so row one
 * no longer carries a 538px hole and the seventh tab no longer sits alone.
 * Below ~900px the block layouts further down take over. */
.rf-subnav ul { flex: 1 1 auto; justify-content: flex-end; gap: 0; }
.rf-subnav li { display: flex; }
.rf-subnav a {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  border-bottom: 3px solid transparent;
  padding-inline: var(--space-2);
  white-space: nowrap;
}
.rf-subnav a.is-active { background: var(--colour-bg-subtle); }
.rf-subnav__step { color: var(--colour-text-muted); font-size: .67rem; letter-spacing: .04em; }
/* Written as `a.rf-subnav__help`, not `.rf-subnav__help`, on purpose: the tab
   rule above is `.rf-subnav a` (0,1,1) and outranks a lone class (0,1,0), so
   the `white-space: normal` this cell has always declared never actually
   applied — the label sat on one nowrap line and only fitted because nothing
   capped its width. Measured 2026-08-24: 266px of text in a 192px box, clipped
   by the nav's own `overflow: hidden`. Wrapping is what lets the cell be
   narrow enough for all seven tabs to share the row. */
.rf-subnav a.rf-subnav__help {
  flex: 0 0 auto;
  max-width: 11rem;
  padding-inline: var(--space-3);
  border-bottom-color: transparent;
  border-left: 1px solid var(--colour-border);
  color: var(--colour-primary);
  font-size: var(--text-xs);
  font-weight: 750;
  line-height: 1.35;
  white-space: normal;
}

.rf-skip-filters {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.rf-skip-filters:focus {
  position: static;
  display: inline-flex;
  width: auto;
  height: auto;
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-3);
  overflow: visible;
  clip-path: none;
  border: 2px solid var(--colour-primary);
  border-radius: var(--radius-sm);
  background: var(--colour-bg);
  color: var(--colour-primary);
  font-weight: 750;
  white-space: normal;
}
#results:focus { outline: 3px solid var(--colour-primary); outline-offset: var(--space-2); }

.rf-sec { padding-block: var(--space-6); }
.rf-sec + .rf-sec { border-top: 0; }
/* ONE size per heading ROLE, never per nesting depth.
 *
 * Measured 2026-08-24 at 1280px before this rule existed: an `h2` opening a
 * band rendered at 30.72px in `.rf-story-intro__copy`, 28.8px in
 * `.rf-story-connections__head` (no rule matched, so the core.css base clamp
 * won), 18.4px in `.rf-explore__head` and 29.6px in `.rf-brief` — four sizes
 * for one role. Every wrapper that opens a band is listed here so adding a
 * band means adding it to this list, not inventing a fifth size. */
.rf-sec > h2,
.rf-story-intro__copy > h2,
.rf-overview-story__lead > h2,
.rf-story-connections__head > h2,
.rf-explore__head > h2,
.rf-brief > h2,
.rf-source-excerpt > h2,
.rf-full-record > h2 {
  max-width: 28ch;
  margin: 0 0 var(--space-3);
  font-size: clamp(var(--text-xl), 2.4vw, var(--text-3xl));
  line-height: 1.12;
  letter-spacing: -.025em;
  text-wrap: balance;
}
.rf-sec__standfirst { font-size: var(--text-base); line-height: 1.65; }
.rf-eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--colour-primary);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.rf-overview-story {
  display: grid;
  grid-template-columns: minmax(16rem, .7fr) minmax(0, 1.6fr);
  gap: var(--space-6);
  align-items: end;
}
.rf-overview-story__lead > p:last-child { color: var(--colour-text-light); line-height: 1.7; }
.rf-story-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
/* Two cards, not three — a pair of routes rather than a set of chapters. */
.rf-story-grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); margin-top: var(--space-4); }
/* `.rf-story-card` was built as a link. A non-link card (there is nowhere to send
   the reader — the addresses are on the invitations above) keeps the same shape
   but must not pretend to be clickable. */
.rf-story-card:not([href]) { cursor: default; }
.rf-story-card:not([href]):hover { transform: none; box-shadow: 0 1rem 2.5rem color-mix(in srgb, var(--colour-text) 8%, transparent); border-color: var(--colour-border); }
.rf-story-card:not([href]) .rf-story-card__action { color: var(--colour-text-muted); font-weight: 600; }
.rf-story-card {
  display: flex;
  min-height: 17rem;
  flex-direction: column;
  padding: var(--space-5);
  border: 1px solid var(--colour-border);
  border-top: 4px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  color: inherit;
  box-shadow: 0 1rem 2.5rem color-mix(in srgb, var(--colour-text) 8%, transparent);
  text-decoration: none;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.rf-story-card:nth-child(2) { border-top-color: var(--colour-secondary); }
.rf-story-card:nth-child(3) { border-top-color: var(--colour-info); }
.rf-story-card:hover,
.rf-story-card:focus-visible {
  border-color: var(--colour-border-strong);
  box-shadow: 0 1.25rem 3rem color-mix(in srgb, var(--colour-text) 13%, transparent);
  transform: translateY(-3px);
}
.rf-story-card__step { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.rf-story-card > strong { margin-top: var(--space-5); font-size: var(--text-xl); line-height: 1.15; text-wrap: balance; }
.rf-story-card > strong + span { margin-top: var(--space-3); color: var(--colour-text-light); font-size: var(--text-sm); line-height: 1.55; }
.rf-story-card__action { margin-top: auto; padding-top: var(--space-5); color: var(--colour-primary); font-size: var(--text-sm); font-weight: 700; }

.rf-method {
  margin: var(--space-4) 0;
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-method > summary,
.rf-era__archive > summary,
.rf-bills__journey > summary {
  min-height: 3rem;
  padding: var(--space-3) var(--space-4);
  color: var(--colour-text);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
}
.rf-method > p,
.rf-method__body {
  padding: 0 var(--space-4) var(--space-4);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  line-height: 1.7;
}
.rf-method__body > * + * { margin-top: var(--space-3); }
.rf-story-note {
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  border-left: 4px solid var(--colour-info);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--colour-info-bg);
  color: var(--colour-text-light);
  font-size: var(--text-sm);
  line-height: 1.6;
}

.rf-window {
  margin-top: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}
.rf-window__notes { display: block; margin-top: var(--space-5); }
.rf-window__note { margin: 0; }
.rf-window__note + .rf-window__note { margin-top: var(--space-3); }
.rf-comp__cell,
.rf-people__card,
.rf-win,
.rf-card { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.rf-comp__cell:hover,
.rf-people__card:hover,
.rf-win:hover,
.rf-card:hover { border-color: var(--colour-border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }

.rf-story-intro {
  display: grid;
  grid-template-columns: minmax(18rem, 1fr) minmax(24rem, 1.25fr);
  gap: var(--space-6);
  align-items: end;
}
/* Inside a paired intro band the tiles are the right-hand column, so they carry
 * no outer margin of their own and stay narrow enough to sit beside the copy. */
.rf-story-intro .rf-comp,
.rf-roadmap-intro .rf-comp { margin: 0; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); }

.rf-chapter-map {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-2);
  grid-column: 1 / -1;
  margin: var(--space-5) 0;
  padding: 0;
  list-style: none;
}
.rf-chapter-map a {
  display: flex;
  min-height: 10rem;
  flex-direction: column;
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-bottom: 4px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  color: inherit;
  text-decoration: none;
}
.rf-chapter-map a:hover { background: var(--colour-bg-subtle); border-color: var(--colour-primary); }
.rf-chapter-map strong { margin-top: var(--space-3); font-size: var(--text-sm); line-height: 1.3; text-wrap: balance; }
.rf-chapter-map strong + span { margin-top: auto; padding-top: var(--space-3); color: var(--colour-text-muted); font-size: var(--text-xs); }
.rf-chapter-map__span { color: var(--colour-primary); font-size: var(--text-xs); font-weight: 800; font-variant-numeric: tabular-nums; }

.rf-explore {
  margin: var(--space-6) 0 var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-explore__head h2 { margin: 0; }
.rf-explore .rf-filterbar { padding: 0; border: 0; background: transparent; }
.rf-filterbar {
  padding: var(--space-3);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}

.rf-era { scroll-margin-top: var(--space-5); }
.rf-era__band { padding-block: var(--space-4); background: var(--colour-bg-subtle); }
.rf-era__label { font-size: var(--text-xl); letter-spacing: -.015em; }
.rf-era__blurb { margin-bottom: var(--space-5); line-height: 1.65; }
.rf-era__archive {
  margin: var(--space-4) 0 var(--space-6);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-era__archive > summary { color: var(--colour-primary); }
.rf-era__archive-body { padding: var(--space-2) var(--space-4) var(--space-4); background: var(--colour-bg); border-radius: 0 0 var(--radius-md) var(--radius-md); }
.rf-feed__item { padding: var(--space-4); }
.rf-feed__item:hover { background: var(--colour-bg-subtle); }
.rf-feed__title { font-size: var(--text-base); }

.rf-bills { grid-template-columns: repeat(auto-fit, minmax(min(27rem, 100%), 1fr)); align-items: start; gap: var(--space-5); }
.rf-bills__card { overflow: clip; padding: 0; box-shadow: var(--shadow-sm); }
.rf-bills__card[open] { border-color: var(--colour-primary); box-shadow: var(--shadow-md); }
.rf-bills__summary {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-5);
  cursor: pointer;
  list-style: none;
}
.rf-bills__summary::-webkit-details-marker { display: none; }
.rf-bills__summary:hover { background: var(--colour-bg-subtle); }
.rf-bills__identity,
.rf-bills__ref,
.rf-bills__title { display: block; }
.rf-bills__purpose {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3);
  border-left: 4px solid var(--colour-secondary);
  border-radius: var(--radius-sm);
  background: var(--colour-bg-subtle);
}
.rf-bills__purpose > span { color: var(--colour-text-muted); font-size: .67rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.rf-bills__purpose strong { font-size: var(--text-sm); line-height: 1.4; }
.rf-bills__open { color: var(--colour-primary); font-size: var(--text-sm); font-weight: 800; }
.rf-bills__open::before { content: "+"; display: inline-block; width: 1.2rem; }
.rf-bills__card[open] .rf-bills__open::before { content: "−"; }
.rf-bills__open-open { display: none; }
.rf-bills__card[open] .rf-bills__open-closed { display: none; }
.rf-bills__card[open] .rf-bills__open-open { display: inline; }
.rf-bills__card-body { padding: var(--space-5); border-top: 1px solid var(--colour-border); }
.rf-bills__record-link { margin: 0 0 var(--space-3); font-size: var(--text-sm); font-weight: 800; }
.rf-bills__head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(10rem, .42fr); gap: var(--space-4); align-items: start; }
.rf-bills__position {
  display: flex;
  min-height: 8rem;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-3);
  border-left: 4px solid var(--colour-info);
  border-radius: var(--radius-sm);
  background: var(--colour-info-bg);
}
.rf-bills__position--assented { border-left-color: var(--colour-success); background: var(--colour-success-bg); }
.rf-bills__position--introduced { border-left-color: var(--colour-warning); background: var(--colour-warning-bg); }
.rf-bills__position-label { color: var(--colour-text-muted); font-size: .67rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.rf-bills__position strong { margin-top: var(--space-2); font-size: var(--text-base); line-height: 1.2; }
.rf-bills__position strong + span { margin-top: var(--space-1); color: var(--colour-text-light); font-size: var(--text-xs); }
.rf-bills__journey { margin-top: var(--space-4); border-top: 1px solid var(--colour-border); }
.rf-bills__journey > summary { padding-inline: 0; color: var(--colour-primary); }
.rf-bills__journey > summary span { margin-left: var(--space-2); color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 500; }
.rf-bills__journey-body { padding-top: var(--space-2); }
.rf-bill-brief {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border-left: 4px solid var(--colour-secondary);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-bill-brief h3 { margin: 0 0 var(--space-2); font-size: var(--text-lg); }
.rf-bill-brief .rf-brief__summary { margin-bottom: var(--space-2); font-size: var(--text-base); }
.rf-bill-brief details { margin-top: var(--space-3); border-top: 1px solid var(--colour-border); }
.rf-bill-brief details > summary { padding: var(--space-3) 0 0; color: var(--colour-primary); font-weight: 750; }
.rf-bill-brief ol { display: grid; gap: var(--space-2); margin-bottom: 0; padding-left: var(--space-5); }
.rf-bill-brief-pending { margin: var(--space-3) 0 0; color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-bill-funnel {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin: var(--space-5) 0 var(--space-3);
  padding: 0;
  list-style: none;
}
.rf-bill-funnel__step a {
  display: grid;
  gap: var(--space-2);
  min-height: 11rem;
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  color: var(--colour-text);
  text-decoration: none;
}
.rf-bill-funnel__step a:hover,
.rf-bill-funnel__step a:focus-visible { border-color: var(--colour-primary); box-shadow: var(--shadow-sm); }
.rf-bill-funnel__number { color: var(--colour-primary); font-size: var(--text-xs); font-weight: 850; }
.rf-bill-funnel__step strong { font-size: var(--text-lg); }
.rf-bill-funnel__step strong + span { color: var(--colour-text-muted); font-size: var(--text-sm); }
.rf-bill-funnel__bar { align-self: end; height: .6rem; margin-top: auto; overflow: hidden; border-radius: var(--radius-pill); background: var(--colour-bg-subtle); }
.rf-bill-funnel__bar > span { display: block; width: var(--share); height: 100%; background: var(--colour-warning); }
.rf-bill-funnel__step--advanced .rf-bill-funnel__bar > span { background: var(--colour-info); }
.rf-bill-funnel__step--assented .rf-bill-funnel__bar > span { background: var(--colour-success); }
.rf-bill-footprint { margin-bottom: var(--space-5); color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-learn-intro { padding-bottom: var(--space-4); }
.rf-learn-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-5);
}
.rf-learn-card {
  display: grid;
  align-content: start;
  gap: var(--space-2);
  min-height: 15rem;
  padding: var(--space-5);
  border: 1px solid var(--colour-border);
  border-top: 5px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
  color: var(--colour-text);
  text-decoration: none;
}
.rf-learn-card:hover { border-color: var(--colour-primary); box-shadow: var(--shadow-md); }
.rf-learn-card__number { color: var(--colour-secondary); font-size: var(--text-3xl); font-weight: 850; line-height: 1; }
.rf-learn-card__title { color: var(--colour-primary); font-size: var(--text-xl); font-weight: 800; line-height: 1.2; }
.rf-learn-card small { margin-top: auto; color: var(--colour-text-muted); }
.rf-vote-journey {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin: var(--space-5) 0;
  padding: 0;
  list-style: none;
}
.rf-vote-step { min-width: 0; }
.rf-vote-step__details {
  height: 100%;
  overflow: clip;
  border: 1px solid var(--colour-border);
  border-top: 5px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}
.rf-vote-step:nth-child(3n + 2) .rf-vote-step__details { border-top-color: var(--colour-secondary); }
.rf-vote-step:nth-child(3n) .rf-vote-step__details { border-top-color: var(--colour-info); }
.rf-vote-step__details[open] { border-color: var(--colour-primary); box-shadow: var(--shadow-md); }
.rf-vote-step__details > summary {
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--space-2);
  min-height: 11rem;
  padding: var(--space-5) 3.25rem var(--space-5) var(--space-5);
  cursor: pointer;
  list-style: none;
}
.rf-vote-step__details > summary::-webkit-details-marker { display: none; }
.rf-vote-step__details > summary::after {
  content: "+";
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  color: var(--colour-primary);
  font-size: var(--text-xl);
  font-weight: 800;
}
.rf-vote-step__details[open] > summary { min-height: auto; background: var(--colour-bg-subtle); }
.rf-vote-step__details[open] > summary::after { content: "−"; }
.rf-vote-step__number { color: var(--colour-secondary); font-size: var(--text-xs); font-weight: 850; letter-spacing: .08em; }
.rf-vote-step__details > summary strong { color: var(--colour-primary); font-size: var(--text-xl); line-height: 1.2; }
.rf-vote-step__details > summary strong + span { color: var(--colour-text-muted); font-size: var(--text-sm); }
.rf-vote-step__body { padding: var(--space-5); border-top: 1px solid var(--colour-border); }
.rf-vote-step__body > p { margin-top: 0; line-height: 1.65; }
.rf-vote-step__body dl { display: grid; gap: var(--space-3); margin: var(--space-4) 0 0; }
.rf-vote-step__body dl > div { padding-top: var(--space-3); border-top: 1px solid var(--colour-border); }
.rf-vote-step__body dt { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.rf-vote-step__body dd { margin: var(--space-1) 0 0; font-size: var(--text-sm); line-height: 1.55; }
.rf-source-note { color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-roadmap-intro { display: grid; grid-template-columns: minmax(18rem, 1fr) minmax(22rem, .9fr); gap: var(--space-6); align-items: end; }
.rf-board { grid-template-columns: 1fr; align-items: start; }
.rf-board__col { padding: var(--space-3); border-radius: var(--radius-md); background: var(--colour-bg-subtle); }
.rf-board__col > h3 { border: 0; padding: var(--space-2); }
.rf-board__col ol { grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); align-items: start; }
.rf-card { box-shadow: none; }

.rf-pending { border: 1px solid var(--colour-border); border-radius: var(--radius-md); background: var(--colour-bg-subtle); }
.rf-pending > summary {
  display: flex;
  min-height: 4.5rem;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  cursor: pointer;
}
.rf-pending > summary span { color: var(--colour-primary); font-size: var(--text-sm); font-weight: 700; }
.rf-pending__body { padding: 0 var(--space-4) var(--space-5); }
.rf-source-excerpt {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border-inline-start: .25rem solid var(--colour-secondary);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--colour-bg);
}
.rf-source-excerpt h2 { margin-top: var(--space-1); }
.rf-source-excerpt blockquote {
  margin: var(--space-3) 0;
  color: var(--colour-text);
  font-size: var(--text-lg);
  line-height: 1.65;
}
.rf-source-excerpt .rf-claim-source { margin-bottom: 0; }

.rf-connections__legend {
  color: var(--colour-text-muted);
}
.rf-story-connections {
  margin-top: var(--space-6);
  padding: clamp(var(--space-4), 3vw, var(--space-6));
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-lg);
  background: var(--colour-bg);
}
.rf-story-connections__head h2 { margin-top: var(--space-1); }
.rf-connections__list {
  display: grid;
  gap: var(--space-4);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}
.rf-connection {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(7rem, .45fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-connection__node {
  display: grid;
  gap: var(--space-1);
  min-height: 5.5rem;
  align-content: center;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--colour-bg);
}
.rf-connection__node.is-current { box-shadow: inset .25rem 0 0 var(--colour-primary); }
.rf-connection__node span {
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.rf-connection__node a,
.rf-connection__node strong { line-height: 1.35; }
.rf-connection__flow {
  position: relative;
  min-height: 2.5rem;
  border-top: .2rem solid var(--colour-primary);
  text-align: center;
}
.rf-connection--analysis .rf-connection__flow { border-top-style: dotted; }
.rf-connection__flow::after {
  position: absolute;
  inset-inline-end: -.1rem;
  top: -.48rem;
  width: .7rem;
  height: .7rem;
  border-top: .2rem solid var(--colour-primary);
  border-right: .2rem solid var(--colour-primary);
  content: "";
  transform: rotate(45deg);
}
.rf-connection__flow span {
  position: relative;
  top: -.85rem;
  padding: 0 var(--space-2);
  background: var(--colour-bg-subtle);
  font-size: var(--text-xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.rf-connection__basis,
.rf-connection__evidence { grid-column: 1 / -1; margin: 0; }
.rf-connection__basis { color: var(--colour-text-muted); }
.rf-connection__evidence { font-size: var(--text-sm); }

@media (max-width: 42rem) {
  .rf-connection { grid-template-columns: 1fr; }
  .rf-connection__flow {
    width: 2px;
    min-height: 3rem;
    margin-inline-start: var(--space-5);
    border-top: 0;
    border-left: .2rem solid var(--colour-primary);
    text-align: start;
  }
  .rf-connection--analysis .rf-connection__flow {
    border-left-style: dotted;
  }
  .rf-connection__flow::after {
    inset-inline-start: -.3rem;
    inset-inline-end: auto;
    top: auto;
    bottom: 0;
    transform: rotate(135deg);
  }
  .rf-connection__flow span {
    top: var(--space-2);
    left: var(--space-3);
    white-space: nowrap;
  }
  .rf-connection__basis,
  .rf-connection__evidence { grid-column: 1; }
}

.rf-brief-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
  max-width: 58rem;
  margin-inline: auto;
}
.rf-language {
  display: inline-flex;
  width: fit-content;
  gap: var(--space-1);
  padding: var(--space-1);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-language a {
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  color: var(--colour-text);
  font-weight: 700;
  text-decoration: none;
}
.rf-language a[aria-current="page"] { background: var(--colour-primary); color: var(--colour-bg); }
.rf-record-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-record-meta > div { padding: var(--space-4); }
.rf-record-meta > div + div { border-left: 1px solid var(--colour-border); }
.rf-record-meta dt { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.rf-record-meta dd { margin: var(--space-1) 0 0; font-weight: 700; }
.rf-translation-note {
  padding: var(--space-4);
  border-left: 4px solid var(--colour-warning);
  border-radius: var(--radius-sm);
  background: var(--colour-warning-bg);
}
.rf-translation-note strong { display: block; margin-bottom: var(--space-1); }
.rf-brief {
  padding: clamp(var(--space-5), 5vw, var(--space-7));
  border: 1px solid var(--colour-border);
  border-top: 5px solid var(--colour-primary);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-md);
}
.rf-brief h2 { margin-top: 0; text-wrap: balance; }
.rf-brief__summary { font-size: var(--text-xl); font-weight: 650; line-height: 1.45; text-wrap: pretty; }
.rf-brief__why,
.rf-brief__next { margin-top: var(--space-5); padding: var(--space-4); border-radius: var(--radius-md); background: var(--colour-bg-subtle); }
.rf-brief__why h3,
.rf-brief__next h3 { margin-top: 0; }
.rf-claim-source { color: var(--colour-text-muted); font-size: var(--text-sm); }
.rf-brief__points { margin-top: var(--space-5); border: 1px solid var(--colour-border); border-radius: var(--radius-md); }
.rf-brief__points > summary { color: var(--colour-primary); font-weight: 800; }
.rf-brief__points ol { display: grid; gap: var(--space-3); margin: 0; padding: 0 var(--space-5) var(--space-5) 3rem; }
.rf-brief__points li { padding-left: var(--space-2); }
.rf-brief__points li p { margin-bottom: var(--space-1); }
.rf-brief__review { margin: var(--space-5) 0 0; color: var(--colour-text-muted); font-size: var(--text-sm); }
.rf-brief--pending { border-top-color: var(--colour-border-strong); box-shadow: none; }
.rf-full-record { padding: var(--space-5); border-radius: var(--radius-md); background: var(--colour-bg-subtle); }
.rf-full-record h2 { margin-top: 0; }
.rf-full-record .btn + .btn { margin-left: var(--space-2); }
.rf-evidence-list { display: grid; gap: var(--space-3); margin: 0; padding-left: 1.4rem; }
.rf-evidence-list li { padding-left: var(--space-2); }
.rf-evidence-list a { display: block; font-weight: 750; }
.rf-evidence-list span { display: block; margin-top: var(--space-1); color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-faq-list {
  display: grid;
  gap: var(--space-3);
  max-width: 58rem;
  margin: var(--space-5) auto 0;
}
.rf-learn-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.rf-translation-pending {
  width: fit-content;
  margin: var(--space-2) 0;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--colour-warning-bg);
  color: var(--colour-text);
  font-size: var(--text-xs);
  font-weight: 800;
}
.rf-faq-card {
  overflow: clip;
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}
.rf-faq-card[open] { border-color: var(--colour-primary); box-shadow: var(--shadow-md); }
.rf-faq-card > summary {
  display: grid;
  gap: var(--space-2);
  min-height: 4.5rem;
  padding: var(--space-5);
  cursor: pointer;
  list-style: none;
}
.rf-faq-card > summary::-webkit-details-marker { display: none; }
.rf-faq-card > summary::after {
  content: "+";
  grid-area: 1 / 2 / span 2;
  align-self: center;
  color: var(--colour-secondary);
  font-size: var(--text-2xl);
  font-weight: 850;
}
.rf-faq-card[open] > summary::after { content: "−"; }
.rf-faq-card__question {
  grid-column: 1;
  color: var(--colour-primary);
  font-size: var(--text-xl);
  font-weight: 850;
  line-height: 1.25;
  text-wrap: balance;
}
.rf-faq-card__answer { grid-column: 1 / -1; font-size: var(--text-lg); line-height: 1.5; }
.rf-faq-card__action { grid-column: 1 / -1; color: var(--colour-text-muted); font-size: var(--text-sm); font-weight: 750; }
.rf-faq-card__body { padding: 0 var(--space-5) var(--space-5); border-top: 1px solid var(--colour-border); }
.rf-faq-card__body > .prose { padding-top: var(--space-4); }
.rf-faq-card__evidence { margin-top: var(--space-5); padding: var(--space-4); border-radius: var(--radius-sm); background: var(--colour-bg-subtle); }
.rf-faq-card__evidence h3 { margin: 0 0 var(--space-3); font-size: var(--text-base); }
.rf-faq-card__evidence dl { display: grid; gap: var(--space-3); margin: 0; }
.rf-faq-card__evidence dl > div { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: var(--space-3); }
.rf-faq-card__evidence dt { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 800; text-transform: uppercase; }
.rf-faq-card__evidence dd { margin: 0; }
.rf-faq-card__evidence dd span { display: block; color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-media-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-5);
}
.rf-media-card {
  overflow: clip;
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}
.rf-media-card__visual { display: grid; place-items: center; min-height: 15rem; background: var(--colour-primary); }
.rf-media-card__visual iframe,
.rf-media-card__visual img { display: block; width: 100%; border: 0; aspect-ratio: 16 / 9; object-fit: cover; }
.rf-media-card__visual audio { width: calc(100% - var(--space-6)); }
.rf-media-card__audio-mark,
.rf-media-card__article-mark { color: var(--colour-bg); font-size: var(--text-3xl); font-weight: 850; letter-spacing: -.03em; }
.rf-media-card__body { padding: var(--space-5); }
.rf-media-card__body h2 { margin-top: 0; color: var(--colour-primary); font-size: var(--text-xl); text-wrap: balance; }
.rf-media-context-note {
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  border-inline-start: .25rem solid var(--colour-accent);
  background: var(--colour-surface-alt);
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
}
.rf-media-card__access { color: var(--colour-success); font-size: var(--text-sm); font-weight: 800; }
.rf-media-card__transcript { margin-top: var(--space-4); border-top: 1px solid var(--colour-border); }
.rf-media-card__transcript > summary { padding: var(--space-4) 0; color: var(--colour-primary); font-weight: 800; }
.rf-media-card__transcript .prose { max-height: 22rem; overflow: auto; padding: 0 var(--space-2) var(--space-3); }

.rf-calendar-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(16rem, .55fr);
  gap: var(--space-6);
  align-items: end;
}
.rf-calendar-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: flex-end; }
.rf-calendar-scope {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin: var(--space-5) 0;
  padding: var(--space-2);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg-subtle);
}
.rf-calendar-scope > span { padding-inline: var(--space-2); color: var(--colour-text-muted); font-size: var(--text-sm); font-weight: 800; }
.rf-calendar-scope a {
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  color: var(--colour-text);
  font-weight: 750;
  text-decoration: none;
}
.rf-calendar-scope a[aria-current="page"] { background: var(--colour-primary); color: var(--colour-bg); }
.rf-calendar-month { margin-top: var(--space-7); }
.rf-calendar-month > h2 {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 3px solid var(--colour-primary);
}
.rf-calendar-month > h2 span { color: var(--colour-text-muted); font-size: var(--text-sm); }
.rf-calendar-list { display: grid; gap: var(--space-3); margin: 0; padding: 0; list-style: none; }
.rf-calendar-event {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  background: var(--colour-bg);
  box-shadow: var(--shadow-sm);
}
.rf-calendar-event--cancelled { border-style: dashed; box-shadow: none; }
.rf-calendar-event--cancelled h3 { text-decoration: line-through; }
.rf-calendar-date {
  display: grid;
  place-items: center;
  min-height: 9rem;
  padding: var(--space-3);
  background: var(--colour-primary);
  color: var(--colour-bg);
  text-align: center;
}
.rf-calendar-date time,
.rf-calendar-date__unknown { display: grid; gap: var(--space-1); }
.rf-calendar-date time > span,
.rf-calendar-date__unknown { font-size: var(--text-3xl); font-weight: 850; line-height: 1; }
.rf-calendar-date small { font-size: var(--text-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.rf-calendar-event__body { min-width: 0; padding: var(--space-4) var(--space-5); }
.rf-calendar-event__head { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: flex-start; }
.rf-calendar-event__head h3 { flex: 1 1 28rem; margin: 0; color: var(--colour-primary); font-size: var(--text-xl); }
.rf-calendar-deadline { margin: var(--space-2) 0 var(--space-3); font-weight: 800; }
.rf-calendar-facts { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6); margin: 0; }
.rf-calendar-facts div { max-width: 30rem; }
.rf-calendar-facts dt { color: var(--colour-text-muted); font-size: var(--text-xs); font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.rf-calendar-facts dd { margin: var(--space-1) 0 0; }
.rf-calendar-event__links { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-4); }
.rf-calendar-event__links a { font-weight: 750; }

@media (max-width: 1100px) {
  .rf-subnav { display: block; padding-top: var(--space-2); }
  .rf-subnav__label { padding-block: var(--space-2); }
  .rf-subnav ul { justify-content: flex-start; }
  .rf-subnav__help {
    min-height: 2.75rem;
    border-top: 1px solid var(--colour-border);
    border-left: 0;
    padding: var(--space-2) var(--space-3);
  }
  .rf-overview-story { grid-template-columns: 1fr; align-items: start; }
  .rf-story-intro { grid-template-columns: 1fr; align-items: start; }
  .rf-chapter-map { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rf-law-map { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 760px) {
  .page-electoral-reforms .page-band { min-height: 14rem; }
  .rf-subnav { overflow: visible; }
  .rf-subnav__label { padding-inline: var(--space-3); }
  .rf-subnav ul {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
  }
  .rf-subnav li { display: block; min-width: 0; }
  .rf-subnav a {
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-height: 3.5rem;
    padding: var(--space-2);
    text-align: center;
    white-space: normal;
  }
  .rf-subnav__help { flex-direction: row; min-height: 3rem; }
  .rf-sec { padding-block: var(--space-5); }
  .rf-story-grid,
  .rf-story-grid--pair { grid-template-columns: 1fr; }
  .rf-story-card { min-height: 13rem; }
  /* The deadline rail becomes a header strip above the title rather than a
     narrow column — a 7rem track beside body text is unreadable on a phone,
     and nothing here may grow a sideways scrollbar (1.4.10 Reflow). */
  .rf-win { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .rf-win__when {
    flex-direction: row;
    align-items: baseline;
    justify-content: flex-start;
    gap: var(--space-2);
    padding-right: 0;
    padding-bottom: var(--space-3);
    border-right: 0;
    border-bottom: 1px solid var(--colour-border);
    text-align: left;
  }
  .rf-win__when-day { font-size: var(--text-2xl); }
  .rf-law-map { grid-template-columns: 1fr; }
  .rf-bill-funnel { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-1); }
  .rf-law-map a,
  .rf-bill-funnel__step a { min-height: auto; }
  .rf-bill-funnel__step a { gap: var(--space-1); padding: var(--space-3); }
  .rf-bill-funnel__step strong { font-size: var(--text-sm); line-height: 1.25; }
  .rf-bill-funnel__step strong + span { font-size: var(--text-xs); }
  .rf-chapter-map { grid-template-columns: 1fr 1fr; }
  .rf-chapter-map a { min-height: 9rem; }
  .rf-window { padding: var(--space-4); }
  .rf-bills__head { grid-template-columns: minmax(0, 1fr) minmax(7.5rem, .42fr); gap: var(--space-2); }
  .rf-bills__summary { gap: var(--space-2); padding: var(--space-3); }
  .rf-bills__title { font-size: var(--text-base); }
  .rf-bills__position { padding: var(--space-2); }
  .rf-bills__position-label { display: none; }
  .rf-bills__position strong { margin-top: 0; font-size: var(--text-sm); }
  .rf-bills__purpose { padding: var(--space-2); }
  .rf-bills__purpose strong { font-size: var(--text-xs); }
  .rf-bills__card-body { padding: var(--space-4); }
  .rf-learn-grid { grid-template-columns: 1fr; }
  .rf-learn-card { min-height: auto; }
  .rf-media-grid { grid-template-columns: 1fr; }
  .rf-vote-journey { grid-template-columns: 1fr; }
  .rf-vote-step__details > summary { min-height: auto; }
  .rf-bills__position { min-height: auto; }
  .rf-laws__records > summary { grid-template-columns: 1fr auto; padding-inline: var(--space-4); }
  .rf-laws__records > summary small { grid-column: 1; }
  .rf-laws__records > summary::after { grid-column: 2; grid-row: 1 / span 2; }
  .rf-laws__records-body { padding: var(--space-4); }
  .rf-roadmap-intro { grid-template-columns: 1fr; }
  .rf-calendar-intro { grid-template-columns: 1fr; }
  .rf-calendar-actions { justify-content: flex-start; }
  .rf-board__col { padding: var(--space-2); }
  .rf-record-meta { grid-template-columns: 1fr; }
  .rf-record-meta > div + div { border-top: 1px solid var(--colour-border); border-left: 0; }
}

@media (max-width: 460px) {
  .rf-chapter-map { grid-template-columns: 1fr; }
  .rf-comp { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .rf-explore { padding: var(--space-3); }
  .rf-full-record .btn { width: 100%; }
  .rf-full-record .btn + .btn { margin-top: var(--space-2); margin-left: 0; }
  .rf-calendar-event { grid-template-columns: 4.5rem minmax(0, 1fr); }
  .rf-calendar-date { min-height: 7rem; padding: var(--space-2); }
  .rf-calendar-event__body { padding: var(--space-4); }
  .rf-calendar-actions .btn { width: 100%; }
  .rf-faq-card > summary,
  .rf-faq-card__body { padding-inline: var(--space-4); }
  .rf-faq-card__evidence dl > div { grid-template-columns: 1fr; gap: var(--space-1); }
}

@media (prefers-reduced-motion: reduce) {
  .rf-story-card,
  .rf-comp__cell,
  .rf-people__card,
  .rf-faq-card,
  .rf-media-card,
  .rf-win,
  .rf-card { transition: none; }
}

/* --- The century spine ----------------------------------------------------
 * The server-rendered picture that ships inside the `reform-spine` island.
 * It is a real chart, not a placeholder: one row per era, the bar its share of
 * the whole dated record. When the island mounts it is replaced by the ECharts
 * scatter; when JavaScript is off or the bundle fails, this is what the reader
 * gets, and it answers the same question (rule 1 in the header).
 */
.rf-spine-fig { margin-block: var(--space-4); }
.rf-spine__fallback { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.rf-spine__row {
  display: grid;
  grid-template-columns: minmax(10rem, 16rem) auto 1fr auto;
  align-items: center;
  gap: var(--space-2);
}
.rf-spine__era { font-weight: 600; }
.rf-spine__span { color: var(--colour-text-muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.rf-spine__track {
  display: block;
  height: 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--colour-bg-subtle);
}
.rf-spine__bar {
  display: block;
  height: 100%;
  width: var(--w, 0%);
  min-width: 2px;
  border-radius: inherit;
  background: var(--colour-primary);
}
.rf-spine__count { font-variant-numeric: tabular-nums; }
.rf-spine__gaps { color: var(--colour-text-muted); font-size: var(--text-sm); max-width: 62ch; }

/* Reflow (rule 2): on a phone each era becomes a stacked card rather than a
 * four-column grid squeezed sideways. */
@media (max-width: 40rem) {
  .rf-spine__row { grid-template-columns: 1fr auto; }
  .rf-spine__track { grid-column: 1 / -1; }
}

/* --- When the rulebook was written ---------------------------------------
 * Server-rendered twin of the `analytics-chart` bar island on the Laws page.
 * The two colours match the island's own first two palette slots
 * (--colour-secondary, then --colour-info) so the picture does not change
 * character when the island mounts. Colour is never the only signal: each row
 * prints "N Acts, M notices" beside the bar, and the mounted chart always
 * draws its legend because it has two series.
 */
.rf-lawyears { margin-block: var(--space-4); }
.rf-lawyears__fallback { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.rf-lawyears__row {
  display: grid;
  grid-template-columns: 4rem 1fr auto;
  align-items: center;
  gap: var(--space-2);
}
.rf-lawyears__year { font-weight: 600; font-variant-numeric: tabular-nums; }
.rf-lawyears__track {
  display: flex;
  gap: 2px;
  height: 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--colour-bg-subtle);
  overflow: hidden;
}
.rf-lawyears__bar { display: block; width: var(--w, 0%); height: 100%; }
.rf-lawyears__bar--act { background: var(--colour-secondary); }
.rf-lawyears__bar--notice { background: var(--colour-info); }
.rf-lawyears__count { color: var(--colour-text-muted); font-size: var(--text-sm); }

@media (max-width: 40rem) {
  .rf-lawyears__row { grid-template-columns: 4rem 1fr; }
  .rf-lawyears__count { grid-column: 1 / -1; }
}

/* --- The download control -------------------------------------------------
 * One per filtered tab, sitting with the "N of M shown" line because that is
 * the number it downloads. It is a plain link carrying ?format=csv plus every
 * active filter, so it works with JavaScript off and can be pasted into a
 * script or a browser tab like any other URL in this section.
 */
.rf-download {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin-block: var(--space-3);
}
.rf-download__link {
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-md);
  font-weight: 600;
  text-decoration: none;
  color: var(--colour-text);
  /* 44px min target (WCAG 2.2 2.5.8) without growing the line box. */
  min-height: 2.75rem;
  line-height: 1.6;
}
.rf-download__link:hover,
.rf-download__link:focus-visible {
  border-color: var(--colour-primary);
  color: var(--colour-primary);
}
.rf-download__note { color: var(--colour-text-muted); font-size: var(--text-sm); }
