/* ==========================================================================
   Mzalendo shared component layer.
   One source of truth for cards, buttons, fields, tabs, badges, stats, tables,
   empty-states and timelines — so every page (members, legislation, sentiment,
   chat, home) looks consistent. All values come from core.css tokens.
   ========================================================================== */

/* ---- Section rhythm ---- */
.section { margin: var(--space-6) 0; }
.section--tight { margin: var(--space-5) 0; }
/* `.section` is the intended rhythm primitive but only ~17 of ~180 content
   templates ever adopted it; the rest name a section and rely on the component
   inside it to bring its own margin, which fails for the section box itself.
   Combined with `* { margin: 0 }` that produced 56 adjacent blocks under 16px
   apart across 25 pages (2026-08-02).

   Rather than editing ~100 templates, give any <section> that follows another
   the same gap. Scoped to DIRECT children of a container on purpose: a bare
   `section + section` would also hit sections nested inside cards, panels and
   tab bodies, where the spacing is deliberate. This is why `.house-header` and
   `.na-position-holders` on /mps-performance/national-assembly/ — neither of
   which has any CSS rule of its own — now separate correctly.

   `:where()` is load-bearing, not decoration. Unwrapped, this selector is
   (0,1,2) and OUTRANKS every component that declares its own margin at (0,1,0)
   — it would have silently forced `.section--tight` from 24px to 32px (two
   adjacent ones exist in tazabu/certified_hansard_index.html) and overridden
   `.ab-band`'s 2.8rem. `:where()` drops it to (0,0,0), so it still beats the
   `* { margin: 0 }` reset — components.css loads after core.css — while losing
   to anything that states a real intent. A fallback, not an override. */
:where(.container > section + section) { margin-top: var(--space-6); }
/* Named like a section, styled like nothing: these appear in templates but
   match no rule anywhere, so they contributed 0px. `.detail-section` alone is
   used in 10 templates and is a <div>, so the section fallback above cannot
   reach it. Bottom-only, matching `.committee-group` / `.region-section` /
   `.data-table` — a symmetric margin would ADD to `.site-content`'s row-gap
   rather than collapse, because flex items do not collapse margins. */
.detail-section,
.house-header,
.na-position-holders,
.senate-position-holders,
.senators-section,
/* `.metric-band` (entity/_metric_comparison.html) needs this even though it IS
   a <section>: the fallback above is `:where()`, so `.region-section`'s
   bottom-only `margin: 0 0 …` legitimately wins on the county pages and leaves
   the pair with 3px of ink. The band owning its trailing margin is the fix. */
.metric-band { margin-bottom: var(--space-6); }
.section__title,
.section-heading,
h2.header-two,
.leadership-heading,
.parliament-section--heading,
.our-work--section-heading { font-size: var(--text-xl); font-weight: var(--fw-bold); color: var(--colour-text); margin: 0 0 var(--space-4); }
.section__title--accent { border-left: 4px solid var(--colour-primary); padding-left: var(--space-3); }
.section__lead { color: var(--colour-text-muted); margin: 0 0 var(--space-5); }

/* ---- Buttons ---- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5); border: 1px solid transparent; border-radius: var(--radius-pill);
  font: inherit; font-weight: var(--fw-semibold); line-height: 1; cursor: pointer; text-decoration: none;
  transition: background-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard),
    border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard),
    transform var(--motion-fast) var(--ease-standard); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.btn[disabled], .btn.is-disabled { opacity: .55; pointer-events: none; box-shadow: none; }
.btn--primary { background: var(--colour-primary); color: #fff; }
.btn--primary:hover { background: var(--colour-primary-dark); box-shadow: var(--shadow-md); }
.btn--secondary { background: var(--colour-secondary); color: #fff; }
.btn--secondary:hover { background: var(--colour-secondary-dark); box-shadow: var(--shadow-md); }
.btn--ghost { background: transparent; color: var(--colour-primary); border-color: var(--colour-border-strong); }
.btn--ghost:hover { border-color: var(--colour-primary); color: var(--colour-primary); background: var(--colour-primary-alpha-10); }
.btn--sm { padding: var(--space-2) var(--space-4); font-size: var(--text-sm); }
.btn--lg { padding: var(--space-4) var(--space-6); font-size: var(--text-lg); }

/* ---- Form fields ---- */
.field { font: inherit; padding: var(--space-3) var(--space-4); border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-pill); background: #fff; color: var(--colour-text); }
.field:focus { outline: none; border-color: var(--colour-primary); box-shadow: 0 0 0 3px var(--colour-primary-alpha-20); }
.field--block { width: 100%; }
.field-label { display: block; font-size: var(--text-sm); font-weight: 600; color: var(--colour-text-muted); margin-bottom: var(--space-1); }
.filter-bar,
.filter-form { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: end; margin: 0 0 var(--space-5); }
.filter-bar .grow,
.filter-form .grow { flex: 1 1 18rem; }
/* Self-sufficient children: bare label/input/select/button inside a filter bar
   get the canonical field/button treatment, so consumers need no per-element
   classes. .filter-form is the same component under its legacy tazabu name. */
.filter-bar > div,
.filter-form > div { display: flex; flex-direction: column; }
.filter-bar label,
.filter-form label { display: block; font-size: var(--text-xs); font-weight: var(--fw-semibold); text-transform: uppercase; letter-spacing: .03em; color: var(--colour-text-muted); margin-bottom: var(--space-1); }
.filter-bar input, .filter-bar select,
.filter-form input, .filter-form select { padding: var(--space-2) var(--space-3); border: 1px solid var(--colour-border-strong); border-radius: var(--radius-md); font: inherit; background: var(--colour-bg); color: var(--colour-text); min-height: 2.5rem; transition: border-color var(--motion-fast, .15s) var(--ease-standard), box-shadow var(--motion-fast, .15s) var(--ease-standard); }
.filter-bar input:focus, .filter-bar select:focus,
.filter-form input:focus, .filter-form select:focus { outline: none; border-color: var(--colour-primary); box-shadow: 0 0 0 3px var(--colour-primary-alpha-20); }
.filter-bar button[type="submit"],
.filter-form button[type="submit"] { padding: var(--space-2) var(--space-5); min-height: 2.5rem; border: 1px solid transparent; border-radius: var(--radius-pill); background: var(--colour-primary); color: #fff; font: inherit; font-weight: var(--fw-semibold); line-height: 1; cursor: pointer; transition: background-color var(--motion-fast, .15s) var(--ease-standard), box-shadow var(--motion-fast, .15s) var(--ease-standard); }
.filter-bar button[type="submit"]:hover,
.filter-form button[type="submit"]:hover { background: var(--colour-primary-dark); box-shadow: var(--shadow-md); }
.filter-bar button[type="submit"]:focus-visible,
.filter-form button[type="submit"]:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }

