/* ==========================================================================
   Data Center Community Benefits Dashboard — styles.css
   ==========================================================================
   Color tokens live on :root + [data-theme="dark"]. Per CLAUDE.md, never
   hard-code colors elsewhere — read CSS vars via getComputedStyle in JS.
   ========================================================================== */

/* Civic-record palette (v2): cool paper, near-black ink, one deep signal blue.
   Deliberately NOT the warm cream the source page uses — a warm-cream-and-gold
   editorial look reads as a consumer AI product, and this is a public record.
   Cool paper reads as a registry or an investigative newsroom, which is what
   the site actually is. The pledge's STRUCTURE is what we borrowed (Roman
   numeral commitments, letterspaced kickers, big display serif); the colour is
   ours.

   Every value below is a literal in BOTH this block and the dark block
   (DESIGN.md 12.12: a `var()` alias in :root only computes on :root and does
   NOT propagate the dark override to descendants). */
:root {
  /* v3 civic palette, taken from whitehouse.gov's own presets (extracted from
     the live site 2026-08-03): white paper, charcoal ink (#293340), deep navy
     (#0D132D / #151A30 / #141F4D), signal red (#B50000), amber (#FFBD00 —
     10.9:1 on the navy band, 1.7:1 on white, so it is a MARK color on light
     surfaces and a text color only on the band), stone (#E8E6E0) and
     pale-gray (#D9DEE8). Every text pairing below was contrast-computed
     before landing; see the commit message for the table. */
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f3f3f3;
  --text: #293340;
  --text-muted: #5a6572;
  --border: #d9dee8;
  --border-strong: #8a8a8a;
  --accent: #141f4d;
  --accent-soft: #e3e7f2;
  /* Deliberately NOT --accent's navy: navy-on-white text and this navy link
     color compute to ~1.23:1 contrast against each other, so a link with no
     other visual cue (many use text-decoration: none at rest, underline only
     on :hover) reads as indistinguishable body copy. #2563eb keeps AA against
     white (5.17:1) while roughly doubling the link/text separation (~2.48:1)
     — the practical ceiling given how dark --text already is; 3:1 would need
     --text itself to lighten, out of scope here. */
  --link: #2563eb;

  /* The signal accent, in two weights. --accent-mark (whitehouse.gov red,
     7.08:1 on white) is text-safe at any size and carries kickers, labels and
     small copy; --accent-rule (deep red) is the darker weight for rules and
     emphasis. Amber (#FFBD00) deliberately does NOT appear here: at 1.68:1 on
     white it is a mark color only, and it lives on the band tokens where it
     passes (10.9:1 on the navy). */
  --accent-mark: #b50000;
  --accent-rule: #730000;

  /* The inked band — the dark section the commitments render on. Deliberately
     dark in BOTH themes (it is a figure, not a surface), so its own foreground
     tokens travel with it rather than inheriting the page theme. */
  --band-bg: #0d132d;
  --band-text: #ffffff;
  --band-text-muted: #abb4c4;
  --band-accent: #ffbd00;
  --band-hairline: rgba(255, 255, 255, 0.18);

  --hairline: rgba(41, 51, 64, 0.16);

  /* Per-stance colors (community responses) */
  --stance-positive: #2f7a4d;
  --stance-positive-soft: #d8eadd;
  --stance-mixed: #b07024;
  --stance-mixed-soft: #f0e2c9;
  --stance-negative: #a3372f;
  --stance-negative-soft: #f0d4d1;

  /* Delivered-vs-promised palette (v1.13). Mirrors stance hues so that
     "delivered ↔ positive", "shortfall ↔ negative", "partial / contested ↔
     mixed" read consistently across the dashboard. */
  --delivered-delivered: #2f7a4d;
  --delivered-delivered-soft: #e2f0e7;
  --delivered-partial: #5a7a90;
  --delivered-partial-soft: #e0e8ee;
  --delivered-contested: #b07024;
  --delivered-contested-soft: #f0e2c9;
  --delivered-shortfall: #a3372f;
  --delivered-shortfall-soft: #f0d4d1;

  /* Ratepayer Protection Pledge palette (v1.15). affirmed ↔ delivered green,
     pledge_only ↔ neutral blue-grey, contested ↔ amber — consistent with the
     delivered/stance signal language. */
  --ratepayer-affirmed: #2f7a4d;
  --ratepayer-affirmed-soft: #e2f0e7;
  --ratepayer-pledge_only: #5a7a90;
  --ratepayer-pledge_only-soft: #e0e8ee;
  --ratepayer-contested: #b07024;
  --ratepayer-contested-soft: #f0e2c9;

  /* Tariff status + coverage colors (v1.17). Light values here; dark overrides
     in the [data-theme="dark"] block below — same pattern as --stance /
     --delivered (DESIGN.md: colors live in tokens with dark-mode overrides, not
     hard-coded per rule). approved↔positive, proposed↔mixed, rejected↔negative;
     included↔positive, partial↔mixed. */
  --tariff-approved: #2f7a4d;
  --tariff-approved-soft: #d8eadd;
  --tariff-proposed: #b07024;
  --tariff-proposed-soft: #f0e2c9;
  --tariff-rejected: #a3372f;
  --tariff-rejected-soft: #f0d4d1;
  --tariff-included: #2f7a4d;
  --tariff-included-soft: #d8eadd;
  --tariff-partial: #b07024;
  --tariff-partial-soft: #f0e2c9;
  --tariff-federal: #2f5d8a;
  --tariff-federal-soft: #f1f0ea;

  /* Moratorium status — three-state hue language shared with tariffs/stance:
     enacted↔in-effect (green), proposed↔pending (amber), failed↔struck (red).
     Literal values in BOTH :root blocks per DESIGN.md 12.12 (a var() alias in
     :root only won't inherit the dark override to descendants). */
  --moratorium-enacted: #2f7a4d;
  --moratorium-enacted-soft: #d8eadd;
  --moratorium-proposed: #b07024;
  --moratorium-proposed-soft: #f0e2c9;
  --moratorium-failed: #a3372f;
  --moratorium-failed-soft: #f0d4d1;

  /* Per-company subtle accent (NOT brand colors — neutral palette so we
     don't imply endorsement). Used for left borders / chips, not fills. */
  --co-meta: #4a6b8e;
  --co-google: #7a6233;
  --co-microsoft: #3d6b50;
  --co-amazon: #8a5a2c;
  --co-openai: #4a4a4a;
  --co-anthropic: #8e6a4a;
  --co-xai: #2c2c2c;
  --co-oracle: #6b3838;
  --co-wonder-valley: #6b4a8e;
  --co-qts: #2f6e7a;
  --co-crusoe: #8e6b4a;
  --co-coreweave: #5b4a8e;
  --co-prologis: #7a5a3a;
  --co-sb-energy: #8e4a6b;
  --co-brookfield: #5a6b3a;

  /* Per-theme accent (used as left border on theme chips + matrix headers) */
  --theme-jobs: #2f5d8a;
  --theme-tax_revenue: #6b4a8a;
  --theme-energy: #8a6a2f;
  --theme-water: #2f7a8a;
  --theme-community_grants: #2f7a4d;
  --theme-infrastructure: #5b6471;
  --theme-education: #8a4a5b;
  --theme-engagement: #4a8a6b;

  /* whitehouse.gov sets Instrument Sans / Instrument Serif. Naming them
     first costs nothing (they engage when locally installed) and the stacks
     fall back to system faces — still no web fonts, per the perf budget. */
  --font-sans:
    "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --font-serif:
    "Instrument Serif", "Charter", "Source Serif 4", "Iowan Old Style",
    "Apple Garamond", "Baskerville", "Times New Roman", "Droid Serif", Times,
    serif;
  --font-mono:
    "SF Mono", Menlo, Consolas, "Liberation Mono", "Roboto Mono", monospace;
  /* Display face for the pledge hero + section titles. The source page uses
     Instrument Serif; this approximates it from fonts already on the machine.
     Deliberately NOT a webfont — the perf baseline (no web fonts, no images)
     is a guardrail, and a display face is the easiest place to blow it. */
  --font-display:
    "Instrument Serif", Georgia, "Iowan Old Style", "Palatino Linotype",
    Palatino, "Book Antiqua", "Times New Roman", serif;

  --radius-sm: 4px;
  --radius: 8px;
  --shadow-sm: 0 1px 2px rgba(17, 21, 28, 0.06);
  --shadow: 0 4px 16px rgba(17, 21, 28, 0.1);
}

[data-theme="dark"] {
  --bg: #0d132d;
  --surface: #151a30;
  --surface-2: #141f4d;
  --text: #e8e6e0;
  --text-muted: #9aa4b6;
  --border: #2a3450;
  --border-strong: #3e4a6b;
  --accent: #ffbd00;
  --accent-soft: #33290a;
  /* Same fix as the light-mode --link: the previous amber-adjacent value
     (#ffcb33) sits at ~1.22:1 contrast against --text (#e8e6e0) — both are
     light, so a link with no static underline was nearly indistinguishable
     from body copy. #4d84ff keeps AA against --bg (5.2:1) and separates from
     --text at ~2.82:1. */
  --link: #4d84ff;

  --accent-mark: #ffbd00;
  --accent-rule: #e6a800;

  /* The band goes darker still in dark mode so it stays a distinct figure
     against the already-dark page rather than blending into it. */
  --band-bg: #070d1f;
  --band-text: #ffffff;
  --band-text-muted: #abb4c4;
  --band-accent: #ffbd00;
  --band-hairline: rgba(255, 255, 255, 0.18);

  --hairline: rgba(232, 230, 224, 0.16);

  --stance-positive: #6cc18a;
  --stance-positive-soft: #1d3a28;
  --stance-mixed: #d6a44c;
  --stance-mixed-soft: #3a2e15;
  --stance-negative: #e07a72;
  --stance-negative-soft: #3a1f1c;

  --delivered-delivered: #6cc18a;
  --delivered-delivered-soft: #1d3a28;
  --delivered-partial: #9bb4cc;
  --delivered-partial-soft: #1f2a36;
  --delivered-contested: #d6a44c;
  --delivered-contested-soft: #3a2e15;
  --delivered-shortfall: #e07a72;
  --delivered-shortfall-soft: #3a1f1c;

  --ratepayer-affirmed: #6cc18a;
  --ratepayer-affirmed-soft: #1d3a28;
  --ratepayer-pledge_only: #9bb4cc;
  --ratepayer-pledge_only-soft: #1f2a36;
  --ratepayer-contested: #d6a44c;
  --ratepayer-contested-soft: #3a2e15;

  /* Tariff status + coverage colors — dark overrides (mirror --stance dark). */
  --tariff-approved: #6cc18a;
  --tariff-approved-soft: #1d3a28;
  --tariff-proposed: #d6a44c;
  --tariff-proposed-soft: #3a2e15;
  --tariff-rejected: #e07a72;
  --tariff-rejected-soft: #3a1f1c;
  --tariff-included: #6cc18a;
  --tariff-included-soft: #1d3a28;
  --tariff-partial: #d6a44c;
  --tariff-partial-soft: #3a2e15;
  --tariff-federal: #7eb6e8;
  --tariff-federal-soft: #1f2630;

  --co-meta: #7eb6e8;
  --co-google: #d6b86a;
  --co-microsoft: #6cc18a;
  --co-amazon: #d6a060;
  --co-openai: #b8b8b8;
  --co-anthropic: #d6b08a;
  --co-xai: #888888;
  --co-oracle: #d68a8a;
  --co-wonder-valley: #b48ad8;
  --co-qts: #7ec1cf;
  --co-crusoe: #d6b08a;
  --co-coreweave: #a896d8;
  --co-prologis: #c89a6a;
  --co-sb-energy: #d68ab0;
  --co-brookfield: #a8c47a;

  --theme-jobs: #7eb6e8;
  --theme-tax_revenue: #b48ad8;
  --theme-energy: #d6b86a;
  --theme-water: #7ec1d8;
  --theme-community_grants: #6cc18a;
  --theme-infrastructure: #a3adba;
  --theme-education: #d68aa3;
  --theme-engagement: #8acfb0;
}

/* ==========================================================================
   Reset / base
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

h1 {
  font-size: 1.25rem;
  line-height: 1.2;
}

h2 {
  font-size: 1.75rem;
  line-height: 1.15;
}

h3 {
  font-size: 1.25rem;
}

h4 {
  font-size: 1rem;
  font-family: var(--font-sans);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

a {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover,
a:focus-visible {
  text-decoration-thickness: 2px;
}

button {
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
}

button:focus-visible,
select:focus-visible,
[role="tab"]:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

[hidden] {
  display: none !important;
}

.muted {
  color: var(--text-muted);
  font-style: italic;
}

/* ==========================================================================
   Draft banner — thin strip above the topbar
   ========================================================================== */

/* draft-banner removed v1.16 — last-refresh date moved to topbar sub-heading */

/* ==========================================================================
   Skip link (accessibility)
   ========================================================================== */

