/* 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;
}
/* The "x" that drops ONE narrowing, beside the name of the thing it drops. The
   line also keeps its "Show all" link, which clears every filter at once: with
   two filters on, "back to the whole ledger" and "back by one step" are
   different journeys and the reader should not have to click twice for either.
   2.75rem because this is a real target, not decoration (WCAG 2.5.8). */
.rf-filter__drop {
  position: relative;
  display: inline-block;
  /* Left only. Padding on the right pushed the sentence's full stop away from
     the × and left it floating mid-line. */
  padding-left: var(--space-1);
  color: var(--colour-text-muted);
  font-weight: 700;
  text-decoration: none;
}
/* The touch target is a centred 2.75rem box that takes NO layout space, rather
   than a 2.75rem-wide inline-flex box. Sized inline, the × opened a visible gap
   between the filter it drops and the punctuation after it, so it read as
   floating between two chips instead of belonging to the one on its left.
   The pseudo-element is part of the anchor, so it is genuinely clickable. */
.rf-filter__drop::before {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  width: 2.75rem;
  height: 2.75rem;
  transform: translate(-50%, -50%);
}
.rf-filter__drop:hover { color: var(--colour-danger); }
.rf-filter__drop:focus-visible { outline: 2px solid var(--colour-primary);
  outline-offset: 2px; }
/* Chips are separated by space, not a comma: the × already closes each one, and
   a comma after it read as punctuation belonging to the button. */
.rf-filter__chip + .rf-filter__chip { margin-left: var(--space-2); }

/* --- 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);
  /* Merged here from a second `.rf-filterbar` block that used to sit ~830 lines
     further down, next to `.rf-explore`. Two rules for one class that far apart
     is how a fix lands in the copy nobody reads; the `.rf-explore` override that
     strips this chrome now sits directly underneath, where it can be seen. */
  padding: var(--space-3); border: 1px solid var(--colour-border);
  border-radius: var(--radius-md); background: var(--colour-bg-subtle); }
/* The timeline's Explore panel already draws its own card, so the bar inside it
   must not draw a second one. Higher specificity, so order does not matter. */
.rf-explore .rf-filterbar { padding: 0; border: 0; background: transparent; }
.rf-filterbar__group { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-1) var(--space-2); min-width: 0; }
/* Was uppercase with extra letter-spacing. Three shouting labels stacked above
   each other is a large part of why a short bar read as a long one — the label
   is a quiet name for the field, not a heading competing with the pills. */
.rf-filterbar__label { color: var(--colour-text-muted); font-size: var(--text-xs);
  font-weight: 700; }
.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); }

/* A folded group (`filters.COLLAPSE_ABOVE`). The summary is the whole control
   when it is shut, so it is sized like one: 2.75rem is the target-size floor
   this file's WCAG 2.5.8 audit settled on, and `.house-tab` does not meet it. */
/* `display: block` UNDOES the `display: flex` this element inherits from
   `.rf-filterbar__group`, and it is not cosmetic. A `<details>` with a non-block
   display leaks its closed content on Safari 16 and older WebViews — the pills
   render with the fold shut. Chromium hides them either way, so the browser lane
   here (Chromium only) would never catch it. */
.rf-filterbar__fold { display: block; }
.rf-filterbar__summary { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-1) var(--space-2); min-height: 2.75rem;
  padding: var(--space-1) var(--space-3); border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-pill); cursor: pointer; list-style: none; }
.rf-filterbar__summary::-webkit-details-marker { display: none; }
/* The value the group is SET TO, which is the point of folding: the reader keeps
   the state and loses only the alternatives. Reads as the pill it stands in for
   — same size and weight as `.house-tab`, in the brand colour so a narrowed
   group is visibly different from one sitting at "All". */
.rf-filterbar__current { color: var(--colour-primary); font-size: var(--text-sm);
  font-weight: var(--fw-semibold); }
/* `::after` and not a `<span>`: the marker is decoration and must never be read
   out as part of the group's name. `\2212` is a real minus, not a hyphen. */
.rf-filterbar__summary::after { content: "+"; margin-left: auto;
  color: var(--colour-primary); font-weight: 700; }
.rf-filterbar__fold[open] > .rf-filterbar__summary::after { content: "\2212"; }
.rf-filterbar__fold[open] > .rf-filterbar__summary { margin-bottom: var(--space-2); }
.rf-filterbar__summary:hover { border-color: var(--colour-primary); }
.rf-filterbar__summary:focus-visible { outline: 2px solid var(--colour-primary);
  outline-offset: 2px; }