/* ---- Cards ---- */
.card { background: var(--colour-bg); border: 1px solid var(--colour-border); border-radius: var(--radius-lg);
  overflow: hidden; transition: box-shadow .15s ease, transform .15s ease; }
.card--link { display: block; text-decoration: none; color: inherit; }
.card--link:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.card--link:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; box-shadow: var(--shadow-md); }
.card--pad { padding: var(--space-4) var(--space-5); }
.card__title { font-size: var(--text-lg); font-weight: var(--fw-bold); line-height: var(--leading-snug); color: var(--colour-text); margin: 0 0 var(--space-2); letter-spacing: -0.008em; }
.card__meta { font-size: var(--text-sm); color: var(--colour-text-muted); display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); }
.card__meta a { color: var(--colour-primary); text-decoration: none; }

/* Data/chart card grid — capped at 3 columns (charts read poorly at 4+), responsive. */
.card-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
@media (min-width: 560px) { .card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 920px) { .card-grid { grid-template-columns: repeat(3, 1fr); } }
.card-grid--wide { --card-min: 260px; }

/* Portrait/member card */
.member-card { display: block; text-decoration: none; color: inherit; background: #fff;
  border: 1px solid var(--colour-border); border-radius: var(--radius-lg); overflow: hidden;
  transition: box-shadow .15s ease, transform .15s ease; }
.member-card:hover,
.member-card:focus-visible { box-shadow: var(--shadow-md); transform: translateY(-2px); outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.member-card:focus-visible .member-card__name { color: var(--colour-primary); }
.member-card:hover .member-card__name { color: var(--colour-primary); }
.member-card__img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; background: var(--colour-bg-subtle); display: block; }
.member-card__body { padding: var(--space-3) var(--space-4); }
.member-card__name { font-weight: 700; line-height: 1.25; }
.member-card__sub { font-size: var(--text-sm); color: var(--colour-text-muted); margin-top: var(--space-1); }

/* ---- Badges ---- */
.badge { display: inline-block; padding: 1px 9px; border-radius: var(--radius-pill);
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .02em;
  background: var(--colour-primary-alpha-10); color: var(--colour-primary); }
.badge--green { background: var(--colour-secondary-alpha-10); color: var(--colour-secondary-dark); }
.badge--muted { background: var(--colour-lighter); color: var(--colour-text-muted); }
.badge--solid { background: var(--colour-primary); color: #fff; }

/* ---- Tabs / sub-nav ---- */
.tabs { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  border-bottom: 2px solid var(--colour-border); margin: 0 0 var(--space-5); }
.tabs a { display: inline-block; padding: var(--space-3) var(--space-1); color: var(--colour-text);
  text-decoration: none; font-weight: 600; border-bottom: 3px solid transparent; }
.tabs a:hover { color: var(--colour-primary); }
.tabs a.is-active { color: var(--colour-primary); border-bottom-color: var(--colour-primary); }
.tabs a:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; border-radius: var(--radius-sm); }
.tabs a .count { opacity: .6; font-weight: 400; margin-left: var(--space-1); }

/* Pill-style filter row (alt to underline tabs) */
.pills { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-5); }
.pills a { padding: var(--space-2) var(--space-4); border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-pill); text-decoration: none; color: var(--colour-text); font-size: var(--text-sm); font-weight: 600;
  transition: background-color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard); }