.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  background: var(--accent);
  color: #fff;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  z-index: 1000;
  text-decoration: none;
}

.skip-link:focus {
  top: 8px;
}

/* In dark mode --accent is the amber mark color (#ffbd00) — white text on it
   is ~1.68:1, the same failing ratio the palette comment documents for
   amber-on-white and the reason amber is kept out of --accent-mark. This is
   the first thing a keyboard/AT user focuses, so it needs real contrast:
   --band-bg is near-black navy, ~10.9:1 on the amber background. */
[data-theme="dark"] .skip-link {
  color: var(--band-bg);
}

/* ==========================================================================
   Topbar
   ========================================================================== */

/* The header is just the title row + tab bar (v2.1): the pledge landing band
   used to live here too, which pushed the tabs below the fold on load. It now
   renders as the "Overview" tab's content inside <main> instead, so the whole
   header is short enough that every tab is reachable without scrolling. The
   tab bar keeps its own sticky wrapper (.tabbar-sticky below) so it stays
   reachable once a tall view (e.g. Overview itself) scrolls past the header. */
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 12px 20px 8px;
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.topbar-title {
  flex: 1;
  min-width: 0;
}

.topbar-sub {
  margin: 4px 0 0;
  font-size: 0.95rem;
  color: var(--text-muted);
}

.topbar-controls {
  display: flex;
  gap: 8px;
}

#theme-toggle {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  width: 36px;
  height: 36px;
  font-size: 1.1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.tabbar {
  display: flex;
  gap: 0;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 20px;
  overflow-x: auto;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none;
}

/* Sticky wrapper so the tab bar survives the hero scrolling past. The
   background lives here rather than on .tabbar because the sticky element must
   be opaque edge-to-edge, not just under the 1280px content column. */
.tabbar-sticky {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

/* ==========================================================================
   Pledge landing band (v2) — now the "Overview" tab's content (v2.1)
   ==========================================================================
   The site's front door. Everything in it answers one of three questions a
   first-time visitor arrives with: who signed / is it working / what about my
   state. Numbers are rendered from data by renderPledgeHero() — never baked
   into the markup, because the roster is a moving target.

   This used to be a full-bleed header band; it is now a normal .view section
   inside <main>, which already centers content to 1280px and adds 20px side
   padding. .pledge-hero-inner only needs its own vertical rhythm now — no
   horizontal padding or max-width of its own, or the Overview tab would render
   narrower than every other tab. */

.pledge-hero-inner {
  padding: clamp(20px, 3vw, 36px) 0 clamp(20px, 3vw, 32px);
}

/* Letterspaced gold overline with a short rule above it — the source page's
   section-tag motif, which is what makes the type feel like the pledge. */
.pledge-kicker {
  position: relative;
  margin: 0 0 18px;
  padding-top: 16px;
  font-family: var(--font-mono);
  font-size: 0.69rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-mark);
}

.pledge-kicker::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 40px;
  height: 2px;
  background: var(--accent-rule);
}

.pledge-kicker-strong {
  color: var(--text);
  font-weight: 600;
}

.pledge-hero-title {
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
  line-height: 1.08;
  letter-spacing: -0.018em;
  /* Wide enough to break to two lines on a desktop viewport — at 20ch it ran
     to three and pushed the pathway cards under the fold, which is exactly
     the metric this band exists to serve. */
  max-width: 28ch;
  color: var(--text);
}

/* One italic gold accent, as on the source page. It is an em dash here rather
   than a word so the emphasis never lands on a claim. */
.pledge-hero-title em {
  font-style: italic;
  color: var(--accent-mark);
}

.pledge-hero-dek {
  margin: 0 0 22px;
  max-width: 62ch;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--text-muted);
}

/* --- stat quartet ------------------------------------------------------- */

.pledge-stats {
  list-style: none;
  margin: 0 0 4px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0;
  border-top: 2px solid var(--text);
}

.pledge-stat {
  padding: 13px 20px 12px 0;
  border-right: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pledge-stat:last-child {
  border-right: none;
}

.pledge-stat-num {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.9vw, 2.4rem);
  line-height: 1;
  color: var(--text);
  letter-spacing: -0.02em;
}

.pledge-stat-lbl {
  font-size: 0.8rem;
  line-height: 1.35;
  color: var(--text-muted);
}

.pledge-stat-note {
  font-size: 0.72rem;
  color: var(--text-muted);
  opacity: 0.85;
}

/* Stats that deep-link are buttons; the rest are plain <li>. Only the
   interactive ones get affordances. */
.pledge-stat button {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pledge-stat button:hover .pledge-stat-num {
  color: var(--accent-mark);
}

.pledge-stat.is-loading .pledge-stat-num {
  color: var(--text-muted);
}

/* --- pathway cards ------------------------------------------------------ */

.pledge-paths {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}

.pledge-path {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 2px solid var(--accent-rule);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    transform 0.15s ease;
}

.pledge-path:hover {
  border-color: var(--border-strong);
  border-top-color: var(--accent-mark);
  transform: translateY(-1px);
}

.pledge-path-tag {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-mark);
}

.pledge-path-title {
  font-family: var(--font-display);
  font-size: 1.12rem;
  line-height: 1.2;
  color: var(--text);
}

.pledge-path-dek {
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--text-muted);
}

@media (max-width: 600px) {
  .pledge-stats {
    grid-template-columns: repeat(2, 1fr);
  }
  .pledge-stat {
    border-right: none;
    border-bottom: 1px solid var(--hairline);
  }
  .pledge-hero-title {
    max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pledge-path {
    transition: none;
  }
  .pledge-path:hover {
    transform: none;
  }
}

.tabbar::-webkit-scrollbar {
  display: none;
}

.tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 10px 16px;
  color: var(--text-muted);
  font-size: 0.95rem;
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}

.tab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--accent);
}

.tab:hover {
  color: var(--text);
}

/* ==========================================================================
   Main / hero
   ========================================================================== */

main {
  max-width: 1280px;
  margin: 0 auto;
  padding: 16px 20px 32px;
}

.view {
  animation: fadein 180ms ease-out;
}

@keyframes fadein {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero {
  margin: 16px 0 24px;
  max-width: 720px;
}

.eyebrow {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.72rem;
  color: var(--text-muted);
  margin: 0 0 6px;
  font-weight: 600;
}

.hero-title {
  margin: 0 0 8px;
}

.hero-dek {
  margin: 0;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1.5;
}

/* ==========================================================================
   Theme legend
   ========================================================================== */

.legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 12px;
  flex-wrap: wrap;
}

.legend-label {
  font-size: 0.8rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.theme-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.theme-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--text);
}

.theme-chip::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--theme-color, var(--accent));
}

/* ==========================================================================
   Comparison matrix
   ========================================================================== */

.matrix-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  margin-bottom: 24px;
}

.matrix {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.matrix th,
.matrix td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  vertical-align: middle;
}

.matrix th:last-child,
.matrix td:last-child {
  border-right: none;
}

.matrix tbody tr:last-child td {
  border-bottom: none;
}

.matrix thead th {
  background: var(--surface-2);
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  position: sticky;
  top: 0;
  z-index: 1;
}

.matrix .col-company {
  width: 160px;
  font-weight: 600;
  background: var(--surface);
}

.matrix .col-theme-head {
  border-bottom: 3px solid var(--theme-color, var(--accent));
  text-align: center;
  min-width: 88px;
}

.matrix .cell {
  text-align: center;
  cursor: pointer;
  transition: background 100ms ease;
}

.matrix .cell:hover,
.matrix .cell:focus-visible {
  background: var(--accent-soft);
}

.matrix .cell.empty {
  color: var(--text-muted);
  font-style: italic;
  cursor: default;
}

.matrix .cell.empty:hover {
  background: transparent;
}

.matrix .cell.active {
  background: var(--accent-soft);
  font-weight: 600;
}

.matrix .count {
  display: inline-block;
  min-width: 24px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Checkmark glyph used when a cell has exactly one claim. Rendered in the
   same accent color the active-cell highlight uses, slightly larger than
   the digit so the binary "yes, claim recorded" signal reads at a glance. */
.matrix .count.check {
  color: var(--accent);
  font-size: 1.05rem;
  line-height: 1;
}

.company-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.company-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--co-color, var(--accent));
  flex-shrink: 0;
}

.claims-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.claim-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--co-color, var(--accent));
  border-radius: var(--radius);
  padding: 10px 14px;
  box-shadow: var(--shadow-sm);
  font-size: 0.92rem;
}

/* Compact variant — used inside the project detail pane (and anywhere
   claim cards appear as supporting context rather than the headline read).
   Reduces font, padding, and drops the box-shadow so density goes up. */
.claims-list.compact {
  gap: 6px;
}

.claims-list.compact .claim-card {
  padding: 8px 12px;
  font-size: 0.85rem;
  box-shadow: none;
}

.claim-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-bottom: 4px;
  line-height: 1.3;
}

.claim-company {
  font-weight: 600;
  color: var(--text);
}

.claim-theme {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 7px;
  background: var(--surface-2);
  border-radius: 999px;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  line-height: 1.6;
}

.claim-theme::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--theme-color, var(--accent));
}

.claim-quote {
  font-family: var(--font-serif);
  font-size: 0.95rem;
  line-height: 1.4;
  margin: 0 0 4px;
  color: var(--text);
}

.claim-quote::before {
  content: "\201C";
  margin-right: 1px;
  color: var(--text-muted);
}

.claim-quote::after {
  content: "\201D";
  margin-left: 1px;
  color: var(--text-muted);
}

.claims-list.compact .claim-quote {
  font-size: 0.88rem;
  line-height: 1.35;
}

.claim-source {
  font-size: 0.72rem;
  margin: 0;
}

.claims-list.compact .claim-source {
  font-size: 0.7rem;
}

.claim-source a {
  color: var(--text-muted);
}

.claim-source a:hover {
  color: var(--link);
}

.claim-metric {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text);
}

/* Delivered-vs-promised panel attached to claim cards (v1.13). The panel
   uses CSS-var-driven hues so dark mode and per-status palettes stay in
   sync with the existing stance palette. */
.claim-delivered {
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border-left: 3px solid currentColor;
  background: var(--surface-2);
  font-size: 0.78rem;
  color: var(--text);
}

.claims-list.compact .claim-delivered {
  font-size: 0.74rem;
  padding: 6px 8px;
  margin-top: 8px;
}

.claim-delivered.delivered-delivered {
  color: var(--delivered-delivered);
  background: var(--delivered-delivered-soft);
}
.claim-delivered.delivered-partial {
  color: var(--delivered-partial);
  background: var(--delivered-partial-soft);
}
.claim-delivered.delivered-contested {
  color: var(--delivered-contested);
  background: var(--delivered-contested-soft);
}
.claim-delivered.delivered-shortfall {
  color: var(--delivered-shortfall);
  background: var(--delivered-shortfall-soft);
}

.delivered-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.delivered-badge {
  display: inline-block;
  padding: 1px 8px;
  background: currentColor;
  color: var(--surface);
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  /* Dark-mode bump: when currentColor is a light token (delivered/positive
     etc), the contrast against --surface needs the surface to be the *light*
     surface variant; matching what the soft backgrounds already do. */
}

[data-theme="dark"] .delivered-badge {
  color: var(--bg);
}

.delivered-label {
  font-size: 0.7rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.delivered-date {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

.delivered-summary {
  margin: 0;
  color: var(--text);
  line-height: 1.4;
}

.delivered-source {
  margin: 6px 0 0;
  font-size: 0.7rem;
  color: var(--text-muted);
}

.delivered-source a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: currentColor;
}

.delivered-source a:hover {
  color: var(--link);
}

/* ==========================================================================
   Explorer view
   ========================================================================== */

.explorer-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: end;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 16px;
}

.filter {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.85rem;
}

.filter span {
  color: var(--text-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.filter select {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  min-width: 160px;
}

.btn-ghost {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 12px;
  font-size: 0.85rem;
}

.btn-ghost:hover {
  background: var(--accent-soft);
}

.explorer-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(280px, 1fr);
  gap: 16px;
  min-height: 480px;
}

.map {
  width: 100%;
  height: 520px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  position: relative;
}

.map-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-style: italic;
}

/* Map legend (Leaflet control) */
.map-legend {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 12px;
  font-size: 0.85rem;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.map-legend h4 {
  margin: 0 0 8px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
}

.legend-content {
  color: var(--text);
}

.legend-section {
  margin-bottom: 8px;
}

.legend-section strong {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 6px 0 4px;
  font-weight: 600;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
  color: var(--text);
}

.legend-dot {
  display: inline-block;
  background: var(--accent);
  border-radius: 50%;
  flex-shrink: 0;
}

.legend-item-opacity-40 {
  color: var(--accent);
  opacity: 0.4;
  font-size: 1.2rem;
}

.legend-item-opacity-65 {
  color: var(--accent);
  opacity: 0.65;
  font-size: 1.2rem;
}

.legend-item-opacity-90 {
  color: var(--accent);
  opacity: 0.9;
  font-size: 1.2rem;
}

.explorer-list {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  max-height: 520px;
  overflow-y: auto;
}

.list-meta {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin: 0 0 8px;
}

.project-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.project-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--co-color, var(--accent));
  border-radius: var(--radius);
  padding: 10px 12px;
  cursor: pointer;
  transition: background 100ms ease;
}