@media (max-width: 480px) {
  .rf-filterbar { gap: var(--space-3); }
  .rf-filterbar .house-tabs { width: auto; }
  .rf-filterbar .house-tab { flex: 0 1 auto; }
  /* A folded group is its own row on a phone; two summaries sharing a line put
     the value further from its label than from the next group's. */
  .rf-filterbar__fold { width: 100%; }
}
@media print { .rf-filterbar, .rf-filterbar__exact { display: none; } }

/* The roadmap's nine exact statuses, one fold below the four board columns the
   bar offers. Deliberately quieter than a filter group: this is the way out for
   a reader who needs Superseded separated from Enacted, not the row most people
   want, and offering both at equal weight is what made the old bar ten pills
   long. Same `.house-tab` pills inside, so the two rows agree about what a
   chosen filter looks like. */
.rf-filterbar__exact { margin: 0 0 var(--space-4); }
.rf-filterbar__exact > summary { min-height: 2.75rem; display: flex;
  align-items: center; color: var(--colour-text-muted); font-size: var(--text-sm);
  font-weight: 700; cursor: pointer; }
.rf-filterbar__exact > summary:focus-visible { outline: 2px solid var(--colour-primary);
  outline-offset: 2px; }
.rf-filterbar__exact .house-tabs { margin: var(--space-2) 0 0; }
.rf-filterbar__exact .house-tab { white-space: normal; max-width: 100%; }

/* --- 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,
.rf-step__link,
.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; }

/* ── Entries the source does not date ───────────────────────────────────────
   99 of the 135 loaded archive rows state no date, so the chronology above —
   which is keyed on a real date — cannot hold them. They get their own era
   band rather than a guessed year. The rows themselves reuse `.rf-feed`
   unchanged, because they ARE the same kind of record with one field missing,
   and giving them a different look would read as a lesser class of evidence.
   Only the date cell differs: it sits in the muted ink every "we do not hold
   this" statement in this section uses, so a reader can see at a glance that
   the gap is in the document and not in the row. */
.rf-era--undated { border-top: 2px solid var(--colour-border); padding-top: var(--space-5); }

/* A source that is a newspaper, not an official record. Owner direction
   2026-09-01 lets reputable Kenyan media source an archive entry; §3a's rule
   that the reader must never have to guess which is which applies here too, so
   the badge carries a WORD ("Press report") and never colour alone, and the
   excerpt block gets a rule the official one does not have. */
.rf-feed__press {
  margin-left: var(--space-2); font-weight: 600;
  color: var(--colour-warning); border: 1px solid var(--colour-warning);
  background: var(--colour-warning-bg);
}
.rf-source-excerpt--press { border-left: 3px solid var(--colour-warning); padding-left: var(--space-3); }
.rf-feed__nodate { display: block; font-style: italic; font-weight: 400; color: var(--colour-text-muted); }
.rf-yr__span { font-weight: 400; font-size: var(--text-sm); color: var(--colour-text-muted); }

/* ── 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. */
/* This section's band is sized by `.page-band` in components.css, like every
   other section's. The `min-height: 17rem` that used to be here held the band
   at 272px around 136px of content — 136px of empty red — which is the
   "very big empty section" the owner rejected on 2026-09-02. Do not put a
   height back on one section; change the shared padding instead. */
.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; }
/* The `.rf-filterbar` chrome and the `.rf-explore` override that strips it both
   moved up beside the rest of the filter bar (~line 702). They are one control
   and were 830 lines apart. */

.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; }
}

/* ── The reform roadmap: threads of consequence, plus a map to orient by ─────
 *
 * Replaces the six isolated A→B cards that `.rf-connection` above still draws
 * on a RECORD page (where a pair is the right shape, because the page is about
 * one of the two ends). On the chronology the same six rows are five connected
 * threads — one of them a real three-step chain — and every one of them now
 * reads forward in time. `services/story_threads.py` holds the ordering; this
 * file only draws it.
 *
 * Colour encodes the EVENT TYPE, and it is the second cue, never the only one:
 * every step prints `get_event_type_display` as text beside its colour, the
 * same rule already written above `.rf-feed__item--law`. Eight families, each
 * an ink dark enough to sit on white and a 96%-lightness tint for the card it
 * washes. Text never takes a family ink — dots, rails and arcs do — so nothing
 * here can move a contrast ratio.
 *
 * The two brand hues anchor the set (`law` is the site red, `civic_action` the
 * site green) so a colourful component still reads as this site. */