.pills a:hover { border-color: var(--colour-primary); color: var(--colour-primary); }
.pills a:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.pills a.is-active { background: var(--colour-primary); color: #fff; border-color: var(--colour-primary); }
.pills a.is-active:hover { color: #fff; }
.pills a .count, .pills a .n { opacity: .6; font-weight: var(--fw-regular); margin-left: var(--space-1); }

/* ---- Meter (proportional magnitude bar) ---- */
.meter { height: 6px; background: var(--colour-lighter); border-radius: var(--radius-pill); overflow: hidden; margin-top: var(--space-2); }
.meter__fill { display: block; height: 100%; background: var(--colour-primary); border-radius: var(--radius-pill); }
.meter--green .meter__fill { background: var(--colour-secondary); }
.meter__stack { display: flex; height: 100%; border-radius: var(--radius-pill); overflow: hidden; }
.meter__seg { display: block; height: 100%; }
.meter__seg--mp { background: var(--colour-primary); }
.meter__seg--sen { background: var(--colour-secondary); }
.meter-legend { display: flex; gap: var(--space-4); font-size: var(--text-sm); color: var(--colour-text-muted); margin: 0 0 var(--space-4); }
.meter-legend i { display: inline-block; width: 11px; height: 11px; border-radius: 2px; margin-right: var(--space-1); vertical-align: middle; }
.meter-legend .mp { background: var(--colour-primary); }
.meter-legend .sen { background: var(--colour-secondary); }

/* ---- Small utilities ---- */
.text-muted { color: var(--colour-text-muted); }
.text-sm { font-size: var(--text-sm); }
.result-count { color: var(--colour-text-muted); font-size: var(--text-sm); margin: 0 0 var(--space-4); }

/* ---- Stats ---- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); margin: 0 0 var(--space-5); }
.stat { background: #fff; border: 1px solid var(--colour-border); border-radius: var(--radius-lg); padding: var(--space-5); text-align: center; box-shadow: var(--shadow-sm); }
.stat__num { display: block; font-size: var(--text-2xl); font-weight: var(--fw-extrabold); color: var(--colour-primary); line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.stat__label { display: block; margin-top: var(--space-1); font-size: var(--text-sm); color: var(--colour-text-muted); text-transform: uppercase; letter-spacing: .03em; }
/* Optional third line: a caveat about the figure ("Partial corpus — not a
   national total"). Sentence case, not the label's uppercase — it is prose. */
.stat__hint { display: block; margin-top: var(--space-2); font-size: var(--text-xs); color: var(--colour-text-muted); text-transform: none; letter-spacing: 0; }
/* An absent figure keeps the tile's geometry — same size, same slot, so a row
   of tiles still shares one baseline — but drops the emphasis. Rendering
   "Unknown" in extrabold brand red would give an absence the visual weight of
   a measurement. */
.stat__num--unknown { color: var(--colour-text-muted); font-weight: var(--fw-semibold); }

/* ---- Data table ---- */
.data-table { width: 100%; border-collapse: collapse; margin: 0 0 var(--space-6); font-variant-numeric: tabular-nums; }
/* `.data-table` declares a trailing margin only, so on /parties/ (and the two
   /research-and-knowledge/ aliases that render the same template) the bordered
   `.card` above it sat directly on the sticky <thead>. The section fallback
   cannot help — a <table> is not a <section>. Scoped to direct children of a
   content container: verified only party_index.html and party_detail.html put
   a `.data-table` there, so this is surgical rather than global.

   `.table-scroll` is listed too: wrapping the party table for the horizontal-
   overflow fix moved the table out of direct-child position, which silently
   stopped this selector matching. Whichever of the two is the container's
   child needs the leading gap. */
.container > * + .data-table,
.container > * + .table-scroll { margin-top: var(--space-6); }
/* Wide tables (e.g. member comparison) scroll horizontally instead of breaking layout on phones. */
@media (max-width: 600px) { .data-table { display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; } }
.data-table th, .data-table td { text-align: left; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--colour-border); font-size: var(--text-sm); }
/* Scoped to `thead` on purpose. This is COLUMN-header styling — uppercase,
   0.72rem, muted — and it was applying to every `th`, including the
   `<th scope="row">` row headers that carry actual data (division subjects,
   party names). That shouted the data in tiny uppercase grey. Row headers are
   content and are styled as content below. */
.data-table thead th { text-transform: uppercase; font-size: 0.72rem; font-weight: var(--fw-bold); color: var(--colour-text-muted); letter-spacing: .03em; }
.data-table tbody th { font-weight: var(--fw-semibold); color: var(--colour-text); }
/* Sticky header for long scrolling tables (opt-in: <thead> stays put). */
.data-table thead th { position: sticky; top: 0; z-index: var(--z-base); background: var(--colour-bg); box-shadow: inset 0 -1px 0 var(--colour-border-strong); }
/* Zebra striping + row hover for scannability. */
.data-table tbody tr:nth-child(even) { background: var(--colour-bg-subtle); }
.data-table tbody tr:hover { background: var(--colour-primary-alpha-10); }
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table tbody tr:last-child td { border-bottom: 0; }

/* ---- Empty state ---- */
.empty-state { text-align: center; padding: var(--space-7) var(--space-5); color: var(--colour-text-muted);
  border: 1px dashed var(--colour-border-strong); border-radius: var(--radius-lg); background: var(--colour-bg-subtle); }
.empty-state__icon { font-size: 2rem; color: var(--colour-border-strong); margin-bottom: var(--space-3); }
.empty-state__title { font-weight: 700; color: var(--colour-text); margin-bottom: var(--space-1); }
/* The explanatory sentence is centred, so without a cap it ran the full panel
   width (measured 145 cpl in a 1236px panel). */
.empty-state p { max-width: var(--container-prose); margin-inline: auto; }
/* Compact variant for an empty state that sits INSIDE a panel which already has
   its own heading — the full-size one spent 263px of box on 177 characters,
   which is its own kind of dead space. */
.empty-state--tight { padding: var(--space-5) var(--space-4); }
.empty-state--tight .empty-state__icon { font-size: 1.25rem; margin-bottom: var(--space-2); }

/* ---- Pagination ---- */
.pager { display: flex; gap: var(--space-3); align-items: center; justify-content: center; margin: var(--space-6) 0; }
.pager a { display: inline-flex; align-items: center; padding: var(--space-2) var(--space-4);
  border: 1px solid var(--colour-border-strong); border-radius: var(--radius-pill);
  color: var(--colour-primary); text-decoration: none; font-weight: var(--fw-semibold); transition: all var(--motion-fast) var(--ease-standard); }
.pager a:hover { background: var(--colour-primary); color: #fff; border-color: var(--colour-primary); }
.pager a:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.pager span { color: var(--colour-text-muted); font-size: var(--text-sm); }

/* ---- Vertical timeline ---- */
.vtimeline { list-style: none; padding: 0; margin: var(--space-4) 0 0 var(--space-2); border-left: 3px solid var(--colour-border); }
.vtimeline__item { position: relative; padding: 0 0 var(--space-5) var(--space-5); }
.vtimeline__item::before { content: ""; position: absolute; left: -9px; top: .2rem; width: 14px; height: 14px;
  border-radius: 50%; background: var(--colour-primary); border: 3px solid #fff; box-shadow: 0 0 0 1px var(--colour-border); }
.vtimeline__date { font-size: 0.76rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--colour-text-muted); }

/* ==========================================================================
   Design-system extensions (Appendix H) — layout primitives, card variants,
   avatars, semantic badges, grade pills, subnav. All token-driven.
   ========================================================================== */

/* ---- Layout primitives ---- */
/* `padding: 0` here meant the page <h1> touched the band's top and bottom
   edges on every page that does NOT opt into `has-brand-hero` — measured at 49
   of 75 pages, with `/ai-tools/` rendering the heading at offset 0. Only the
   branded variant below had ever set `padding-block`.

   `margin-bottom` is deliberately GONE: `.site-content` is a flex column and
   now owns the gap between the band and the content via `row-gap` (core.css).
   Flex-item margins do not collapse, so keeping both would give 64px. */
.page-band {
  background: var(--colour-bg-subtle);
  border-bottom: 1px solid var(--colour-border);
  padding-block: var(--space-5);
}

/* ============================================================
   Branded section hero — opt-in via the `has-brand-hero` body class.
   Replaces the flat near-white page band with a deep civic hero that
   carries the Kenyan tricolour motif (black · red · green) plus a faint
   dot texture, so section landing pages stop reading as white-on-white.
   Reusable: any page can add `has-brand-hero` to its body_class. */
.has-brand-hero .page-band {
  position: relative; isolation: isolate;
  padding-block: var(--space-6); border-bottom: 0;
  color: #fff;
  background:
    radial-gradient(130% 140% at 15% -25%, hsl(358 75% 41% / 0.5), transparent 62%),
    linear-gradient(160deg, hsl(358 77% 37%), hsl(358 80% 31%));
}
.has-brand-hero .page-band::before {              /* faint dot-grid texture, fading down */
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(hsl(0 0% 100% / 0.07) 1px, transparent 1.6px);
  background-size: 24px 24px;
  -webkit-mask-image: linear-gradient(180deg, #000, transparent 85%);
  mask-image: linear-gradient(180deg, #000, transparent 85%);
}
.has-brand-hero .page-band::after {               /* Kenyan tricolour signature rule */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: linear-gradient(90deg,
    #000 0 32%, #fff 32% 34%,
    var(--colour-primary) 34% 64%, #fff 64% 66%,
    var(--colour-secondary) 66% 100%);
}
.has-brand-hero .page-heading { color: #fff; letter-spacing: -0.03em; }
.has-brand-hero .page-band .breadcrumbs,
.has-brand-hero .page-band .breadcrumbs a { color: hsl(0 0% 100% / 0.72); }
.has-brand-hero .page-band .breadcrumb-item.current { color: #fff; }
.has-brand-hero .page-band .breadcrumb-separator { color: hsl(0 0% 100% / 0.4); }

/* Eyebrow kicker sitting above a hero title. */
.hero-kicker {
  display: inline-flex; align-items: center; gap: .55em;
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs); font-weight: var(--fw-bold);
  text-transform: uppercase; letter-spacing: .14em;
  color: hsl(144 52% 72%);
}
.hero-kicker::before {
  content: ""; width: 1.7rem; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--colour-primary), var(--colour-secondary));
}
.prose { max-width: var(--container-prose); margin-inline: auto; }
.prose p { line-height: var(--leading-normal); }
/* Lead/intro paragraphs used to opt OUT of the reading-width cap here
   (`.page-intro--text.prose { max-width: none }`), on the reasoning that they
   should span the same width as the wide table below them. Measured, that
   produced 137-215 characters per line — `p.analysis-intro.prose` rendered at
   161 cpl *while carrying `.prose`*. An intro is still text and still has to
   be readable, so it is capped at its own (shorter) measure instead. Left-
   aligned, not centred: it must line up with the heading above it. */
.page-intro--text,
.section-intro--text,
.section__lead { max-width: var(--measure-lead); margin-inline: 0; }
/* Body copy in the /mps-performance/ section intros. Same family as the two
   `--text` classes above and it was simply missed when they were capped: it
   carried NO measure at all, so it inherited the shell width and measured 156
   cpl at the old 1320px container. Widening `--container-max` on 2026-08-02
   took it to 204 cpl, which is what made the omission visible. It is body
   copy, not a lead, so it gets the longer `--container-prose`. */
.parliament-section--text { max-width: var(--container-prose); }
/* Citation and advisory lines are set small, so the same pixel width buys far
   more characters — these measured 228-304 cpl uncapped.

   `--container-prose` is now `none` (core.css), so this rule no longer caps
   anything — these notes span their container and measure ~270 cpl at 1920px.
   That is the owner's explicit choice; read the core.css note before changing
   it. The declaration is kept rather than deleted so that restoring a measure
   site-wide remains a one-token edit.

   DO NOT flow these into CSS columns. That was tried across the whole site on
   2026-08-02 and REMOVED the same day by owner direction: "remove the multi col
   if the rest of the page is not multi col." Newspaper columns inside an
   otherwise single-column page read as a different document. */
.src-cite,
.prov-ribbon__body { max-width: var(--container-prose); }
/* Cap the TEXT, not the panel. `.note-panel` is a bordered, tinted, flex
   container — putting the measure on it shrank the whole amber banner to 704px
   inside a 1320px container, leaving 616px of white beside a half-width box.
   A max-width on a bordered box is not the same operation as a measure cap. */
.note-panel p { max-width: var(--container-prose); }
.wrap--narrow { max-width: var(--container-narrow); margin-inline: auto; }
/* Opt-in wide container for genuinely dense surfaces (large data tables,
   ranking grids) that legitimately need more room than prose. */
.container--wide { max-width: var(--container-wide); }
/* Horizontal scroll for bespoke tables that do not already provide their own
   scroll wrapper. (.mz-rank__tablewrap and .finance-table-wrap already do.) */
/* The wrapper takes over the table's block role. Once a `.data-table` is put
   inside a scroll wrapper, the table's own `margin-bottom` is trapped INSIDE
   the scrollport and no longer separates the wrapper from the next block —
   measured 0px on /parties/ between `.table-scroll` and the card grid below it
   the moment the wrapper was added. So the wrapper carries the trailing margin
   and the table drops its own to avoid stacking two. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 0 var(--space-6); }
.table-scroll > .data-table { margin-bottom: 0; }

/* Scroll affordance. Under 600px `.data-table` becomes its own horizontal
   scroller, so on a phone the later columns — including the per-row gazette
   SOURCE link the elections hero explicitly promises — sit off-canvas with
   nothing to say so. The content IS reachable; it just looks like the row ends
   at the viewport edge. These background-attachment gradients are the standard
   CSS-only cue: the shadows are painted against the scrollport (`scroll`) and
   the white covers (`local`) slide away as you scroll, so a shadow appears only
   on the side that has more content. No JS, no markup change. */
.table-scroll,
.data-table {
  background:
    linear-gradient(to right, var(--colour-bg) 30%, hsl(0 0% 100% / 0)) left center,
    linear-gradient(to left, var(--colour-bg) 30%, hsl(0 0% 100% / 0)) right center,
    linear-gradient(to right, hsl(0 0% 0% / 0.10), hsl(0 0% 0% / 0)) left center,
    linear-gradient(to left, hsl(0 0% 0% / 0.10), hsl(0 0% 0% / 0)) right center;
  background-repeat: no-repeat;
  background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* Performance Rankings shipped a ranking table with EVERY column left-aligned —
   all 8 headers and all 8 cells measured `text-align: left`, over values
   spanning 0-2,142 across 50 rows, with no zebra. Digits that do not share a
   right edge cannot be compared down a column, which is the entire purpose of
   this table. Columns 3+ are the numeric ones (Overall, Contributions, Division
   participation, Bills, Committees, Initiative). Scoped by element+nth-child so
   it outranks the generated island bundle, which loads after this file. */
.mz-rank__table thead th:nth-child(n + 3),
.mz-rank__table tbody td:nth-child(n + 3) { text-align: right; }
.mz-rank__table tbody tr:nth-child(even) { background: var(--colour-bg-subtle); }

/* Performance Rankings scrolled the WHOLE PAGE on a phone: measured
   document.scrollWidth = 445px at a 390px viewport. The rankings table is not
   the cause — .mz-rank__tablewrap scrolls it. The cause is the filter row,
   whose controls carry `min-width: 14rem` + `min-width: 10rem` (= 384px before
   gaps and the container gutter) and so cannot fit a 390px screen.
   Those rules live in the GENERATED island bundle
   (apps/parliament/static/islands/mz-islands.css, built from wagtail/frontend/),
   which loads after this file via {% block extra_css %} — so this override is
   scoped by an extra class to win on specificity rather than by !important,
   and survives a future `npm run build` of the bundle. */
@media (max-width: 700px) {
  .mz-rank__filters .mz-rank__search,
  .mz-rank__filters .mz-rank__party { min-width: 0; flex: 1 1 100%; }
  .mz-rank__toolbar .mz-rank__filters { width: 100%; }
}
.grid--auto { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--col-min, 240px), 1fr)); gap: var(--space-4); }
.grid-12 { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--space-4); }