.project-card:hover,
.project-card:focus-within {
  background: var(--accent-soft);
}

.project-card.active {
  background: var(--accent-soft);
}

.project-name {
  font-weight: 600;
  margin: 0 0 2px;
  font-size: 0.95rem;
}

.project-meta {
  font-size: 0.78rem;
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
}

.project-stance-row {
  display: inline-flex;
  gap: 4px;
  margin-top: 4px;
}

.stance-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.stance-dot.positive {
  background: var(--stance-positive);
}

.stance-dot.mixed {
  background: var(--stance-mixed);
}

.stance-dot.negative {
  background: var(--stance-negative);
}

/* ==========================================================================
   Comparison view: matrix help line + company-detail pop-out
   ========================================================================== */

.matrix-help {
  margin: 0 0 12px;
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.45;
  max-width: 720px;
}

.company-detail {
  margin-top: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 4px solid var(--co-color, var(--accent));
  border-radius: var(--radius);
  padding: 20px 24px;
  position: relative;
  box-shadow: var(--shadow);
  animation: fadein 180ms ease-out;
  max-width: 760px;
}

.company-summary {
  margin: 0 0 16px;
  font-family: var(--font-serif);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
}

.company-summary.muted {
  color: var(--text-muted);
  font-style: italic;
  font-size: 0.95rem;
}

.detail-cta {
  margin-top: 16px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* ==========================================================================
   Project detail — At-a-glance per-theme summary block
   ========================================================================== */

.at-a-glance {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px dashed var(--border);
}

.at-a-glance h4 {
  margin: 0 0 4px;
}

.at-a-glance-sub {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 0.78rem;
  line-height: 1.4;
}

.at-a-glance-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.at-a-glance-row {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  align-items: baseline;
  font-size: 0.88rem;
}

.at-a-glance-row:last-child {
  border-bottom: none;
}

.at-a-glance-theme {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  font-weight: 600;
}

.at-a-glance-theme::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--theme-color, var(--accent));
  flex-shrink: 0;
}

.at-a-glance-text {
  color: var(--text);
  line-height: 1.4;
}

.at-a-glance-text.curator-override::after {
  content: "";
}

@media (max-width: 640px) {
  .at-a-glance-row {
    grid-template-columns: 1fr;
    gap: 2px;
    padding: 8px 0;
  }
}

/* ==========================================================================
   Project detail
   ========================================================================== */

.project-detail,
.moratorium-detail {
  margin-top: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 4px solid var(--co-color, var(--accent));
  border-radius: var(--radius);
  padding: 20px 24px;
  position: relative;
  box-shadow: var(--shadow);
}

.detail-close {
  position: absolute;
  top: 8px;
  right: 8px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  width: 32px;
  height: 32px;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--text-muted);
}

.detail-close:hover {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}

.detail-header {
  margin-bottom: 8px;
  padding-right: 36px;
}

.detail-sub {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin: 4px 0 0;
}

/* Detail-panel tab strip — same visual language as the top-level tabs but
   one tier smaller. Per CLAUDE.md "[hidden] trap": .dpane[hidden] needs an
   explicit display:none rule (we have a global one in the reset) plus the
   transition is intentionally instant — content swaps, no fade competing
   with the panel's own fade-in. */
.detail-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin: 12px 0 16px;
}

.dtab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 14px 9px;
  margin-bottom: -1px;
  color: var(--text-muted);
  font-size: 0.88rem;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.dtab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--accent);
}

.dtab:hover {
  color: var(--text);
}

.dtab-count {
  display: inline-block;
  background: var(--surface-2);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 0 7px;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.6;
}

.dtab[aria-selected="true"] .dtab-count {
  background: var(--accent-soft);
  color: var(--text);
}

.dpane {
  animation: fadein 150ms ease-out;
}

.kv {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 6px 16px;
  margin: 0;
  font-size: 0.9rem;
}

.kv dt {
  color: var(--text-muted);
  font-weight: 500;
}

.kv dd {
  margin: 0;
  color: var(--text);
}

.kv dd.muted-cell {
  color: var(--text-muted);
  font-style: italic;
}

.response-help {
  margin: 0 0 12px;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.45;
}

.response-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.response-card {
  border-left: 4px solid var(--stance-color, var(--text-muted));
  background: var(--stance-soft, var(--surface-2));
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 0.9rem;
}

.response-card.positive {
  --stance-color: var(--stance-positive);
  --stance-soft: var(--stance-positive-soft);
}

.response-card.mixed {
  --stance-color: var(--stance-mixed);
  --stance-soft: var(--stance-mixed-soft);
}

.response-card.negative {
  --stance-color: var(--stance-negative);
  --stance-soft: var(--stance-negative-soft);
}

.response-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.response-stance {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--stance-color, var(--text));
}

.response-summary {
  margin: 0 0 6px;
  color: var(--text);
  line-height: 1.4;
}

.response-source {
  font-size: 0.8rem;
}

.response-source a {
  color: var(--text-muted);
}

.badge-single-source {
  display: inline-block;
  padding: 0 6px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  max-width: 1280px;
  margin: 24px auto 0;
  padding: 16px 20px 32px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.85rem;
}

.site-footer p {
  margin: 0;
}

/* ==========================================================================
   Toast
   ========================================================================== */

#toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: var(--bg);
  padding: 10px 16px;
  border-radius: var(--radius);
  font-size: 0.9rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
  z-index: 100;
}

#toast.visible {
  opacity: 1;
}

/* ==========================================================================
   Responsive: tablet
   ========================================================================== */

@media (max-width: 960px) {
  .explorer-layout {
    grid-template-columns: 1fr;
  }

  .map {
    height: 360px;
  }

  .explorer-list {
    max-height: 360px;
  }
}

/* ==========================================================================
   Responsive: mobile
   ========================================================================== */

@media (max-width: 640px) {
  main {
    padding: 12px 14px 32px;
  }

  .topbar-inner {
    padding: 10px 14px 6px;
  }

  .tabbar {
    padding: 0 14px;
  }

  .tab {
    padding: 8px 12px;
    font-size: 0.9rem;
  }

  h2 {
    font-size: 1.4rem;
  }

  .hero {
    margin: 8px 0 16px;
  }

  .matrix {
    font-size: 0.78rem;
  }

  .matrix th,
  .matrix td {
    padding: 8px 6px;
  }

  .matrix .col-company {
    width: 110px;
  }

  .matrix .col-theme-head {
    min-width: 56px;
  }

  .kv {
    grid-template-columns: 120px 1fr;
  }

  .filter select {
    min-width: 0;
    width: 100%;
  }

  .explorer-filters .filter {
    flex: 1 1 calc(50% - 6px);
  }
}

/* ==========================================================================
   Ratepayer Protection Pledge view (v1.15)
   ========================================================================== */

/* Stat tiles */
.rp-stats {
  list-style: none;
  margin: 0 0 1.75rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.85rem;
}

@media (max-width: 800px) {
  .rp-stats {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
  }
}

@media (max-width: 560px) {
  .rp-stats {
    grid-template-columns: 1fr;
  }
}

.rp-stat {
  --rp-color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--rp-color);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.rp-stat-value {
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1;
  color: var(--rp-color);
}

.rp-stat-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.3;
}

.rp-stat-breakdown {
  font-size: 0.7rem;
  color: var(--text-muted);
  opacity: 0.75;
  line-height: 1.3;
  margin-top: 0.1rem;
}

/* ================= MORATORIUM SUMMARY CHARTS ================= */
/* Pure CSS/DOM charts (no library). Colors are CSS custom properties so they
   re-theme automatically on the dark swap. */
.mor-charts {
  margin: 0 0 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.mor-chart {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1rem 1.15rem 0.85rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}

.mor-chart-title {
  font-family: var(--font-serif);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.85rem;
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.mor-chart-sub {
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--text-muted);
}

.mor-chart-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 720px) {
  .mor-chart-row {
    grid-template-columns: 1fr;
  }
}

/* ---- Legend (shared) ---- */
.mor-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin-top: 0.8rem;
}

.mor-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  color: var(--text-muted);
}

.mor-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex-shrink: 0;
}

/* ---- Timeline (stacked columns by quarter) ---- */
.mtl-plot {
  display: flex;
  align-items: flex-end;
  /* Gap BETWEEN quarters is wider than the gap within a pair, so the two
     parallel bars read as one group. */
  gap: 0.4rem;
  min-height: calc(var(--plot-h, 150px) + 34px);
  padding-top: 4px;
  /* Two bars per quarter doubles the width, so narrow viewports overflow. Keep
     the scrollbar VISIBLE (a hidden one silently clips data — see the auto-scroll
     in renderMoratoriumCharts, which parks the view on the most recent quarters). */
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.mtl-plot::-webkit-scrollbar {
  height: 6px;
}

.mtl-plot::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 999px;
}

.mtl-col {
  flex: 1 1 0;
  min-width: 26px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
}

@media (max-width: 560px) {
  .mtl-plot {
    gap: 0.25rem;
  }
  .mtl-col {
    min-width: 20px;
  }
  .mtl-label {
    font-size: 0.58rem;
  }
}

.mtl-total {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  font-feature-settings: "tnum" 1;
  min-height: 0.9rem;
  line-height: 1;
  margin-bottom: 3px;
}

.mtl-bar {
  width: 68%;
  min-width: 14px;
  display: flex;
  flex-direction: column-reverse; /* first child (enacted) sits at the base */
  border-radius: 3px 3px 0 0;
  overflow: hidden;
}

.mtl-seg {
  width: 100%;
  transition: height 200ms ease;
}

/* Chart header: title on the left, level toggle on the right. */
.mor-chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.85rem;
}

.mor-chart-head .mor-chart-title {
  margin-bottom: 0;
}

/* Segmented control — jurisdiction level is a FILTER, not a visual encoding. */
.mor-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
}

.mor-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.4;
  padding: 0.18rem 0.6rem;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms ease, color 120ms ease;
}

.mor-toggle-btn:hover {
  color: var(--text);
}