:root {
  --rf-type-constitutional_order: hsl(266 52% 44%);
  --rf-type-election: hsl(35 92% 34%);
  --rf-type-law: var(--colour-primary);
  --rf-type-court: hsl(212 74% 38%);
  --rf-type-inquiry: hsl(184 74% 28%);
  --rf-type-institution: hsl(232 48% 46%);
  --rf-type-civic_action: var(--colour-secondary);
  --rf-type-other: hsl(0 0% 42%);

  --rf-tint-constitutional_order: hsl(266 52% 96.5%);
  --rf-tint-election: hsl(35 92% 95.5%);
  --rf-tint-law: hsl(358 81% 96.5%);
  --rf-tint-court: hsl(212 74% 96.5%);
  --rf-tint-inquiry: hsl(184 74% 95.5%);
  --rf-tint-institution: hsl(232 48% 96.5%);
  --rf-tint-civic_action: hsl(144 45% 95.5%);
  --rf-tint-other: hsl(0 0% 96.5%);
}

/* One family, three jobs: the ink of a step, the start of a gradient, the end
   of one. They are separate class names because a single element (a connector,
   an SVG gradient) has to carry BOTH ends at once, which one `--rf-ink` cannot
   do. */
.rf-ink--constitutional_order { --rf-ink: var(--rf-type-constitutional_order); --rf-tint: var(--rf-tint-constitutional_order); }
.rf-ink--election { --rf-ink: var(--rf-type-election); --rf-tint: var(--rf-tint-election); }
.rf-ink--law { --rf-ink: var(--rf-type-law); --rf-tint: var(--rf-tint-law); }
.rf-ink--court { --rf-ink: var(--rf-type-court); --rf-tint: var(--rf-tint-court); }
.rf-ink--inquiry { --rf-ink: var(--rf-type-inquiry); --rf-tint: var(--rf-tint-inquiry); }
.rf-ink--institution { --rf-ink: var(--rf-type-institution); --rf-tint: var(--rf-tint-institution); }
.rf-ink--civic_action { --rf-ink: var(--rf-type-civic_action); --rf-tint: var(--rf-tint-civic_action); }
.rf-ink--other { --rf-ink: var(--rf-type-other); --rf-tint: var(--rf-tint-other); }

.rf-from--constitutional_order { --rf-from: var(--rf-type-constitutional_order); }
.rf-from--election { --rf-from: var(--rf-type-election); }
.rf-from--law { --rf-from: var(--rf-type-law); }
.rf-from--court { --rf-from: var(--rf-type-court); }
.rf-from--inquiry { --rf-from: var(--rf-type-inquiry); }
.rf-from--institution { --rf-from: var(--rf-type-institution); }
.rf-from--civic_action { --rf-from: var(--rf-type-civic_action); }
.rf-from--other { --rf-from: var(--rf-type-other); }

.rf-to--constitutional_order { --rf-to: var(--rf-type-constitutional_order); }
.rf-to--election { --rf-to: var(--rf-type-election); }
.rf-to--law { --rf-to: var(--rf-type-law); }
.rf-to--court { --rf-to: var(--rf-type-court); }
.rf-to--inquiry { --rf-to: var(--rf-type-inquiry); }
.rf-to--institution { --rf-to: var(--rf-type-institution); }
.rf-to--civic_action { --rf-to: var(--rf-type-civic_action); }
.rf-to--other { --rf-to: var(--rf-type-other); }

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

/* The orientation map. Decorative by design: the SVG is `aria-hidden` and holds
   nothing focusable, because everything it shows is written out in the threads
   below — the dots on its axis are ordinary links, so a keyboard reader takes
   the same route by the same jump. */
.rf-storymap__map { margin: 0; }
/* The end dots sit at x=0 and x=100, so without this inset half of each falls
   outside the figure and the last year label is clipped. The SVG and the dot
   list share the same inset, which is what keeps a dot on its own arc's foot. */