/* ---- Card variants ---- */
.card--row { display: flex; gap: var(--space-4); align-items: stretch; padding: var(--space-4) var(--space-5); }
.card--feature { padding: var(--space-5) var(--space-6); border-left: 4px solid var(--colour-primary); }
.card__media { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--colour-bg-subtle); }
.card__body { padding: var(--space-4) var(--space-5); }
.card__footer { padding: var(--space-3) var(--space-5); border-top: 1px solid var(--colour-border); display: flex; gap: var(--space-3); align-items: center; }
.card__tag-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }

/* ---- Avatar ---- */
.avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; background: var(--colour-bg-subtle); flex: none; }
.avatar--lg { width: 72px; height: 72px; }
.avatar--initial { display: grid; place-items: center; color: #fff; font-weight: var(--fw-extrabold); background: var(--colour-primary); }

/* ---- Committee directory (row card: small chair photo left, details right —
   the chair is a supporting detail, not the headline) ---- */
/* `align-items: flex-start` let each card shrink to its own content, so a row
   of three ended at three different depths and the House badge floated at a
   different height in every card. Stretch the card and push the badge row to
   the bottom, so the badges line up across a row and the grid reads as rows
   rather than as ragged columns. */
.committee-card { align-items: stretch; }
.committee-card__avatar { border: 2px solid var(--colour-bg-subtle); box-shadow: var(--shadow-sm); align-self: flex-start; }
.committee-card__body { min-width: 0; display: flex; flex-direction: column; flex: 1; }
.committee-card__title { margin-bottom: var(--space-1); }
.committee-card .card__tag-row { margin-top: auto; padding-top: var(--space-2); }
.committee-group { margin-bottom: var(--space-6); }
.committees-search { width: min(24rem, 100%); }

/* ---- Semantic badges (extend .badge) ---- */
.badge--success { background: var(--colour-success-bg); color: var(--colour-success); }
.badge--warning { background: var(--colour-warning-bg); color: var(--colour-warning); }
.badge--info { background: var(--colour-info-bg); color: var(--colour-info); }
.badge--danger { background: var(--colour-danger-bg); color: var(--colour-danger); }

/* ---- Grade pill (scorecards): meaning, not alarm — A/B green … D/E/F red ---- */
.grade { display: inline-grid; place-items: center; min-width: 2.4rem; padding: var(--space-1) var(--space-3);
  border: 3px solid currentColor; border-radius: var(--radius-md); font-size: var(--text-2xl);
  font-weight: var(--fw-extrabold); line-height: 1; color: var(--colour-primary); }
.grade--a, .grade--b { color: var(--colour-success); }
.grade--c { color: var(--colour-warning); }
.grade--d, .grade--e, .grade--f { color: var(--colour-danger); }

/* ---- Shared sub-nav (alias of .tabs for section sub-navigation) ---- */
.subnav { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  border-bottom: 2px solid var(--colour-border); margin: 0 0 var(--space-5); }
.subnav a { display: inline-block; padding: var(--space-3) var(--space-1); color: var(--colour-text);
  text-decoration: none; font-weight: var(--fw-semibold); border-bottom: 3px solid transparent; }
.subnav a:hover { color: var(--colour-primary); }
.subnav a:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; border-radius: var(--radius-sm); }
.subnav a.is-active { color: var(--colour-primary); border-bottom-color: var(--colour-primary); }