.mor-toggle-btn.is-active {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.mor-toggle-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.mor-toggle-count {
  font-weight: 500;
  opacity: 0.65;
  font-feature-settings: "tnum" 1;
}

.mtl-label {
  font-size: 0.64rem;
  color: var(--text-muted);
  margin-top: 5px;
  white-space: nowrap;
  font-feature-settings: "tnum" 1;
}

/* ---- Horizontal bars (concerns, jurisdiction) ---- */
.mor-hbar-set {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.mhb-row {
  display: grid;
  grid-template-columns: 8.5rem 1fr 2rem;
  align-items: center;
  gap: 0.55rem;
}

.mhb-label {
  font-size: 0.76rem;
  color: var(--text);
  text-align: right;
  line-height: 1.2;
}

.mhb-track {
  display: flex;
  height: 16px;
  background: var(--surface-2);
  border-radius: 4px;
  overflow: hidden;
}

.mhb-fill {
  height: 100%;
  min-width: 2px;
  transition: width 200ms ease;
}

.mhb-val {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  text-align: left;
  font-feature-settings: "tnum" 1;
}

@media (max-width: 460px) {
  .mhb-row {
    grid-template-columns: 6.5rem 1fr 1.6rem;
    gap: 0.4rem;
  }
  .mhb-label {
    font-size: 0.7rem;
  }
}

@media (max-width: 720px) {
}

/* ==========================================================================
   SECTION LANGUAGE — one heading treatment for every tab.

   Before this each view had invented its own: .summary-section (no rules at
   all — it inherited the global serif h3), .agg-section-heading (1.05rem
   sans), .hot-rail-title (1rem sans), .matrix-help (720px, no heading).
   Six tabs, five heading scales. The Ratepayer view's shape won — display
   serif at 400 weight, a muted 64ch dek — and the legacy class names are
   aliased onto it here rather than renamed, so no JS selector or test id
   has to move.

   Adding a new section? Use the .acc accordion below -- every section on the
   dashboard is one now. (.rp-section itself is gone: its last holder, the
   non-signatory block, became a sub-tab panel.) Don't add a sixth heading
   rule.
   ========================================================================== */

.hot-rail-title,
.acc-title {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  /* The display face carries weight optically; 600 makes it look printed
     twice. Same 400 the pledge band and .rp-subhead already use. */
  font-weight: 400;
  font-size: 1.28rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
  color: var(--text);
  /* The global h4 rule uppercases + switches to sans; any heading in this
     family that happens to be an h4 has to opt back out. */
  text-transform: none;
}

.rp-section-sub,
.agg-section-sub,
.hot-rail-sub,
.matrix-help,
.acc-sub {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: var(--text-muted);
  max-width: 64ch;
  line-height: 1.45;
}

/* ==========================================================================
   ACCORDION — the one collapsible-section component.

   Replaces three unrelated <details> skins that had grown up separately:
   .directory-section (a filled button-looking bar), .china-context-section
   (an accent-left callout) and .rp-roster-details (a bare bold summary).
   All three now render as this.

   Structure:
     <details class="acc" [open]>
       <summary><h3 class="acc-title">…</h3><span class="acc-count">…</span></summary>
       <div class="acc-body">…</div>
     </details>

   The heading lives INSIDE the summary so the section still appears in a
   screen reader's heading list; <details>/<summary> supplies the expand
   semantics natively, so no aria-expanded bookkeeping is needed.

   Don't put buttons in the summary — a click inside it toggles the panel.
   Export toolbars go in .acc-body. (The old .directory-section shipped its
   CSV/PDF buttons inside the summary and collapsed the table out from under
   the reader on every export click.)
   ========================================================================== */

.acc {
  margin: 0 0 1.5rem;
  border-top: 1px solid var(--border);
}

.acc > summary {
  display: flex;
  align-items: baseline;
  /* The count chip can carry an as-of date ("302 signatories · as of Jul 25,
     2026"), which is too wide to sit beside a title on a phone. Let it wrap to
     its own line rather than overflow or squeeze the heading. */
  flex-wrap: wrap;
  gap: 12px;
  padding: 0.9rem 0 0.75rem;
  cursor: pointer;
  user-select: none;
  /* Suppress the native disclosure triangle in both engines; .acc-chevron
     replaces it so the marker can sit on the right and animate. */
  list-style: none;
}

.acc > summary::-webkit-details-marker {
  display: none;
}

.acc > summary:focus-visible {
  outline: 2px solid var(--accent-mark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.acc > summary:hover .acc-title {
  color: var(--accent-mark);
}

.acc-title {
  /* Typography comes from the section-language rule above. */
  flex: 1 1 auto;
  min-width: 0;
}

/* Belt-and-braces against the <details>-collapse trap: an author `display:`
   rule on a direct child of <details> outranks the UA rule that hides content
   while closed, and a closed panel that keeps painting its body is a silent,
   total failure of the component. Nothing here sets `display` on .acc-body
   today — this makes sure nothing can. */
.acc:not([open]) > :not(summary) {
  display: none;
}

/* Count of what's inside, so the reader can judge a collapsed panel without
   opening it. Rendered by setAccCount() in app.js; stays empty (and hidden)
   until the data it counts has loaded. */
.acc-count {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-mark);
  white-space: nowrap;
}

/* Fires only when the count is genuinely unloaded -- a zero renders "0". */
.acc-count:empty {
  display: none;
}

.acc-chevron {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-left: 2px;
  border-right: 1.5px solid var(--text-muted);
  border-bottom: 1.5px solid var(--text-muted);
  transform: translateY(-3px) rotate(45deg);
  transition: transform 0.18s ease;
}

.acc[open] > summary .acc-chevron {
  transform: translateY(1px) rotate(225deg);
}

.acc-body {
  padding-bottom: 0.5rem;
  animation: acc-reveal 0.18s ease;
}

@keyframes acc-reveal {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .acc-chevron,
  .acc-body {
    transition: none;
    animation: none;
  }
}

/* ==========================================================================
   SUB-TABS — for sections that are ALTERNATIVES, not a sequence.

   Used in exactly two places, and the distinction is the whole rule:

     Ratepayer "Tracked sites" — Assessed / Awaiting / Before the pledge /
       Non-signatory are one list of sites bucketed four ways. You read one.
     Aggregate — By company / By signatory category / By state are three
       rollups of the same numbers. You read one.

   Everything else on the dashboard stays an .acc, because those sections are
   read together (the moratorium charts AND the directory) and sub-tabs would
   hide content from Ctrl-F and from the PDF exports, which walk the DOM.

   Don't add a sub-tab group to a tab whose sections are complementary. The
   test is: would a reader ever want two of these on screen at once? If yes,
   accordion.
   ========================================================================== */

.subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0 0 1.1rem;
  border-bottom: 1px solid var(--border);
}

.subtab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.88rem;
  cursor: pointer;
  white-space: nowrap;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}

.subtab:hover {
  color: var(--text);
}

.subtab:focus-visible {
  outline: 2px solid var(--accent-mark);
  outline-offset: -2px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.subtab[aria-selected="true"] {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--accent-mark);
}

.subtab-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 1px 7px;
}

.subtab[aria-selected="true"] .subtab-count {
  color: var(--accent-mark);
}

/* See .acc-count:empty -- a zero cohort renders "0", not blank. */
.subtab-count:empty {
  display: none;
}

/* 44px touch floor, coarse pointers only. At the desktop scale a sub-tab is
   ~37px tall (8px padding + 0.88rem text), which is fine for a mouse and below
   the floor for a thumb. Scoping to `pointer: coarse` keeps the desktop strip
   at its natural chip scale instead of bloating seven tabs into CTAs. */
@media (pointer: coarse) {
  .subtab {
    min-height: 44px;
    padding-top: 10px;
    padding-bottom: 10px;
  }
}

/* Panels are toggled with the `hidden` attribute. The global [hidden] rule
   carries !important, so this display value can't resurrect a hidden pane —
   see CLAUDE.md > "The [hidden] trap". */
.subtab-panel {
  display: block;
  animation: acc-reveal 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
  .subtab-panel {
    animation: none;
  }
}

/* --- Band variant: the pledge itself ------------------------------------
   The five commitments sit in the dark band (.rp-band). Collapsing it means
   the summary row has to read on the band's own background, not the page's,
   so the hairline and marker flip to the band palette. */

.acc--band {
  border-top: none;
}

.acc--band > summary {
  padding: clamp(20px, 3vw, 32px) clamp(18px, 3vw, 36px);
  align-items: center;
}

.acc--band > summary:hover .acc-title,
.acc--band > summary:hover .rp-band-title {
  color: var(--band-accent);
}

/* The kicker is a <span> nested in the <h3> (see index.html for why), so it
   needs an explicit block to keep sitting above the title. */
.acc--band .rp-band-kicker {
  display: block;
  margin-bottom: 10px;
}

.acc--band .rp-band-title {
  margin: 0;
  max-width: 30ch;
}

.acc--band .acc-chevron {
  border-right-color: var(--band-accent);
  border-bottom-color: var(--band-accent);
}

.acc--band .acc-count {
  color: var(--band-accent);
}

.acc--band > summary:focus-visible {
  outline-color: var(--band-accent);
}

/* The band's own padding lives on the summary and this body, so the
   collapsed state is a single clean bar. */
.acc--band > .acc-body {
  padding: 0 clamp(18px, 3vw, 36px) clamp(20px, 3vw, 32px);
}

/* Signatory roster */
.rp-roster {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

@media (max-width: 480px) {
  .rp-roster { grid-template-columns: 1fr; }
}

/* Scorecard toolbar: legend chips + export button on the same row */
.rp-scorecard-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

/* Status legend — renderRatepayerLegend() only emits chips for statuses
   actually present in the cohort (honest-absence principle). Chip color
   comes from --rp-color, set per-status in JS. */
.rp-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.rp-legend-chip {
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  color: var(--rp-color);
  background: color-mix(in srgb, var(--rp-color) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--rp-color) 45%, transparent);
  white-space: nowrap;
}

/* Scorecard — multi-column so 11 sites don't become a tall single stack.
   Cards hold short content, so a ~340px min keeps two (often three) per row
   on desktop and collapses to one column on mobile. */
.rp-scorecard {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.7rem;
  align-items: start;
}

/* Expanded card spans all columns so it fills horizontal space first */
.rp-card:has(.rp-card-details[open]) {
  grid-column: 1 / -1;
}

.rp-card {
  --co-color: var(--accent);
  --rp-color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--co-color);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  box-shadow: var(--shadow-sm);
}

.rp-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
}

.rp-card-title {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.rp-card-company {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--co-color);
}

.rp-card-name {
  font-size: 0.88rem;
  font-weight: 650;
  line-height: 1.3;
}

.rp-card-loc {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.rp-card-dates {
  font-size: 0.72rem;
  color: var(--text-muted);
  opacity: 0.8;
}

/* Claim-basis badge + conflict flag — makes "individual vs company-wide"
   and "disputed by an independent report" legible without expanding the card. */
.rp-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.1rem 0;
}

.rp-basis {
  display: inline-flex;
  align-items: center;
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.08rem 0.5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  line-height: 1.3;
}

.rp-basis--individual {
  color: var(--ratepayer-affirmed);
  background: var(--ratepayer-affirmed-soft);
  border-color: color-mix(in srgb, var(--ratepayer-affirmed) 30%, transparent);
}

.rp-basis--company-wide {
  color: var(--ratepayer-pledge_only);
  background: var(--ratepayer-pledge_only-soft);
  border-color: color-mix(in srgb, var(--ratepayer-pledge_only) 30%, transparent);
}

.rp-conflict-flag {
  display: inline-flex;
  align-items: center;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 0.08rem 0.5rem;
  border-radius: 999px;
  color: var(--ratepayer-contested);
  background: var(--ratepayer-contested-soft);
  border: 1px solid color-mix(in srgb, var(--ratepayer-contested) 35%, transparent);
}

/* Conflicting-reports block inside an expanded card */
.rp-conflicts {
  margin: 0.75rem 0 0.5rem;
  border: 1px solid color-mix(in srgb, var(--ratepayer-contested) 30%, var(--border));
  border-left: 3px solid var(--ratepayer-contested);
  border-radius: 8px;
  background: color-mix(in srgb, var(--ratepayer-contested-soft) 55%, var(--surface));
  padding: 0.6rem 0.8rem;
}

.rp-conflicts-head {
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--ratepayer-contested);
  margin-bottom: 0.5rem;
  line-height: 1.35;
}

.rp-conflicts-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.rp-conflict-summary {
  margin: 0 0 0.25rem;
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.4;
}

.rp-conflict-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  font-size: 0.7rem;
  color: var(--text-muted);
}

.rp-conflict-who {
  font-weight: 600;
  text-transform: capitalize;
}

.rp-conflict-single {
  color: var(--ratepayer-contested);
  font-style: italic;
}

.rp-conflict-meta a {
  color: var(--accent);
  font-weight: 600;
}

/* Pre-pledge section — compact one-line rows, not full scorecards */
.rp-pre-pledge-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.rp-pre-card {
  --co-color: var(--accent);
  display: grid;
  grid-template-columns: 9rem 1fr 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.75rem;
  align-items: baseline;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--co-color);
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem;
  opacity: 0.85;
}

.rp-pre-company {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--co-color);
  grid-column: 1;
  grid-row: 1;
}

.rp-pre-name {
  font-size: 0.82rem;
  font-weight: 600;
  grid-column: 2;
  grid-row: 1;
}

.rp-pre-loc {
  font-size: 0.75rem;
  color: var(--text-muted);
  grid-column: 3;
  grid-row: 1;
}

.rp-pre-dates {
  font-size: 0.72rem;
  color: var(--text-muted);
  opacity: 0.8;
  grid-column: 2 / -1;
  grid-row: 2;
}

@media (max-width: 640px) {
  .rp-pre-card {
    grid-template-columns: 1fr;
    grid-template-rows: repeat(4, auto);
  }
  .rp-pre-company { grid-column: 1; grid-row: 1; }
  .rp-pre-name    { grid-column: 1; grid-row: 2; }
  .rp-pre-loc     { grid-column: 1; grid-row: 3; }
  .rp-pre-dates   { grid-column: 1; grid-row: 4; }
}

/* Collapsible card */
.rp-card-details {
  /* reset browser default triangle marker */
}
.rp-card-details > summary {
  list-style: none;
  cursor: pointer;
}
.rp-card-details > summary::-webkit-details-marker { display: none; }

.rp-card-body {
  padding-top: 0.6rem;
}

/* X/5 met pill — fixed width so all pills align regardless of digit */
.rp-met-pill {
  flex: none;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 0.2rem 0;
  border-radius: 999px;
  white-space: nowrap;
  min-width: 4.2rem;
  text-align: center;
}

.rp-met-pill--met {
  color: var(--ratepayer-affirmed);
  background: color-mix(in srgb, var(--ratepayer-affirmed) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ratepayer-affirmed) 45%, transparent);
}

.rp-met-pill--partial {
  color: var(--ratepayer-pledge_only);
  background: color-mix(in srgb, var(--ratepayer-pledge_only) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ratepayer-pledge_only) 45%, transparent);
}

.rp-met-pill--low {
  color: var(--ratepayer-contested);
  background: color-mix(in srgb, var(--ratepayer-contested) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ratepayer-contested) 45%, transparent);
}

.rp-card-summary {
  margin: 0.7rem 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text);
}