.rf-storymap__plot {
  --map-h: clamp(5.5rem, 11vw, 9rem);
  --map-inset: .85rem;
  position: relative;
  padding-inline: var(--map-inset);
  padding-bottom: var(--space-5);
}
/* The SVG and the dot list MUST share one height and one inset, or the dots
   stop sitting on the axis their arcs spring from. Both read the two custom
   properties above rather than repeating the values. */
.rf-storymap__arcs {
  display: block;
  width: 100%;
  height: var(--map-h);
  overflow: visible;
}
.rf-storymap__axis { stroke: var(--colour-border-strong); stroke-width: 1; }
.rf-storymap__arc {
  stroke-width: 3;
  stroke-linecap: round;
  opacity: .9;
}
.rf-storymap__arcs stop { stop-color: var(--rf-from, var(--rf-to, var(--colour-primary))); }

/* `--baseline` comes from `StoryMap.baseline_pct` — where the axis lands as a
   percentage of the drawn height. The SVG is stretched with
   `preserveAspectRatio="none"`, so y maps linearly whatever the container
   width, and these HTML dots then sit exactly on the line their arcs spring
   from. The fallback is the current geometry (21 of 24). */
.rf-storymap__dots {
  position: absolute;
  inset-inline: var(--map-inset);
  top: 0;
  height: var(--map-h);
  margin: 0;
  padding: 0;
  list-style: none;
}
.rf-storymap__dot {
  position: absolute;
  left: var(--x);
  top: var(--baseline, 87.5%);
  transform: translate(-50%, -50%);
}
/* 1.5rem of hit area around a .7rem dot — WCAG 2.2 AA 2.5.8, the same target
   size the block near `.rf-people__name` enforces for standalone links. */
.rf-storymap__dot > a {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
}
.rf-storymap__dot > a::before {
  width: .7rem;
  height: .7rem;
  border-radius: 50%;
  background: var(--rf-ink, var(--colour-primary));
  box-shadow: 0 0 0 .18rem var(--colour-bg);
  content: "";
  transition: transform .15s ease;
}
.rf-storymap__dot > a:hover::before,
.rf-storymap__dot > a:focus-visible::before { transform: scale(1.5); }
.rf-storymap__dot > a:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.rf-storymap__year {
  position: absolute;
  top: 1.45rem;
  left: 50%;
  color: var(--colour-text-muted);
  font-size: .66rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  transform: translateX(-50%);
}
.rf-storymap__map figcaption {
  max-width: 62ch;
  margin-top: var(--space-2);
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
}

.rf-threads { display: grid; gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.rf-thread {
  padding: var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-lg);
  background: var(--colour-bg);
}
.rf-thread:target { box-shadow: 0 0 0 2px var(--colour-primary); }
.rf-thread__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}
.rf-thread__num {
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--colour-text);
  color: var(--colour-bg);
  font-size: var(--text-xs);
  font-weight: 800;
}
.rf-thread__span { font-weight: 800; font-variant-numeric: tabular-nums; }
.rf-thread__count { color: var(--colour-text-muted); font-size: var(--text-sm); }

.rf-thread__run {
  display: flex;
  align-items: stretch;
  margin: 0;
  padding: 0;
  list-style: none;
}
.rf-step {
  display: grid;
  flex: 1 1 0;
  align-content: start;
  gap: .15rem;
  min-width: 0;
  padding: var(--space-3);
  border-top: .22rem solid var(--rf-ink, var(--colour-primary));
  border-radius: var(--radius-md);
  background: var(--rf-tint, var(--colour-bg-subtle));
}
.rf-step__dot { display: none; }
.rf-step__when {
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  text-transform: uppercase;
}
/* A judgment fragment used as a title runs to 120 characters. Clamp the drawn
   lines, never the accessible name: the full string stays in the link's `title`
   and in the disclosure below. */
.rf-step__title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  font-weight: 600;
  line-height: 1.3;
  text-wrap: pretty;
}
/* The card is the affordance — a coloured edge, a tinted ground, a hover lift
   — so the title does not also need a permanent underline; five of them
   stacked read as a wall of rules. It returns on hover and on focus, which is
   where WCAG 1.4.1 actually asks for it. */
/* Classed on purpose: `core.css`'s `.site-content a:not([class])` gives every
   BARE link a permanent underline, and its specificity beats any `.parent > a`
   rule. Carrying a class is how that stylesheet says a UI link opts out. */