/* ---- Vote-decision chips (voting pages) ---- */
.vote-chip { display: inline-flex; align-items: center; gap: var(--space-1); padding: 1px 9px; border-radius: var(--radius-pill); font-size: var(--text-sm); font-weight: var(--fw-semibold); }
.vote-chip--yes { background: var(--colour-success-bg); color: var(--colour-success); }
.vote-chip--no { background: var(--colour-danger-bg); color: var(--colour-danger); }
.vote-chip--abstain, .vote-chip--absent { background: var(--colour-lighter); color: var(--colour-text-muted); }

/* ---- House (chamber) tabs — National Assembly | Senate. Never mix Houses. ----
   Outlined-pill treatment (matches the look formerly bespoke to Bills' .leg-toggle,
   now the one shared style used everywhere a page has real chamber data). */
.house-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-3); }
.house-tab { padding: var(--space-2) var(--space-4); border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-pill, 999px); text-decoration: none; color: var(--colour-text);
  font-size: var(--text-sm, .9rem); font-weight: var(--fw-semibold, 600); white-space: nowrap;
  transition: border-color var(--motion-fast, .15s) var(--ease-standard), color var(--motion-fast, .15s) var(--ease-standard); }
.house-tab:hover { border-color: var(--colour-primary); color: var(--colour-primary); }
.house-tab:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
.house-tab.is-active { background: var(--colour-primary); color: #fff; border-color: var(--colour-primary); }
@media (max-width: 480px) { .house-tabs { display: flex; width: 100%; }
  .house-tab { flex: 1; text-align: center; } }

/* Timeframe (year) filter — sits beside the house tabs on metric pages. */
.timeframe-filter { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-3); font-size: var(--text-sm); }
.timeframe-filter select { padding: 6px 10px; border: 1px solid var(--colour-border, #ddd); border-radius: var(--radius-md, 8px); background: #fff; font-family: inherit; }

/* ---- Explorer scope bar: chamber (NA | Senate) + time window, shared across analysis pages ---- */
.scope-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5); margin: 0 0 var(--space-3); }
.scope-bar > * { margin-bottom: 0; }
.scope-bar__periods { margin-bottom: 0; }
.scope-bar__custom { margin-bottom: 0; }
.scope-bar__window { margin: 0 0 var(--space-5); }
.scope-bar__notice { margin: 0 0 var(--space-2); color: var(--colour-warning); }