.rp-principles {
  list-style: none;
  margin: 0.65rem 0 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.pp-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.35rem 0.6rem;
  border-left: 3px solid;
  cursor: default;
}

.pp-row + .pp-row {
  border-top: 1px solid var(--border);
}

.pp-row-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  min-width: 0;
}

.pp-row-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
}

.pp-row-note {
  font-size: 0.76rem;
  color: var(--text);
  line-height: 1.45;
}

.pp-row-status {
  font-size: 0.7rem;
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
  padding-top: 0.05rem;
  display: flex;
  align-items: center;
  gap: 0.2rem;
}

.pp-row-src {
  font-size: 0.72rem;
  font-weight: 400;
  color: inherit;
  opacity: 0.7;
  text-decoration: none;
  line-height: 1;
}
.pp-row-src:hover {
  opacity: 1;
  text-decoration: underline;
}

.pp-row--met {
  border-left-color: var(--ratepayer-affirmed);
  background: color-mix(in srgb, var(--ratepayer-affirmed) 6%, transparent);
}
.pp-row--met .pp-row-status { color: var(--ratepayer-affirmed); }

.pp-row--partial {
  border-left-color: var(--ratepayer-pledge_only);
  background: color-mix(in srgb, var(--ratepayer-pledge_only) 6%, transparent);
}
.pp-row--partial .pp-row-status { color: var(--ratepayer-pledge_only); }

.pp-row--not_met {
  border-left-color: var(--ratepayer-contested);
  background: color-mix(in srgb, var(--ratepayer-contested) 6%, transparent);
}
.pp-row--not_met .pp-row-status { color: var(--ratepayer-contested); }

.pp-row--unknown {
  border-left-color: var(--border);
  background: transparent;
}
.pp-row--unknown .pp-row-status { color: var(--text-muted); }

/* Always-visible sources footer on every ratepayer site card (v1.17 fix) */
.rp-card-sources {
  margin-top: 0.7rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--border);
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-muted);
}
.rp-card-sources .rp-sources-label {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
  margin-right: 0.3rem;
}
.rp-card-sources a {
  color: var(--accent);
  text-decoration: none;
}
.rp-card-sources a:hover {
  text-decoration: underline;
}
.rp-card-sources .rp-src-sep {
  color: var(--border-strong, var(--text-muted));
}
/* The pre-pledge / unassessed card is a grid; let the sources span full width */
.rp-pre-card .rp-card-sources {
  grid-column: 1 / -1;
  margin-top: 0.5rem;
}

/* Per-claim audit trail (v1.20): one row per claim tied to the site, each with
   its own source link. Sits above the project-level "Sources:" footer so every
   claim is individually traceable. */
.rp-card-claims {
  margin-top: 0.7rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--border);
}
.rp-card-claims .rp-claims-label {
  display: block;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-bottom: 0.45rem;
}
.rp-claims-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.32rem;
}
.rp-claim-src {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  font-size: 0.8rem;
  line-height: 1.45;
}
.rp-claim-theme {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 0 7px;
  background: var(--surface-2);
  border-radius: 999px;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  line-height: 1.7;
}
.rp-claim-theme::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--theme-color, var(--text-muted));
}
.rp-claim-link {
  color: var(--accent);
  text-decoration: none;
}
.rp-claim-link:hover {
  text-decoration: underline;
}
.rp-claim-date {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
}
.rp-claim-flag {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--ratepayer-affirmed, var(--accent));
  white-space: nowrap;
}
/* In the pre-pledge / unassessed grid card, span the full row. */
.rp-pre-card .rp-card-claims {
  grid-column: 1 / -1;
}

.rp-footnote {
  margin: 1.5rem 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
  max-width: 70ch;
  line-height: 1.45;
}

/* ── Ratepayer: tablet ──────────────────────────────────────────────── */
@media (max-width: 900px) {
  .rp-scorecard {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }
}

/* ── Ratepayer: mobile ──────────────────────────────────────────────── */
@media (max-width: 560px) {
  /* Single column, full-width cards */
  .rp-scorecard {
    grid-template-columns: 1fr;
  }

  /* Stack badge under the title */
  .rp-card-head {
    flex-direction: column;
    gap: 0.5rem;
  }
}

/* ==========================================================================
   Summary stats bar (v1.18 — ported), matrix CSV toolbar,
   Recently-Contested rail, theme-filter chips
   ========================================================================== */

.summary-stats {
  max-width: 1280px;
  margin: 0 auto;
  padding: 4px 20px 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 18px 28px;
  align-items: baseline;
  border-bottom: 1px solid var(--border);
  font-feature-settings: "tnum" 1, "lnum" 1;
}

.stat-group {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}

.stat-num {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}

.stat-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  text-transform: lowercase;
  letter-spacing: 0.01em;
}

.stance-breakdown {
  font-size: 0.74rem;
  color: var(--text-muted);
  margin-left: 4px;
}

.stance-breakdown .stance-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin: 0 3px 0 8px;
  transform: translateY(-1px);
}

.stance-breakdown .stance-dot.positive {
  background: var(--stance-positive);
}

.stance-breakdown .stance-dot.mixed {
  background: var(--stance-mixed);
}

.stance-breakdown .stance-dot.negative {
  background: var(--stance-negative);
}

/* Matrix CSV toolbar */
.matrix-toolbar {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin: 8px 0 12px;
}

.matrix-toolbar .matrix-help {
  flex: 1;
  margin: 0;
}

.matrix-csv {
  white-space: nowrap;
  flex-shrink: 0;
}

/* Recently-Contested rail */
.hot-rail {
  margin-bottom: 20px;
}

.hot-rail-head {
  margin-bottom: 10px;
}

.hot-rail-title::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  background: var(--stance-negative);
  border-radius: 50%;
  margin-right: 8px;
  transform: translateY(-2px);
}

.hot-rail-sub {
  margin: 0;
}

.hot-rail-list {
  list-style: none;
  margin: 0;
  padding: 0 0 4px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}

.hot-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--co-color, var(--accent));
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: background 120ms ease, transform 120ms ease;
}

.hot-card:hover,
.hot-card:focus-visible {
  background: var(--surface-2);
  outline: none;
}

.hot-card:focus-visible {
  box-shadow: 0 0 0 2px var(--accent);
}

.hot-card-eyebrow {
  margin: 0;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.hot-card-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
}

.hot-card-loc {
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.hot-card-hint {
  margin: 6px 0 0;
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.4;
}

.hot-card-cta {
  margin: 8px 0 0;
  font-size: 0.78rem;
  color: var(--link);
  align-self: flex-end;
}

/* Theme-filter chips */
.theme-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.theme-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--text);
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.theme-filter-chip:hover {
  background: var(--surface-2);
}

.theme-filter-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.theme-filter-chip.is-active {
  background: var(--accent-soft);
  border-color: var(--theme-color, var(--accent));
  color: var(--text);
}

.theme-filter-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--theme-color, var(--accent));
}

@media (max-width: 640px) {
  .summary-stats {
    padding: 4px 14px 8px;
    gap: 12px 20px;
  }
  .stat-num {
    font-size: 1rem;
  }
  .stat-label {
    font-size: 0.72rem;
  }
  .stance-breakdown {
    display: none;
  }
  .matrix-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .matrix-csv {
    align-self: flex-start;
  }
}

/* ==========================================================================
   Aggregate view
   ========================================================================== */

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.agg-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  background: var(--surface);
}

.agg-table th {
  background: var(--surface-2, var(--surface));
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.55rem 0.75rem;
  border-bottom: 2px solid var(--border);
  white-space: nowrap;
  text-align: left;
}

.agg-table th.num,
.agg-table td.num {
  text-align: right;
}

.agg-table td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  white-space: nowrap;
  color: var(--text);
}

.agg-table tbody tr:last-child td {
  border-bottom: none;
}

.agg-table tfoot td {
  border-top: 2px solid var(--border);
  border-bottom: none;
  background: var(--surface-2, var(--surface));
  padding: 0.55rem 0.75rem;
  white-space: nowrap;
}

.agg-table tbody tr:hover td {
  background: var(--hover-bg, rgba(0,0,0,0.03));
}