.rf-step__link { color: var(--colour-text); text-decoration: none; }
.rf-step__link:hover,
.rf-step__link:focus-visible {
  color: var(--colour-link-hover);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: .16em;
}
.rf-step:hover { box-shadow: 0 1px 10px hsl(0 0% 0% / .09); }
.rf-step__type {
  color: var(--colour-text-muted);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}

.rf-link {
  display: grid;
  flex: 0 1 9rem;
  align-content: center;
  justify-items: center;
  gap: .3rem;
  padding: 0 var(--space-2);
  text-align: center;
}
.rf-link__rail {
  position: relative;
  width: 100%;
  height: .3rem;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--rf-from, var(--colour-primary)), var(--rf-to, var(--colour-primary)));
}
/* Analysis is dashed, exactly as the standfirst promises; an official link is
   solid. The dash is a mask rather than a border so the gradient survives it. */
.rf-link--analysis .rf-link__rail {
  -webkit-mask-image: repeating-linear-gradient(90deg, black 0 .45rem, transparent .45rem .8rem);
  mask-image: repeating-linear-gradient(90deg, black 0 .45rem, transparent .45rem .8rem);
}
.rf-link__rail::after {
  position: absolute;
  inset-inline-end: -.1rem;
  top: 50%;
  border-top: .32rem solid transparent;
  border-bottom: .32rem solid transparent;
  border-left: .42rem solid var(--rf-to, var(--colour-primary));
  content: "";
  transform: translateY(-50%);
}
.rf-link__label {
  color: var(--colour-text);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: .03em;
  line-height: 1.25;
  text-transform: uppercase;
  text-wrap: balance;
}
.rf-link__kind { color: var(--colour-text-muted); font-size: .66rem; }

.rf-thread__why { margin-top: var(--space-3); }
.rf-thread__why > summary {
  color: var(--colour-text-muted);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: 700;
  padding-block: var(--space-1);
}
.rf-thread__basis { display: grid; gap: var(--space-3); margin: var(--space-3) 0 0; padding: 0 0 0 var(--space-4); }
.rf-thread__quote { margin: 0; color: var(--colour-text-muted); }
.rf-thread__cite { margin: var(--space-1) 0 0; font-size: var(--text-sm); }
.rf-thread__raw {
  margin: var(--space-3) 0 0;
  color: var(--colour-text-muted);
  font-size: var(--text-sm);
}

@media (max-width: 48rem) {
  /* Eleven points on a 360px axis leave 14px between the closest pair, which
     no year label survives. The dot keeps the year in its accessible name. */
  .rf-storymap__year { display: none; }
  .rf-thread__run { flex-direction: column; }
  .rf-link {
    flex: 0 0 auto;
    grid-template-columns: auto minmax(0, 1fr);
    justify-items: start;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-2) 0 var(--space-2) var(--space-4);
    text-align: start;
  }
  .rf-link__rail {
    grid-row: 1 / span 2;
    width: .3rem;
    min-height: 2.5rem;
    height: 100%;
    background: linear-gradient(180deg, var(--rf-from, var(--colour-primary)), var(--rf-to, var(--colour-primary)));
  }
  .rf-link--analysis .rf-link__rail {
    -webkit-mask-image: repeating-linear-gradient(180deg, black 0 .45rem, transparent .45rem .8rem);
    mask-image: repeating-linear-gradient(180deg, black 0 .45rem, transparent .45rem .8rem);
  }
  .rf-link__rail::after {
    inset-inline-end: auto;
    inset-inline-start: 50%;
    top: auto;
    bottom: -.1rem;
    border-top: .42rem solid var(--rf-to, var(--colour-primary));
    border-right: .32rem solid transparent;
    border-bottom: 0;
    border-left: .32rem solid transparent;
    transform: translateX(-50%);
  }
  .rf-link__label { align-self: end; }
  .rf-link__kind { align-self: start; }
}

@media (prefers-reduced-motion: reduce) {
  .rf-storymap__dot > a::before { transition: none; }
}

.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); }
/* Published for the client to look at before an editor has checked the wording.
   It sits ABOVE the summary and uses the warning wash, not the muted grey of
   `.rf-brief__review` — a reader must meet it before the text, not after. It is
   deliberately not `display:none` at any width; see `.rf-notice` at line 489,
   which the phone layout does hide, and which this must never be folded into. */