/* ---- Site-wide detail / drill-down drawer (right side panel; bottom sheet on mobile) ---- */
.lmodal { position: fixed; inset: 0; z-index: var(--z-modal, 1000); }
.lmodal[hidden] { display: none; }
.lmodal__backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); }
.lmodal__dialog { position: fixed; top: 0; right: 0; bottom: 0; z-index: 1; width: min(480px, 100%);
  display: flex; flex-direction: column; background: var(--colour-bg, #fff);
  box-shadow: -8px 0 40px rgba(0,0,0,.25); animation: lmodal-slide-in .22s cubic-bezier(.16,1,.3,1); }
.lmodal__header { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--colour-border, #e6e6e6); }
.lmodal__title { margin: 0; font-size: 1.05rem; color: var(--colour-text); }
.lmodal__close { background: none; border: 0; font-size: 1.9rem; line-height: 1; color: var(--colour-text-muted); cursor: pointer; }
.lmodal__close:hover { color: var(--colour-primary); }
.lmodal__body { overflow-y: auto; padding: var(--space-4) var(--space-5); flex: 1; }
.lmodal__loading, .lmodal__error { padding: 2.5rem 0; color: var(--colour-text-muted); text-align: center; }
body.lmodal-open { overflow: hidden; }
@keyframes lmodal-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
@media (max-width: 640px) {
  .lmodal__dialog { top: auto; left: 0; right: 0; width: 100%; height: 82vh; border-radius: 14px 14px 0 0;
    animation: lmodal-slide-up .22s cubic-bezier(.16,1,.3,1); }
  @keyframes lmodal-slide-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
}
/* Drill-down list (members/bills/etc. inside the drawer) */
.drill-list { list-style: none; margin: 0; padding: 0; }
.drill-list__item { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--colour-border, #eee); }
.drill-list__item a { color: var(--colour-text); text-decoration: none; font-weight: 600; }
.drill-list__item a:hover { color: var(--colour-primary); }
.drill-list__meta { font-size: var(--text-sm); color: var(--colour-text-muted); }
.drill-list__count { color: var(--colour-text-muted); font-size: var(--text-sm); margin: 0 0 var(--space-3); }
/* Clickable stat (opens the count's breakdown in the drawer). */
.stat--link { text-decoration: none; color: inherit; cursor: pointer; transition: box-shadow .15s, transform .15s; }
.stat--link:hover { box-shadow: var(--shadow-md, 0 4px 14px rgba(0,0,0,.12)); transform: translateY(-1px); }
.stat--link .stat__num { color: var(--colour-primary); }
.drill-list__item--stack { flex-direction: column; align-items: flex-start; gap: 3px; }
.drill-list__item--stack a { font-weight: 500; line-height: 1.35; }
/* Presiding-officer speech: shown for the record, de-emphasised, and badged so
   it reads as not-counted-in-metrics. */
.drill-list__item--presiding { opacity: .72; }
.drill-list__badge {
  display: inline-block; font-size: var(--text-xs, .72rem); font-weight: 600;
  line-height: 1; padding: 3px 7px; border-radius: 999px;
  color: var(--colour-text-muted); background: var(--colour-surface-2, #f1f1f3);
  border: 1px solid var(--colour-border, #e3e3e6); letter-spacing: .02em;
}

/* ---- Data export actions (Download CSV / Print-PDF) + print styles ---- */
.data-actions { display: flex; gap: var(--space-2); margin: 0 0 var(--space-4); flex-wrap: wrap; }
.data-actions__btn { display: inline-flex; align-items: center; gap: .35rem; padding: .4rem .85rem;
  border: 1px solid var(--colour-border-strong, #ccc); border-radius: var(--radius-pill, 999px);
  background: #fff; color: var(--colour-text); font: inherit; font-size: var(--text-sm); font-weight: 600;
  cursor: pointer; text-decoration: none; }
.data-actions__btn:hover { border-color: var(--colour-primary); color: var(--colour-primary); }
.data-actions__btn:focus-visible { outline: 2px solid var(--colour-primary); outline-offset: 2px; }
@media print {
  .site-header, .site-footer, #lmodal, .data-actions, .main-nav, .mobile-menu, .breadcrumbs,
  .timeframe-filter, .house-tabs, .tabs, .desktop-search-form, .filter-bar { display: none !important; }
  body { background: #fff; }
  .container { max-width: none !important; width: 100% !important; }
}

/* ---- Data & Downloads page (/data/) ----
   Download/feed catalogue built from the shared card + button components. */
.page-data .prose a,
.page-data .card__meta a { color: var(--colour-primary); font-weight: var(--fw-semibold); }
.page-data .prose a:hover,
.page-data .card__meta a:hover { text-decoration: underline; }
.page-data .data-stats { margin-top: var(--space-5); }
.page-data .data-jump { margin: var(--space-3) 0 var(--space-6); }
/* On this page card__meta holds descriptive sentences, not the meta chip row,
   so flow it as normal text instead of the shared flex layout. */
.page-data .card__meta { display: block; }

.dl-card { display: flex; flex-direction: column; }
.dl-card > .card--pad { flex: 1 1 auto; }
.dl-card .card__title { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
/* Actions pinned to the card base: a row of "open page" buttons, then a subtle
   direct-CSV line beneath. */
.dl-card__foot { padding: var(--space-3) var(--space-5) var(--space-4);
  border-top: 1px solid var(--colour-border); display: flex; flex-direction: column; gap: var(--space-2); }
.dl-card__open { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.dl-card__csv { margin: 0; font-size: var(--text-sm); color: var(--colour-text-muted); }
.dl-card__csv a { color: var(--colour-primary); font-weight: var(--fw-semibold); }
.dl-card__csv a:hover { text-decoration: underline; }
.dl-card__actions { flex-wrap: wrap; }
.dl-card__icon { display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--radius-md); flex: none;
  background: var(--colour-primary-alpha-10); color: var(--colour-primary);
  font-size: var(--text-sm); }
.dl-card__icon--feed { background: var(--colour-secondary-alpha-10); color: var(--colour-secondary-dark); }

/* ---- Text links ----
   Affordance contract: every anchor a user must discover is affordant iff
   (a) it is a block/card with hover elevation + focus ring, (b) a button/chip
   with fill or border, or (c) it carries link colour with an at-rest underline
   (inline prose) or at-rest colour + hover underline (record titles in lists).
   Bare unclassed links inside .site-content get this automatically (core.css);
   any CLASSED inline link must add .text-link (or provide its own affordance
   per the contract). Quiet-at-rest is reserved for chrome: nav, tabs,
   breadcrumbs, pagination, footer, and whole-card links. */
.text-link {
  color: var(--colour-link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.text-link:hover,
.text-link:focus-visible {
  color: var(--colour-link-hover);
  text-decoration-thickness: 2px;
}

/* ---- Generic JS-optional tabs ----
   Pair a <nav class="tabs"> of #hash links with sibling
   <section class="tab-panel" id="..."> panels inside a .tab-panels wrapper.
   The panel matching the URL hash shows; with no hash the .tab-panel--default
   one shows. Pure CSS — works with JS off; parliament.js only syncs the active
   underline. (Promoted out of the page-scoped mp.css so any page can reuse it.) */
.tab-panel { display: none; }
.tab-panel:target { display: block; }
.tab-panels:not(:has(:target)) .tab-panel--default { display: block; }

/* ---- Provenance affordance (trust-building, never a warning) ----
   Tier 1: a calm source ribbon leading a data page. Tier 2: a muted citation
   line under a table/chart. Both token-only. */
.prov-ribbon {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); margin: var(--space-5) 0;
  border: 1px solid var(--colour-border); border-left-width: 4px;
  border-radius: var(--radius-md); background: var(--colour-bg-subtle);
  font-size: var(--text-sm); line-height: var(--leading-normal);
}
.prov-ribbon--certified { background: var(--colour-success-bg); border-color: var(--colour-success); }
.prov-ribbon--preview { background: var(--colour-warning-bg); border-color: var(--colour-warning); }
.prov-ribbon__body { color: var(--colour-text); }
.prov-ribbon__body strong { color: var(--colour-text); }

.src-cite { font-size: var(--text-xs); color: var(--colour-text-muted); margin: var(--space-2) 0 var(--space-5); }
.src-cite a { color: var(--colour-link); }
.src-cite a:hover, .src-cite a:focus-visible { color: var(--colour-link-hover); }

/* Non-interactive pill chip (e.g. a step in a path); interactive pills use .pills a. */
.pill {
  padding: var(--space-2) var(--space-4); border: 1px solid var(--colour-border-strong);
  border-radius: var(--radius-pill); font-size: var(--text-sm); font-weight: 600;
  color: var(--colour-text); background: var(--colour-bg-subtle);
}

/* ---- Feature icon tile ----
   A tinted square holding a Font Awesome glyph, for feature/tool cards. Lifts to
   solid primary when its enclosing .card--link is hovered. */
.feature-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.6rem; height: 2.6rem; flex: none;
  border-radius: var(--radius-md);
  background: var(--colour-primary-alpha-10); color: var(--colour-primary);
  font-size: var(--text-lg);
}
.card--link:hover .feature-icon { background: var(--colour-primary); color: var(--colour-bg); }

/* Official Source Library — paginated two-column directory of sources; contents collapsed until expanded. */
/* Soft green-tinted page wash near the top, fading to white — breaks the flat
   all-white field without hurting text contrast. */
body.page-analysis-official-sources { background: linear-gradient(180deg, hsl(150 34% 97.5%), var(--colour-bg) 460px); }

/* Quarantine note: an amber advisory panel (semantic warning tone) with an
   icon rail, so the governance caveat reads as a deliberate notice. */
/* The trailing margin follows the convention every other shared block here uses
   (`.filter-bar`, `.data-table`, `.committee-group`, `.section__lead`): a note
   panel is a block in the flow, not a decoration glued to what follows it.
   Without it, /analysis/official-sources/ rendered this bordered box sitting
   directly on the search form below it. */
.note-panel { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-4) var(--space-5); margin: 0 0 var(--space-6); border: 1px solid hsl(45 80% 82%); border-left: 4px solid var(--colour-warning); background: linear-gradient(120deg, var(--colour-warning-bg), hsl(45 100% 97%)); border-radius: var(--radius-lg); }
.note-panel__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; border-radius: var(--radius-md); background: hsl(45 90% 88%); color: var(--colour-warning); font-size: var(--text-lg); }
.note-panel p { margin: 0; }
.note-panel strong { color: var(--colour-warning); }

/* Metric chips — the counts summary as coloured pills instead of a grey run-on line. */
.metric-chips { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; margin: var(--space-5) 0 var(--space-4); }
.metric-chip { display: inline-flex; align-items: baseline; gap: .45em; padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill); font-size: var(--text-sm); font-weight: var(--fw-semibold); border: 1px solid transparent; }
.metric-chip b { font-size: var(--text-lg); font-weight: var(--fw-extrabold); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.metric-chip--docs { background: var(--colour-secondary-alpha-10); color: var(--colour-secondary-dark); border-color: var(--colour-secondary-alpha-20); }
.metric-chip--excerpts { background: var(--colour-primary-alpha-10); color: var(--colour-primary-dark); border-color: var(--colour-primary-alpha-20); }
.metric-chips__note { font-size: var(--text-sm); color: var(--colour-text-muted); }

.source-doc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); align-items: start; }
@media (max-width: 640px) { .source-doc-grid { grid-template-columns: 1fr; } }
.source-doc { position: relative; font-size: var(--text-sm); transition: box-shadow var(--motion-base) var(--ease-standard), transform var(--motion-base) var(--ease-standard), border-color var(--motion-base) var(--ease-standard); }
.source-doc::before {                             /* green→red accent rail, revealed on hover/open */
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--colour-secondary), var(--colour-primary));
  opacity: 0; transition: opacity var(--motion-base) var(--ease-standard);
}
.source-doc:hover { transform: translateY(-2px); border-color: var(--colour-secondary-alpha-20); box-shadow: 0 10px 26px hsl(150 40% 18% / 0.13); }
.source-doc[open] { border-color: var(--colour-secondary-alpha-20); }
.source-doc:hover::before, .source-doc[open]::before { opacity: 1; }
.source-doc__summary { cursor: pointer; list-style: none; display: flex; align-items: flex-start; gap: var(--space-3); }
.source-doc__summary::-webkit-details-marker { display: none; }
.source-doc__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; border-radius: var(--radius-md); background: var(--colour-secondary-alpha-10); color: var(--colour-secondary-dark); font-size: var(--text-base); }
.source-doc__head { flex: 1 1 auto; min-width: 0; }
.source-doc__chevron { flex: none; color: var(--colour-text-muted); margin-top: .3rem; transition: transform var(--motion-base) var(--ease-standard); }
.source-doc[open] .source-doc__chevron { transform: rotate(180deg); }
.source-doc[open] .source-doc__icon { background: var(--colour-secondary); color: #fff; }
.source-doc__name { display: block; font-weight: var(--fw-bold); color: var(--colour-text); }
.source-doc__meta { display: block; margin-top: 2px; color: var(--colour-text-muted); }
.source-doc__body { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--colour-border); }
.source-excerpts { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.source-excerpt { border: 1px solid var(--colour-border); border-radius: var(--radius-md); background: var(--colour-bg); }
.source-excerpt__summary { cursor: pointer; padding: var(--space-2) var(--space-3); font-size: var(--text-sm); color: var(--colour-text); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: baseline; }
.source-excerpt__summary::-webkit-details-marker { color: var(--colour-text-muted); }
.source-excerpt__locator { font-weight: var(--fw-bold); color: var(--colour-text-muted); white-space: nowrap; }
.source-excerpt__snippet { color: var(--colour-text-muted); }
.source-excerpt[open] .source-excerpt__summary { border-bottom: 1px solid var(--colour-border); }
.source-excerpt[open] .source-excerpt__snippet { display: none; }
.source-excerpt__full { margin: 0; padding: var(--space-3); font-size: var(--text-sm); }
.source-pagination { display: flex; gap: var(--space-3); align-items: center; justify-content: center; flex-wrap: wrap; margin-top: var(--space-5); }
.source-pagination__status { color: var(--colour-text-muted); font-size: var(--text-sm); }


/* ---- Entity metrics: bullet-style KPI cards (member/region/party/committee) ----
   Form follows the job: each metric is a magnitude PLUS its position in a peer
   distribution, which is a bullet chart, not a chart-chart. One entity means one
   series, so no legend and no categorical palette — brand fill, neutral ink.
   Borrows the compare page's grammar (figure adjacent to a proportional bar). */
/* Hidden ONLY once the radar island has actually mounted (it sets data-mounted
   on itself). A failed or skipped mount leaves the cards visible, which is the
   whole point of a progressive-enhancement fallback. */
.island[data-mounted] + .metric-grid--islanded { display: none; }
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--space-4); margin: 0 0 var(--space-4); }
.metric-card { background: var(--colour-bg); border: 1px solid var(--colour-border); border-radius: var(--radius-lg); padding: var(--space-4) var(--space-4) var(--space-3); box-shadow: var(--shadow-sm); }
.metric-card__eyebrow { display: block; font-size: var(--text-xs); font-weight: var(--fw-semibold); letter-spacing: 0.04em; text-transform: uppercase; color: var(--colour-text-muted); margin: 0 0 var(--space-2); }
.metric-card__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.metric-card__figure { font-size: var(--text-2xl); font-weight: var(--fw-extrabold); line-height: var(--leading-tight); color: var(--colour-text); font-variant-numeric: tabular-nums; }
.metric-card__rank { flex: none; font-size: var(--text-xs); font-weight: var(--fw-semibold); color: var(--colour-text-muted); background: var(--colour-bg-subtle); border: 1px solid var(--colour-border); border-radius: var(--radius-pill); padding: 2px var(--space-2); white-space: nowrap; }
/* The bullet track: the share of peers strictly below this entity. No median
   reference line — ties are heavy enough here (most members sponsor no Bills)
   that the median is not at the 50% mark, so a fixed tick would lie. */