.agg-table .name-col {
  text-align: left;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.co-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.agg-status-pills {
  display: inline-flex;
  gap: 0.2rem;
  margin-left: 0.35rem;
  vertical-align: middle;
}

.agg-pill {
  display: inline-block;
  font-size: 0.67rem;
  font-weight: 600;
  padding: 1px 4px;
  border-radius: 3px;
  line-height: 1.4;
  vertical-align: middle;
}

.agg-pill.announced   { background: var(--status-announced-bg,  #e8f4fd); color: var(--status-announced-fg,  #1a6fa8); }
.agg-pill.construction{ background: var(--status-construction-bg,#fef3cd); color: var(--status-construction-fg,#856404); }
.agg-pill.operational { background: var(--status-operational-bg, #d1f0e0); color: var(--status-operational-fg, #1a7a4a); }

[data-theme="dark"] .agg-pill.announced    { background: #1b3a50; color: #7ecbf5; }
[data-theme="dark"] .agg-pill.construction { background: #3a2e0a; color: #f0c040; }
[data-theme="dark"] .agg-pill.operational  { background: #0a3020; color: #50d090; }

.responses-col {
  min-width: 8rem;
}

#agg-stats {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 720px) {
  #agg-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Moratoriums table - aligned with aggregate table styling */
.moratorium-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  background: var(--surface);
}

.moratorium-table th {
  background: var(--surface-2, var(--surface));
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.55rem 0.75rem;
  border-bottom: 2px solid var(--border);
  white-space: nowrap;
  text-align: left;
}

.moratorium-table td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}

.moratorium-table tbody tr:last-child td {
  border-bottom: none;
}

.moratorium-table tbody tr:hover td {
  background: var(--hover-bg, rgba(0,0,0,0.03));
}

[data-theme="dark"] .moratorium-table tbody tr:hover td {
  background: rgba(255,255,255,0.05);
}

/* ==========================================================================
   Utility Tariffs view (v1.17)
   ========================================================================== */

.tariff-table tbody tr {
  cursor: pointer;
}
.tariff-table tbody tr:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* --------------------------------------------------------------------------
   Moratorium detail modal — same overlay pattern as the tariff modal.
   -------------------------------------------------------------------------- */
.moratorium-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(16px, 6vh, 72px) 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.moratorium-modal[hidden] {
  display: none;
}
.moratorium-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  cursor: pointer;
}
/* Override .moratorium-detail's inline layout so it becomes the centered dialog. */
.moratorium-modal__dialog.moratorium-detail {
  position: relative;
  z-index: 1;
  margin: auto;
  width: min(760px, 100%);
  max-height: calc(100vh - clamp(32px, 12vh, 144px));
  overflow-y: auto;
  box-shadow: 0 18px 56px rgba(0, 0, 0, 0.38);
  animation: moratorium-modal-in 160ms ease-out;
}
@keyframes moratorium-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .moratorium-modal__dialog.moratorium-detail { animation: none; }
}
.moratorium-modal__dialog .detail-close {
  position: sticky;
  top: 0;
  float: right;
  margin: -6px -10px 0 0;
  background: var(--surface);
  z-index: 2;
}
body.moratorium-modal-open {
  overflow: hidden;
}
@media (max-width: 640px) {
  .moratorium-modal { padding: 0; }
  .moratorium-modal__dialog.moratorium-detail {
    width: 100%;
    min-height: 100vh;
    max-height: 100vh;
    border-radius: 0;
  }
}

/* Stakeholders section inside the moratorium modal */
.moratorium-stakeholders {
  margin-top: 20px;
}
.moratorium-stakeholders h4 {
  font-size: 0.9rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin: 0 0 10px;
}
.mstakeholder-group {
  margin-bottom: 10px;
}
.mstakeholder-category {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  margin: 0 0 4px;
}
.mstakeholder-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.mstakeholder-list li {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  font-size: 0.8rem;
  color: var(--text);
}
/* Opposed group gets a subtle red tint */
.mstakeholder-group[data-category="opposed"] .mstakeholder-list li {
  background: color-mix(in srgb, var(--stance-negative) 8%, var(--surface-2));
  border-color: color-mix(in srgb, var(--stance-negative) 20%, var(--border));
}

/* --------------------------------------------------------------------------
   Tariff detail modal (v1.19) — promotes the inline pop-out to a centered
   overlay so the full LBL element checklist + sources read as a real modal.
   -------------------------------------------------------------------------- */
.tariff-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(16px, 6vh, 72px) 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* [hidden] trap: an explicit display override would beat the attribute, so
   restore display:none for the hidden state. */
.tariff-modal[hidden] {
  display: none;
}
.tariff-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  cursor: pointer;
}
/* Override .moratorium-detail's inline (margin-top, position:relative) layout
   so the shared card becomes the centered, self-scrolling dialog. */
.tariff-modal__dialog.tariff-detail {
  position: relative;
  z-index: 1;
  margin: auto;
  width: min(780px, 100%);
  max-height: calc(100vh - clamp(32px, 12vh, 144px));
  overflow-y: auto;
  box-shadow: 0 18px 56px rgba(0, 0, 0, 0.38);
  animation: tariff-modal-in 160ms ease-out;
}
@keyframes tariff-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .tariff-modal__dialog.tariff-detail { animation: none; }
}
/* Keep the close control reachable while the dialog body scrolls. */
.tariff-modal__dialog .detail-close {
  position: sticky;
  top: 0;
  float: right;
  margin: -6px -10px 0 0;
  background: var(--surface);
  z-index: 2;
}
/* Coverage count surfaced in the params heading. */
.td-elem-tally {
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-left: 0.4rem;
}
/* Lock the page behind the modal. */
body.tariff-modal-open {
  overflow: hidden;
}
@media (max-width: 640px) {
  .tariff-modal { padding: 0; }
  .tariff-modal__dialog.tariff-detail {
    width: 100%;
    min-height: 100vh;
    max-height: 100vh;
    border-radius: 0;
  }
}

.tariff-table th.num,
.tariff-table td.num {
  text-align: right;
  white-space: nowrap;
}
.tariff-row-name {
  font-weight: 600;
}
.tariff-row-type {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.1rem;
}
.tariff-elem-count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}

/* Status badges + row accent (approved↔green, proposed↔amber, rejected↔red) */
.badge-tariff-status-approved,
.badge-tariff-status-proposed,
.badge-tariff-status-rejected,
.badge-tariff-federal {
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
}
.badge-tariff-status-approved {
  background-color: var(--tariff-approved-soft);
  color: var(--tariff-approved);
}
.badge-tariff-status-proposed {
  background-color: var(--tariff-proposed-soft);
  color: var(--tariff-proposed);
}
.badge-tariff-status-rejected {
  background-color: var(--tariff-rejected-soft);
  color: var(--tariff-rejected);
}
.badge-tariff-federal {
  background-color: var(--tariff-federal-soft);
  color: var(--tariff-federal);
  border: 1px solid var(--border);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-left: 0.3rem;
}
.tariff-status-approved td:first-child {
  box-shadow: inset 3px 0 0 var(--tariff-approved);
}
.tariff-status-proposed td:first-child {
  box-shadow: inset 3px 0 0 var(--tariff-proposed);
}
.tariff-status-rejected td:first-child {
  box-shadow: inset 3px 0 0 var(--tariff-rejected);
}
.tariff-table tbody tr:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* LBL element coverage grid */
.tariff-coverage-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 0.5rem;
}
.tariff-coverage-group-title {
  margin: 0 0 0.4rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}
.tariff-coverage-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.tariff-coverage-card {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.7rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 18px;
  cursor: pointer;
  font: inherit;
  font-size: 0.82rem;
  color: var(--text);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tariff-coverage-card:hover {
  border-color: var(--border-strong, #888);
}
.tariff-coverage-card.active {
  border-color: var(--accent);
  background: var(--tariff-included-soft);
}
.tariff-coverage-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tariff-coverage-card.empty {
  opacity: 0.5;
}
.tariff-coverage-card .tcc-count,
.reason-card .tcc-count {
  min-width: 1.4rem;
  height: 1.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2, rgba(0,0,0,0.06));
  border-radius: 50%;
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tariff-coverage-card.active .tcc-count {
  background: var(--accent);
  color: var(--surface);
}

/* Coverage popout (which tariffs address an element) */
.tariff-coverage-popout {
  margin-top: 1rem;
}
.tariff-popout {
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  background: var(--surface);
}
.tariff-popout-title {
  margin: 0 0 0.25rem;
  font-size: 1rem;
}
.tariff-popout-n {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
  margin-left: 0.4rem;
}
.tariff-popout-desc {
  margin: 0 0 0.75rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.tariff-popout-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.tariff-popout-item {
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--border);
}
.tariff-popout-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.tpi-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-size: 0.88rem;
}
.tpi-state {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted);
}
.tpi-detail {
  margin: 0.25rem 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.tariff-partial-tag {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tariff-partial);
  background: var(--tariff-partial-soft);
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
}

/* Detail pop-out: per-element checklist */
.tariff-detail .tariff-params {
  margin-top: 1.25rem;
}
.tparam-group {
  margin-bottom: 1rem;
}
.tparam-group-title {
  margin: 0 0 0.4rem;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.25rem;
}
.tparam-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.tparam-row {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}
.tparam-icon {
  flex: 0 0 auto;
  width: 1.3rem;
  height: 1.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.8rem;
  font-weight: 700;
  margin-top: 0.05rem;
}
.tparam-included .tparam-icon {
  background: var(--tariff-included-soft);
  color: var(--tariff-included);
}
.tparam-partial .tparam-icon {
  background: var(--tariff-partial-soft);
  color: var(--tariff-partial);
}
.tparam-absent .tparam-icon {
  background: var(--surface-2, rgba(0,0,0,0.06));
  color: var(--text-muted);
}
.tparam-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.tparam-label {
  font-size: 0.86rem;
  font-weight: 600;
}
.tparam-status {
  font-weight: 500;
  color: var(--text-muted);
}
.tparam-absent .tparam-label {
  color: var(--text-muted);
  font-weight: 500;
}
.tparam-detail {
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.4;
}
.tparam-src {
  text-decoration: none;
  font-size: 0.8rem;
}

/* Additional terms + legislation lists */
.tariff-additional-list,
.tariff-legislation-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.tariff-additional-list li,
.tariff-legislation-list li {
  font-size: 0.86rem;
  line-height: 1.45;
}
.tleg-meta {
  display: inline-block;
  font-size: 0.74rem;
  color: var(--text-muted);
  margin-left: 0.4rem;
}
.tleg-summary {
  display: block;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 0.1rem;
}

/* ==========================================================================
   Print
   ========================================================================== */

/* ==========================================================================
   Matrix cell tooltip (v1.17)
   ========================================================================== */

.matrix-tooltip {
  position: absolute;
  z-index: 200;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  padding: 10px 12px;
  max-width: 320px;
  pointer-events: none;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--text);
}

.mtt-theme {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-color, var(--text-muted));
  margin-bottom: 6px;
}

.mtt-quote {
  margin: 0 0 6px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text);
}

.mtt-hint {
  font-size: 0.72rem;
  color: var(--text-muted);
  display: block;
  margin-top: 2px;
}

[data-theme="dark"] .matrix-tooltip {
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}

/* ==========================================================================
   CBA / Formal agreement badge on claim cards (v1.17)
   ========================================================================== */

.claim-cba-badge {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 3px;
  background: var(--stance-positive-soft);
  color: var(--stance-positive);
  border: 1px solid color-mix(in srgb, var(--stance-positive) 30%, transparent);
  vertical-align: 1px;
  cursor: default;
}

[data-theme="dark"] .claim-cba-badge {
  background: color-mix(in srgb, var(--stance-positive) 18%, transparent);
  color: var(--stance-positive);
  border-color: color-mix(in srgb, var(--stance-positive) 35%, transparent);
}

/* ==========================================================================
   Constituency response breakdown in company pop-out (v1.17)
   ========================================================================== */

.cd-responses-breakdown {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.cd-breakdown-heading {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin: 0 0 10px;
}

.cb-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 0.82rem;
}

.cb-label {
  flex: 0 0 120px;
  color: var(--text);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cb-bars {
  flex: 1;
  display: flex;
  height: 10px;
  border-radius: 3px;
  overflow: hidden;
  min-width: 40px;
  gap: 1px;
}

.cb-seg {
  min-width: 4px;
  border-radius: 2px;
}

.cb-seg.positive { background: var(--stance-positive); }
.cb-seg.mixed    { background: var(--stance-mixed); }
.cb-seg.negative { background: var(--stance-negative); }

.cb-total {
  flex: 0 0 20px;
  text-align: right;
  font-size: 0.75rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.cb-summary {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin: 8px 0 0;
}

/* ==========================================================================
   Aggregate table sort indicators (v1.17)
   ========================================================================== */

.agg-table th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.agg-table th.sortable:hover {
  background: var(--surface-2);
}

.sort-ind {
  font-size: 0.7em;
  color: var(--text-muted);
  letter-spacing: 0;
}

/* ==========================================================================
   Print styles (v1.17 — expanded from v1.4 stub)
   ========================================================================== */

/* ---- Project Moratorium Badges ---- */

.project-moratoriums-row {
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.badge-moratorium {
  display: inline-block;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
}

.badge-moratorium-enacted {
  background-color: #d1fae5;
  color: #065f46;
  border-left: 3px solid #059669;
}

.badge-moratorium-proposed {
  background-color: #fef3c7;
  color: #78350f;
  border-left: 3px solid #d97706;
}

.badge-moratorium-failed {
  background-color: #fee2e2;
  color: #7f1d1d;
  border-left: 3px solid #dc2626;
}

/* ===================== Moratoriums View ===================== */

#moratorium-filters {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

#moratorium-filters label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
}

#moratorium-filters select {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  cursor: pointer;
}

#moratoriums-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 2rem;
}

#moratoriums-table thead {
  background-color: var(--bg-header);
}

#moratoriums-table th {
  padding: 0.75rem;
  text-align: left;
  font-weight: 600;
  border-bottom: 2px solid var(--border-color);
  cursor: pointer;
}

#moratoriums-table th:hover {
  background-color: var(--bg-secondary);
}

#moratoriums-table tbody tr {
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

#moratoriums-table tbody tr:hover {
  background-color: var(--bg-secondary);
}

#moratoriums-table td {
  padding: 0.75rem;
}

/* Status badge colors */
.moratorium-status-enacted {
  --status-color: #2f7a4d;
}

.moratorium-status-proposed {
  --status-color: #f59e0b;
}

.moratorium-status-failed {
  --status-color: #dc2626;
}

.badge-moratorium-status-enacted {
  background-color: #d1fae5;
  color: #065f46;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
}

.badge-moratorium-status-proposed {
  background-color: #fef3c7;
  color: #78350f;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
}

.badge-moratorium-status-failed {
  background-color: #fee2e2;
  color: #7f1d1d;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
}

/* Reason badges */
.badge-jurisdiction-type {
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
  border: 1px solid var(--border-color);
}

.badge-reason-energy {
  background-color: #fef3c7;
  color: #78350f;
}

.badge-reason-water {
  background-color: #dbeafe;
  color: #0c2d6b;
}

.badge-reason-air_quality {
  background-color: #fee2e2;
  color: #7f1d1d;
}

.badge-reason-transparency {
  background-color: #f3e8ff;
  color: #4c1d95;
}

.badge-reason-noise {
  background-color: #e2e8f0;
  color: #1e293b;
}

.badge-reason-equity {
  background-color: #d1fae5;
  color: #065f46;
}

.badge-reason-energy,
.badge-reason-water,
.badge-reason-air_quality,
.badge-reason-transparency,
.badge-reason-noise,
.badge-reason-equity {
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
  display: inline-block;
  margin: 0 0.25rem 0.25rem 0;
}

/* Reason breakdown / summary */
#moratorium-summary {
  margin-top: 2rem;
  padding-top: 2rem;
  border-top: 2px solid var(--border-color);
}

#moratorium-summary h3 {
  margin-top: 0;
  margin-bottom: 1rem;
}

/* Theme cards grid — clickable theme pills */
.reason-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 0;
  padding-bottom: 1rem;
}

.reason-card {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.7rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 18px;
  cursor: pointer;
  font: inherit;
  font-size: 0.82rem;
  color: var(--text);
  transition: border-color 0.15s ease, background 0.15s ease;
  white-space: nowrap;
}