/* The same caveat as `.rf-brief__draftnotice`, sized for a feed row: this text
   is one line among many and also one cell of the CSV export, so the label has
   to travel WITH it (see `Entry.csv_detail`) rather than sit elsewhere on the
   page where a download would strip it. */
.rf-feed__draft {
  display: inline-block;
  margin-right: var(--space-1);
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--colour-warning-bg);
  color: var(--colour-text);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.rf-brief__draftnotice {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--colour-warning);
  border-radius: var(--radius-sm);
  background: var(--colour-warning-bg);
  color: var(--colour-text);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.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) {
  .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__years { list-style: none; margin: var(--space-3) 0 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); }

/* --- Figures that are now links -------------------------------------------
 *
 * Every count in this section opens what it is made of: a plain `href` to the
 * filtered tab, plus `data-drawer-url` for the shared side panel. That turned
 * a set of numbers, bars and chart labels into anchors, and an unclassed
 * anchor inside `.site-content` arrives underlined and link-coloured — which
 * on a chart reads as damage, not as an affordance.
 *
 * **Each selector is prefixed with `.site-content` for SPECIFICITY, not for
 * scope.** `core.css` styles content links with `.site-content a:not([class])`,
 * which is (0,2,1); `.rf-themes__head h3 a` is only (0,1,2) and LOSES, despite
 * looking more specific. Measured in the browser: the theme headings computed
 * `text-decoration: underline` with the unprefixed rule in place. Adding the
 * ancestor class ties the count and this file loads later, so it wins.
 *
 * Prose links are deliberately NOT in this list — the "10 commitments tracked"
 * sentence should keep looking like a sentence with links in it.
 *
 * Focus is never removed, only restyled: a keyboard reader has no hover.
 */
.site-content .rf-spine__count,
.site-content .rf-themes__count,
.site-content .rf-themes__head h3 a,
.site-content .rf-lawyears__count,
.site-content .rf-people__count a,
.site-content .rf-board__col > h3 .rf-count,
.site-content .rf-window__lab,
.site-content .rf-gantt__theme a,
.site-content .meter-legend a,
.site-content .data-table td a[data-drawer-url] {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.site-content .rf-spine__count:hover,
.site-content .rf-themes__count:hover,
.site-content .rf-themes__head h3 a:hover,
.site-content .rf-lawyears__count:hover,
.site-content .rf-people__count a:hover,
.site-content .rf-board__col > h3 .rf-count:hover,
.site-content .rf-window__lab:hover,
.site-content .rf-gantt__theme a:hover,
.site-content .meter-legend a:hover,
.site-content .data-table td a[data-drawer-url]:hover {
  color: var(--colour-primary);
  text-decoration: underline;
}

.site-content .rf-spine__count:focus-visible,
.site-content .rf-themes__count:focus-visible,
.site-content .rf-themes__head h3 a:focus-visible,
.site-content .rf-lawyears__count:focus-visible,
.site-content .rf-people__count a:focus-visible,
.site-content .rf-board__col > h3 .rf-count:focus-visible,
.site-content .rf-gantt__theme a:focus-visible,
.site-content .meter-legend a:focus-visible,
.site-content .data-table td a[data-drawer-url]:focus-visible {
  outline: 2px solid var(--colour-primary);
  outline-offset: 2px;
}

/* The theme meter's bands. They sit inside a `role="img"` and are out of the
 * tab order, so the LEGEND beneath is the keyboard route to the same rows —
 * every band has one. Here the band only has to stop looking like a link and
 * start looking like something a pointer can press. */
.site-content .rf-themes .meter__stack a.meter__seg { text-decoration: none; cursor: pointer; }
.site-content .rf-themes .meter__stack a.meter__seg:hover { filter: brightness(1.15); }

/* A milestone label on the cycle strip keeps its two-line shape as a link. */
.site-content .rf-window__lab:hover b { color: var(--colour-primary); }

/* ---- Follow control (TOR §5.3 "subscribe from the section") --------------
 * Deliberately quiet. It sits under a commitment, a window or a Bill and must
 * not compete with the record itself — the reader came for the fact, not the
 * mailing list. Uses only existing tokens: the design lint has zero headroom
 * and refuses a raw hex in this file. */
.site-content .rf-follow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--colour-border);
}
.site-content .rf-follow__terms {
  color: var(--colour-text-muted);
  font-size: var(--text-xs);
}