.metric-card__track { position: relative; height: 8px; margin: var(--space-3) 0 0; background: var(--colour-lighter); border-radius: var(--radius-pill); }
.metric-card__fill { display: block; height: 100%; min-width: 4px; background: var(--colour-primary); border-radius: var(--radius-pill); }
.metric-card__foot { font-size: var(--text-xs); color: var(--colour-text-muted); margin: var(--space-2) 0 0; font-variant-numeric: tabular-nums; }
/* A refused metric. The reason IS the content; there is never a number here. */
.metric-card--refused { background: var(--colour-bg-subtle); box-shadow: none; }
.metric-card--refused .metric-card__figure { font-size: var(--text-lg); font-weight: var(--fw-semibold); color: var(--colour-text-muted); }
.metric-card__reason { font-size: var(--text-xs); color: var(--colour-text-muted); margin: var(--space-2) 0 0; line-height: var(--leading-snug); }
/* Meta + the collapsed honesty note. Compact by default, one click for the full
   statement — the wording is load-bearing but it must not out-shout the figures. */
.metric-meta { font-size: var(--text-xs); color: var(--colour-text-muted); margin: 0 0 var(--space-4); }
.metric-disclosure { border-top: 1px solid var(--colour-border); margin-top: var(--space-4); padding-top: var(--space-3); }
.metric-disclosure > summary { cursor: pointer; font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--colour-text-muted); list-style: none; display: flex; align-items: center; gap: var(--space-2); }
.metric-disclosure > summary::-webkit-details-marker { display: none; }
.metric-disclosure > summary::before { content: "+"; display: inline-flex; align-items: center; justify-content: center; width: 1.1rem; height: 1.1rem; border: 1px solid var(--colour-border); border-radius: var(--radius-sm); font-weight: var(--fw-bold); }
.metric-disclosure[open] > summary::before { content: "\2212"; }
.metric-disclosure dl { margin: var(--space-3) 0 0; font-size: var(--text-sm); color: var(--colour-text-muted); max-width: var(--container-prose); }
.metric-disclosure dt { font-weight: var(--fw-semibold); color: var(--colour-text); margin-top: var(--space-2); }
.metric-disclosure dd { margin: 0 0 var(--space-1); }
@media (max-width: 420px) {
  .metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
  .metric-card { padding: var(--space-3); }
  .metric-card__figure { font-size: var(--text-xl); }
  /* The median line is the first thing to go when space is tight; the track and
     the rank pill still carry the comparison. */
  .metric-card__foot { display: none; }
}

/* Topic pills on the classic member profile stay ANCHORS (drawer.js binds on
   [data-drawer-url] and preventDefaults, so they open the member's own drawer
   with JS and still navigate without it). Only the no-drill fallback needs a
   rule, so it sits in .pills exactly as an anchor does. */
.pills .pill-static { font: inherit; cursor: default; }