.reason-card:hover {
  border-color: var(--border-strong, #888);
}

.reason-card.active {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.reason-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.reason-card.active .tcc-count {
  background: var(--accent);
  color: var(--surface);
}

/* Theme detail pop-out — wide horizontal below grid */
.theme-popout {
  display: none;
  margin-top: 1.5rem;
  padding: 1.5rem;
  background-color: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  animation: slideDown 0.3s ease;
}

.theme-popout.active {
  display: block;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.theme-popout-header {
  margin-bottom: 1.2rem;
  border-bottom: 2px solid var(--border);
  padding-bottom: 0.8rem;
}

.theme-popout-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 0.3rem 0;
}

.theme-popout-desc {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin: 0;
}

.theme-evidence {
  display: grid;
  gap: 1.2rem;
}

@media (min-width: 768px) {
  .theme-evidence {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

@media (max-width: 767px) {
  .theme-evidence {
    grid-template-columns: 1fr;
  }
}

.evidence-item {
  padding: 1rem;
  background-color: var(--surface);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
}

.evidence-moratorium {
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0 0 0.5rem 0;
}

.evidence-text {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text);
  margin: 0 0 0.8rem 0;
  font-style: italic;
}

.evidence-proposals {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.evidence-proposals li {
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--text);
  padding-left: 1.2rem;
  position: relative;
}

.evidence-proposals li:before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--stance-positive);
  font-weight: bold;
}

/* Moratorium detail resources list */
.moratorium-resources {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

.moratorium-resources h4 {
  font-size: 0.95rem;
  font-weight: 600;
  margin-bottom: 0.85rem;
  color: var(--text);
}

.resources-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.resources-list li {
  margin: 0;
  padding: 0;
}

.resources-list a {
  color: var(--link);
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.resources-list a:hover {
  text-decoration: underline;
}

.moratorium-summary {
  margin: 1rem 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text);
}

/* Bill number chip shown in the jurisdiction table cell */
.moratorium-bill-id {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  font-family: monospace;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0 4px;
  margin-top: 2px;
  letter-spacing: 0.02em;
}

/* .gov badge on official government links in the resources list */
.badge-gov {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--stance-positive, #1a7a4a);
  color: #fff;
  border-radius: 3px;
  padding: 1px 4px;
  vertical-align: middle;
  margin-right: 2px;
}

/* China national security context. The outer collapsible skin is now the
   shared .acc component; only the inner content styling lives here. */
.china-context-detail {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text);
}

.china-context-detail h4 {
  margin-top: 1.25rem;
  margin-bottom: 0.6rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  border-bottom: 1px solid var(--border-strong);
  padding-bottom: 0.4rem;
}

.china-context-detail h4:first-child {
  margin-top: 0;
}

.china-context-detail ul {
  list-style: disc;
  margin-left: 1.5rem;
  margin-bottom: 0.9rem;
}

.china-context-detail li {
  margin-bottom: 0.5rem;
}

.china-context-detail a {
  color: var(--link);
  text-decoration: none;
}

.china-context-detail a:hover {
  text-decoration: underline;
}

.china-context-detail table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0;
  font-size: 0.85rem;
}

.china-context-detail table thead {
  background-color: var(--surface);
  border-bottom: 2px solid var(--border-strong);
}

.china-context-detail table th,
.china-context-detail table td {
  padding: 0.6rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}

.china-context-detail table tr:hover {
  background-color: var(--surface);
}

[data-theme="dark"] .china-context-detail table tr:hover {
  background-color: var(--surface);
}

/* Export buttons for a directory table. These sit in .acc-body, never in the
   <summary> — a click inside a summary toggles the panel, so an export button
   there collapsed the table out from under the reader. */
.table-controls {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

@media print {
  /* ---- Hide chrome ---- */
  .topbar-controls,
  .tabbar,
  .summary-stats,
  .hot-rail,
  .theme-filter-row,
  .matrix-toolbar .matrix-csv,
  #theme-toggle,
  .skip-link,
  .explorer-filters,
  .detail-close,
  .map,
  #rp-export-csv,
  .cd-responses-breakdown,
  .detail-cta,
  .matrix-tooltip,
  button,
  nav {
    display: none !important;
  }

  /* ---- Page setup ---- */
  @page {
    margin: 1.5cm 2cm;
  }

  body {
    font-size: 10pt;
    line-height: 1.5;
    color: #000;
    background: #fff;
  }

  /* ---- Topbar: show site name and refresh date, strip nav ---- */
  .topbar {
    display: block;
    background: none;
    border: none;
    box-shadow: none;
    padding: 0 0 12pt;
    margin-bottom: 12pt;
    border-bottom: 1pt solid #ccc;
  }
  .topbar-inner { padding: 0; }
  .topbar h1 { font-size: 14pt; margin: 0; }
  .topbar-sub { font-size: 9pt; color: #555; margin: 2pt 0 0; }

  /* ---- Show only the active (comparison) view for print ---- */
  /* All views hidden by default; unhide the comparison one */
  .view[hidden] { display: none !important; }
  #view-comparison { display: block !important; }

  /* ---- Matrix ---- */
  .matrix-wrap { overflow: visible; }
  .matrix { width: 100%; border-collapse: collapse; font-size: 9pt; }
  .matrix th, .matrix td { border: 0.5pt solid #ccc; padding: 4pt 6pt; }
  .matrix .cell .count.check { color: #2f7a4d; font-weight: bold; }
  .matrix .cell.empty { color: #999; }
  .col-company { font-weight: 600; text-align: left; }

  /* ---- Company detail pop-out: hide if visible ---- */
  .company-detail { display: none !important; }

  /* ---- Claim cards ---- */
  .claim-card { break-inside: avoid; box-shadow: none; border: 0.5pt solid #ddd; }
  .claim-quote { font-size: 9pt; }

  /* ---- Links: show href after anchor text ---- */
  a[href]::after { content: " (" attr(href) ")"; font-size: 8pt; color: #555; }

  /* ---- Suppress animations ---- */
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   Ratepayer v2 — commitments band, coverage, roster, state panel
   ========================================================================== */

/* --- 1. The pledge: five commitments on an inked band -------------------- */

/* The band is dark in BOTH themes — it is a figure on the page, not a
   surface — so it carries its own foreground tokens rather than inheriting. */
.rp-band {
  background: var(--band-bg);
  color: var(--band-text);
  border-top: 2px solid var(--band-bg);
  margin: 28px 0;
  border-radius: var(--radius);
  overflow: hidden;
}

.rp-band-kicker {
  position: relative;
  margin: 0 0 14px;
  padding-top: 14px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--band-accent);
}

.rp-band-kicker::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 40px;
  height: 2px;
  background: var(--band-accent);
}

.rp-band-title {
  margin: 0 0 24px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.35rem, 2.8vw, 2.1rem);
  line-height: 1.12;
  letter-spacing: -0.012em;
  color: var(--band-text);
  max-width: 26ch;
}

.rp-commit-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--band-hairline);
}

.rp-commit {
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: clamp(14px, 2.5vw, 32px);
  padding: 22px 0;
  border-bottom: 1px solid var(--band-hairline);
  align-items: start;
}

.rp-commit-num {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(2.2rem, 4.5vw, 3.4rem);
  line-height: 0.85;
  color: var(--band-accent);
}

.rp-commit-title {
  /* Overrides the global h4 (uppercase, sans, muted) — these are display
     headings quoting the pledge, not eyebrow labels. */
  text-transform: none;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  line-height: 1.18;
  color: var(--band-text);
}

.rp-commit-dek {
  margin: 0 0 12px;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--band-text-muted);
  max-width: 62ch;
}

.rp-commit-meter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rp-commit-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--band-hairline);
  font-size: 0.76rem;
  color: var(--band-text);
}

.rp-commit-chip-num {
  font-weight: 700;
}

.rp-commit-chip.is-met {
  border-color: var(--stance-positive);
  color: var(--stance-positive);
}
.rp-commit-chip.is-partial {
  border-color: var(--stance-mixed);
  color: var(--stance-mixed);
}
.rp-commit-chip.is-not_met {
  border-color: var(--stance-negative);
  color: var(--stance-negative);
}

.rp-commit-empty,
.rp-commit-chip.is-unknown {
  font-size: 0.78rem;
  color: var(--band-text-muted);
}

.rp-band-source {
  margin: 18px 0 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--band-text-muted);
}

.rp-band-source a {
  color: var(--band-accent);
}

/* --- 2. Coverage --------------------------------------------------------- */

.rp-cat-stats {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  border-top: 2px solid var(--text);
}

.rp-cat-stat {
  padding: 14px 16px 12px 0;
  border-right: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rp-cat-stat:last-child {
  border-right: none;
}

.rp-cat-num {
  font-family: var(--font-display);
  font-size: 1.7rem;
  line-height: 1;
  color: var(--text);
}

.rp-cat-lbl {
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* The source page disagrees with its own list; the note says so out loud. */
.rp-drift-note {
  margin: 0 0 20px;
  padding: 10px 12px;
  border-left: 3px solid var(--accent-rule);
  background: var(--surface-2);
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.rp-subhead {
  /* Same override as .rp-commit-title — see the global h4 rule. */
  text-transform: none;
  letter-spacing: -0.01em;
  font-family: var(--font-display);
  font-weight: 400;
  margin: 26px 0 6px;
  font-size: 1.15rem;
  color: var(--text);
}

.rp-state-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.rp-state-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 104px;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-rule);
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
}

.rp-state-chip:hover {
  border-color: var(--border-strong);
  border-left-color: var(--accent-mark);
}

/* A governor state we hold no records for. Rendered hollow rather than hidden:
   "my governor signed and there is nothing on file" is itself an answer. */
.rp-state-chip.is-empty {
  background: transparent;
  border-style: dashed;
  border-left-color: var(--border-strong);
}

.rp-state-code {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--text);
}

.rp-state-gov {
  position: absolute;
  margin-left: 30px;
  margin-top: -2px;
  color: var(--accent-mark);
  font-size: 0.7rem;
}

.rp-state-meta {
  font-size: 0.7rem;
  color: var(--text-muted);
}

/* --- 3. Signatory roster ------------------------------------------------- */

/* The roster's collapsible skin is the shared .acc component; #rp-roster-details
   keeps its id because the render-on-first-expand wiring and the e2e suite
   both address it. */

.rp-roster-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 10px 0;
}

.rp-roster-search input {
  min-width: 240px;
  padding: 7px 10px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.88rem;
}

.rp-roster-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rp-roster-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 11px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--text-muted);
  cursor: pointer;
}

.rp-roster-chip[aria-pressed="true"] {
  background: var(--surface-2);
  border-color: var(--accent-mark);
  color: var(--text);
}

.rp-roster-chip-n {
  font-size: 0.72rem;
  opacity: 0.75;
}

.rp-roster-count {
  margin: 4px 0 10px;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.rp-sig-row {
  display: grid;
  grid-template-areas: "name cat track domain";
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.85rem;
}

.rp-sig-name {
  grid-area: name;
  color: var(--text);
  font-weight: 500;
}

.rp-sig-cat { grid-area: cat; }
.rp-sig-track { grid-area: track; }
.rp-sig-domain { grid-area: domain; }

.rp-sig-cat,
.rp-sig-track,
.rp-sig-domain {
  font-size: 0.76rem;
  color: var(--text-muted);
}

.rp-sig-domain {
  overflow-wrap: anywhere;
}

.rp-sig-tracked {
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-mark);
}

@media (max-width: 700px) {
  .rp-sig-row,
  .rp-sig-row.has-lens {
    grid-template-areas: none;
    grid-template-columns: 1fr;
    gap: 2px;
  }
  .rp-sig-row > * {
    grid-area: auto;
  }
}

/* --- 4. State panel ------------------------------------------------------ */

.state-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(16px, 6vh, 72px) 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* [hidden] trap: the display override above would beat the attribute. */
.state-modal[hidden] {
  display: none;
}

.state-modal__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  cursor: pointer;
}

.state-modal__dialog {
  position: relative;
  z-index: 1;
  margin: auto;
  width: min(720px, 100%);
  max-height: calc(100vh - clamp(32px, 12vh, 144px));
  overflow-y: auto;
  padding: 22px 24px 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 18px 56px rgba(0, 0, 0, 0.38);
  animation: state-modal-in 160ms ease-out;
}

@keyframes state-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .state-modal__dialog { animation: none; }
}

body.state-modal-open {
  overflow: hidden;
}

.state-detail .detail-header h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.8rem;
  margin: 2px 0 6px;
}

.sd-gov-name {
  color: var(--text);
}

.sd-gov-link {
  margin-left: 8px;
  font-size: 0.78rem;
}

.sd-gov-none {
  color: var(--text-muted);
  font-style: italic;
}

.state-detail-body {
  margin-top: 18px;
}

.sd-section {
  margin-bottom: 22px;
}

.sd-section-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.95rem;
  color: var(--text);
}

.sd-section-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}

.sd-empty {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-muted);
  font-style: italic;
}

.sd-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sd-item {
  padding: 6px 0;
  border-bottom: 1px solid var(--hairline);
}

.sd-item:last-child {
  border-bottom: none;
}

.sd-item-btn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 2px 0;
  background: none;
  border: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.sd-item-btn:hover .sd-item-label {
  color: var(--link);
}

.sd-item-label {
  font-size: 0.88rem;
  color: var(--text);
}

.sd-item-meta {
  font-size: 0.74rem;
  color: var(--text-muted);
}

.state-loading {
  color: var(--text-muted);
  font-style: italic;
}

/* ==========================================================================
   Landing panels (v2) — coverage bar, commitment meters, state strip, activity
   ==========================================================================
   The landing answers three questions with SHAPE, not just numbers: the
   proportional bar shows the coalition is mostly rural co-ops; the meters show
   how thin the evidence still is; the strip shows how partial our state
   coverage is. Four stat tiles said none of that.
   ========================================================================== */

.pledge-panels {
  display: grid;
  /* Asymmetric on purpose: the meter rows carry a label, a track and a count,
     and at an even split the labels ellipsised to "New power su…". */
  grid-template-columns: minmax(240px, 0.8fr) minmax(340px, 1.2fr);
  gap: 18px 32px;
  margin: 18px 0 16px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}

.pledge-panel--wide {
  grid-column: 1 / -1;
}

.pledge-panel-h {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  /* Overrides the global h3; these are panel labels, not section headings. */
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent-mark);
  white-space: nowrap;
}

.pledge-panel-more {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}

.pledge-panel-more:hover {
  color: var(--accent-mark);
}

/* --- coverage bar -------------------------------------------------------- */

.pledge-bar {
  display: flex;
  height: 14px;
  border-radius: 2px;
  overflow: hidden;
  background: var(--surface-2);
}

.pledge-bar-seg {
  min-width: 2px;
}

/* One accent, stepped by weight — categories are parts of a whole, not
   independent series, so they share a hue rather than getting five colours. */
.pledge-bar-seg.cat-cooperative { background: #1f4e79; }
.pledge-bar-seg.cat-utility     { background: #3d7ab0; }
.pledge-bar-seg.cat-developer   { background: #6ba3d6; }
.pledge-bar-seg.cat-hyperscaler { background: #11151c; }
.pledge-bar-seg.cat-governor    { background: #9dc2e3; }

[data-theme="dark"] .pledge-bar-seg.cat-cooperative { background: #4a8ec4; }
[data-theme="dark"] .pledge-bar-seg.cat-utility     { background: #6ba3d6; }
[data-theme="dark"] .pledge-bar-seg.cat-developer   { background: #8fbde4; }
[data-theme="dark"] .pledge-bar-seg.cat-hyperscaler { background: #e8ebf0; }
[data-theme="dark"] .pledge-bar-seg.cat-governor    { background: #b5d2ec; }

.pledge-bar-key {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
}

.pledge-bar-key-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.74rem;
  color: var(--text-muted);
}

.pledge-bar-swatch {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: var(--border-strong);
}

.cat-cooperative .pledge-bar-swatch { background: #1f4e79; }
.cat-utility     .pledge-bar-swatch { background: #3d7ab0; }
.cat-developer   .pledge-bar-swatch { background: #6ba3d6; }
.cat-hyperscaler .pledge-bar-swatch { background: #11151c; }
.cat-governor    .pledge-bar-swatch { background: #9dc2e3; }

[data-theme="dark"] .cat-cooperative .pledge-bar-swatch { background: #4a8ec4; }
[data-theme="dark"] .cat-utility     .pledge-bar-swatch { background: #6ba3d6; }
[data-theme="dark"] .cat-developer   .pledge-bar-swatch { background: #8fbde4; }
[data-theme="dark"] .cat-hyperscaler .pledge-bar-swatch { background: #e8ebf0; }
[data-theme="dark"] .cat-governor    .pledge-bar-swatch { background: #b5d2ec; }

.pledge-bar-key-n {
  color: var(--text);
  font-weight: 600;
}

.pledge-bar-note {
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 0.72rem;
  color: var(--text-muted);
  font-style: italic;
}

.pledge-bar-loading {
  font-size: 0.76rem;
  color: var(--text-muted);
  font-style: italic;
}

/* --- commitment meters --------------------------------------------------- */

.pledge-meters {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.pledge-meter {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 8px;
  align-items: center;
}

.pledge-meter-num {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.86rem;
  color: var(--accent-mark);
  text-align: right;
}

.pledge-meter-body {
  display: grid;
  grid-template-columns: 150px minmax(72px, 1fr) auto;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.pledge-meter-lbl {
  font-size: 0.76rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pledge-meter-track {
  display: flex;
  height: 8px;
  border-radius: 2px;
  overflow: hidden;
  background: var(--surface-2);
}

.pledge-meter-seg.is-met     { background: var(--stance-positive); }
.pledge-meter-seg.is-partial { background: var(--stance-mixed); }
.pledge-meter-seg.is-not_met { background: var(--stance-negative); }
.pledge-meter-seg.is-unknown { background: var(--border-strong); }
.pledge-meter-seg.is-none {
  flex: 1;
  background: repeating-linear-gradient(
    45deg,
    var(--surface-2),
    var(--surface-2) 3px,
    var(--border) 3px,
    var(--border) 6px
  );
}

.pledge-meter-count {
  font-size: 0.68rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* --- state strip --------------------------------------------------------- */

.pledge-state-strip {
  display: grid;
  grid-template-columns: repeat(25, minmax(0, 1fr));
  gap: 3px;
}

.pledge-state-cell {
  position: relative;
  aspect-ratio: 1;
  min-width: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--surface);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Four density steps rather than a continuous ramp — the counts are small and
   a smooth scale would imply precision the data doesn't carry. */
.pledge-state-cell.lvl-0 { background: var(--surface); }
.pledge-state-cell.lvl-1 { background: #dbe6f1; border-color: #c3d5e8; }
.pledge-state-cell.lvl-2 { background: #9dc2e3; border-color: #7fb0d8; }
.pledge-state-cell.lvl-3 { background: #3d7ab0; border-color: #2f6796; }

[data-theme="dark"] .pledge-state-cell.lvl-1 { background: #1c2f42; border-color: #27435e; }
[data-theme="dark"] .pledge-state-cell.lvl-2 { background: #2f6796; border-color: #3d7ab0; }
[data-theme="dark"] .pledge-state-cell.lvl-3 { background: #6ba3d6; border-color: #8fbde4; }

.pledge-state-cell:hover {
  outline: 2px solid var(--accent-mark);
  outline-offset: 1px;
}

.pledge-state-abbr {
  font-size: 0.56rem;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  color: var(--text);
}

.pledge-state-cell.lvl-3 .pledge-state-abbr { color: #ffffff; }
[data-theme="dark"] .pledge-state-cell.lvl-3 .pledge-state-abbr { color: #0e1117; }

/* Governor-signed states carry a corner mark, not a colour — colour is already
   carrying record density and must not do two jobs. */
.pledge-state-cell.is-gov::after {
  content: "★";
  position: absolute;
  top: -1px;
  right: 1px;
  font-size: 0.44rem;
  line-height: 1;
  color: var(--accent-rule);
}

[data-theme="dark"] .pledge-state-cell.is-gov::after { color: #b5d2ec; }

.pledge-strip-key {
  margin: 8px 0 0;
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* --- activity feed ------------------------------------------------------- */

/* --- What's next: dated docket milestones on Home ------------------------ */

.whats-next {
  margin-bottom: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}

.wn-sub {
  margin: 0 0 10px;
  font-size: 0.8rem;
  color: var(--text-muted);
  max-width: 64ch;
}

.wn-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.wn-btn {
  display: grid;
  grid-template-columns: 104px 44px 1fr;
  gap: 12px;
  align-items: start;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 8px 10px;
  cursor: pointer;
  color: inherit;
  font: inherit;
}

.wn-btn:hover,
.wn-btn:focus-visible {
  border-color: var(--accent-rule);
  background: var(--surface-2);
}

.wn-date {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--accent-mark);
  white-space: nowrap;
  padding-top: 2px;
}

.wn-date--open {
  color: var(--text-muted);
}

.wn-state {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 1px 5px;
  text-align: center;
  justify-self: start;
}

.wn-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.wn-text {
  font-size: 0.82rem;
  line-height: 1.45;
}

.wn-meta {
  font-size: 0.72rem;
  color: var(--text-muted);
}

@media (max-width: 760px) {
  .wn-btn { grid-template-columns: 1fr; gap: 3px; }
  .wn-state { display: none; }
}

/* --- Utility rollup (aggregate "By utility" sub-tab) --------------------- */

.agg-utility-signed {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tariff-approved);
  border: 1px solid var(--tariff-approved);
  border-radius: 4px;
  padding: 1px 6px;
}

/* --- Rate cases & proceedings (Tariffs tab) ------------------------------ */

.rc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.rc-item {
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 10px 12px;
}

.rc-item--empty {
  color: var(--text-muted);
  border-style: dashed;
}

.rc-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.rc-state {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 1px 6px;
}

.rc-state--fed {
  color: var(--tariff-federal);
  border-color: var(--tariff-federal);
}

.rc-title {
  font-weight: 600;
  font-size: 0.9rem;
}

.rc-meta {
  margin: 4px 0 0;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.rc-src {
  white-space: nowrap;
}

/* 44px touch floor, coarse pointers only — see the .subtab rule above for the
   same pattern. At the desktop scale this inline link inherits .rc-meta's
   0.75rem line box with no padding, well under the floor for a thumb. */
@media (pointer: coarse) {
  .rc-src {
    display: inline-block;
    min-height: 44px;
    min-width: 44px;
    padding: 12px 4px;
    margin: -12px -4px;
  }
}

.rc-summary {
  margin: 6px 0 0;
  font-size: 0.82rem;
  line-height: 1.5;
  max-width: 78ch;
}

.rc-next {
  margin: 6px 0 0;
  font-size: 0.78rem;
}

.rc-next-lbl {
  font-weight: 700;
  color: var(--accent-mark);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.68rem;
}

.rc-next-date {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}

.pledge-activity {
  margin-bottom: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}

.pledge-activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.pledge-activity-item {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 12px;
  font-size: 0.8rem;
  line-height: 1.45;
}

.pledge-activity-date {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--accent-mark);
  white-space: nowrap;
  padding-top: 1px;
}

.pledge-activity-text {
  color: var(--text-muted);
}

@media (max-width: 860px) {
  .pledge-panels { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .pledge-state-strip { grid-template-columns: repeat(13, minmax(0, 1fr)); }
  .pledge-meter-body { grid-template-columns: 1fr; gap: 3px; }
  .pledge-meter-lbl { white-space: normal; }
  .pledge-activity-item { grid-template-columns: 1fr; gap: 1px; }
}

/* --- Scorecard filter bar (v2) --------------------------------------------
   Sticky under the tab bar. The scorecard runs to 39 cards and growing, and
   before this the only way to reach a site was to scroll past all of them
   (BACKLOG: "Long Ratepayer scorecard"). Sticky offset matches the tab bar's
   height so the two never overlap. */

.rp-filterbar {
  position: sticky;
  top: 41px;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin: 10px 0 12px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.rp-filter-search input {
  min-width: 220px;
  padding: 6px 10px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.85rem;
}

.rp-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rp-filter-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 11px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--text-muted);
  cursor: pointer;
}

.rp-filter-chip[aria-pressed="true"] {
  border-color: var(--accent-mark);
  color: var(--text);
  background: var(--accent-soft);
}

/* Status chips carry the same hue language as the cards they filter. */
.rp-filter-chip.is-affirmed[aria-pressed="true"] {
  border-color: var(--ratepayer-affirmed);
}
.rp-filter-chip.is-pledge_only[aria-pressed="true"] {
  border-color: var(--ratepayer-pledge_only);
}
.rp-filter-chip.is-contested[aria-pressed="true"] {
  border-color: var(--ratepayer-contested);
}

.rp-filter-chip-n {
  font-size: 0.72rem;
  opacity: 0.75;
}

.rp-filter-flag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  color: var(--text-muted);
  cursor: pointer;
}

.rp-filter-count {
  margin: 0 0 0 auto;
  font-size: 0.76rem;
  color: var(--text-muted);
}

@media (max-width: 700px) {
  .rp-filterbar {
    position: static;
  }
  .rp-filter-count {
    margin-left: 0;
  }
}

/* --- Signatory roster lens (v2, P5) ---------------------------------------
   The roster row IS the lens — no per-signatory pages for 300 organizations.
   A row only becomes expandable when we can say something concrete about it;
   most cooperatives stay flat, which is the honest state. */

.rp-sig-row.has-lens {
  grid-template-areas:
    "name cat track domain"
    "expand expand expand expand"
    "lens lens lens lens";
}

.rp-sig-expand {
  grid-area: expand;
  justify-self: start;
  margin-top: 2px;
  padding: 2px 0;
  background: none;
  border: none;
  font: inherit;
  font-size: 0.72rem;
  color: var(--accent-mark);
  cursor: pointer;
}

.rp-sig-expand:hover {
  text-decoration: underline;
}

.rp-sig-lens {
  grid-area: lens;
  margin: 6px 0 4px;
  padding: 10px 12px;
  background: var(--surface-2);
  border-left: 2px solid var(--accent-rule);
  border-radius: var(--radius-sm);
}

/* [hidden] trap: the block display above would beat the attribute. */
.rp-sig-lens[hidden] {
  display: none;
}

.rp-sig-lens-h {
  /* Overrides the global uppercase h4/h5 treatment. */
  margin: 0 0 4px;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.rp-sig-lens-h + .rp-sig-lens-list {
  margin-bottom: 8px;
}

.rp-sig-lens-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rp-sig-lens-link {
  background: none;
  border: none;
  padding: 2px 0;
  font: inherit;
  font-size: 0.78rem;
  color: var(--link);
  text-align: left;
  cursor: pointer;
}

.rp-sig-lens-link:hover {
  text-decoration: underline;
}

.rp-sig-lens-note,
.rp-sig-lens-loading {
  margin: 4px 0 0;
  font-size: 0.74rem;
  line-height: 1.45;
  color: var(--text-muted);
  font-style: italic;
}
