:root {
  --navy: #0b2545;
  --navy-deep: #061531;
  --navy-soft: #13335d;
  --white: #ffffff;
  --ink: #13293d;
  --ink-soft: #3d5672;
  --muted: #8da4c0;
  --surface: #f6f8fb;
  --surface-2: #edf1f7;
  --border: #d9e0ea;
  --accent: #2ecc71;
  --error: #e74c3c;
  --warn: #f39c12;
  --blue: #1c5fd8;
  --blue-deep: #143ea3;
  --dem: #1c5fd8;
  --rep: #d9322f;
  --ind: #c7a008;
  --off-white: #f4f6fb;
  --blue-pale: #e8f0ff;
  --red-pale: #ffeaea;
  --gold: #f5a623;
  --gold-pale: #fff8e6;
  --green: #1a9660;
  --green-pale: #e6f9f0;
  --purple: #6b46c1;
  --purple-pale: #f1ecff;
  --radius: 12px;
  --radius-sm: 8px;
  --radius-lg: 20px;
  --shadow-sm: 0 2px 6px rgba(6, 21, 49, 0.08);
  --shadow: 0 8px 24px rgba(6, 21, 49, 0.12);
  --shadow-lg: 0 18px 50px rgba(6, 21, 49, 0.22);
  --space: 1rem;
  --header-h: 64px;
  --font-sans: 'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-serif: 'DM Serif Display', Georgia, serif;
}

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

html,
body {
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  color: var(--ink);
  background: var(--surface);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

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

h1 { font-size: clamp(1.75rem, 3.5vw, 2.5rem); }
h2 { font-size: clamp(1.35rem, 2.5vw, 1.8rem); }
h3 { font-size: 1.15rem; }

button {
  font: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

/* ---------- Header ---------- */
/* ════════════════════════════════════════════
   Site header — visual match to v5.27 design template.
   Navy bar, gold-tinted "Lens" logo, icon-prefixed nav with
   Legislative dropdown, gold-tinted Compare pill, search-bar pill,
   and a "← Back" rectangular pill (only visible mid-flow).
   ════════════════════════════════════════════ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 300;
  height: var(--header-h);
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  /* Layout (user feedback 2026-05-21, refined):
   *   - LEFT padding uses calc to position the cluster so the
   *     FIRST NAV BUTTON (Legislative) aligns with the .page
   *     content edge. The logo sits in the space to its left,
   *     not constrained to the visible content area. -137px in
   *     the calc accounts for the logo's intrinsic width (~125px)
   *     + the flex gap between logo and Legislative (~12px), so
   *     Legislative ends up at the same x as the hero card.
   *   - RIGHT padding is fixed 18px so the right cluster (Donate
   *     / search / auth-zone) flows naturally without being
   *     pushed against any container edge. .header-right has no
   *     margin-left: auto, so it sits immediately after Brief.
   *   - At narrower viewports the calc floors at 0px so the logo
   *     can hug the very edge and Legislative still appears close
   *     to where the .page content starts.
   *   - 100% (not 100vw) excludes the scrollbar width. The +20px
   *     accounts for .page's 1.25rem padding-inline. */
  padding: 0 18px 0 max(0px, calc((100% - 1200px) / 2 + 20px - 137px));
  gap: 8px;
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.22);
}

/* Desktop header packing rules (>600px).
 *
 * User feedback 2026-05-21: keep all header items packed together
 * (Donate/Search/Avatar adjacent to Brief), not spread to the right
 * edge of a widened viewport.
 *
 *   - .primary-nav defaults to flex: 0 1 auto — natural width, no
 *     growing into empty space. min-width: 0 + overflow-x: auto
 *     keep it shrinkable + scrollable at narrow widths without
 *     overlapping the right cluster.
 *   - .header-right gets NO margin-left: auto — so the right
 *     cluster sits immediately after .primary-nav, not at the
 *     viewport edge.
 *
 * On mobile .header-collapsible is display:none so this is
 * desktop-only by structure. */
@media (min-width: 601px) {
  .primary-nav { min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .primary-nav::-webkit-scrollbar { display: none; }
}
/* Header media queries live after the auth-zone block, below — placing them
   here would lose to higher-specificity rules later in the cascade. */

/* .header-back rules removed 2026-05-20 — browser's own back/forward
 * already handles SPA history (every navigateTo pushes/replaces a
 * history entry), and the in-header back affordance was crowding the
 * mobile header next to the logo. */

.logo {
  font-family: var(--font-serif);
  font-size: 22px;
  color: var(--white);
  letter-spacing: -0.01em;
  white-space: nowrap;
  flex-shrink: 0;
  user-select: none;
}
.logo span { color: var(--gold); }

.primary-nav {
  display: flex;
  gap: 3px;
  flex-shrink: 0;
  align-items: center;
}
.primary-nav button {
  /* Bumped from rgba(255,255,255,0.6) → full white. The original 60% alpha
   * was visually muted against the dark header — labels read as
   * "decoration" rather than nav. Hover/active still pop via the
   * background pill below. Icons (emoji) render at native saturation
   * regardless of color, but they read brighter alongside full-white
   * text than alongside dimmed text. */
  color: var(--white);
  padding: 8px 11px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 13px;
  font-family: 'DM Sans', sans-serif;
  white-space: nowrap;
  transition: all 0.18s;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
/* :hover gated behind @media (hover: hover) so iOS Safari doesn't
 * intercept the first tap to apply hover state and swallow the
 * click (a known iOS quirk when :hover combines with transition:
 * all). On touchscreens we use :active for tap feedback instead. */
@media (hover: hover) {
  .primary-nav button:hover { background: rgba(255, 255, 255, 0.14); }
}
.primary-nav button:active { background: rgba(255, 255, 255, 0.18); }
.primary-nav button.active { background: rgba(255, 255, 255, 0.14); }
.primary-nav button.hidden { display: none; }
.nav-icon { font-size: 14px; line-height: 1; }
.nav-caret { font-size: 10px; opacity: 0.7; margin-left: 2px; }

/* Legislative dropdown — Senate / House submenu opens on hover OR when
   `.open` is set imperatively (so a click on the trigger pins it open
   for keyboard / touch users). */
.nav-dropdown { position: relative; display: flex; align-items: center; }
.nav-dropdown-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: var(--navy-mid, #152d50);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  padding: 5px;
  min-width: 180px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  z-index: 400;
  flex-direction: column;
  gap: 2px;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown.open .nav-dropdown-menu { display: flex; }
.nav-dropdown-menu button {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.75);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px;
  font-weight: 500;
  padding: 9px 13px;
  border-radius: 7px;
  text-align: left;
  width: 100%;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.15s;
}
.nav-dropdown-menu button:hover { background: rgba(255, 255, 255, 0.10); color: var(--white); }

.header-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* Gold-tinted Donate pill, lifted directly from the template.
 * Class formerly .compare-btn-header — same styling, swapped to make
 * Donate more prominent than Compare per design tweak 2026-05-02. */
.donate-btn-header {
  background: rgba(245, 166, 35, 0.18);
  border: 1px solid rgba(245, 166, 35, 0.4);
  color: var(--gold);
  font-family: 'DM Sans', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 20px;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  transition: all 0.2s;
}
@media (hover: hover) {
  .donate-btn-header:hover { background: rgba(245, 166, 35, 0.28); }
}
.donate-btn-header:active { background: rgba(245, 166, 35, 0.34); }

.header-search {
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 24px;
  padding: 7px 15px;
  gap: 7px;
  transition: all 0.2s;
  margin: 0;
}
.header-search:focus-within {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(255, 255, 255, 0.28);
}
.header-search-icon {
  color: rgba(255, 255, 255, 0.4);
  font-size: 14px;
}
.header-search input {
  background: none;
  border: none;
  outline: none;
  color: var(--white);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px;
  width: 190px;
  padding: 0;
}
.header-search input::placeholder { color: rgba(255, 255, 255, 0.36); }

.auth-zone { display: flex; align-items: center; gap: 0.5rem; }

/* Header responsive rules — placed AFTER the base header block so they win
   the cascade for selectors of equal specificity. */
@media (min-width: 1400px) {
  /* The base .site-header calc already widens the inline padding
   * on bigger viewports to keep the inner content aligned with the
   * 1200px page container; we only bump the inter-item gap here. */
  .site-header { gap: 12px; }
}
@media (max-width: 1280px) {
  .primary-nav { gap: 1px; }
  .primary-nav button { padding: 7px 8px; font-size: 12.5px; gap: 4px; }
  .header-search input { width: 130px; }
}
@media (max-width: 1100px) {
  .donate-btn-header span:not(.nav-icon) { display: none; }
  .header-search input { width: 110px; }
}
@media (max-width: 920px) {
  .primary-nav button span:not(.nav-icon):not(.nav-caret) { display: none; }
  .header-search input { width: 90px; }
  /* Tablets / phones: 9 nav icons + logo + donate + search + avatar
   * exceeds the available header width. Make the nav horizontally
   * scrollable so every icon stays reachable via swipe. The
   * scrollbar itself is hidden visually since this is a horizontal
   * thumb-strip pattern (Instagram stories, app stores), not a
   * page-level scroll users need a visible track for. */
  .primary-nav {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }
  .primary-nav::-webkit-scrollbar { display: none; }
  .primary-nav button { flex: 0 0 auto; }
}
@media (max-width: 820px) {
  /* Search stays visible (just compact) — was previously
   * `display: none` which made global search unreachable on phones
   * + tablets. The compact form below at <600px shrinks the input
   * further; here it just gets a smaller footprint. */
  .header-search input { width: 80px; }
}

.btn-signin {
  background: var(--white);
  color: var(--navy);
  padding: 0.5rem 1rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.9rem;
  transition: transform 0.15s;
}
.btn-signin:hover { transform: translateY(-1px); }
.btn-signin.hidden { display: none; }

/* ──────────────────────────────────────────────────────────────
 * Mobile hamburger menu (<= 600px)
 *
 * Below 600px the inline header overflows the viewport by ~140px:
 * logo + 9 emoji nav + search + donate + Sign In doesn't fit on
 * a 375px iPhone. The hamburger collapses .primary-nav + .header-
 * right into a slide-down drawer triggered by a single 44x44
 * button that sits next to the logo.
 *
 * Drawer state lives on body.nav-open: when set, the .primary-nav
 * and .header-right transform from translateY(-100%) (off-screen
 * above the header) to translateY(0) (visible below the header),
 * with a backdrop overlay underneath. Press ESC, tap the backdrop,
 * or tap any nav link to close.
 * ────────────────────────────────────────────────────────────── */

/* Mobile quick-action row — 3 single-icon buttons that surface My HQ
 * (signed-in only), Brief (signed-in only), and Donate (always) right
 * next to the logo on mobile. Provides one-tap access to the three
 * highest-value destinations without opening the hamburger drawer.
 *
 * Visibility:
 *   - Desktop (>600px): .mq-row hides entirely; those entries live in
 *     the normal inline header instead.
 *   - Mobile (<=600px): .mq-row shows; .mq-myhq / .mq-brief are gated
 *     on `body.is-authed`, .mq-donate is always shown.
 *
 * Auth state comes from auth.js's body class toggle (is-authed /
 * is-unauthed) so no extra JS wiring is needed for these buttons —
 * the same toggle that hides the Sign In button drives the gate here. */
.mq-row {
  display: none;
}
.mq-btn {
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: var(--white);
  /* User feedback 2026-05-20: make these wider. Switched from fixed
   * 40x40 squares to flex-grow rectangles capped at 120px each, so
   * they expand to fill the space between logo and hamburger without
   * getting absurdly wide when only one is visible (signed-out
   * Donate). min-height stays at 40px for touch-target compliance. */
  flex: 1 1 0;
  min-width: 48px;
  max-width: 120px;
  height: 40px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: background 0.18s, transform 0.15s;
  touch-action: manipulation;
}
@media (hover: hover) {
  .mq-btn:hover { background: rgba(255, 255, 255, 0.20); }
}
.mq-btn:active { background: rgba(255, 255, 255, 0.28); transform: scale(0.94); }

/* Header collapsible wrapper — desktop-only now. Inline flex row
 * grouping .primary-nav and .header-right side-by-side. At mobile
 * widths it's hidden entirely (the new <details>.mobile-nav takes
 * over). */
.header-collapsible {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

/* ── New mobile nav (rebuilt 2026-05-20) ─────────────────────
 * Native <details>/<summary> disclosure with anchor-based items.
 * Replaces the prior transform-drawer hamburger that had a
 * persistent click-swallow bug on iOS. Inline expansion below the
 * header — no position:fixed on the panel content, no transform
 * during open/close, so iOS never sees a mid-click visibility
 * change. <a href="..."> ensures the browser navigates natively
 * even if the SPA's JS interception fails. */
.mobile-nav {
  display: none; /* hidden on desktop */
}
.mobile-nav-trigger {
  list-style: none;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  gap: 5px;
  cursor: pointer;
  border-radius: 8px;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.mobile-nav-trigger::-webkit-details-marker { display: none; }
.mobile-nav-trigger::marker { content: ''; }
.mobile-nav-trigger .bar {
  width: 22px;
  height: 2px;
  background: var(--white);
  border-radius: 1px;
  transition: transform 0.18s ease, opacity 0.18s ease;
}
/* Native [open] attribute drives the X-animation — no JS needed. */
.mobile-nav[open] .mobile-nav-trigger .bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.mobile-nav[open] .mobile-nav-trigger .bar:nth-child(2) {
  opacity: 0;
}
.mobile-nav[open] .mobile-nav-trigger .bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}
.mobile-nav-panel {
  position: absolute;
  top: 64px;
  left: 0;
  right: 0;
  background: var(--navy-deep, #061531);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px 16px;
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  z-index: 390;
}
.mn-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 8px;
  color: var(--white);
  font-family: 'DM Sans', sans-serif;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  min-height: 44px;
  width: 100%;
  text-align: left;
  /* No transition on background — iOS hover-trap mitigations don't
   * matter here because we use anchors (browser-native navigation)
   * and don't rely on JS click events at all. */
}
.mn-link:active { background: rgba(255, 255, 255, 0.18); }
@media (hover: hover) {
  .mn-link:hover { background: rgba(255, 255, 255, 0.10); }
}
.mn-icon {
  font-size: 18px;
  width: 24px;
  text-align: center;
  flex-shrink: 0;
}
.mn-divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.08);
  margin: 8px 4px;
}
.mn-signin {
  /* Hide when signed in — auth.js's body.is-authed flag drives it. */
}
body.is-authed .mn-signin { display: none; }

@media (max-width: 600px) {
  /* Show the new mobile nav, hide the desktop inline cluster. */
  .mobile-nav { display: inline-block; margin-left: auto; }
  .header-collapsible { display: none; }
  .site-header { padding: 0 14px; gap: 6px; }
  /* .mq-row gets flex: 1 so it eats the available width between the
   * logo and the hamburger; .mq-btn inside also flex: 1 so each
   * button shares that space evenly. Together: buttons expand to
   * fill, with each capped at 120px so they stay touch-comfortable
   * but don't get absurdly wide on tablets. */
  .mq-row {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
  }
  body.is-unauthed .mq-myhq,
  body.is-unauthed .mq-brief { display: none; }
  /* Signed-out users only see Donate. Center it in the available
   * row space (between logo and hamburger) so it sits visually
   * mid-banner rather than crammed against the logo on the left. */
  body.is-unauthed .mq-row { justify-content: center; }
}

/* ---------- Avatar + Menu ----------
 *
 * Structure:
 *   .avatar-btn (button, sized 38x38, the click target)
 *     └─ .avatar-face (the visual circle, holds initials or img)
 *           ├─ .avatar-img (shown when window.currentUser.avatarUrl set)
 *           └─ .avatar-initials (fallback, shown otherwise)
 *     └─ .avatar-pro-star (corner overlay, only when body.user-is-pro)
 *
 * Pro treatment: gold ring around the avatar + a small ⭐ overlay at
 * the bottom-right corner. Driven by body.user-is-pro so the same
 * visual is applied wherever an avatar appears (header today;
 * profile pages tomorrow).
 */
.avatar-btn {
  position: relative;          /* anchors the .avatar-pro-star overlay */
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  background: transparent;     /* the colored circle moves to .avatar-face */
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s;
}
.avatar-btn:hover { transform: translateY(-1px); }
.avatar-btn.hidden { display: none; }

.avatar-face {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: linear-gradient(135deg, #4a90e2, #1c5fd8);
  color: var(--white);
  font-weight: 700;
  font-size: 0.85rem;
  overflow: hidden;            /* clips uploaded images to circle */
  box-shadow: var(--shadow-sm);
  /* Smooth transition for the Pro ring fading in / out. */
  box-shadow: var(--shadow-sm), 0 0 0 0 rgba(245, 166, 35, 0);
  transition: box-shadow 0.2s;
}
.avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.avatar-img[hidden],
.avatar-initials[hidden] { display: none; }

.avatar-pro-star {
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--white);
  display: none;               /* hidden by default; shown when Pro */
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  pointer-events: none;
}

/* Pro treatment — gold ring + corner star. */
body.user-is-pro .avatar-face {
  box-shadow: var(--shadow-sm), 0 0 0 2px var(--gold);
}
body.user-is-pro .avatar-pro-star {
  display: inline-flex;
}

.user-menu {
  /* Fixed (not absolute) so the menu stays anchored to the viewport
     when the page scrolls — matches the sticky header above it. With
     `absolute` it was anchored to the document instead and slid out
     of view as the user scrolled down. */
  position: fixed;
  top: calc(var(--header-h) + 0.35rem);
  right: 1rem;
  background: var(--white);
  color: var(--ink);
  min-width: 220px;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 0.5rem;
  display: none;
  /* Above page content + the sticky header (z-index 300) so the menu
     overlays cleanly even on pages that have absolutely-positioned
     elements like map tooltips. */
  z-index: 320;
  animation: fadeUp 0.2s ease;
}
.user-menu.open { display: block; }
.user-menu-name {
  padding: 0.6rem 0.9rem 0.35rem;
  font-weight: 700;
}
.user-menu-email {
  padding: 0 0.9rem 0.6rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.4rem;
}
.user-menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  color: var(--ink);
}
.user-menu button:hover { background: var(--surface-2); }
.user-menu .divider { height: 1px; background: var(--border); margin: 0.3rem 0; }

/* ---------- Pages ---------- */
.page {
  display: none;
  padding: 2rem 1.25rem 4rem;
  max-width: 1200px;
  margin: 0 auto;
}
.page.active {
  display: block;
  animation: fadeUp 0.3s ease;
}

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

.page-header { margin-bottom: 1.5rem; }
.page-header p { color: var(--ink-soft); margin: 0; }

/* ---------- v5 Breadcrumb hero ---------- */
.page-hero {
  background: linear-gradient(135deg, var(--navy) 0%, #152d50 55%, #1a3a6e 100%);
  border-radius: 16px;
  padding: 40px 36px 44px;
  color: #fff;
  position: relative;
  overflow: hidden;
  margin-bottom: 1.75rem;
}
.page-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 78% 30%, rgba(46, 125, 247, 0.18) 0%, transparent 55%),
    radial-gradient(ellipse at 15% 80%, rgba(245, 166, 35, 0.08) 0%, transparent 50%);
  pointer-events: none;
}
.page-hero > * { position: relative; }
.page-hero.accent-purple { background: linear-gradient(135deg, #2d1b4e 0%, #3b2568 55%, #4b3280 100%); }
.page-hero.accent-green { background: linear-gradient(135deg, #0e3d2a 0%, #145139 55%, #1a6a4a 100%); }
.page-hero.accent-violet { background: linear-gradient(135deg, #261848 0%, #3a2670 55%, #4b3490 100%); }
.breadcrumb-trail {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.58);
  margin-bottom: 14px;
}
.breadcrumb-trail a { cursor: pointer; color: rgba(255, 255, 255, 0.82); }
.breadcrumb-trail a:hover { color: #fff; text-decoration: underline; }
.breadcrumb-trail .sep { margin: 0 0.45rem; opacity: 0.45; }
.page-hero h1 {
  font-family: var(--font-serif);
  font-size: clamp(28px, 4.5vw, 44px);
  color: #fff;
  font-weight: 400;
  line-height: 1.12;
  margin: 0 0 10px;
}
.page-hero h1 em { color: var(--gold); font-style: normal; }
.page-hero .hero-sub {
  color: rgba(255, 255, 255, 0.66);
  font-size: 15px;
  max-width: 640px;
  line-height: 1.6;
  margin: 0;
}

/* ---------- Legislative index (chamber cards) ---------- */
.chamber-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  margin-bottom: 28px;
}
.chamber-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 26px 24px;
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.26s cubic-bezier(0.34, 1.2, 0.64, 1);
}
.chamber-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
}
.chamber-card.senate::before { background: var(--blue); }
.chamber-card.house::before { background: var(--rep); }
.chamber-card.tool::before { background: var(--gold); }
.chamber-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}
.chamber-icon {
  font-size: 34px;
  line-height: 1;
  margin-bottom: 14px;
}
.chamber-card h3 {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 400;
  color: var(--navy);
  margin: 0 0 6px;
}
.chamber-card .chamber-desc {
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
}
.chamber-stats {
  display: flex;
  gap: 14px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.chamber-stat {
  font-size: 12px;
  color: var(--ink-soft);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.chamber-stat strong { color: var(--navy); font-weight: 700; font-size: 13px; }
.chamber-cta {
  color: var(--blue);
  font-size: 13px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chamber-card:hover .chamber-cta { gap: 10px; }

/* ---------- Legislative facts strip ---------- */
.legislative-facts {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px 26px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.legislative-facts h4 {
  grid-column: 1 / -1;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 4px;
}
.fact-item .fact-value {
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 400;
  color: var(--navy);
  line-height: 1.1;
}
.fact-item .fact-label {
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 2px;
}

/* ---------- v5 Chamber page: filter row & controls ---------- */
.filter-row {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  margin-bottom: 1.25rem;
}
.filter-row .filter-party {
  display: inline-flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
}
.filter-row .filter-party button {
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s;
}
.filter-row .filter-party button:hover { color: var(--navy); }
.filter-row .filter-party button.active {
  color: var(--navy);
  border-bottom-color: var(--gold);
}
.filter-row .state-select {
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--white);
  font: inherit;
  font-size: 13px;
  color: var(--ink);
}
.filter-row .view-toggle {
  margin-left: auto;
  display: inline-flex;
  background: var(--off-white);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
}
.filter-row .view-toggle button {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  border-radius: 6px;
}
.filter-row .view-toggle button.active {
  background: var(--white);
  color: var(--navy);
  box-shadow: var(--shadow-sm);
}

/* ---------- v5 Members grid ---------- */
.members-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
}
/* Mobile: tighten the grid to 2 columns at iPhone widths (was 1 col
 * because the 200px minmax doesn't fit 2 in a 375px viewport). Also
 * shrink tile padding + avatar so the tiles fit snugly around their
 * content rather than wasting half the card on whitespace. User
 * feedback 2026-05-20: "tiles fit just around their profile picture
 * and info … at least 2 members per row in the grid view." */
@media (max-width: 600px) {
  .members-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  .members-grid .member-tile {
    padding: 14px 10px 12px;
    gap: 2px;
  }
  .members-grid .member-avatar {
    width: 56px;
    height: 56px;
    font-size: 1rem;
    margin-bottom: 6px;
  }
  .members-grid .member-name {
    font-size: 13.5px;
    line-height: 1.2;
  }
  .members-grid .member-sub {
    font-size: 11.5px;
    margin-bottom: 6px;
  }
}
.members-list { display: flex; flex-direction: column; gap: 0.5rem; }

/* Shared card styling for both views — bug fix 2026-05-06: previously
 * these were scoped to `.members-grid .member-tile`, so the list view
 * rendered as unstyled text + avatar with no background/border/hover.
 * Hoisted to the base `.member-tile` so both views get the same card
 * shell; per-view rules below override layout (block vs flex) + the
 * decorative top-stripe (grid only). */
.member-tile {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1), box-shadow 0.22s, border-color 0.22s;
  position: relative;
  overflow: hidden;
  text-align: left;
  box-shadow: none;
}
.member-tile:hover {
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}

.members-grid .member-tile {
  padding: 22px 18px 18px;
  /* Grid view: portrait-card layout — large avatar centered above
   * name/state/badge. Reads as a "card" rather than a row. The
   * party color stripe at top + larger avatar are what differentiate
   * grid from list visually. */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
}
.members-grid .member-tile::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--border);
}
.members-grid .member-tile.dem::before { background: var(--blue); }
.members-grid .member-tile.rep::before { background: var(--rep); }
.members-grid .member-tile.ind::before { background: var(--gold); }
.members-grid .member-tile:hover { transform: translateY(-4px); }
.members-grid .member-avatar {
  /* Bigger avatar in grid view — was 52px, now 72px — gives the
   * card a clear focal point and makes member identity scannable
   * at a glance even when names are abbreviated. */
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: linear-gradient(135deg, #dde3f0, #bcc7e0);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--navy);
  font-weight: 700;
  font-size: 1.15rem;
  font-family: var(--font-serif);
  overflow: hidden;
  /* Subtle shadow ring so the avatar pops off the card background
   * without needing a hard border. */
  box-shadow: 0 2px 8px rgba(15, 29, 46, 0.08);
}
/* Avatar img sizing applies regardless of view (grid or list).
 * Prior version was grid-scoped → list view photos rendered at
 * native dimensions and overflowed the 40x40 circle. */
.member-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.members-grid .member-name {
  font-weight: 700;
  font-size: 15px;
  color: var(--navy);
  line-height: 1.25;
  margin-bottom: 2px;
}
.members-grid .member-sub {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.party-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
}
.party-badge.dem { background: var(--blue-pale); color: var(--blue); }
.party-badge.rep { background: var(--red-pale); color: var(--rep); }
.party-badge.ind { background: var(--gold-pale); color: #8a6a00; }

.members-list .member-tile {
  display: flex;
  align-items: center;
  /* Tighter horizontal rhythm + bigger avatar = denser, more
   * "directory listing" feel. Padding starts wider on the left so
   * the party stripe gets breathing room from the avatar. */
  gap: 14px;
  padding: 12px 16px 12px 22px;
  border-radius: 10px;
}
/* List view: a slim 5px LEFT color stripe (party indicator). Wider
 * than a typical 4px so it reads at a glance even when scanning a
 * long list. Top-stripe (used by grid) is suppressed by the more
 * specific selector below. */
.members-list .member-tile::before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 5px;
  height: auto;
  background: var(--border);
}
.members-list .member-tile.dem::before { background: var(--blue); }
.members-list .member-tile.rep::before { background: var(--rep); }
.members-list .member-tile.ind::before { background: var(--gold); }
.members-list .member-tile:hover { transform: translateX(3px); }
/* Bigger avatar (54px vs 40px) with the same shadow ring as grid.
 * Fills the row height proportionally and makes member faces the
 * primary visual scan target. */
.members-list .member-avatar {
  width: 54px;
  height: 54px;
  margin: 0;
  font-size: 1rem;
  flex-shrink: 0;
  box-shadow: 0 2px 6px rgba(15, 29, 46, 0.08);
}
.members-list .member-name {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1.2;
}
.members-list .member-sub {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}
.members-list .member-stack { flex: 1; min-width: 0; }
/* Party badge in list rows: slightly larger so it doesn't read as a
 * footnote next to the bigger name + avatar. */
.members-list .party-badge { padding: 4px 10px; font-size: 10.5px; }

@media (max-width: 680px) {
  .page-hero { padding: 30px 22px 34px; }
  .chamber-cards { grid-template-columns: 1fr; }
  .filter-row .view-toggle { margin-left: 0; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-weight: 600;
  padding: 0.65rem 1.15rem;
  border-radius: var(--radius);
  font-size: 0.95rem;
  transition: transform 0.15s, background 0.15s, border-color 0.15s;
}
.btn-primary {
  background: var(--blue);
  color: var(--white);
}
.btn-primary:hover { background: var(--blue-deep); }
.btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary {
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--border);
}
.btn-secondary:hover { border-color: var(--ink-soft); }
.btn-danger {
  background: var(--error);
  color: var(--white);
}

/* ---------- Member tiles ---------- */
.member-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}
.member-list { display: flex; flex-direction: column; gap: 0.5rem; }

.member-tile {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
}
.member-tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
}

/* ---------- Home hero (v5) ---------- */
#page-home { padding-top: 1rem; }

/* Unauth-only signup CTA banner. Visible only when <body> has the
   `is-unauthed` class (set in app.js after restoreSession). Subtle gold
   accent matches the brand "Source" gold without competing with the navy
   hero below. */
[data-unauth-only] { display: none; }
body.is-unauthed [data-unauth-only] { display: flex; }

.unauth-cta {
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  background: linear-gradient(135deg, #fff8e1 0%, #ffefb8 100%);
  border: 1px solid #f3d87a;
  border-radius: 14px;
  padding: 14px 22px;
  margin: 0 0 14px;
}
.unauth-cta-text {
  font-size: 0.95rem;
  color: #614500;
  line-height: 1.4;
}
.unauth-cta-text strong {
  color: var(--navy);
  font-weight: 700;
}
.unauth-cta-btn {
  flex-shrink: 0;
  background: var(--navy);
  color: #fff;
  font-weight: 600;
  font-size: 0.9rem;
  padding: 10px 20px;
  border-radius: 999px;
  border: 0;
  cursor: pointer;
  transition: background 0.15s;
}
.unauth-cta-btn:hover { background: #1c3a6c; }

/* Signed-in-but-unverified banner. Mirror layout of .unauth-top-cta but
   uses red-orange tones — it's a "please act" banner, not a marketing
   pitch. Hidden by default (visibility flipped via .is-visible class
   added by updateUnverifiedBanner() in auth.js). */
.unverified-banner {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  background: linear-gradient(135deg, #fff4eb 0%, #ffe1c8 100%);
  border: 1px solid #f3b87a;
  border-radius: 14px;
  padding: 12px 22px;
  margin: 16px auto 0;
  max-width: 1200px;
}
.unverified-banner.is-visible { display: flex; }
.unverified-text {
  font-size: 0.95rem;
  color: #6a3d00;
  line-height: 1.4;
}
.unverified-text strong {
  color: var(--navy);
  font-weight: 700;
}
.unverified-btn {
  flex-shrink: 0;
  background: var(--navy);
  color: #fff;
  font-weight: 600;
  font-size: 0.9rem;
  padding: 10px 20px;
  border-radius: 999px;
  border: 0;
  cursor: pointer;
  transition: background 0.15s;
}
.unverified-btn:hover { background: #1c3a6c; }
.unverified-btn:disabled { opacity: 0.6; cursor: default; }

/* Footer link inside the login form (right-justified "Forgot password?"). */
.auth-form-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}
.auth-form-link {
  color: var(--blue);
  font-size: 13px;
  text-decoration: none;
}
.auth-form-link:hover { text-decoration: underline; }

/* Verify-email + reset-password landing pages. Centered card with the
   form / status message inside. Both pages share the same shell. */
.auth-flow-card {
  max-width: 480px;
  margin: 32px auto;
  padding: 32px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.auth-flow-form .field { margin-bottom: 16px; }
.auth-flow-form .field-hint {
  margin-top: 4px;
  font-size: 12px;
  color: var(--ink-soft);
}
.auth-flow-form .btn { width: 100%; }
.auth-flow-form .form-error:empty { display: none; }
.auth-flow-form .form-error {
  margin: 0 0 16px;
  padding: 12px 16px;
  background: var(--red-pale);
  border: 1px solid #f5c8c5;
  border-radius: 8px;
  color: var(--rep);
  font-size: 13px;
}
.auth-flow-status {
  text-align: center;
  padding: 16px 0;
}
.auth-flow-status .spinner {
  margin: 0 auto 16px;
}
.auth-flow-status p {
  margin: 8px 0;
  color: var(--ink);
  font-size: 14px;
}
.auth-flow-status .btn {
  margin-top: 16px;
}
.auth-flow-result h2 {
  margin: 0 0 12px;
  font-size: 18px;
  font-weight: 600;
  color: var(--navy);
}
.auth-flow-result p { margin: 12px 0; color: var(--ink); font-size: 14px; line-height: 1.5; }
.auth-flow-success h2 { color: var(--green, #1a9660); }
.auth-flow-error h2 { color: var(--rep); }
.auth-flow-card .hidden { display: none !important; }

/* Preferences page card. One row per setting; right side has a control
   (toggle for on/off settings, dropdown / input for others later). */
.prefs-card {
  max-width: 720px;
  margin: 32px auto;
  padding: 0;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.prefs-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 24px 28px;
  border-bottom: 1px solid var(--border);
}
.prefs-row:last-child { border-bottom: 0; }
.prefs-row-text { flex: 1; min-width: 0; }
.prefs-row-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--navy);
  margin-bottom: 4px;
}
.prefs-row-desc {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.prefs-status:empty { display: none; }
.prefs-status {
  padding: 12px 28px 20px;
  font-size: 13px;
  color: var(--ink-soft);
}

/* (Removed: .prefs-subscription-card and .prefs-sub-* — Subscription
 * management lives at /pro and the user-menu's "Manage Pro" link, not
 * inline on Preferences. Kept the existing .prefs-card / .prefs-row
 * for the vote-digest toggle.) */

/* My HQ Pro pill — top-right of the .accent-myreps page-hero, only
 * visible when a Pro member is signed in (rendered conditionally by
 * myreps.js renderShell). Consistent visual language with the user-
 * menu badge + the Pro page's member badge. */
/* ──────────────────────────────────────────────────────────────────
 * Pro Member pill — 3D glossy gold badge.
 *
 * Visual language inspired by premium-tier badges (LinkedIn Premium,
 * Discord Nitro, physical gold-foil membership cards). The depth
 * comes from layered effects, not from any single trick:
 *
 *   1. Three-stop gradient (champagne → brand gold → amber)
 *      gives the surface a curved-metal look.
 *   2. ::before pseudo-element with a white-to-transparent gradient
 *      adds the specular highlight at the top — like light hitting
 *      a polished surface.
 *   3. Layered box-shadows:
 *        - inset top highlight (rim light)
 *        - inset bottom shadow (groove / depth at the base)
 *        - close drop shadow (contact shadow on the hero card)
 *        - soft outer drop shadow (elevation off the page)
 *   4. 1px darker-gold border crisps the edge against the navy
 *      background.
 *   5. Subtle text-shadow lifts the navy text above the metallic
 *      surface without screaming.
 *   6. Hover bumps the gradient brighter + lifts 2px + amplifies
 *      the shadow — the badge feels alive when interacted with.
 * ─────────────────────────────────────────────────────────────── */
/* ──────────────────────────────────────────────────────────────────
 * Pro Member badge — chrome bezel + royal-purple jewel + large gold star.
 *
 * Static, non-interactive status badge (renders as <span>, no click
 * affordance). Visual language inspired by the round glossy buttons
 * from the design references: bright silver metallic bezel wrapping
 * a deep violet jewel center, with a strong specular highlight on
 * the top half. The custom gold star dominates the left side —
 * sized large so it reads as the badge's emblem, not a decoration.
 * ─────────────────────────────────────────────────────────────── */
.myhq-pro-pill {
  position: absolute;
  top: 18px;
  right: 24px;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 8px 18px 8px 14px;
  border-radius: 999px;
  font-size: 0.88rem;
  font-weight: 800;
  letter-spacing: 0.045em;
  color: #ffffff;
  z-index: 2;
  overflow: hidden;                       /* clips the ::before highlight */

  /* Royal-purple jewel: light top → deep base, three-stop for depth */
  background: linear-gradient(
    180deg,
    #6d3fa3 0%,
    #4b2879 50%,
    #2e174f 100%
  );

  /* Chrome bezel: silver outer ring */
  border: 2px solid #c8c8c8;

  /* Layered shadows recreate the metallic bezel + jewel depth */
  box-shadow:
    inset 0 0 0 1px #f0f0f0,                  /* bright inner chrome edge */
    inset 0 1px 0 rgba(255, 255, 255, 0.45),  /* top rim light */
    inset 0 -2px 3px rgba(0, 0, 0, 0.35),     /* bottom inner groove */
    0 0 0 1px rgba(0, 0, 0, 0.3),             /* dark outer ring (settles bezel on bg) */
    0 4px 12px rgba(0, 0, 0, 0.35);           /* drop shadow for elevation */

  /* Text-shadow lifts the white letters off the purple */
  text-shadow:
    0 1px 1px rgba(0, 0, 0, 0.55),
    0 0 1px rgba(0, 0, 0, 0.4);
}

/* Static specular highlight — top half catches a soft reflection. */
.myhq-pro-pill::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 55%;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.4) 0%,
    rgba(255, 255, 255, 0.08) 60%,
    rgba(255, 255, 255, 0) 100%
  );
  border-radius: 999px 999px 0 0;
  pointer-events: none;
  z-index: 1;
}

/* Lift content above the highlight layer */
.myhq-pro-pill > * {
  position: relative;
  z-index: 2;
}

/* Custom SVG star — bumped to 22px so it dominates the badge as the
 * primary emblem. Gradient + stroke live in the inline SVG; this rule
 * sizes it and drops a soft shadow so the star "floats" off the
 * jewel surface. */
.myhq-pro-pill .myhq-pro-pill-star {
  width: 22px;
  height: 22px;
  display: inline-flex;
  flex: 0 0 auto;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}

/* The page-hero needs position:relative for the pill's absolute
 * positioning to anchor against it. .accent-myreps is the specific
 * variant on My HQ; we're not changing the base .page-hero. */
.page-hero.accent-myreps { position: relative; }
@media (max-width: 600px) {
  .myhq-pro-pill { top: 12px; right: 14px; padding: 5px 10px; font-size: 0.75rem; }
}

/* iOS-style on/off toggle. Hides the native checkbox but keeps it
   keyboard-accessible (focus ring on the slider). */
.toggle-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
}
.toggle-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.toggle-slider {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
  background: var(--border);
  border-radius: 999px;
  transition: background 0.18s;
  flex-shrink: 0;
}
.toggle-slider::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  transition: transform 0.18s;
}
.toggle-switch input:checked + .toggle-slider { background: var(--green, #1a9660); }
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(20px); }
.toggle-switch input:focus-visible + .toggle-slider { outline: 2px solid var(--blue); outline-offset: 2px; }
.toggle-label {
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
  min-width: 24px;
}

/* Blog — index page (post list + tag sidebar) and per-post detail.
   Markdown body is rendered via marked → bodyHtml; styling here covers
   typography for the rendered HTML (headings, code, blockquotes, etc.). */
.blog-page-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 32px;
  align-items: start;
  margin-top: 24px;
}
@media (max-width: 920px) {
  .blog-page-grid { grid-template-columns: 1fr; }
}
.blog-loading {
  padding: 24px;
  text-align: center;
  color: var(--ink-soft);
  font-size: 14px;
}
.blog-posts {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.blog-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  transition: border-color 0.15s, transform 0.15s;
}
.blog-card:hover {
  border-color: var(--blue);
  transform: translateY(-1px);
}
.blog-card-link {
  display: block;
  padding: 22px 24px;
  color: inherit;
  text-decoration: none;
}
.blog-card-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.blog-card-meta time { font-variant-numeric: tabular-nums; }
.blog-card-title {
  font-family: var(--font-serif);
  font-size: 22px;
  line-height: 1.25;
  color: var(--navy);
  margin: 0 0 8px;
}
.blog-card-excerpt {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink);
  margin: 0 0 12px;
}
.blog-card-readmore {
  font-size: 13px;
  color: var(--blue);
  font-weight: 600;
}
.blog-tag-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  background: var(--off-white, #fafbfc);
  color: var(--ink-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  text-decoration: none;
  text-transform: lowercase;
}
.blog-tag-pill:hover {
  border-color: var(--blue);
  color: var(--blue);
}
.blog-tag-count {
  font-size: 10.5px;
  color: var(--ink-soft);
}
.blog-sidebar {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.blog-sidebar-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 20px;
}
.blog-sidebar-card h3 {
  margin: 0 0 12px;
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 400;
  color: var(--navy);
}
.blog-tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.blog-sidebar-text {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
}
.blog-sidebar-text a {
  color: var(--blue);
  text-decoration: none;
  font-weight: 600;
}
.blog-sidebar-text a:hover { text-decoration: underline; }

/* Single post detail */
.blog-post {
  max-width: 760px;
  margin: 0 auto;
}
.blog-post-hero {
  padding-bottom: 24px;
}
.blog-post-title {
  margin: 0 0 14px;
  font-size: 36px;
  line-height: 1.15;
}
.blog-post-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.8);
}
.blog-post-author { color: rgba(255, 255, 255, 0.85); }
.blog-post-meta .blog-tag-pill {
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.9);
  border-color: rgba(255, 255, 255, 0.2);
}
.blog-post-meta .blog-tag-pill:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.blog-post-body {
  padding: 32px 0;
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink);
}
.blog-post-body h2 {
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 400;
  color: var(--navy);
  margin: 36px 0 14px;
  line-height: 1.25;
}
.blog-post-body h3 {
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 400;
  color: var(--navy);
  margin: 28px 0 12px;
}
.blog-post-body p { margin: 0 0 18px; }
.blog-post-body a {
  color: var(--blue);
  text-decoration: underline;
  text-decoration-color: rgba(46, 125, 247, 0.4);
  text-underline-offset: 3px;
}
.blog-post-body a:hover { text-decoration-color: var(--blue); }
.blog-post-body ul,
.blog-post-body ol {
  margin: 0 0 18px;
  padding-left: 24px;
}
.blog-post-body li { margin-bottom: 8px; }
.blog-post-body blockquote {
  margin: 0 0 18px;
  padding: 12px 18px;
  border-left: 3px solid var(--blue);
  background: var(--off-white, #fafbfc);
  font-style: italic;
  color: var(--ink-soft);
}
.blog-post-body code {
  background: var(--off-white, #fafbfc);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 14px;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}
.blog-post-body pre {
  background: #0f1d2e;
  color: #eef0f4;
  padding: 16px 20px;
  border-radius: 8px;
  overflow-x: auto;
  font-size: 13.5px;
  line-height: 1.5;
  margin: 0 0 18px;
}
.blog-post-body pre code {
  background: transparent;
  border: 0;
  color: inherit;
  padding: 0;
  font-size: 13.5px;
}
.blog-post-body hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 28px 0;
}
.blog-post-foot {
  padding: 24px 0;
  border-top: 1px solid var(--border);
  margin-top: 24px;
}
.blog-empty {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0;
}

/* Donation page (Stripe Checkout). Single big card with amount picker
   + optional email + Donate button. Stripe-hosted Checkout means we
   render no card form here — just the amount selector. */
.donate-card {
  max-width: 520px;
  margin: 32px auto;
  padding: 28px 32px 32px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.donate-test-banner {
  margin: 0 0 18px;
  padding: 10px 14px;
  background: #fff8e1;
  border: 1px solid #f3d87a;
  border-radius: 8px;
  font-size: 12.5px;
  color: #614500;
  line-height: 1.45;
}
.donate-test-banner.hidden { display: none; }
.donate-test-banner code {
  background: rgba(0, 0, 0, 0.06);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 12px;
}
.donate-card-title {
  margin: 0 0 14px;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 400;
  color: var(--navy);
}
.donate-amount-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 18px;
}
.donate-amount-btn {
  background: var(--off-white, #fafbfc);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 12px 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
  cursor: pointer;
  transition: all 0.15s;
}
.donate-amount-btn:hover {
  border-color: var(--blue);
  background: #fff;
}
.donate-amount-btn.active {
  background: var(--navy);
  color: #fff;
  border-color: var(--navy);
}
.donate-custom-row {
  margin-bottom: 14px;
}
.donate-custom-row.hidden { display: none; }
.donate-custom-label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
}
.donate-custom-inputwrap {
  position: relative;
  display: flex;
  align-items: center;
}
.donate-custom-prefix {
  position: absolute;
  left: 12px;
  font-size: 16px;
  color: var(--ink-soft);
  font-weight: 500;
}
.donate-custom-inputwrap input {
  width: 100%;
  padding: 10px 12px 10px 26px;
  font-size: 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: inherit;
  font-variant-numeric: tabular-nums;
}
.donate-email-row {
  margin: 0 0 14px;
}
.donate-email-row label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 500;
}
.donate-optional {
  font-weight: 400;
  font-style: italic;
  color: var(--ink-soft);
}
.donate-email-row input {
  width: 100%;
  padding: 10px 12px;
  font-size: 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: inherit;
}
.donate-error:empty { display: none; }
.donate-error {
  margin: 0 0 12px;
  padding: 10px 14px;
  background: var(--red-pale);
  border: 1px solid #f5c8c5;
  border-radius: 8px;
  font-size: 13px;
  color: var(--rep);
}
.donate-submit {
  width: 100%;
  padding: 14px;
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 14px;
}
.donate-submit:disabled {
  opacity: 0.6;
  cursor: default;
}
.donate-foot {
  margin: 0;
  font-size: 11.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  text-align: center;
}
.donate-foot a {
  color: var(--blue);
  text-decoration: none;
}
.donate-foot a:hover { text-decoration: underline; }

/* Top-of-main CTA banner. Same visual treatment as the home-hero
   .unauth-cta but lives outside the .page sections so it persists across
   navigation. Visibility is gated by:
     1. body.is-unauthed (the [data-unauth-only] rule above) — only shown
        to signed-out visitors.
     2. The :has() rules below — hidden when the user is on a page that
        has its own hero CTA (#page-home) or where a signup prompt would
        be off-tone (legal pages, credits).
   Same .unauth-cta-* inner classes so we get the gold-card styling for
   free. */
.unauth-top-cta {
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  background: linear-gradient(135deg, #fff8e1 0%, #ffefb8 100%);
  border: 1px solid #f3d87a;
  border-radius: 14px;
  padding: 12px 22px;
  margin: 16px auto 0;
  max-width: 1200px;
}
body.is-unauthed:has(#page-home.active) .unauth-top-cta,
body.is-unauthed:has(#page-about.active) .unauth-top-cta,
body.is-unauthed:has(#page-privacy.active) .unauth-top-cta,
body.is-unauthed:has(#page-terms.active) .unauth-top-cta,
body.is-unauthed:has(#page-credits.active) .unauth-top-cta {
  display: none;
}
.hero {
  background: linear-gradient(135deg, var(--navy) 0%, #152d50 55%, #1a3a6e 100%);
  padding: 72px 40px 90px;
  text-align: center;
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  color: #fff;
}
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 72% 40%, rgba(46, 125, 247, 0.18) 0%, transparent 55%),
    radial-gradient(ellipse at 18% 75%, rgba(245, 166, 35, 0.09) 0%, transparent 50%);
  pointer-events: none;
}
.hero-badge {
  display: inline-block;
  background: rgba(245, 166, 35, 0.14);
  border: 1px solid rgba(245, 166, 35, 0.32);
  color: #f5a623;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 5px 14px;
  border-radius: 20px;
  margin-bottom: 20px;
  position: relative;
}
.hero h1 {
  font-family: var(--font-serif);
  font-size: clamp(32px, 5vw, 56px);
  color: #fff;
  line-height: 1.1;
  margin: 0 0 15px;
  position: relative;
  font-weight: 400;
}
.hero h1 em {
  color: #f5a623;
  font-style: normal;
}
.hero > p {
  color: rgba(255, 255, 255, 0.62);
  font-size: 16px;
  max-width: 500px;
  margin: 0 auto 44px;
  line-height: 1.65;
  position: relative;
}
.branch-cards {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
  position: relative;
}
.branch-card {
  background: rgba(255, 255, 255, 0.065);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  padding: 26px 22px 22px;
  width: 188px;
  cursor: pointer;
  transition: all 0.26s cubic-bezier(0.34, 1.5, 0.64, 1);
  backdrop-filter: blur(12px);
  text-align: center;
  color: #fff;
  /* The card is now a <button> (2026-05-20) — reset the browser
   * defaults so the visual design from the prior <div> implementation
   * stays unchanged. touch-action: manipulation kills the 300ms tap
   * delay iOS Safari adds to elements that look pinch-zoomable. */
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  touch-action: manipulation;
}
@media (hover: hover) {
  .branch-card:hover {
    background: rgba(255, 255, 255, 0.13);
    border-color: rgba(255, 255, 255, 0.26);
    transform: translateY(-7px) scale(1.025);
    box-shadow: 0 22px 64px rgba(0, 0, 0, 0.32);
  }
}
.branch-card:active { background: rgba(255, 255, 255, 0.18); }
.branch-icon {
  font-size: 32px;
  margin-bottom: 11px;
  display: block;
  line-height: 1;
}
.branch-card h3 {
  color: #fff;
  font-size: 14.5px;
  font-weight: 600;
  margin: 0 0 5px;
  font-family: var(--font-sans);
  letter-spacing: 0;
}
.branch-card p {
  color: rgba(255, 255, 255, 0.46);
  font-size: 11px;
  margin: 0;
  line-height: 1.5;
}
.branch-count {
  display: inline-block;
  margin-top: 10px;
  font-size: 10.5px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 20px;
  background: rgba(245, 166, 35, 0.18);
  color: #f5a623;
}

/* ---------- Stats strip ---------- */
.stats-strip {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  margin: 20px 0;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}
.stat-item {
  padding: 18px 38px;
  text-align: center;
  border-right: 1px solid var(--border);
  flex: 1 0 auto;
}
.stat-item:last-child { border-right: none; }
.stat-num {
  font-family: var(--font-serif);
  font-size: 26px;
  color: var(--navy);
  display: block;
  line-height: 1.15;
}
.stat-label {
  font-size: 11px;
  color: #8a96b0;
  text-transform: uppercase;
  letter-spacing: 0.9px;
  font-weight: 500;
}

/* ---------- Map container (home) ---------- */
.map-section { margin: 0 0 24px; }
.map-container {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px;
  overflow: hidden;
}
.map-container .map-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 5px;
}
.map-container .map-head h3 {
  font-family: var(--font-serif);
  font-size: 19px;
  color: var(--navy);
  margin: 0;
  font-weight: 400;
}
.map-container .map-head #map-hover-label {
  font-size: 13px;
  color: var(--blue);
  font-weight: 600;
  min-height: 20px;
}
.map-container .map-subtext {
  font-size: 12.5px;
  color: #4a5670;
  margin: 0 0 20px;
}
.map-container .map-legend {
  display: flex;
  gap: 18px;
  margin-top: 16px;
  justify-content: center;
  flex-wrap: wrap;
}
.map-container .legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: #4a5670;
}
.map-container .legend-dot {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  display: inline-block;
}
.map-container .legend-dot.dem { background: var(--dem); }
.map-container .legend-dot.rep { background: var(--rep); }
.map-container .legend-dot.split { background: #7c4fa0; }

/* ---------- Feature cards section ---------- */
.home-section { padding: 40px 0; }
.section-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 8px;
}
.home-section-title {
  font-family: var(--font-serif);
  font-size: 28px;
  color: var(--navy);
  margin-bottom: 32px;
  line-height: 1.2;
}
.features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
}

/* "This Week in Congress" feed — two-column list of recent votes +
   recent bills. Rendered by renderHomeFeed() in app.js. Each item is
   a clickable card linking to its detail (or congress.gov for items
   we can't deep-link to yet). */
.home-feed-section { padding-top: 24px; }
.home-feed-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
@media (max-width: 768px) {
  .home-feed-grid { grid-template-columns: 1fr; gap: 16px; }
}
.home-feed-col {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px 22px;
}
.home-feed-col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.home-feed-col-head h3 {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 400;
  color: var(--navy);
}
.home-feed-more {
  font-size: 12.5px;
  color: var(--blue);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
}
.home-feed-more:hover { text-decoration: underline; }
.home-feed-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.home-feed-loading,
.home-feed-empty {
  font-size: 13px;
  color: var(--ink-soft);
  padding: 8px 0;
  text-align: center;
}
.home-feed-item {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--off-white, #fafbfc);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
.home-feed-item:hover {
  border-color: var(--blue);
  transform: translateY(-1px);
}
.home-feed-item-meta {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 4px;
  font-size: 11px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}
.home-feed-item-date { color: var(--ink-soft); }
.home-feed-item-chamber {
  background: var(--surface-2, #eef0f4);
  color: var(--ink);
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 700;
}
.home-feed-item-title {
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--navy);
  font-weight: 500;
  margin-bottom: 6px;
}
.home-feed-item-desc {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--ink-soft);
  font-weight: 400;
  line-height: 1.4;
}
.home-feed-item-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 4px;
}
.home-feed-item-result {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  letter-spacing: 0.04em;
  background: var(--gold-pale);
  color: #8a6a00;
}
.home-feed-item-result.good { background: var(--green-pale); color: #0f6a44; }
.home-feed-item-result.bad { background: var(--red-pale); color: var(--rep); }
.home-feed-item-result.pending { background: var(--gold-pale); color: #8a6a00; }
.home-feed-item-result.status-enacted { background: var(--green-pale); color: #0f6a44; }
.home-feed-item-result.status-passed-house { background: var(--blue-pale); color: var(--blue); }
.home-feed-item-result.status-passed-senate { background: rgba(11, 37, 69, 0.08); color: var(--navy); }
.home-feed-item-result.status-failed { background: var(--red-pale); color: var(--rep); }
.home-feed-item-result.status-introduced { background: var(--gold-pale); color: #8a6a00; }
.home-feed-item-sponsor {
  font-size: 11.5px;
  color: var(--ink-soft);
}
.feature-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px;
  transition: box-shadow 0.2s, transform 0.2s;
  cursor: default;
}
.feature-card-link { cursor: pointer; }
.feature-card-link:hover {
  box-shadow: 0 4px 24px rgba(11, 31, 58, 0.1);
  transform: translateY(-2px);
}
.feature-icon {
  width: 40px;
  height: 40px;
  background: #e8f0ff;
  border-radius: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  margin-bottom: 12px;
  line-height: 1;
}
.feature-card h4 {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 6px;
  color: var(--navy);
  font-family: var(--font-sans);
  letter-spacing: 0;
}
.feature-card p {
  font-size: 12.5px;
  color: #4a5670;
  line-height: 1.6;
  margin: 0 0 12px;
}
.feature-cta {
  font-size: 12px;
  font-weight: 600;
  color: var(--blue);
}

@media (max-width: 680px) {
  .hero { padding: 40px 16px 56px; }
  .hero h1 { font-size: clamp(26px, 7.5vw, 40px); }
  .branch-card { width: calc(50% - 8px); padding: 18px 14px 16px; }
  /* When stats wrap to multiple rows the per-cell border-right
   * leaves a stray vertical line at row-ends. Drop the borders on
   * mobile and rely on the gap + wrap for visual separation. */
  .stat-item { padding: 14px 20px; border-right: none; }
  .stats-strip { gap: 4px; }
  .map-container { padding: 18px; }
}

/* Smaller phones — branch cards become single-column. */
@media (max-width: 420px) {
  .branch-card { width: 100%; }
}

.member-photo {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  font-weight: 700;
  font-size: 1.35rem;
  font-family: var(--font-serif);
  overflow: hidden;
  background-position: center;
  background-size: cover;
}
.member-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.member-name { font-weight: 600; font-size: 0.98rem; }
.member-meta { font-size: 0.85rem; color: var(--ink-soft); }

.member-row {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  cursor: pointer;
  transition: background 0.15s;
}
.member-row:hover { background: var(--surface-2); }
.member-row .member-photo { width: 42px; height: 42px; font-size: 0.9rem; }

/* ---------- Party badges ---------- */
.badge-party {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--white);
  vertical-align: middle;
}
.badge-party.dem { background: var(--dem); }
.badge-party.rep { background: var(--rep); }
.badge-party.ind { background: var(--ind); color: #3a2f00; }

/* ---------- Filter tabs & controls ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-bottom: 1.25rem;
}
.filter-tabs {
  display: inline-flex;
  background: var(--surface-2);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.filter-tabs button {
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--ink-soft);
  font-weight: 600;
}
.filter-tabs button.active {
  background: var(--white);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.filter-select, .filter-input {
  height: 36px;
  padding: 0 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--white);
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink);
}
.filter-input { min-width: 200px; }

/* ---------- Banner ---------- */
.banner {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  margin-bottom: 1rem;
  font-size: 0.9rem;
}
.banner-warn { background: #fff4d9; color: #7a5500; border: 1px solid #f3d87a; }

/* ---------- Spinner ---------- */
.spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--border);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin: 2rem auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Auth modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(11, 37, 69, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 1rem;
}
.modal-overlay.open { display: flex; animation: fadeIn 0.2s ease; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.auth-card {
  background: var(--white);
  border-radius: var(--radius-lg);
  max-width: 440px;
  width: 100%;
  padding: 1.75rem;
  box-shadow: var(--shadow-lg);
  animation: fadeUp 0.25s ease;
  /* User feedback 2026-05-20: keep the modal the SAME size whether
   * the user is on the Sign In tab or Create Account tab. Sign In's
   * natural height is ~520px. Capping max-height at that figure
   * forces the longer Create Account form to scroll inside the
   * modal instead of growing it. Falls back to 90vh on shorter
   * viewports so the modal still fits on small phones. */
  max-height: min(540px, 90vh);
  display: flex;
  flex-direction: column;
}

/* Tabs stay pinned at the top of the modal — they're flex-shrink: 0
 * so the form (below) eats any remaining vertical space and scrolls
 * within itself. This keeps the tab switcher always reachable even
 * when the user has scrolled to the bottom of the longer Create
 * Account form. */
.auth-card .auth-tabs { flex-shrink: 0; }
.auth-card .auth-context,
.auth-card .auth-error { flex-shrink: 0; }
.auth-card .auth-form {
  min-height: 0; /* allows the flex item to shrink below its content */
}
.auth-card .auth-form.active {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Keep the submit button reachable: padding-bottom adds breathing
   * room so it's never flush against the modal edge after scrolling. */
  padding-bottom: 4px;
}

.auth-tabs {
  display: flex;
  background: var(--surface-2);
  border-radius: var(--radius);
  padding: 4px;
  margin-bottom: 1.25rem;
}
.auth-tabs button {
  flex: 1;
  padding: 0.55rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  color: var(--ink-soft);
}
.auth-tabs button.active {
  background: var(--white);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

.auth-form { display: none; flex-direction: column; gap: 0.75rem; }
.auth-form.active { display: flex; }

/* min-width: 0 lets .field shrink below its intrinsic content width when it
   sits inside a flex/grid track that's narrower — without it, the default
   min-width: auto keeps the cell as wide as its widest atomic child (a text
   input has a ~170-200px min-content width by default), and the parent grid
   blows past its container width. Combined with `width: 100%; box-sizing:
   border-box` on the input itself, this keeps the field-row pair (First /
   Last name) inside the 440px-wide auth modal. */
.field { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.field label { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); }
.field input {
  width: 100%;
  box-sizing: border-box;
  height: 42px;
  padding: 0 0.85rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--white);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.field input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(28, 95, 216, 0.12);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
/* State + ZIP on one row, both sized to their content. State holds two
   letters (~"CA"), ZIP holds five digits (~"12345"). Fixed widths keep
   each input's visual size proportional to what it actually contains so
   they don't read as oversized empty boxes. The remaining horizontal
   space sits to the right of the ZIP, leaving a clean left-aligned pair
   beneath the City field. */
.field-row-state-zip {
  display: grid;
  grid-template-columns: 90px 110px;
  gap: 0.6rem;
}

.password-strength {
  display: flex;
  gap: 4px;
  margin-top: 0.3rem;
}
.password-strength span {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  transition: background 0.2s;
}
.password-strength.weak span:nth-child(1) { background: var(--error); }
.password-strength.fair span:nth-child(-n+2) { background: var(--warn); }
.password-strength.strong span { background: var(--accent); }
.password-strength-label {
  font-size: 0.75rem;
  color: var(--ink-soft);
  margin-top: 0.2rem;
}

.auth-error {
  background: #fde7e6;
  color: #8b1a14;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  display: none;
}
.auth-error.active { display: block; }

/* Contextual line above the auth form, shown when the gate intercepts a
   navigation attempt (e.g. "Sign in or create a free account to view
   California."). Visually distinct from .auth-error — informational, not
   alarming. Hidden via the `hidden` attribute when no message is set. */
.auth-context {
  background: #eaf2ff;
  color: #1d4f9e;
  border: 1px solid #bfd4f5;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  margin-bottom: 0.9rem;
  line-height: 1.4;
}

/* ---------- Profile (v5) ---------- */
.profile-hero {
  background: linear-gradient(135deg, var(--navy) 0%, #152d50 55%, #1a3a6e 100%);
  border-radius: 16px;
  padding: 32px 36px 30px;
  margin-bottom: 1.5rem;
  color: #fff;
  position: relative;
  overflow: hidden;
}
.profile-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 82% 30%, rgba(46, 125, 247, 0.2) 0%, transparent 55%),
    radial-gradient(ellipse at 12% 82%, rgba(245, 166, 35, 0.09) 0%, transparent 50%);
  pointer-events: none;
}
.profile-hero > * { position: relative; }
.profile-hero-row {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  flex-wrap: wrap;
}
.profile-avatar {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: linear-gradient(135deg, #dde3f0, #bcc7e0);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--navy);
  font-weight: 700;
  font-size: 2rem;
  font-family: var(--font-serif);
  overflow: hidden;
  border: 3px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
}
.profile-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.profile-hero-text {
  flex: 1 1 280px;
  min-width: 0;
}
.profile-hero-text .party-badge {
  margin-bottom: 10px;
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 3px 10px;
}
.profile-hero-text .party-badge.on-dark.dem {
  background: rgba(46, 125, 247, 0.22);
  color: #9fc0ff;
}
.profile-hero-text .party-badge.on-dark.rep {
  background: rgba(217, 50, 47, 0.22);
  color: #ffb3b0;
}
.profile-hero-text .party-badge.on-dark.ind {
  background: rgba(245, 166, 35, 0.22);
  color: #ffd892;
}
.profile-name {
  font-family: var(--font-serif);
  font-size: clamp(28px, 4.2vw, 42px);
  color: #fff;
  line-height: 1.12;
  margin: 0 0 8px;
  font-weight: 400;
}
.profile-title {
  color: rgba(255, 255, 255, 0.66);
  font-size: 15px;
  line-height: 1.5;
}

.breadcrumb {
  font-size: 0.85rem;
  opacity: 0.85;
  margin-bottom: 1rem;
}
.breadcrumb a { text-decoration: underline; cursor: pointer; }

.profile-tabs {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 6px 10px;
  display: flex;
  gap: 2px;
  margin-bottom: 1.25rem;
  overflow-x: auto;
}
.profile-tabs .tab {
  padding: 10px 14px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}
.profile-tabs .tab:hover { color: var(--navy); }
.profile-tabs .tab.active {
  color: var(--navy);
  border-bottom-color: var(--gold);
}

/* Hero actions row (Watch + Compare chips). Sits at the top-right of
 * the hero on desktop, flows to the bottom of the hero on mobile so
 * the chips don't overlap the title. */
.profile-actions {
  position: absolute;
  top: 20px;
  right: 24px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
}
/* When the actions row contains the watch button via the slot, that
 * slot is no longer absolutely positioned itself — its parent row is. */
.profile-actions .profile-watch-slot {
  position: static;
  top: auto;
  right: auto;
}

/* Compare is duplicated: hero chip (mobile only) AND tab in the
 * .profile-tabs strip (desktop only). Hide each copy at the wrong
 * viewport so the user only sees one. Differentiated visibility is
 * intentional (user request 2026-05-20): mobile gets the
 * touch-friendly chip in the hero, desktop gets the conventional
 * tab next to its peers. */
.profile-action-chip[data-profile-tab="compare"] { display: inline-flex; }
.tab-compare-desktop { display: inline-block; }
@media (max-width: 600px) {
  /* Desktop Compare tab hidden on mobile. */
  .tab-compare-desktop { display: none; }
}
@media (min-width: 601px) {
  /* Mobile Compare chip hidden on desktop. */
  .profile-action-chip[data-profile-tab="compare"] { display: none; }
}

/* Compare chip. Styled to match Watch's visual language — white pill
 * on the dark hero gradient, gold accent when active (Compare panel
 * visible). The data-profile-tab="compare" attribute hooks into the
 * existing top-level tab-switch delegator. */
.profile-action-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: var(--navy);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  touch-action: manipulation;
  white-space: nowrap;
}
@media (hover: hover) {
  .profile-action-chip:hover {
    background: var(--white);
    border-color: var(--gold);
    color: #8c5c12;
  }
}
.profile-action-chip:active { background: var(--white); }
.profile-action-chip.active {
  background: rgba(245, 166, 35, 0.95);
  border-color: var(--gold);
  color: #4a2f06;
}
.profile-action-chip .chip-ic { font-size: 14px; line-height: 1; }

.profile-panel { display: none; animation: fadeUp 0.25s ease-out; }
.profile-panel.active { display: block; }

.profile-grid {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 1.75rem;
  align-items: start;
}
.info-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px 22px;
  height: fit-content;
  position: sticky;
  top: calc(var(--header-h) + 1rem);
}
.info-card-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 14px;
}
.info-row {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 10px 0;
  font-size: 13.5px;
  border-bottom: 1px solid var(--border);
}
.info-row:last-child { border-bottom: none; }
.info-k { color: var(--ink-soft); }
.info-v { color: var(--navy); font-weight: 600; text-align: right; }

.bio-col h2 {
  font-family: var(--font-serif);
  font-size: 26px;
  color: var(--navy);
  font-weight: 400;
  margin: 0 0 12px;
}
.bio p {
  margin: 0 0 14px;
  color: var(--ink-soft);
  font-size: 14.5px;
  line-height: 1.7;
}

.align-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px 24px;
  margin-top: 18px;
}
.align-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 14px;
}
.align-title {
  font-family: var(--font-serif);
  font-size: 18px;
  color: var(--navy);
  font-weight: 400;
  margin-bottom: 2px;
}
.align-sub {
  font-size: 12.5px;
  color: var(--ink-soft);
}
.align-score {
  font-family: var(--font-serif);
  color: var(--navy);
  line-height: 1;
  white-space: nowrap;
}
.align-num { font-size: 34px; font-weight: 400; }
.align-denom { font-size: 14px; color: var(--ink-soft); margin-left: 2px; }
.align-bar {
  height: 8px;
  background: var(--off-white);
  border-radius: 999px;
  overflow: hidden;
}
.align-fill {
  height: 100%;
  background: var(--navy);
  border-radius: 999px;
  transition: width 0.4s ease;
}
.align-fill.party-dem { background: var(--blue); }
.align-fill.party-rep { background: var(--rep); }
.align-fill.party-ind { background: var(--gold); }

/* Votes */
.banner {
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  margin-bottom: 0.9rem;
}
.banner-warn { background: #fff4dd; color: #7a5700; border: 1px solid #f2d68a; }
.banner-ok { background: #e8f6ee; color: #1c5a34; border: 1px solid #b7debf; }
/* Informational, not a warning — used when state is intentional/expected
   (e.g. illustrative voting data while we don't yet have a live source). */
.banner-info { background: #eaf2ff; color: #1d4f9e; border: 1px solid #bfd4f5; }

.vote-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.vote-row {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: 0.9rem;
  align-items: center;
  padding: 0.75rem 0.9rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
/* Anchor variant: same grid, but inherits color and removes default
   underline so the row reads as a tile rather than text. The hover
   ring matches the bill-card affordance. */
a.vote-row-link {
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
  cursor: pointer;
}
a.vote-row-link:hover,
a.vote-row-link:focus-visible {
  border-color: var(--blue);
  box-shadow: 0 1px 6px rgba(45, 108, 223, 0.18);
  background: #f7faff;
  outline: none;
}
.vote-badge {
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  color: var(--white);
  background: var(--ink-soft);
}
.vote-badge.yea { background: #2ecc71; }
.vote-badge.nay { background: var(--rep); }
.vote-badge.present { background: var(--ind); color: #3a2e00; }
.vote-badge.abstain { background: var(--muted); }
.vote-text { min-width: 0; }
.vote-bill { font-weight: 600; color: var(--navy); }
.vote-desc { color: var(--ink-soft); font-size: 0.9rem; }
.vote-date { color: var(--ink-soft); font-size: 0.85rem; white-space: nowrap; }

/* Finance */
.finance-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
.finance-sub { color: var(--ink-soft); font-size: 0.92rem; }
.badge-live {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.7rem;
  background: #e8f6ee;
  color: #1c5a34;
  border: 1px solid #b7debf;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
}
.pulse {
  display: inline-block;
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(46,204,113, 0.6);
  animation: pulse 1.6s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(46,204,113, 0.6); }
  70% { box-shadow: 0 0 0 10px rgba(46,204,113, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46,204,113, 0); }
}

.finance-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-bottom: 1.25rem;
}
.kpi {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  box-shadow: var(--shadow-sm);
}
.kpi-lbl { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 0.25rem; }
.kpi-num {
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  color: var(--navy);
}
.finance-prior h4 { margin: 0 0 0.6rem; font-family: var(--font-sans); font-weight: 600; }
.finance-prior-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.75rem;
}
.finance-prior-card {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: 0.75rem 0.9rem;
}
.prior-cycle { color: var(--ink-soft); font-size: 0.8rem; }
.prior-num { font-family: var(--font-serif); font-size: 1.15rem; color: var(--navy); }
.prior-lbl { color: var(--ink-soft); font-size: 0.78rem; }
.finance-foot { margin-top: 1rem; }
.finance-foot a { color: var(--blue-deep); text-decoration: underline; font-size: 0.9rem; }

/* ════════════════════════════════════════════
   Per-member campaign finance panel (template match)
   ════════════════════════════════════════════ */
.finance-head-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.badge-fec-live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--green-pale, #e6f9f0);
  color: var(--green, #1a9660);
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 20px;
  letter-spacing: 0.4px;
}
.badge-fec-est {
  background: var(--gold-pale, #fff8e6);
  color: #b07a00;
}
.fec-pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 0 currentColor;
  animation: pulse 1.8s infinite;
}
.finance-cand-id {
  font-size: 12px;
  color: var(--ink-soft);
}
.finance-cand-id strong { color: var(--navy); }
.finance-fec-link {
  margin-left: auto;
  font-size: 12px;
  color: var(--blue, var(--dem));
  font-weight: 600;
  text-decoration: none;
}
.finance-fec-link:hover { text-decoration: underline; }

.finance-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.finance-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  overflow: hidden;
}
.finance-card-full { grid-column: 1 / -1; }
.finance-card h3 {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--navy);
  margin: 0 0 4px;
}
.finance-card-sub {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-bottom: 18px;
}
.finance-total {
  font-family: var(--font-serif);
  font-size: 36px;
  color: var(--navy);
  margin-bottom: 4px;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.finance-cycle {
  font-size: 12px;
  color: var(--ink-soft);
}
.finance-summary-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.finance-summary-row:last-child { border-bottom: none; }
.finance-summary-row .lbl { color: var(--ink-soft); }
.finance-summary-row .val {
  font-weight: 600;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.finance-note {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.finance-note a { color: var(--blue, var(--dem)); }

/* Financial Summary card — election-cycle dropdown + click-to-expand
   sections that mirror the breakdown layout on fec.gov's candidate page. */
.finance-card-summary { /* slightly more vertical room for the collapsibles */ }
.fin-summary-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.fin-summary-head h3 { margin: 0; }
.fin-cycle-picker { display: inline-flex; align-items: center; }
.fin-cycle-select {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--navy);
  background: var(--card-bg, #fff);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 28px 4px 10px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
                    linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.fin-cycle-select:focus {
  outline: 2px solid var(--blue, var(--dem));
  outline-offset: 1px;
}
.fin-time-period {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 0 0 10px;
  display: flex;
  gap: 6px;
}
.fin-time-period-label { font-weight: 600; }
.fin-time-period-val { font-variant-numeric: tabular-nums; }

.fin-section {
  border-top: 1px solid var(--border);
}
.fin-section:last-of-type { border-bottom: 1px solid var(--border); }
.fin-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  cursor: pointer;
  list-style: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  user-select: none;
}
.fin-section-head::-webkit-details-marker { display: none; }
.fin-section-head:hover { background: rgba(29, 95, 201, 0.04); }
.fin-section-arrow {
  display: inline-block;
  font-size: 11px;
  color: var(--ink-soft);
  width: 12px;
  transition: transform 150ms ease;
}
.fin-section[open] > .fin-section-head .fin-section-arrow { transform: rotate(90deg); }
.fin-section-title { flex: 1; }
.fin-section-total {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--navy);
}
.fin-section-total-cash { color: var(--green, #1a9660); }
.fin-section-body { padding: 0 0 10px 22px; }
.fin-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 0;
  font-size: 12.5px;
  color: var(--ink, #2a3550);
}
.fin-row-lbl { color: var(--ink-soft); }
.fin-row-val { font-variant-numeric: tabular-nums; font-weight: 600; }
.fin-row-indent-1 { padding-left: 14px; }
.fin-row-indent-2 { padding-left: 28px; }
.fin-row-muted {
  color: var(--ink-soft);
  font-style: italic;
}

/* ─────────────────────────────────────────────────────────────────────
   Finance v2 — sub-tabbed Campaign Finance panel (Overview / Raising /
   Spending / Outside Spending / Filings). All styles scoped under
   `.finance-v2` so they don't bleed into the other profile tabs.
   ───────────────────────────────────────────────────────────────────── */

.finance-v2 {
  --fv-card-bg: #fff;
  --fv-card-border: #e8ecf0;
  --fv-card-radius: 12px;
  --fv-gray-50: #f9fafb;
  --fv-gray-100: #f3f4f6;
  --fv-gray-300: #d1d5db;
  --fv-gray-400: #9ca3af;
  --fv-gray-500: #6b7280;
  --fv-amber: #f59e0b;
  --fv-blue-pale: var(--blue-pale);
  --fv-green-pale: var(--green-pale);
  --fv-red-pale: var(--red-pale);
  font-family: 'DM Sans', system-ui, sans-serif;
  color: var(--ink);
}

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

/* ── Meta bar (FEC badge / candidate ID / cycle dropdown / FEC link) ── */
.finv2-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
}
.finv2-meta-left, .finv2-meta-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.finv2-live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--green);
}
.finv2-live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 0 rgba(26, 150, 96, 0.6);
  animation: finv2-pulse 2s ease-in-out infinite;
}
@keyframes finv2-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(26, 150, 96, 0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(26, 150, 96, 0); }
  100% { box-shadow: 0 0 0 0 rgba(26, 150, 96, 0); }
}
.finv2-cand-id {
  font-size: 13px;
  color: var(--fv-gray-500);
}
.finv2-cand-id strong { color: var(--ink); font-weight: 600; }
.finv2-cycle-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.finv2-cycle-text {
  font-size: 13px;
  color: var(--fv-gray-500);
}
.finv2-cycle-select {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  background: var(--fv-card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 28px 6px 10px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--fv-gray-500) 50%),
                    linear-gradient(135deg, var(--fv-gray-500) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.finv2-cycle-select:focus {
  outline: 2px solid var(--blue);
  outline-offset: 1px;
}
.finv2-fec-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--blue);
  text-decoration: none;
}
.finv2-fec-link:hover { text-decoration: underline; }

/* ── Time-period buttons (under the meta bar; FEC.gov-style toggle) ──
   The row is right-justified so it sits beneath the Election dropdown on
   the right side of the meta bar. On narrow screens it wraps and the label
   stays with its buttons. */
.finv2-period-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 14px;
}
.finv2-period-row-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--fv-gray-500);
}
.finv2-period-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.finv2-period-btn {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--fv-card-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 5px 12px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-family: inherit;
}
.finv2-period-btn:hover {
  border-color: var(--blue);
  color: var(--navy);
}
.finv2-period-btn.active {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}
.finv2-period-btn:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* ── Sub-tab nav (sticky inside panel) ── */
.finv2-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  margin-bottom: 18px;
  position: sticky;
  top: 0;
  background: var(--card-bg, #fff);
  z-index: 1;
}
.finv2-tab {
  background: none;
  border: none;
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 400;
  color: var(--fv-gray-500);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
  font-family: inherit;
}
.finv2-tab:hover { color: var(--ink); }
.finv2-tab.active {
  color: var(--navy);
  font-weight: 600;
  border-bottom-color: var(--blue);
}

/* ── Tab content layout primitives ── */
.finv2-stack {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.finv2-row {
  display: grid;
  gap: 18px;
}
.finv2-row-1-1     { grid-template-columns: 1fr 1fr; }
.finv2-row-1-1p4   { grid-template-columns: 1fr 1.4fr; }
.finv2-row-1p4-1   { grid-template-columns: 1.4fr 1fr; }
.finv2-row-between {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
}
@media (max-width: 768px) {
  .finv2-row-1-1, .finv2-row-1-1p4, .finv2-row-1p4-1 {
    grid-template-columns: 1fr;
  }
}

/* ── Card ── */
.finv2-card {
  background: var(--fv-card-bg);
  border: 1px solid var(--fv-card-border);
  border-radius: var(--fv-card-radius);
  padding: 22px;
}
.finv2-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 14px;
}
.finv2-card-title {
  font-family: 'DM Serif Display', Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: 15px;
  color: var(--navy);
}
.finv2-card-sub {
  font-size: 12px;
  color: var(--fv-gray-400);
  margin-top: 2px;
}
.finv2-card-foot {
  font-size: 13px;
  color: var(--fv-gray-500);
  margin-top: 6px;
}
.finv2-bignum {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-size: 36px;
  font-weight: 700;
  color: var(--navy);
  margin: 14px 0 4px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.finv2-bignum-2 {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-size: 28px;
  font-weight: 700;
  color: var(--navy);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.finv2-headline-num {
  font-size: 26px;
  font-weight: 700;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

/* Accent left-border cards (Outside Spending support/oppose) */
.finv2-card-accent-green { border-left: 4px solid var(--green); }
.finv2-card-accent-red   { border-left: 4px solid var(--rep); }
.finv2-accent-eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.finv2-eyebrow-green { color: var(--green); }
.finv2-eyebrow-red   { color: var(--rep); }

/* ── Financial Summary list (Overview tab) ── */
.finv2-summary-list { display: flex; flex-direction: column; gap: 0; }
.finv2-summary-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-top: 1px solid var(--fv-gray-100);
}
.finv2-summary-row:first-child { border-top: none; }
.finv2-summary-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--fv-gray-500);
}
.finv2-summary-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--fv-gray-300);
}
.finv2-summary-val {
  font-size: 16px;
  font-weight: 700;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.finv2-summary-val-positive { color: var(--green); }

/* ── Itemized list (Raising / Spending) ── */
.finv2-itemized { margin-top: 10px; }
.finv2-item-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--fv-gray-100);
}
.finv2-item-row:last-child { border-bottom: none; }
.finv2-item-sub { padding: 6px 0 6px 24px; }
.finv2-item-sub .finv2-item-lbl,
.finv2-item-sub .finv2-item-val {
  font-size: 12px;
  color: var(--fv-gray-400);
  font-weight: 400;
}
.finv2-item-lbl { font-size: 13px; color: var(--ink-soft); }
.finv2-item-val {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

/* ── Progress bar (Raising tab top card) ── */
.finv2-progress {
  height: 6px;
  border-radius: 3px;
  background: var(--fv-gray-100);
  margin: 16px 0;
  overflow: hidden;
}
.finv2-progress-fill {
  height: 100%;
  width: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--blue), rgba(28, 95, 216, 0.55));
}

/* ── Bars ── */
.finv2-bars { margin-top: 8px; }
.finv2-bar { margin-bottom: 12px; }
.finv2-bar:last-child { margin-bottom: 0; }
.finv2-bar-head {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}
.finv2-bar-lbl  { font-size: 13px; color: var(--ink-soft); }
.finv2-bar-val  { font-size: 13px; font-weight: 600; color: var(--navy); font-variant-numeric: tabular-nums; }
.finv2-bar-track {
  height: 8px;
  border-radius: 4px;
  background: var(--fv-gray-100);
  overflow: hidden;
}
.finv2-bar-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.6s ease;
}

/* ── Donut chart ── */
.finv2-donut { position: relative; flex-shrink: 0; }
.finv2-donut-row {
  display: flex;
  align-items: center;
  gap: 28px;
  margin-top: 12px;
  flex-wrap: wrap;
}
.finv2-donut-center { display: flex; justify-content: center; margin-bottom: 14px; }
.finv2-donut-center-label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.finv2-donut-center-pct {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy);
}
.finv2-donut-center-name {
  font-size: 11px;
  color: var(--fv-gray-500);
}
.finv2-donut-legend {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
  min-width: 0;
}
.finv2-legend-stack { gap: 8px; }
.finv2-donut-legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.finv2-donut-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.finv2-donut-name {
  font-size: 13px;
  color: var(--ink-soft);
  flex: 1;
}
.finv2-donut-pct {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.finv2-donut-pct-secondary {
  font-weight: 400;
  color: var(--fv-gray-400);
  margin-left: 6px;
  min-width: 36px;
  text-align: right;
}

/* ── "Who's Funding [Name]" card — Top PACs + Top Organizations ──
 *
 * Sits on the Campaign Finance Overview tab right below the existing
 * Funding Sources donut. The donut answers "what kind of money came
 * in"; this card answers "from which donors."
 *
 * Markup is generated by renderDonorsCardBody() / renderDonorColumn()
 * in public/js/finance.js. Each column carries a colored icon disc,
 * a ranked list of donor rows (name + dollar amount + a tinted
 * horizontal scale bar), and an optional view-all link in the foot.
 *
 * Columns get their per-section accent via the .pacs / .orgs / etc.
 * modifier classes — same currentColor trick the Bills tile uses so
 * the tinted bar fill, icon disc background, and any future highlight
 * inherit from one CSS variable per column. */
.fs-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 12px;
}
/* 3-column variant (PACs + Orgs + Industries). Drops to 2 cols on
 * tablets and 1 col on phones — keeps each row's [rank|name|amount]
 * layout readable rather than crushing the donor names. */
.fs-columns-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 1000px) {
  .fs-columns-3 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  .fs-columns,
  .fs-columns-3 { grid-template-columns: 1fr; gap: 1.5rem; }
}

.fs-col {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.fs-col.pacs        { color: #ea580c; }
.fs-col.orgs        { color: var(--blue); }
.fs-col.industries  { color: var(--purple); }

.fs-col-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.fs-col-title {
  font-weight: 700;
  color: var(--navy);
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.fs-col-icon {
  font-size: 16px;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.fs-col-total {
  font-size: 11px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.fs-row {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  grid-template-rows: auto auto;
  column-gap: 8px;
  align-items: center;
  padding: 6px 0;
}
.fs-rank {
  grid-row: 1 / 3;
  font-weight: 700;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.fs-name {
  grid-column: 2;
  color: var(--navy);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Inline industry icon shown next to the industry name in the
 * Industries column (e.g. ⚕️ Healthcare, 💻 Technology). Smaller
 * than the column-header icon disc, no background. */
.fs-name-ic {
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
}
.fs-amount {
  grid-column: 3;
  font-size: 12px;
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fs-bar {
  grid-column: 2 / 4;
  height: 4px;
  background: var(--surface);
  border-radius: 999px;
  overflow: hidden;
  margin-top: 4px;
}
.fs-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.65;
}

.fs-col-empty {
  font-size: 12.5px;
  color: var(--ink-soft);
  padding: 8px 0;
  font-style: italic;
}

.fs-empty {
  margin: 12px 0 4px;
  padding: 14px;
  text-align: center;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 10px;
  font-size: 13px;
  color: var(--ink-soft);
}

.fs-card-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--ink-soft);
}
.fs-card-foot strong { color: var(--ink); }
.fs-card-foot a { color: var(--blue); text-decoration: none; }
.fs-card-foot a:hover { text-decoration: underline; }
.fs-card-foot-note { font-style: italic; }

/* Loading skeleton — paired with the placeholder card rendered by
 * renderOverview() before loadDonorsCard() returns. Two ghost columns
 * that gently pulse so the user gets immediate feedback that
 * something is on its way. */
.fs-loading { padding: 12px 0; }
.fs-skeleton-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
.fs-skeleton-cols-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 1000px) {
  .fs-skeleton-cols-3 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  .fs-skeleton-cols,
  .fs-skeleton-cols-3 { grid-template-columns: 1fr; }
}
.fs-skeleton-col {
  height: 220px;
  border-radius: 10px;
  background: linear-gradient(
    90deg,
    var(--surface) 0%,
    color-mix(in srgb, var(--border) 35%, var(--surface)) 50%,
    var(--surface) 100%
  );
  background-size: 200% 100%;
  animation: fs-skeleton 1.4s ease-in-out infinite;
}
@keyframes fs-skeleton {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── About card rows ── */
.finv2-about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 32px;
  margin-top: 10px;
}
@media (max-width: 600px) {
  .finv2-about { grid-template-columns: 1fr; }
}
.finv2-about-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--fv-gray-100);
  font-size: 13px;
}
.finv2-about-lbl { color: var(--fv-gray-500); }
.finv2-about-val { color: var(--navy); font-weight: 500; }

/* ── Sample-data badges/banners ── */
.finv2-sample-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 8px;
  background: var(--fv-blue-pale);
  color: var(--navy);
  font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--blue) 12%, transparent);
}
.finv2-sample-banner-icon { font-size: 14px; }
.finv2-sample-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--fv-amber);
  background: rgba(245, 158, 11, 0.12);
  padding: 3px 8px;
  border-radius: 12px;
}
.finv2-sample-inline { color: var(--fv-amber); font-weight: 600; }
.finv2-banner {
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--fv-blue-pale);
  color: var(--navy);
  font-size: 13px;
  line-height: 1.5;
}
.finv2-banner-warn {
  background: #fff5e0;
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--fv-amber) 30%, transparent);
}
.finv2-empty, .finv2-empty-sm {
  font-size: 13px;
  color: var(--fv-gray-400);
  margin: 4px 0;
}
.finv2-empty { padding: 12px 0; }

/* ── Note footer ── */
.finv2-note {
  font-size: 12px;
  color: var(--fv-gray-500);
  line-height: 1.5;
  margin-top: 4px;
}
.finv2-note a { color: var(--blue); }

/* ── Sortable table ── */
.finv2-table-wrap { margin-top: 4px; }
.finv2-search {
  position: relative;
  margin-bottom: 12px;
}
.finv2-search-ic {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--fv-gray-400);
  pointer-events: none;
}
.finv2-search-input {
  width: 100%;
  font: inherit;
  font-size: 13px;
  padding: 8px 8px 8px 32px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--fv-gray-50);
  outline: none;
  color: var(--ink);
}
.finv2-search-input:focus {
  border-color: var(--blue);
  background: #fff;
}
.finv2-table-scroll { overflow-x: auto; }
.finv2-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.finv2-table th {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 2px solid var(--border);
  color: var(--fv-gray-500);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  user-select: none;
  background: #fff;
}
.finv2-table th[data-sortable="1"] { cursor: pointer; }
.finv2-table th[data-sortable="1"]:hover { color: var(--navy); }
.finv2-table th[data-align="right"] { text-align: right; }
.finv2-table th[data-align="right"] .finv2-th-inner { justify-content: flex-end; }
.finv2-th-inner {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.finv2-sort-ic { flex-shrink: 0; }
.finv2-sort-up, .finv2-sort-down { fill: var(--fv-gray-300); }
.finv2-table th.active[data-dir="asc"]  .finv2-sort-up   { fill: var(--navy); }
.finv2-table th.active[data-dir="desc"] .finv2-sort-down { fill: var(--navy); }
.finv2-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--fv-gray-100);
  color: var(--ink);
  white-space: nowrap;
}
.finv2-table td[data-align="right"] { text-align: right; font-variant-numeric: tabular-nums; }
.finv2-table td.td-bold { font-weight: 600; color: var(--navy); }
.finv2-table tr.row-zebra { background: var(--fv-gray-50); }
.finv2-table .finv2-td-empty {
  text-align: center;
  padding: 24px;
  color: var(--fv-gray-400);
}
.finv2-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
}
.finv2-pill-support { background: var(--green-pale); color: var(--green); }
.finv2-pill-oppose  { background: var(--red-pale);   color: var(--rep);   }
.finv2-pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
  font-size: 13px;
}
.finv2-pager:empty { display: none; }
.finv2-pager-count { color: var(--fv-gray-500); }
.finv2-pager-btns { display: flex; gap: 4px; }
.finv2-pager-btn {
  padding: 4px 12px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  cursor: pointer;
  color: var(--ink-soft);
  font-size: 13px;
  font-family: inherit;
}
.finv2-pager-btn:hover:not(:disabled) {
  border-color: var(--blue);
  color: var(--navy);
}
.finv2-pager-btn:disabled {
  background: var(--fv-gray-50);
  color: var(--fv-gray-300);
  cursor: not-allowed;
}

/* Funding Sources donut + side legend. */
.source-donut-wrap {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-top: 8px;
}
.source-donut { flex-shrink: 0; }
.source-legend {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.source-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}
.source-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
}
.source-name {
  color: var(--ink-soft);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.source-pct { font-weight: 600; color: var(--navy); }

/* Top Contributors horizontal bars. */
.donor-bar-wrap { margin-top: 4px; }
.donor-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.donor-row:last-child { margin-bottom: 0; }
.donor-label {
  font-size: 12px;
  color: var(--ink-soft);
  width: 200px;
  flex-shrink: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.donor-track {
  flex: 1;
  height: 8px;
  background: var(--off-white, #f4f6fb);
  border-radius: 20px;
  overflow: hidden;
}
.donor-fill {
  height: 100%;
  border-radius: 20px;
  background: var(--dem);
}
.donor-amount {
  font-size: 12px;
  font-weight: 600;
  color: var(--navy);
  width: 70px;
  text-align: right;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
  .finance-grid { grid-template-columns: 1fr; }
  .source-donut-wrap { flex-direction: column; align-items: flex-start; gap: 14px; }
  .donor-label { width: 130px; }
}

.compare-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
}
.compare-note { margin-top: 0.8rem; color: var(--ink-soft); font-size: 0.9rem; }

@media (max-width: 780px) {
  .profile-grid { grid-template-columns: 1fr; }
  .finance-kpis { grid-template-columns: 1fr; }
  .vote-row { grid-template-columns: 60px 1fr; }
  .vote-date { grid-column: 2; }
}

/* ---------- Empty state ---------- */
.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--ink-soft);
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .header-search { flex: 0 1 200px; }
  .primary-nav { gap: 0; }
  .primary-nav button { padding: 0.4rem 0.55rem; font-size: 0.85rem; }
}

@media (max-width: 600px) {
  /* Legacy inline-header rules removed 2026-05-19 — the new hamburger
   * drawer (see the .header-collapsible block earlier in this file)
   * handles label visibility, search width, and placeholder color
   * inside the drawer where the elements actually live. Keeping
   * label-hides + width-shrinks here would actively fight the
   * drawer because they're later in the cascade than the drawer's
   * own override block. */
  .logo { font-size: 1.1rem; }
  .member-grid { grid-template-columns: repeat(auto-fill, minmax(155px, 1fr)); }
  /* .field-row collapses to single column on narrow viewports.
     .field-row-state-zip stays 2-column (State 90px + ZIP 1fr) — both fit
     comfortably inside the mobile modal width. */
  .field-row { grid-template-columns: 1fr; }
}

/* Sub-mobile block removed 2026-05-19 — the legacy rules hid the
 * Donate label and the entire header-search at ≤380px to give the
 * inline header room. The hamburger drawer makes both obsolete:
 * at ≤600px the header is just logo + hamburger, and Donate +
 * search live inside the drawer where they have full width to
 * breathe. Keeping the old rules would actively hide them inside
 * the drawer too. */

@media (max-width: 375px) {
  .auth-card { padding: 1.25rem; border-radius: var(--radius); }
  .member-grid { grid-template-columns: 1fr 1fr; gap: 0.6rem; }
  .member-photo { width: 60px; height: 60px; font-size: 1rem; }
}

/* ---------- My Representatives page ---------- */
.myreps-hero {
  background: linear-gradient(135deg, var(--navy-deep), var(--navy-soft));
  color: var(--white);
  border-radius: var(--radius-lg);
  padding: 2rem 2rem 1.75rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--shadow);
}
.myreps-hero-inner { max-width: 720px; }
.myreps-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.myreps-title {
  font-family: var(--font-serif);
  font-size: 2.4rem;
  margin: 0.3rem 0 0.4rem;
  line-height: 1.1;
  color: var(--white);
}
.myreps-addr {
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 0.4rem 0.75rem;
  border-radius: 999px;
  display: inline-block;
}

.myreps-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 1.5rem;
  align-items: start;
}
.myreps-sidebar { display: grid; gap: 1rem; position: sticky; top: calc(var(--header-h) + 1rem); }
.myreps-main { display: grid; gap: 1.5rem; }

.myreps-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow-sm);
}
.myreps-card-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.6rem;
}

.myreps-map {
  aspect-ratio: 4 / 3;
  width: 100%;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.myreps-map-fallback {
  font-family: var(--font-serif);
  font-size: 3rem;
  color: var(--navy);
  letter-spacing: 0.05em;
}
.state-svg { width: 100%; height: 100%; display: block; }
.state-shape {
  fill: var(--blue);
  stroke: var(--navy);
  stroke-width: 1.2;
}
.state-svg-label {
  fill: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
}

.law-item {
  padding: 0.7rem 0;
  border-top: 1px solid var(--border);
}
.law-item:first-of-type { border-top: 0; padding-top: 0.2rem; }
.law-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}
.law-tag {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue-deep);
  background: rgba(28, 95, 216, 0.1);
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
}
.law-date { font-size: 0.78rem; color: var(--ink-soft); }
.law-title { font-weight: 600; font-size: 0.95rem; margin-bottom: 0.15rem; }
.law-desc { font-size: 0.85rem; color: var(--ink-soft); line-height: 1.45; }

/* ── My HQ tab nav (My HQ / Elections) ── */
.myhq-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin: 1.5rem 0 1.5rem;
  position: sticky;
  top: 0;
  background: var(--surface, #fff);
  z-index: 1;
}
.myhq-tab {
  background: none;
  border: none;
  padding: 12px 22px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  font-family: inherit;
  transition: color 0.12s, border-color 0.12s;
}
.myhq-tab:hover { color: var(--navy); }
.myhq-tab.active {
  color: var(--navy);
  font-weight: 600;
  border-bottom-color: var(--blue);
}
.myhq-tab-panel[hidden] { display: none; }
.myhq-tab-panel { display: flex; flex-direction: column; gap: 1.25rem; }

/* ── State Legislation tab — topic-themed tiles ──
 *
 * Each tile carries a topic icon at the top-left, the enactment date
 * at the top-right, the bill code chip, a serif title, a short
 * description, and a topic chip at the foot. Per-topic color variants
 * (.topic-education, .topic-health, …) drive the left border accent,
 * icon-disc background, and topic chip tint so the user can scan a
 * page of bills and immediately spot which ones touch which issue
 * area.
 *
 * Markup lives in stateBillCard() / STATE_LAW_TOPICS in
 * public/js/myreps.js. */
.statelaw-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 18px;
}
.statelaw-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 20px 16px;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 4px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1),
              box-shadow 0.22s ease,
              border-color 0.22s ease;
}
.statelaw-tile::after {
  /* Subtle tinted wash in the top-right corner — picks up the topic
   * color via currentColor inheritance from the per-topic rules below,
   * giving each tile a hint of its category without overwhelming the
   * white background. */
  content: '';
  position: absolute;
  top: -40px;
  right: -40px;
  width: 140px;
  height: 140px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.05;
  pointer-events: none;
}
.statelaw-tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 24px rgba(11, 37, 69, 0.10);
}
.statelaw-head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.statelaw-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  font-size: 22px;
  line-height: 1;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.statelaw-head-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.statelaw-num {
  font-weight: 700;
  color: var(--navy);
  font-size: 13px;
  letter-spacing: 0.02em;
}
.statelaw-date {
  font-size: 11.5px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.statelaw-title {
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1.3;
  color: var(--navy);
  font-weight: 500;
  margin: 0;
  /* Override default h3 margins / sizing inside our tile. */
}
.statelaw-desc {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
}
.statelaw-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  margin-top: auto;
  padding-top: 4px;
}
.statelaw-topic-chip {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.statelaw-status {
  font-size: 10.5px;
  font-weight: 700;
  color: #0f6a44;
  background: var(--green-pale);
  padding: 3px 9px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Per-topic colors. `color:` drives both currentColor-derived
 * backgrounds (icon disc, corner wash, topic chip) and the left border
 * accent — one declaration per topic keeps adding new topics cheap. */
.statelaw-tile.topic-education      { color: #4f46e5; border-left-color: #4f46e5; }
.statelaw-tile.topic-health         { color: #e11d48; border-left-color: #e11d48; }
.statelaw-tile.topic-justice        { color: #7c3aed; border-left-color: #7c3aed; }
.statelaw-tile.topic-environment    { color: #059669; border-left-color: #059669; }
.statelaw-tile.topic-economy        { color: #d97706; border-left-color: #d97706; }
.statelaw-tile.topic-finance        { color: #16a34a; border-left-color: #16a34a; }
.statelaw-tile.topic-housing        { color: #ea580c; border-left-color: #ea580c; }
.statelaw-tile.topic-labor          { color: #475569; border-left-color: #475569; }
.statelaw-tile.topic-technology     { color: #0891b2; border-left-color: #0891b2; }
.statelaw-tile.topic-immigration    { color: #0d9488; border-left-color: #0d9488; }
.statelaw-tile.topic-infrastructure { color: #b45309; border-left-color: #b45309; }
.statelaw-tile.topic-elections      { color: #1e3a8a; border-left-color: #1e3a8a; }
.statelaw-tile.topic-other          { color: var(--ink-soft); border-left-color: var(--border); }

/* Topic chips inherit the per-topic color from the parent tile, so
 * there's nothing to repeat per topic — color-mix(currentColor) does
 * the lifting. Override text color so the chip stays readable on its
 * own tinted background. */
.statelaw-topic-chip.topic-education      { color: #4f46e5; }
.statelaw-topic-chip.topic-health         { color: #be123c; }
.statelaw-topic-chip.topic-justice        { color: #6d28d9; }
.statelaw-topic-chip.topic-environment    { color: #047857; }
.statelaw-topic-chip.topic-economy        { color: #b45309; }
.statelaw-topic-chip.topic-finance        { color: #15803d; }
.statelaw-topic-chip.topic-housing        { color: #c2410c; }
.statelaw-topic-chip.topic-labor          { color: #334155; }
.statelaw-topic-chip.topic-technology     { color: #0e7490; }
.statelaw-topic-chip.topic-immigration    { color: #0f766e; }
.statelaw-topic-chip.topic-infrastructure { color: #92400e; }
.statelaw-topic-chip.topic-elections      { color: #1e3a8a; }
.statelaw-topic-chip.topic-other          { color: var(--ink-soft); }

@media (max-width: 600px) {
  .statelaw-grid { grid-template-columns: 1fr; }
  .statelaw-title { font-size: 16px; }
}

/* ── State Legislation sub-tabs (Recent activities / Enacted bills)
 *
 * Lighter-weight than the parent .myhq-tabs strip — these are nested
 * navigation, so the visual treatment is a thin pill row instead of a
 * full underlined tab bar. Active state mirrors the parent strip's
 * brand color so the hierarchy reads naturally. */
.statelaw-subtabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 4px;
  background: #f1f4fb;
  border: 1px solid var(--border);
  border-radius: 999px;
  margin: 0 0 16px;
}
.statelaw-subtab {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.statelaw-subtab:hover { color: var(--navy); }
.statelaw-subtab.active {
  background: var(--white);
  color: var(--navy);
  box-shadow: 0 1px 3px rgba(11, 37, 69, 0.08);
}
.statelaw-subtab:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}
.statelaw-subpanel { display: block; }
.statelaw-subpanel[hidden] { display: none; }

/* Live-bill tile is a real <a>; clear default link styling so the tile
 * reads as a card, not as a hyperlink. Hover/focus rings already come
 * from .statelaw-tile:hover above — match them here for keyboard nav. */
a.statelaw-tile-link {
  text-decoration: none;
  color: inherit;
}
a.statelaw-tile-link:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* Topic chip row (live tiles can carry multiple subjects; the curated
 * Enacted tab carries one). Wraps to a second line on narrow tiles
 * rather than forcing single-line overflow. */
.statelaw-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}
.statelaw-chip-more {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-soft);
  align-self: center;
}

/* Status pill — color-coded by bucket. Mirrors the iOS StateBillTile
 * statusColor() palette so the two platforms render the same bill in
 * the same color. */
.statelaw-status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.statelaw-status-dot { font-size: 9px; }
.statelaw-status-enacted { color: #0f6a44; background: var(--green-pale); }
.statelaw-status-passed  { color: #1c5fd8; background: #e3edff; }
.statelaw-status-failed  { color: #b42318; background: #fde4e1; }
.statelaw-status-intro   { color: #8a6500; background: #fff4d6; }
.statelaw-status-default { color: var(--ink-soft); background: #eef0f4; }

/* ── Elections tab — sample candidate-vs-candidate cards ── */
.myhq-elections-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--blue-pale);
  color: var(--navy);
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--blue) 14%, transparent);
}
.myhq-elections-banner-icon { font-size: 14px; flex-shrink: 0; }
.myhq-elections-header h2 {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  color: var(--navy);
  margin: 0 0 0.4rem;
}
.myhq-elections-header p {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin: 0 0 0.5rem;
}
.myhq-race {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem;
  box-shadow: var(--shadow-sm);
}
.myhq-race-head {
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}
.myhq-race-title {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  color: var(--navy);
  margin: 0 0 0.25rem;
}
.myhq-race-date {
  color: var(--ink-soft);
  font-size: 13px;
  margin: 0;
}
.myhq-vs-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1rem;
  align-items: stretch;
}
.myhq-vs-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.5rem;
  color: var(--ink-soft);
  font-weight: 600;
}
.myhq-candidate {
  background: #f9fafb;
  border-radius: 10px;
  padding: 1rem;
  border-left: 4px solid var(--border);
  /* Vertical stack — avatar+name on top, body below — so two tiles
   * fit side-by-side with the VS divider on the parent grid. */
  display: flex;
  flex-direction: column;
  color: inherit;
  cursor: pointer;
  transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
  /* Anchor for the .myhq-candidate-overlay stretched link below. */
  position: relative;
}
.myhq-candidate:hover {
  background: #fff;
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(11, 37, 69, 0.08);
}
.myhq-candidate.party-dem { border-left-color: var(--dem); }
.myhq-candidate.party-rep { border-left-color: var(--rep); }
.myhq-candidate.party-ind { border-left-color: var(--purple); }
/* Stretched-link pattern: a transparent <a> that covers the whole
 * tile so the user can click anywhere on the card to open the
 * candidate's profile, without nesting <a> tags (invalid HTML — see
 * note in myreps.js renderCandidateCard). The outbound links in the
 * footer are lifted above the overlay via z-index so they retain
 * their own click targets. */
.myhq-candidate-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  /* Visually empty: aria-label provides the accessible name. */
  font-size: 0;
  color: transparent;
  text-decoration: none;
  background: transparent;
}
.myhq-candidate-overlay:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}
.myhq-candidate-foot a {
  position: relative;
  z-index: 2;
}
.myhq-candidate-head {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  align-items: center;
}
.myhq-candidate-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 16px;
  flex-shrink: 0;
  color: #fff;
}
.myhq-candidate-avatar.party-dem { background: linear-gradient(135deg, var(--dem), var(--blue-deep)); }
.myhq-candidate-avatar.party-rep { background: linear-gradient(135deg, var(--rep), #8a1f1d); }
.myhq-candidate-avatar.party-ind { background: linear-gradient(135deg, var(--purple), #4b2e8e); }
/* Photo variant — keeps the same circular footprint as the initials
 * disc but shows a real portrait when one was matched server-side
 * (bioguide for federal incumbents, openstates for state officials).
 * Object-cover keeps non-square portraits from getting stretched.
 * The party-colored ring takes the place of the solid gradient so the
 * party signal isn't lost. */
.myhq-candidate-avatar-photo {
  object-fit: cover;
  background: #e6e9ef;
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px transparent;
}
.myhq-candidate-avatar-photo.party-dem { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--dem); }
.myhq-candidate-avatar-photo.party-rep { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--rep); }
.myhq-candidate-avatar-photo.party-ind { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--purple); }
.myhq-candidate-name {
  font-weight: 700;
  color: var(--navy);
  font-size: 1rem;
  line-height: 1.2;
}
.myhq-candidate-party {
  color: var(--ink-soft);
  font-size: 12px;
  margin-top: 2px;
}
.myhq-candidate-bio {
  color: var(--ink);
  font-size: 13px;
  margin: 0 0 0.75rem;
  line-height: 1.45;
}
.myhq-candidate-section {
  margin-bottom: 0.75rem;
}
.myhq-candidate-section h4 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-weight: 700;
  margin: 0 0 0.4rem;
}
.myhq-candidate-section ul {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 13px;
  color: var(--ink);
}
.myhq-candidate-section ul li {
  padding-left: 0.9rem;
  position: relative;
  margin-bottom: 0.3rem;
  line-height: 1.4;
}
.myhq-candidate-section ul li::before {
  content: '•';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--blue);
  font-weight: 700;
}
.myhq-candidate-foot {
  margin-top: auto;
  padding-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.myhq-candidate-cta-disabled {
  display: inline-block;
  font-size: 12px;
  color: var(--ink-soft);
  font-style: italic;
}


/* Phase 2 additions: stat list, external links, loading + empty states,
   and the Uncontested placeholder card. */
.myhq-candidate-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0 0 0.75rem;
  padding: 0;
}
.myhq-candidate-stat {
  background: rgba(28, 95, 216, 0.08);
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
}
.myhq-candidate-stat dt {
  font-weight: 600;
  color: var(--ink-soft);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}
.myhq-candidate-stat dd {
  margin: 2px 0 0;
  font-weight: 700;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.myhq-candidate-link {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  color: var(--blue);
  text-decoration: none;
}
.myhq-candidate-link:hover { text-decoration: underline; }
.myhq-candidate-link-secondary { color: var(--ink-soft); }

.myhq-race-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
}
.myhq-race-empty {
  padding: 1.25rem;
  background: var(--surface-2, #f9fafb);
  border-radius: 8px;
  color: var(--ink-soft);
  font-size: 13px;
  text-align: center;
}

.myhq-candidate-uncontested {
  background: var(--surface-2, #f9fafb);
  border-left: 4px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.25rem;
  color: var(--ink-soft);
}
.myhq-uncontested-icon {
  font-size: 2rem;
  color: var(--ink-soft);
  margin-bottom: 0.4rem;
  line-height: 1;
}
.myhq-uncontested-title {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 0.4rem;
}
.myhq-uncontested-desc {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.45;
  margin: 0;
}
@media (max-width: 720px) {
  .myhq-vs-row { grid-template-columns: 1fr; }
  .myhq-vs-divider { padding: 0.4rem 0; }
}

/* ── State Elections tab — county election map (toggle + svg) ── */
.state-election-map-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.75rem;
}
.state-election-map-toggle {
  background: #f3f4f6;
  border: 1px solid var(--border);
  color: var(--navy);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.state-election-map-toggle:hover { background: #e5e7eb; }
.state-election-map-toggle.active {
  background: var(--navy);
  color: #fff;
  border-color: var(--navy);
}
.state-election-map-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.state-election-map {
  position: relative;
  width: 100%;
  background: #f9fafb;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.5rem;
  min-height: 220px;
}
.state-election-map-svg {
  width: 100%;
  height: auto;
  display: block;
}
.state-county-path {
  transition: filter 0.15s ease;
}
.state-county-path:hover {
  filter: brightness(0.9);
  cursor: default;
}
.state-election-map-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  font-size: 11px;
  color: var(--ink-soft);
}
.state-election-map-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.state-election-swatch {
  display: inline-block;
  width: 36px;
  height: 8px;
  border-radius: 2px;
}
.state-election-swatch-dem {
  background: linear-gradient(to right, #f0f0f0, #1c5fd8);
}
.state-election-swatch-rep {
  background: linear-gradient(to right, #f0f0f0, #c0282e);
}
.state-election-map-source {
  font-size: 11px;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.45;
}

/* ── State Elections tab — Governor candidate tiles (hand-curated) ── */
.state-governor-note {
  background: var(--blue-pale);
  color: var(--navy);
  border-left: 3px solid var(--blue);
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 12.5px;
  line-height: 1.5;
  margin: 0 0 0.85rem;
}
.state-governor-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.9rem;
}
.state-governor-tile {
  background: #fff;
  border: 1px solid var(--border);
  border-left: 4px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.1rem 0.85rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.state-governor-tile.party-dem { border-left-color: var(--dem); }
.state-governor-tile.party-rep { border-left-color: var(--rep); }
.state-governor-tile.party-ind { border-left-color: var(--purple); }
.state-governor-tile-head {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 0.8rem;
  align-items: center;
}
.state-governor-tile-photo {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}
.state-governor-tile-photo.party-dem { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--dem); }
.state-governor-tile-photo.party-rep { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--rep); }
.state-governor-tile-photo.party-ind { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--purple); }
.state-governor-tile-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.02em;
}
.state-governor-tile-avatar.party-dem { background: linear-gradient(135deg, var(--dem), var(--blue-deep)); }
.state-governor-tile-avatar.party-rep { background: linear-gradient(135deg, var(--rep), #8a1f1d); }
.state-governor-tile-avatar.party-ind { background: linear-gradient(135deg, var(--purple), #4b2e8e); }
.state-governor-tile-head-text { min-width: 0; }
.state-governor-tile-name {
  font-weight: 700;
  color: var(--navy);
  font-size: 15px;
}
.state-governor-tile-meta {
  font-size: 12px;
  color: var(--ink-soft);
}
.state-governor-tile-bio {
  font-size: 13px;
  color: var(--ink);
  margin: 0;
  line-height: 1.45;
  font-style: italic;
}
.state-governor-tile-platform {
  background: var(--surface-2, #f9fafb);
  border-radius: 8px;
  padding: 0.55rem 0.7rem 0.5rem;
}
.state-governor-tile-platform-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.3rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}
.state-governor-tile-platform-source {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  opacity: 0.85;
  font-style: italic;
}
.state-governor-tile-platform-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.state-governor-tile-platform-list li {
  position: relative;
  padding-left: 1rem;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink);
}
.state-governor-tile-platform-list li::before {
  content: '•';
  position: absolute;
  left: 0.2rem;
  color: var(--ink-soft);
}
.state-governor-tile-platform-empty {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 0;
  font-style: italic;
  line-height: 1.45;
}
.state-governor-tile-platform-empty a {
  color: var(--blue);
  text-decoration: none;
}
.state-governor-tile-platform-empty a:hover { text-decoration: underline; }
.state-governor-tile-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 0.1rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}
.state-governor-tile-link {
  font-size: 12px;
  font-weight: 600;
  color: var(--blue);
  text-decoration: none;
}
.state-governor-tile-link:hover { text-decoration: underline; }
.state-governor-source {
  font-size: 11px;
  color: var(--ink-soft);
  margin: 0.6rem 0 0;
  line-height: 1.45;
}
.state-governor-source a { color: var(--blue); text-decoration: none; }
.state-governor-source a:hover { text-decoration: underline; }

/* ── State Elections tab — Polymarket prediction-market panel ── */
.state-prediction-slot {
  margin-top: 1.1rem;
}
.state-prediction-subhead {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  color: var(--navy);
  margin: 0 0 0.3rem;
}
.state-prediction-note {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 0 0 0.6rem;
  line-height: 1.5;
}
.state-prediction-note a {
  color: var(--blue);
  text-decoration: none;
}
.state-prediction-note a:hover { text-decoration: underline; }
/* Legacy grid still referenced in case any caller falls back to it —
 * harmless rule for forward compatibility. */
.state-prediction-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
@media (max-width: 720px) {
  .state-prediction-grid { grid-template-columns: 1fr; }
}
.state-prediction-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.1rem 0.9rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.state-prediction-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.state-prediction-card-title {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  color: var(--navy);
  margin: 0;
}
.state-prediction-card-meta {
  font-size: 11px;
  color: var(--ink-soft);
  text-align: right;
}
.state-prediction-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.state-prediction-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.6fr auto;
  gap: 0.6rem;
  align-items: center;
  font-size: 13px;
}
.state-prediction-name {
  font-weight: 600;
  color: var(--navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.state-prediction-bar {
  position: relative;
  height: 8px;
  background: #f3f4f6;
  border-radius: 4px;
  overflow: hidden;
}
.state-prediction-bar-fill {
  display: block;
  height: 100%;
  background: linear-gradient(to right, #c7d2fe, #1c5fd8);
  border-radius: 4px;
  min-width: 2px;
}
.state-prediction-pct {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--navy);
  text-align: right;
  min-width: 3.5em;
}
.state-prediction-card-foot {
  margin-top: 0.2rem;
}
.state-prediction-source {
  font-size: 12px;
  color: var(--blue);
  font-weight: 600;
  text-decoration: none;
}
.state-prediction-source:hover { text-decoration: underline; }
.state-prediction-card-empty {
  background: var(--surface-2, #f9fafb);
}
.state-prediction-empty {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.45;
}

/* ── State Elections tab — info banner + compact house-race tiles ── */
.state-elections-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--blue-pale);
  color: var(--navy);
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--blue) 14%, transparent);
}
.state-elections-banner-icon { font-size: 14px; flex-shrink: 0; }

/* Grid of one tile per House district — 2 cols at desktop,
 * single col below 720px. Each tile compresses the VS layout into
 * two stacked candidate rows (avatar | name+sub | raise). */
.state-house-races-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
}
@media (max-width: 720px) {
  .state-house-races-grid { grid-template-columns: 1fr; }
}
.state-house-race-tile {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.85rem 0.9rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.state-house-race-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
}
.state-house-race-label {
  font-family: var(--font-serif);
  font-weight: 700;
  color: var(--navy);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.state-house-race-sub {
  color: var(--ink-soft);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.state-house-race-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.state-house-cand-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.45rem 0.5rem;
  border-radius: 8px;
  border-left: 3px solid var(--border);
  background: #f9fafb;
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease, transform 0.15s ease;
}
.state-house-cand-row:hover {
  background: #fff;
  transform: translateX(2px);
}
.state-house-cand-row.party-dem { border-left-color: var(--dem); }
.state-house-cand-row.party-rep { border-left-color: var(--rep); }
.state-house-cand-row.party-ind { border-left-color: var(--purple); }
.state-house-cand-row-empty {
  background: transparent;
  color: var(--ink-soft);
  cursor: default;
}
.state-house-cand-row-empty:hover { transform: none; background: transparent; }
.state-house-cand-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.02em;
  object-fit: cover;
  flex-shrink: 0;
}
.state-house-cand-avatar.party-dem { background: linear-gradient(135deg, var(--dem), var(--blue-deep)); }
.state-house-cand-avatar.party-rep { background: linear-gradient(135deg, var(--rep), #8a1f1d); }
.state-house-cand-avatar.party-ind { background: linear-gradient(135deg, var(--purple), #4b2e8e); }
.state-house-cand-avatar-empty {
  background: var(--surface-2, #f3f4f6);
  color: var(--ink-soft);
  font-size: 16px;
  font-weight: 400;
}
.state-house-cand-meta { min-width: 0; }
.state-house-cand-name {
  font-weight: 600;
  color: var(--navy);
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.state-house-cand-sub {
  font-size: 11px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.state-house-cand-raise {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--navy);
  font-size: 13px;
  flex-shrink: 0;
}

.myreps-section {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem 1.25rem 1rem;
  box-shadow: var(--shadow-sm);
}
.myreps-section-title {
  font-family: var(--font-serif);
  font-size: 1.35rem;
  margin: 0 0 0.9rem;
}
.myreps-note {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.75rem;
  font-style: italic;
}
.myreps-empty {
  color: var(--ink-soft);
  font-size: 0.9rem;
  padding: 0.5rem 0;
}

.myreps-rep-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0.75rem;
}
.rep-card {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.rep-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
  border-color: var(--blue);
}
.rep-photo {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.95rem;
  background-size: cover;
  background-position: center top;
  flex-shrink: 0;
}
.rep-body { min-width: 0; }
.rep-name { font-weight: 600; font-size: 0.95rem; }
.rep-meta { font-size: 0.82rem; color: var(--ink-soft); margin-top: 0.15rem; }

.myreps-deleg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.6rem;
}
.deleg-card {
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.deleg-card:hover { border-color: var(--blue); transform: translateY(-1px); }
.deleg-name { font-weight: 600; font-size: 0.9rem; }
.deleg-meta { font-size: 0.8rem; color: var(--ink-soft); margin-top: 0.15rem; }

.myreps-recent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.6rem;
}
.recent-card {
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.12s ease;
}
.recent-card:hover { border-color: var(--blue); }
.recent-name { font-weight: 600; font-size: 0.9rem; }
.recent-time { font-size: 0.78rem; color: var(--muted); margin-top: 0.15rem; }

/* Recent Searches — same visual family as Recently Viewed but laid
 * out as a list (one row per search) with a magnifying-glass icon
 * + the query text + the relative time. "Clear all" sits below. */
.recent-searches-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.recent-search-card {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.recent-search-card:hover {
  border-color: var(--blue);
  background: var(--white);
}
.recent-search-icon { font-size: 0.95rem; line-height: 1; }
.recent-search-text {
  font-size: 0.9rem;
  color: var(--ink);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.recent-search-time {
  font-size: 0.76rem;
  color: var(--muted);
}
.recent-searches-clear {
  background: transparent;
  border: 0;
  color: var(--ink-soft);
  font-size: 0.78rem;
  cursor: pointer;
  margin-top: 8px;
  padding: 4px 0;
  text-decoration: underline;
}
.recent-searches-clear:hover { color: var(--ink); }

@media (max-width: 900px) {
  .myreps-layout { grid-template-columns: 1fr; }
  .myreps-sidebar { position: static; }
}
@media (max-width: 540px) {
  .myreps-hero { padding: 1.5rem 1.25rem; }
  .myreps-title { font-size: 1.9rem; }
  .myreps-rep-grid { grid-template-columns: 1fr; }
}

/* ---------- Home US map ---------- */
.home-map-wrap {
  margin: 0 auto 2rem;
  max-width: 960px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1rem 1rem 0.5rem;
  box-shadow: var(--shadow-sm);
}
.home-map { width: 100%; }
.home-svg { width: 100%; height: auto; display: block; }
.home-svg .state { transition: opacity 0.15s; }
.home-svg .state:hover { opacity: 0.82; }
.home-map-legend {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  font-size: 0.82rem;
  color: var(--ink-soft);
  padding: 0.4rem 0;
}
.home-map-legend .swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-right: 0.3rem;
  vertical-align: middle;
}
.home-map-legend .swatch.dem { background: var(--dem); }
.home-map-legend .swatch.rep { background: var(--rep); }
.home-map-legend .swatch.split { background: #7b4f9e; }
.home-map-tip {
  text-align: center;
  min-height: 1.25rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* ---------- Section titles ---------- */
.section-title {
  margin: 1.75rem 0 0.75rem;
  font-family: var(--font-serif);
  font-size: 1.4rem;
  color: var(--ink);
}

/* ---------- Executive (v5) ---------- */
.exec-tab-bar {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
}
.exec-tabs {
  display: inline-flex;
  gap: 2px;
}
.exec-tab {
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  transition: color 0.15s, border-color 0.15s;
}
.exec-tab:hover { color: var(--navy); }
.exec-tab.active {
  color: var(--navy);
  border-bottom-color: var(--gold);
}

.exec-section { margin-bottom: 32px; }
.exec-section-title {
  font-family: var(--font-serif);
  font-size: 20px;
  color: var(--navy);
  font-weight: 400;
  margin: 0 0 5px;
}
.exec-section-sub {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 0 18px;
}

.principal-cards {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.principal-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px 22px;
  width: 220px;
  cursor: pointer;
  text-align: center;
  position: relative;
  overflow: hidden;
  transition: all 0.22s cubic-bezier(0.34, 1.2, 0.64, 1);
}
.principal-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--gold), var(--blue));
}
.principal-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}
.principal-icon {
  font-size: 38px;
  margin-bottom: 11px;
  line-height: 1;
}
/* Photo variant of .principal-icon — drops the emoji styling and
 * renders a circular portrait. The non-photo emoji rule above stays
 * intact for fallback when an official has no photo on file. */
.principal-icon-photo {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  overflow: hidden;
  margin: 0 auto 11px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}
.principal-icon-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.principal-role {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.principal-name {
  font-family: var(--font-serif);
  font-size: 17px;
  color: var(--navy);
  margin-bottom: 4px;
  font-weight: 400;
  line-height: 1.2;
}
.principal-since {
  font-size: 11.5px;
  color: var(--ink-soft);
}

.cabinet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: 13px;
}
.cabinet-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 15px 17px;
  display: flex;
  gap: 13px;
  align-items: center;
  cursor: pointer;
  transition: all 0.18s;
}
.cabinet-card:hover {
  box-shadow: var(--shadow);
  transform: translateY(-2px);
  border-color: transparent;
}
.cabinet-seal {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: linear-gradient(135deg, #2a3f66, #1a2d50);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}
/* Photo variant — same dimensions, but no gradient background and
 * the <img> fills the circle. */
.cabinet-seal-photo {
  background: none;
  overflow: hidden;
}
.cabinet-seal-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.cabinet-body { flex: 1; min-width: 0; }
.cabinet-dept {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cabinet-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 1px;
}
.cabinet-sub {
  font-size: 11.5px;
  color: var(--ink-soft);
}
.cabinet-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.dot-dem { background: var(--blue); }
.dot-rep { background: var(--rep); }
.dot-ind { background: var(--gold); }

/* Executive profile */
.exec-avatar {
  font-size: 52px;
  background: linear-gradient(135deg, #2a3f66, #1a2d50);
  color: #fff;
}
.exec-hero-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.exec-tag {
  font-size: 11px;
  font-weight: 500;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.78);
  background: rgba(255, 255, 255, 0.09);
}
.exec-panel {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px 24px;
  margin-bottom: 16px;
}
.exec-panel h3 {
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
  margin: 0 0 14px;
}
.exec-panel p {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.7;
  margin: 0 0 10px;
}
.priority-item {
  display: flex;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  align-items: flex-start;
}
.priority-item:last-child { border-bottom: none; padding-bottom: 0; }
.priority-num {
  width: 26px;
  height: 26px;
  min-width: 26px;
  border-radius: 50%;
  background: var(--blue-pale);
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 2px;
}
.priority-text {
  font-size: 13px;
  color: var(--navy);
  line-height: 1.5;
  padding-top: 4px;
}

/* ---------- Judicial (v5) ---------- */
/* The .court-composition / .composition-bar / .comp-con/.comp-lib /
   .comp-dot / .comp-legend-meta / .justice-lean rules used to render a
   "Conservative supermajority" pill chart + per-justice lean badges.
   Both were removed when the lean-labeling concept was retired (the
   Privacy page commits to color-coding politicians by declared party
   only, never by ideology). Kept this comment so future "where did
   the comp bars go?" archaeology has a pointer. */

.section-meta {
  font-size: 13px;
  color: var(--ink-soft);
  margin: -8px 0 16px;
}

.scotus-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 8px;
}
.justice-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px 18px 20px;
  cursor: pointer;
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1),
              box-shadow 0.22s, border-color 0.22s;
  position: relative;
  overflow: hidden;
  text-align: center;
}
.justice-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
}
.justice-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}
.justice-avatar {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: linear-gradient(135deg, #2d1a5e, #1a2a5e);
  margin: 0 auto 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.88);
  /* When a photo is present we replace the gradient/initials look with the
     official portrait. The img fills the same 68px circle and crops to the
     face via object-fit + a subtle top-bias on object-position (most SCOTUS
     portraits frame the head in the upper third). */
  overflow: hidden;
}
.justice-avatar-photo {
  /* Drop the gradient so the photo isn't tinted by it. */
  background: #1a1a1a;
}
.justice-avatar-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  display: block;
}
/* Profile-page avatar (.profile-avatar.exec-avatar) photo variant — same
   crop behavior at the larger profile-page size. */
.profile-avatar-photo {
  overflow: hidden;
  background: #1a1a1a;
}
.profile-avatar-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  display: block;
}
.justice-name {
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--navy);
  margin-bottom: 2px;
  line-height: 1.25;
}
.justice-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.justice-appointed {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-bottom: 10px;
  line-height: 1.4;
}

.exec-avatar {
  background: linear-gradient(135deg, #2d1a5e, #1a2a5e) !important;
  color: rgba(255, 255, 255, 0.9) !important;
}

.opinion-item {
  display: flex;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  align-items: flex-start;
}
.opinion-item:last-child { border-bottom: none; padding-bottom: 0; }
.opinion-marker {
  color: var(--blue);
  font-size: 16px;
  line-height: 1.2;
  flex-shrink: 0;
}
.opinion-text {
  font-size: 13px;
  color: var(--navy);
  line-height: 1.55;
}

.circuit-table-wrap {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 1.5rem;
}
.circuit-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.circuit-table th {
  background: var(--off-white);
  padding: 12px 16px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--border);
}
.circuit-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--ink);
}
.circuit-table tbody tr:last-child td { border-bottom: none; }
.circuit-table tbody tr:hover td { background: var(--off-white); }

.circuit-name {
  font-family: var(--font-serif);
  font-size: 15px;
  color: var(--navy);
  line-height: 1.2;
}
.circuit-judges {
  text-align: center;
  font-weight: 700;
  color: var(--navy);
}
.circuit-balance { min-width: 140px; }
.circuit-bar {
  display: flex;
  height: 8px;
  width: 120px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--border);
}
.circuit-bar-dem { background: var(--blue); }
.circuit-bar-rep { background: var(--rep); }
.circuit-bar-lbl {
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 4px;
}
.circuit-bar-lbl .dem { color: var(--blue); font-weight: 700; }
.circuit-bar-lbl .rep { color: var(--rep); font-weight: 700; }

.circuit-chief {
  font-size: 12.5px;
  color: var(--ink);
  white-space: nowrap;
}
.circuit-chief-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.circuit-chief-photo {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.02em;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.circuit-chief-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.circuit-chief-photo-fallback { background: var(--navy); color: var(--white); }
.circuit-chief-name { font-size: 12.5px; color: var(--ink); white-space: normal; }
.circuit-notes {
  font-size: 12.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  max-width: 360px;
}

/* ---------- Historical (modernized: bill-card aesthetic) ---------- */
.hist-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px;
}
.hist-card {
  position: relative;
  padding: 20px 22px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--white);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1), box-shadow 0.22s, border-color 0.22s;
}
.hist-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--border);
}
.hist-card.party-dem::before { background: var(--dem); }
.hist-card.party-rep::before { background: var(--rep); }
.hist-card.party-ind::before { background: var(--gold); }
.hist-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}
.hist-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  margin-top: 4px;
}
.hist-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  overflow: hidden;
}
.hist-avatar-photo { background: #e9ecf3; padding: 0; }
.hist-avatar-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hist-name {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1.28;
  color: var(--navy);
  font-weight: 400;
  margin-top: 4px;
}
.hist-meta {
  font-size: 12.5px;
  color: var(--ink-soft);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.hist-note {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.55;
  margin-top: auto;
  padding-top: 4px;
}

/* ---------- Bills (v6 "mission control") ----------
 *
 * Replaced the v5 `.bill-card` listing tile on 2026-05-19 with this
 * `.bt-tile` ("bill-tile") layout. Each tile has three regions:
 *
 *   1. Top strip (`.bt-strip`)  — status-colored gradient carrying
 *      the bill number, its legislative stage label, and a 4-step
 *      progress stepper (Intro → House → Senate → Enacted).
 *   2. Body (`.bt-body`)        — serif title, plain description, and
 *      a hero vote-tally split block (yea side green / nay red).
 *   3. Footer (`.bt-foot`)      — topic tags with icons, plus the
 *      sponsor + party + date in the right column.
 *
 * Class names are `.bt-*` prefixed (not `.bill-*`) to keep them
 * cleanly separated from the bill-DETAIL page's heavy `.bill-*`
 * vocabulary (.bill-num-hero, .bill-status-bar, .bill-tally-row,
 * .bill-sponsor as the sidebar list, …).
 *
 * Markup is generated by billCard() in public/js/pages.js. */
.bt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 18px;
}
.bt-tile {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(11, 37, 69, 0.04);
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1),
              box-shadow 0.22s ease;
}
.bt-tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 24px rgba(11, 37, 69, 0.10);
}

/* ── Status strip ── */
.bt-strip {
  padding: 14px 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: #fff;
}
.bt-strip.s-enacted       { background: linear-gradient(135deg, var(--green), #137a4e); }
.bt-strip.s-passed-house  { background: linear-gradient(135deg, var(--blue),  var(--blue-deep)); }
.bt-strip.s-passed-senate { background: linear-gradient(135deg, var(--navy-soft), var(--navy)); }
.bt-strip.s-failed        { background: linear-gradient(135deg, var(--rep),   #a82622); }
.bt-strip.s-introduced    { background: linear-gradient(135deg, var(--gold),  #c98215); }

.bt-strip-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.bt-strip-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
  opacity: 0.92;
}
.bt-strip-num {
  font-size: 13px;
  font-weight: 700;
  opacity: 0.92;
  font-variant-numeric: tabular-nums;
}

/* ── Stepper inside the strip ──
 * Done steps: bright dot, full label. Current: bright dot with a soft
 * outer ring. Pending: muted dot + label. The visual progression
 * tells the user how far through the legislative pipeline this bill
 * has gotten, regardless of the color of the strip. */
.bt-stepper {
  display: flex;
  align-items: center;
  gap: 4px;
}
.bt-step {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.55;
  text-align: center;
}
.bt-step.done, .bt-step.current { opacity: 1; }
.bt-step-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
  border: 2px solid #fff;
}
.bt-step.done .bt-step-dot { background: #fff; }
.bt-step.current .bt-step-dot {
  background: #fff;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.25);
}

/* ── Body ── */
.bt-body {
  padding: 16px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.bt-title {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1.28;
  color: var(--navy);
  font-weight: 500;
  margin: 0;
}
.bt-desc {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
}

/* ── Vote-tally split block ──
 * 50/50 layout regardless of vote outcome — the numeric strength is
 * carried by the bold count + percentage, not by varying the side
 * widths. That keeps the tally row visually stable across tiles even
 * when results are lopsided (e.g. 91–3 Kids Online Safety Act). */
.bt-tally {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  font-size: 13px;
  margin-top: auto;
}
.bt-tally-side {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 8px;
}
.bt-tally-side.yea { background: rgba(26, 150, 96, 0.10); color: #0f6a44; }
.bt-tally-side.nay { background: rgba(217, 50, 47, 0.10); color: #a82622; }
.bt-tally-side strong {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.bt-tally-side span {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.bt-no-tally {
  text-align: center;
  padding: 10px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: auto;
}

/* ── Footer ── */
.bt-foot {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 12px 20px 14px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  flex-wrap: wrap;
}
.bt-topics {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.bt-topic {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
}
.bt-topic-ic { font-size: 13px; line-height: 1; }
.bt-meta {
  font-size: 11.5px;
  color: var(--ink-soft);
  text-align: right;
  line-height: 1.45;
}
.bt-meta-party { font-weight: 700; }
.bt-meta-date { font-variant-numeric: tabular-nums; }

/* Per-topic color accents on topic tags. Each rule only sets `color:`
 * so adding a topic costs one line. The bt-topic baseline keeps icon
 * + label readable on the surface background; the per-topic color
 * here paints the LABEL color for stronger topic recognition. */
.bt-topic.t-immigration    { color: #0f766e; }
.bt-topic.t-justice        { color: #6d28d9; }
.bt-topic.t-border         { color: #92400e; }
.bt-topic.t-health         { color: #be123c; }
.bt-topic.t-reproductive   { color: #9d174d; }
.bt-topic.t-technology     { color: #0e7490; }
.bt-topic.t-children       { color: #be185d; }
.bt-topic.t-education      { color: #4338ca; }
.bt-topic.t-environment    { color: #047857; }
.bt-topic.t-climate        { color: #047857; }
.bt-topic.t-economy        { color: #b45309; }
.bt-topic.t-finance        { color: #15803d; }
.bt-topic.t-budget         { color: #15803d; }
.bt-topic.t-housing        { color: #c2410c; }
.bt-topic.t-labor          { color: #334155; }
.bt-topic.t-infrastructure { color: #92400e; }
.bt-topic.t-elections      { color: #1e3a8a; }
.bt-topic.t-defense        { color: #334155; }
.bt-topic.t-disasters      { color: #57534e; }
.bt-topic.t-foreign        { color: #0369a1; }
.bt-topic.t-families       { color: #db2777; }
.bt-topic.t-consumer       { color: #0e7490; }
.bt-topic.t-guns           { color: #991b1b; }
.bt-topic.t-surveillance   { color: #4338ca; }
.bt-topic.t-veterans       { color: #1e3a8a; }
.bt-topic.t-other          { color: var(--ink-soft); }

@media (max-width: 600px) {
  .bt-grid { grid-template-columns: 1fr; }
  .bt-title { font-size: 17px; }
  .bt-foot { flex-direction: column; align-items: flex-start; }
  .bt-meta { text-align: left; }
}

.bills-search {
  min-width: 240px;
  font-size: 13px;
}
@media (max-width: 600px) {
  /* Bills page on phones: filter-party buttons wrap (otherwise the
   * 6-button row overflows and forces horizontal scroll on the
   * filter card); search input stretches full-width below them. */
  .filter-row .filter-party { flex-wrap: wrap; border-bottom: none; gap: 4px; }
  .filter-row .filter-party button { border-bottom: 0; border: 1px solid var(--border); border-radius: 999px; padding: 6px 12px; }
  .filter-row .filter-party button.active { border-color: var(--gold); color: var(--gold); }
  .bills-search { min-width: 0; width: 100%; }
}

/* ════════════════════════════════════════════
   Bill detail page — visual match to v5.27 design template.
   White hero, status-step pipeline, 1fr/300px body grid with 3 main
   sections (Vote Tally / Summary / Sponsor / Timeline) and a 3-card
   sidebar (Bill Details / Subject Tags / Vote Breakdown).
   ════════════════════════════════════════════ */
.bill-detail-hero {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 28px 40px;
  /* Anchor for the .bill-detail-watch-slot in the top-right corner. */
  position: relative;
}
.bill-detail-hero .breadcrumb-trail {
  color: var(--ink-soft);
  margin-bottom: 14px;
  font-size: 12.5px;
}
.bill-detail-hero .breadcrumb-trail a { color: var(--ink-soft); }
.bill-detail-type-badge {
  display: inline-block;
  background: var(--blue-pale, #e8f0ff);
  color: var(--blue, var(--dem));
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: 20px;
  margin-bottom: 12px;
}
.bill-detail-title {
  font-family: var(--font-serif);
  font-size: 26px;
  color: var(--navy);
  margin-bottom: 8px;
  line-height: 1.25;
  font-weight: 400;
}
.bill-detail-short {
  font-size: 14px;
  color: var(--ink-soft);
  margin-bottom: 16px;
}
.bill-detail-meta-row {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}
.bill-meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-soft);
}
.bill-meta-chip strong { color: var(--navy); }

/* Status pipeline. Each step has a numbered dot + label; the connector line
   between dots turns green for done, the active dot pulses in blue. */
.bill-status-bar {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 20px 40px;
}
.bill-status-steps {
  display: flex;
  align-items: flex-start;
  gap: 0;
}
.bill-status-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  position: relative;
  text-align: center;
}
.bill-status-step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 14px;
  left: 50%;
  width: 100%;
  height: 2px;
  background: var(--border);
  z-index: 0;
}
.bill-status-step.done:not(:last-child)::after { background: var(--green, #1a9660); }
.bill-step-dot {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 12px;
  color: var(--ink-soft);
  position: relative;
  z-index: 1;
}
.bill-status-step.done .bill-step-dot {
  background: var(--green, #1a9660);
  border-color: var(--green, #1a9660);
  color: var(--white);
}
.bill-status-step.current .bill-step-dot {
  background: var(--blue, var(--dem));
  border-color: var(--blue, var(--dem));
  color: var(--white);
}
.bill-step-label {
  margin-top: 8px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-soft);
}
.bill-status-step.done .bill-step-label { color: var(--green, #1a9660); }
.bill-status-step.current .bill-step-label {
  color: var(--blue, var(--dem));
  font-weight: 600;
}

.bill-detail-body {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 20px;
  padding: 26px 40px;
  max-width: 1180px;
}
.bill-detail-main { min-width: 0; }
.bill-detail-section {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  margin-bottom: 16px;
}
.bill-detail-section:last-child { margin-bottom: 0; }
.bill-detail-section h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--navy);
  margin: 0 0 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.bill-detail-section p {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.7;
  margin-bottom: 10px;
}
.bill-detail-section p:last-child { margin-bottom: 0; }
.bill-detail-section a { color: var(--blue, var(--dem)); }

/* Vote tally — 3 colored boxes + a stacked horizontal bar. */
.bill-tally-row {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}
.bill-tally-box {
  flex: 1;
  border-radius: 10px;
  padding: 16px;
  text-align: center;
}
.bill-tally-box.yeas { background: var(--green-pale, #e6f9f0); border: 1px solid #b2e8d0; }
.bill-tally-box.nays { background: var(--red-pale, #ffeaea); border: 1px solid #f5c0c0; }
.bill-tally-box.abs  { background: var(--off-white, #f4f6fb); border: 1px solid var(--border); }
.bill-tally-num {
  font-family: var(--font-serif);
  font-size: 36px;
  display: block;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.bill-tally-box.yeas .bill-tally-num { color: var(--green, #1a9660); }
.bill-tally-box.nays .bill-tally-num { color: var(--rep); }
.bill-tally-box.abs  .bill-tally-num { color: var(--ink-soft); }
.bill-tally-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-top: 4px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.bill-tally-bar {
  height: 10px;
  border-radius: 20px;
  overflow: hidden;
  display: flex;
  background: #dde3f0;
  margin-bottom: 8px;
}
.bill-tally-bar-yes { background: var(--green, #1a9660); }
.bill-tally-bar-no  { background: var(--rep); }
.bill-tally-bar-abs { background: #dde3f0; }
.bill-tally-foot {
  font-size: 12px !important;
  color: var(--ink-soft) !important;
  margin-top: 8px !important;
  margin-bottom: 0 !important;
}

/* Sponsor card row + timeline rows. */
.bill-sponsor-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  cursor: pointer;
  transition: background 0.15s;
  border-radius: 8px;
}
.bill-sponsor-avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: linear-gradient(135deg, #dde3f0, #bcc7e0);
  color: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-family: var(--font-serif);
  flex-shrink: 0;
}
.bill-sponsor-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
}
.bill-sponsor-role {
  font-size: 11px;
  color: var(--ink-soft);
}
.bill-action-item {
  font-size: 12.5px;
  color: var(--ink-soft);
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: 12px;
}
.bill-action-item:last-child { border-bottom: none; }
.bill-action-date {
  font-size: 11px;
  color: var(--ink-soft);
  white-space: nowrap;
  font-weight: 600;
  flex-shrink: 0;
  width: 90px;
}

/* Sidebar cards. */
.bill-detail-sidebar { display: flex; flex-direction: column; gap: 0; }
.bill-sidebar-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 14px;
}
.bill-sidebar-card:last-child { margin-bottom: 0; }
.bill-sidebar-card h4 {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 12px;
}
.bill-sidebar-card .info-row {
  font-size: 12.5px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.bill-sidebar-card .info-row:last-child { border-bottom: none; }
.bill-detail-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.bill-detail-tag {
  display: inline-block;
  background: var(--blue-pale, #e8f0ff);
  color: var(--blue, var(--dem));
  font-size: 11px;
  font-weight: 500;
  padding: 3px 10px;
  border-radius: 20px;
}

@media (max-width: 900px) {
  .bill-detail-body { grid-template-columns: 1fr; }
  .bill-detail-hero,
  .bill-status-bar,
  .bill-detail-body { padding-left: 20px; padding-right: 20px; }
  .bill-status-steps { flex-wrap: wrap; gap: 8px; }
  .bill-status-step::after { display: none; }
}

/* Legacy dark-hero classes kept for any cached references — superseded by
   the new white-hero design above. */
.bill-hero-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.bill-num-hero {
  font-family: var(--font-serif);
  font-size: 20px;
  color: var(--gold);
  font-weight: 400;
  letter-spacing: 0.02em;
}
.bill-hero-title {
  font-size: clamp(24px, 3.8vw, 34px) !important;
  line-height: 1.18 !important;
  margin-bottom: 10px !important;
}
.bill-detail-topics {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 6px 0 18px;
}
.tally-card .vote-bar {
  display: flex;
  height: 32px;
  border-radius: 8px;
  overflow: hidden;
  color: #fff;
  font-weight: 700;
  font-size: 12.5px;
  margin-top: 4px;
}
.tally-card .vote-bar-yea {
  background: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
}
.tally-card .vote-bar-nay {
  background: var(--rep);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
}
.tally-card .vote-bar-lbl {
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 6px;
  font-weight: 500;
}
.vote-bar {
  display: flex;
  height: 34px;
  border-radius: 8px;
  overflow: hidden;
  color: #fff;
  font-weight: 700;
  font-size: 12.5px;
}
.vote-bar-yea {
  background: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
}
.vote-bar-nay {
  background: var(--rep);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
}
.vote-bar-lbl {
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 6px;
}

/* ════════════════════════════════════════════
   Finance page — visual match to v5.27 design template's `.member-tile`.
   Top color stripe by party, avatar + name + state-sub row, an inset
   "Total Raised" sub-card with a serif amount, and a footer row with the
   party badge + "View breakdown →" affordance.
   ════════════════════════════════════════════ */
.fin-grid-wrap {
  padding: 22px 24px;
  max-width: 1300px;
}
.fin-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.fin-card {
  position: relative;
  padding: 18px 16px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--white);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 11px;
  overflow: hidden;
  transition: transform 0.22s cubic-bezier(0.34, 1.2, 0.64, 1), box-shadow 0.22s, border-color 0.22s;
}
.fin-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--border);
}
.fin-card.party-dem::before { background: var(--dem); }
.fin-card.party-rep::before { background: var(--rep); }
.fin-card.party-ind::before { background: var(--gold); }
.fin-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}

.fin-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}
.fin-avatar {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: linear-gradient(135deg, #dde3f0, #bcc7e0);
  color: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 16px;
  font-family: var(--font-serif);
  flex-shrink: 0;
  overflow: hidden;
}
.fin-avatar-photo { background: #e9ecf3; padding: 0; }
.fin-avatar-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fin-card-id { min-width: 0; flex: 1; }
.fin-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--navy);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: 'DM Sans', sans-serif;
}
.fin-sub {
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 2px;
}

/* Inset "Total Raised" sub-card — visual focal point of each tile. */
.fin-amount-box {
  background: var(--off-white, #f4f6fb);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.fin-raised-lbl {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.fin-raised {
  font-family: var(--font-serif);
  font-size: 26px;
  color: var(--green, #1a9660);
  line-height: 1;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.fin-cycle {
  font-size: 10.5px;
  color: var(--ink-soft);
  margin-top: 3px;
}
/* FEC returned no match for this candidate (nickname mismatch, hasn't filed,
   or simply isn't in the index). Render muted so users don't read it as $0. */
.fin-raised-empty { color: var(--muted); }

.fin-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: auto;
}
.fin-cta {
  font-size: 11.5px;
  color: var(--blue, var(--dem));
  font-weight: 600;
}
/* ---------- Compare ---------- */
.cmp-slots {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1rem;
  align-items: stretch;
  margin: 0.5rem 0 1rem;
}
.cmp-slot {
  min-height: 150px;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--white);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.cmp-slot.party-dem { border-left: 4px solid var(--dem); }
.cmp-slot.party-rep { border-left: 4px solid var(--rep); }
.cmp-slot.party-ind { border-left: 4px solid var(--ind); }
.cmp-slot-empty {
  border-style: dashed;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--ink-soft);
  transition: border-color 0.12s, background 0.12s;
}
.cmp-slot-empty:hover { border-color: var(--blue); background: var(--surface); }
.cmp-slot-plus {
  font-size: 2.4rem;
  line-height: 1;
  color: var(--blue);
  font-weight: 300;
}
.cmp-slot-label { margin-top: 0.35rem; font-size: 0.88rem; }
.cmp-slot-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cmp-slot-clear {
  background: transparent;
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0 0.25rem;
}
.cmp-slot-clear:hover { color: var(--rep); }

/* Profile-tab compare: slot A is "locked" — pinned to the current
 * profile's member, no clear button. Tinted slightly so it reads as
 * the anchor card vs the freely-changeable B slot. The "📍 Current"
 * pill in the head clarifies which side is which. */
.cmp-slot-locked {
  background: linear-gradient(135deg, rgba(45, 108, 223, 0.04), var(--white));
  border-color: var(--border);
}
.cmp-slot-pin {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--blue);
  background: rgba(45, 108, 223, 0.1);
  padding: 3px 8px;
  border-radius: 999px;
}

/* Profile-tab compare shell — same .cmp-shell foundation as the
 * /compare page but with a leading intro paragraph above the slot
 * grid, and tighter top spacing so it reads as a tab section
 * rather than a full page. */
.cmp-shell-profile { margin-top: 0; }
.cmp-tab-intro {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0 0 18px;
}
.cmp-tab-intro strong { color: var(--ink); font-weight: 700; }
.cmp-slot-name {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  margin-top: 0.5rem;
}
.cmp-slot-meta { font-size: 0.84rem; color: var(--ink-soft); margin-top: 0.15rem; }
.cmp-vs {
  align-self: center;
  font-family: var(--font-serif);
  font-size: 1.6rem;
  color: var(--ink-soft);
  padding: 0 0.25rem;
}
.cmp-actions {
  display: flex;
  justify-content: center;
  margin: 0.75rem 0 1rem;
}
.cmp-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.cmp-table th,
.cmp-table td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.cmp-table th {
  background: var(--surface);
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
}
.cmp-table tbody tr:last-child td { border-bottom: none; }
.cmp-foot {
  font-size: 0.8rem;
  text-align: center;
  margin-top: 0.5rem;
}
@media (max-width: 700px) {
  .cmp-slots { grid-template-columns: 1fr; }
  .cmp-vs { text-align: center; }
}

/* Compare search overlay */
.cmp-search-card {
  max-width: 560px;
  width: calc(100% - 2rem);
  background: var(--white);
  border-radius: var(--radius);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.cmp-search-head {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}
.cmp-search-head input {
  flex: 1;
  border: none;
  padding: 0.5rem 0;
  font-size: 1rem;
  outline: none;
}
.cmp-search-head button {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-2);
  font-size: 1.1rem;
  line-height: 1;
}
.cmp-search-list {
  overflow-y: auto;
  flex: 1;
}
.cmp-search-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s;
}
.cmp-search-row:hover { background: var(--surface); }
.cmp-search-row:last-child { border-bottom: none; }
.cmp-search-name { font-weight: 600; font-size: 0.95rem; }
.cmp-search-meta { font-size: 0.82rem; color: var(--ink-soft); margin-top: 0.15rem; }
.btn.btn-sm {
  padding: 0.3rem 0.7rem;
  font-size: 0.82rem;
}

/* ---------- Search page ---------- */
.search-bar {
  margin: 0 0 1rem;
}
.search-bar input {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 2px solid var(--border);
  border-radius: var(--radius);
  font-size: 1rem;
  background: var(--white);
  outline: none;
  transition: border-color 0.12s;
}
.search-bar input:focus { border-color: var(--blue); }
.search-section {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.5rem 0;
  margin-bottom: 1rem;
}
.search-section h3 {
  margin: 0;
  padding: 0.65rem 1rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--border);
}
.search-list .search-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s;
}
.search-list .search-row:last-child { border-bottom: none; }
.search-list .search-row:hover { background: var(--surface); }

/* Federal vs state-leg badge on search-result rows. Inline pill so the
 * jurisdiction is clear at a glance — important now that the same name
 * (e.g. "John Smith") can match both a federal and a state legislator. */
.search-row-badge {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.08rem 0.45rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  border-radius: 4px;
  vertical-align: middle;
  text-transform: uppercase;
}
.badge-federal { background: rgba(45, 108, 223, 0.13); color: #1d4f99; }
.badge-state { background: rgba(120, 90, 180, 0.14); color: #5a3d99; }

/* Compare picker — sister badges for federal vs state result rows.
 * Same color treatment as the global search badges but on a row
 * background that's slightly darker, so we tighten the contrast. */
.cmp-search-badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.08rem 0.4rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  border-radius: 4px;
  vertical-align: middle;
  text-transform: uppercase;
}
.cmp-badge-federal { background: rgba(45, 108, 223, 0.13); color: #1d4f99; }
.cmp-badge-state { background: rgba(120, 90, 180, 0.14); color: #5a3d99; }

/* ─────────────────────────────────────────────────────────────────────
 * State bills — list rows on the State Legislature tab + detail page
 * (Phase 1.6).
 * ───────────────────────────────────────────────────────────────────── */

.state-bills-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.5rem;
}
.state-bill-row {
  display: block;
  padding: 0.85rem 1rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.state-bill-row:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  border-color: var(--blue);
}
.state-bill-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}
.state-bill-row-id {
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--text-primary);
  letter-spacing: 0.3px;
}
.state-bill-row-title {
  font-size: 0.95rem;
  color: var(--text-primary);
  line-height: 1.4;
  margin-bottom: 0.3rem;
  /* 2-line clamp so long titles don't blow row height */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.state-bill-row-meta {
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.bill-status-pill {
  display: inline-block;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  white-space: nowrap;
}
.bill-status-pill.status-pending  { background: rgba(120, 120, 130, 0.14); color: #555; }
.bill-status-pill.status-progress { background: rgba(243, 156, 18, 0.18); color: #8a5e00; }
.bill-status-pill.status-success  { background: rgba(15, 106, 68, 0.16);  color: #0f6a44; }
.bill-status-pill.status-fail     { background: rgba(214, 55, 55, 0.16);  color: #962727; }

/* Bill detail page */
.bill-hero-row {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0.5rem 0 0.6rem;
  flex-wrap: wrap;
}
.bill-identifier {
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: rgba(255, 255, 255, 0.95);
}
.page-hero .bill-status-pill {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.bill-title {
  margin: 0.1rem 0 0.5rem;
  font-size: 1.65rem;
  font-weight: 600;
  line-height: 1.25;
  color: #ffffff;
}
.bill-meta {
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.78);
  margin: 0;
}

.bill-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr);
  gap: 2rem;
  margin: 1.5rem 0 2rem;
}
.bill-main, .bill-side {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.bill-abstract {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text-primary);
  margin: 0;
}

/* Action history — vertical timeline */
.bill-actions {
  list-style: none;
  padding: 0;
  margin: 0;
}
.bill-action {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.92rem;
}
.bill-action:last-child { border-bottom: none; }
.bill-action-date {
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 0.82rem;
  padding-top: 0.1rem;
  white-space: nowrap;
}
.bill-action-desc {
  color: var(--text-primary);
  line-height: 1.5;
}
.bill-action-org {
  font-size: 0.78rem;
  color: var(--text-secondary);
  margin-top: 0.2rem;
}
.bill-action.is-latest .bill-action-desc {
  font-weight: 600;
}
/* "Latest" badge — sits inline at the start of the description so the
 * left-hand date column stays 100px and the badge can never overflow
 * into the body column (the old ::after on .bill-action-date forced a
 * nowrap overflow that overlapped the next-column description). */
.bill-action-latest {
  display: inline-block;
  margin-right: 0.5rem;
  padding: 0.1rem 0.45rem;
  background: rgba(45, 108, 223, 0.13);
  color: #1d4f99;
  border-radius: 4px;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
}

/* Sponsors */
.bill-sponsors {
  list-style: none;
  padding: 0;
  margin: 0;
}
.bill-sponsor {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.9rem;
}
.bill-sponsor:last-child { border-bottom: none; }
.bill-sponsor-name { color: var(--text-primary); }
.bill-sponsor-tag {
  font-size: 0.7rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}

/* Subjects */
.bill-subjects {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.bill-subject-tag {
  display: inline-block;
  padding: 0.18rem 0.55rem;
  background: var(--bg-soft, #f8f9fb);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--text-primary);
}

.bill-sources {
  list-style: none;
  padding: 0;
  margin: 0 0 0.5rem;
}
.bill-sources li {
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.88rem;
}
.bill-sources li:last-child { border-bottom: none; }
.bill-sources a { color: var(--blue); text-decoration: none; word-break: break-all; }
.bill-sources a:hover { text-decoration: underline; }
.bill-os-link {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
}
.bill-os-link a { color: var(--blue); text-decoration: none; font-weight: 600; }
.bill-os-link a:hover { text-decoration: underline; }

@media (max-width: 860px) {
  .bill-grid { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .bill-action { grid-template-columns: 1fr; }
  .bill-action-date { font-size: 0.74rem; }
  .bill-identifier { font-size: 1.3rem; }
  .bill-title { font-size: 1.3rem; }
}
mark {
  background: rgba(243, 156, 18, 0.35);
  color: inherit;
  padding: 0 0.1rem;
  border-radius: 2px;
}

/* ---------- Edit Profile modal ---------- */
.profile-edit-card {
  background: var(--white);
  border-radius: var(--radius);
  width: calc(100% - 2rem);
  max-width: 580px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.profile-edit-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.profile-edit-head h2 {
  margin: 0;
  font-size: 1.3rem;
}
.profile-edit-close {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-2);
  font-size: 1.2rem;
  line-height: 1;
}
.profile-edit-body {
  padding: 1rem 1.25rem 1.5rem;
  overflow-y: auto;
}
.ep-section h3 {
  margin: 0 0 0.75rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}
.ep-divider {
  height: 1px;
  background: var(--border);
  margin: 1.25rem 0;
}
.ep-msg {
  display: none;
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  margin-bottom: 0.5rem;
}
.ep-msg.active { display: block; }
.ep-msg.success {
  background: rgba(46, 204, 113, 0.15);
  color: #1c7a44;
}
.ep-msg.error {
  background: rgba(217, 50, 47, 0.12);
  color: var(--rep);
}
.ep-hint { font-size: 0.78rem; margin-top: 0.2rem; }
.ep-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.75rem;
}
.ep-danger { }
.ep-danger-toggle {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 0.55rem 0;
  font-weight: 600;
  color: var(--rep);
  font-size: 0.9rem;
}
.ep-chev { transition: transform 0.15s; }
.ep-danger-toggle[aria-expanded='true'] .ep-chev { transform: rotate(180deg); }
.ep-danger-body { margin-top: 0.75rem; }
.ep-goodbye {
  font-family: var(--font-serif);
  font-size: 1.3rem;
  text-align: center;
  padding: 3rem 0;
  color: var(--ink-soft);
}

/* ============================================================
   v5 Phase-5+ migration: shared layout, accents, footer, a11y
   ============================================================ */

/* ---------- Skip-to-main link (a11y) ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--navy);
  color: #fff;
  padding: 10px 18px;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-weight: 600;
  z-index: 10000;
}
.skip-link:focus {
  left: 1rem;
  top: 0.5rem;
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ---------- Site footer ---------- */
.site-footer {
  background: var(--navy);
  color: rgba(255, 255, 255, 0.78);
  padding: 28px 36px 24px;
  margin-top: 3rem;
}
.footer-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 18px 28px;
  align-items: center;
}
.footer-brand {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.footer-logo {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  letter-spacing: 0.01em;
  color: #fff;
}
.footer-tagline {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 0.85rem;
}
.footer-nav a {
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
}
.footer-nav a:hover {
  color: #fff;
  text-decoration: underline;
}
.footer-meta {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.72rem;
  color: rgba(255, 255, 255, 0.45);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-top: 14px;
  margin-top: 6px;
}

/* Legal links live in their own footer row, smaller + more muted than the
   primary navigation. Keeps About/Privacy/Terms accessible without
   competing visually with the topical navigation above. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 0.78rem;
  margin-top: 4px;
}
.footer-legal a {
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
}
.footer-legal a:hover {
  color: #fff;
  text-decoration: underline;
}

/* About / Privacy / Terms body — comfortable reading width, modest type. */
.legal-page {
  max-width: 720px;
  margin: 24px auto 60px;
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--ink);
}
.legal-page h2 {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  margin: 1.6rem 0 0.5rem;
  color: var(--navy);
}
.legal-page p { margin: 0 0 0.9rem; }
.legal-page ul {
  margin: 0 0 1rem;
  padding-left: 1.4rem;
}
.legal-page li { margin-bottom: 0.5rem; }
.legal-page a {
  color: var(--blue, var(--dem));
  text-decoration: underline;
  text-underline-offset: 2px;
}
.legal-page code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85em;
  background: rgba(0, 0, 0, 0.05);
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
}
@media (max-width: 720px) {
  .footer-inner { grid-template-columns: 1fr; }
  .site-footer { padding: 22px 18px 18px; }
}

/* ---------- Extend accent classes to profile heroes ---------- */
.profile-hero.accent-purple { background: linear-gradient(135deg, #2d1b4e 0%, #3b2568 55%, #4b3280 100%); }
.profile-hero.accent-green  { background: linear-gradient(135deg, #0e3d2a 0%, #145139 55%, #1a6a4a 100%); }
.profile-hero.accent-violet { background: linear-gradient(135deg, #261848 0%, #3a2670 55%, #4b3490 100%); }

/* ---------- New accent variants for migrated pages ---------- */
/* Historical: sage forest → navy */
.page-hero.accent-history,
.profile-hero.accent-history {
  background: linear-gradient(135deg, #1a2a1a 0%, #243d2e 55%, #1a2e3a 100%);
}
/* Compare: navy with red+blue radial accents (handled via ::before) */
.page-hero.accent-compare {
  background: linear-gradient(135deg, var(--navy) 0%, #1a3a6e 100%);
}
.page-hero.accent-compare::before {
  background:
    radial-gradient(ellipse at 28% 50%, rgba(46, 125, 247, 0.18) 0%, transparent 55%),
    radial-gradient(ellipse at 72% 50%, rgba(214, 58, 58, 0.14) 0%, transparent 55%);
}
/* MyReps: lighter blue navy */
.page-hero.accent-myreps {
  background: linear-gradient(135deg, #11305d 0%, #1a4485 55%, #245aa5 100%);
}

/* ---------- Historical page filter row tweaks ---------- */
.hist-filter-row {
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.hist-filter-row .filter-party {
  flex-wrap: wrap;
}
.hist-count {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--ink-soft);
  font-weight: 500;
}
@media (max-width: 600px) {
  .hist-count { margin-left: 0; }
}

/* ---------- Compare page (v5) ---------- */
.cmp-shell {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
  margin-bottom: 1.25rem;
}
.cmp-slots {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: 16px;
  margin-bottom: 18px;
}
.cmp-slot {
  background: var(--off-white, #f7f7f1);
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: 22px 20px;
  cursor: pointer;
  transition: border-color 0.18s, background 0.18s, transform 0.18s;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 110px;
  position: relative;
}
.cmp-slot:hover { border-color: var(--blue); background: var(--blue-pale, #eaf2ff); transform: translateY(-1px); }
.cmp-slot-empty {
  align-items: center;
  justify-content: center;
  text-align: center;
}
.cmp-slot-plus {
  font-size: 28px;
  color: var(--blue);
  font-weight: 300;
  line-height: 1;
}
.cmp-slot-label {
  font-size: 0.85rem;
  color: var(--ink-soft);
  font-weight: 500;
}
.cmp-slot:not(.cmp-slot-empty) {
  border-style: solid;
  background: var(--white);
}
.cmp-slot-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cmp-slot-clear {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
.cmp-slot-clear:hover { background: var(--red-pale, #fde7e6); border-color: var(--rep); color: var(--rep); }
.cmp-slot-name {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  color: var(--ink);
  margin-top: 4px;
}
.cmp-slot-meta { font-size: 0.78rem; color: var(--ink-soft); }
.cmp-slot.party-dem { box-shadow: inset 4px 0 0 var(--blue); }
.cmp-slot.party-rep { box-shadow: inset 4px 0 0 var(--rep); }
.cmp-slot.party-ind { box-shadow: inset 4px 0 0 var(--gold); }
.cmp-vs {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  color: var(--ink-soft);
  align-self: center;
  padding: 0 4px;
}
.cmp-actions {
  display: flex;
  justify-content: flex-end;
}
.cmp-actions .btn-primary[disabled] { opacity: 0.55; cursor: not-allowed; }
.cmp-result { margin-top: 1rem; }
.cmp-result .section-title { margin-bottom: 0.75rem; }
.cmp-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.cmp-table th,
.cmp-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  font-size: 0.92rem;
}
.cmp-table th {
  background: var(--surface-2, #f5f3ec);
  font-weight: 600;
  color: var(--navy);
  font-size: 0.85rem;
}
.cmp-table tr:last-child td { border-bottom: none; }
.cmp-foot {
  margin-top: 0.85rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
  font-style: italic;
}
@media (max-width: 720px) {
  .cmp-slots { grid-template-columns: 1fr; }
  .cmp-vs { padding: 4px 0; }
}

/* ---------- Finance filter-row + progress ---------- */
/* Sticky-feeling white toolbar under the dark green hero. Matches the
   template: search input on the left, filter pill groups in the middle,
   sort select pinned to the right, member-count tag last. */
.fin-toolbar {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 14px 24px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.fin-toolbar-search {
  display: flex;
  align-items: center;
  background: var(--off-white, #f4f6fb);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 7px 13px;
  gap: 7px;
  flex: 1;
  max-width: 320px;
}
.fin-toolbar-search-icon {
  color: var(--ink-soft);
  font-size: 14px;
}
.fin-toolbar-search input {
  border: none;
  outline: none;
  background: transparent;
  font-family: 'DM Sans', sans-serif;
  font-size: 13px;
  color: var(--ink, #1a2540);
  width: 100%;
}
.fin-sort {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: 'DM Sans', sans-serif;
  font-size: 12.5px;
  color: var(--ink, #1a2540);
  background: var(--white);
  cursor: pointer;
  outline: none;
  margin-left: auto;
}
.fin-toolbar-count {
  font-size: 12px;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Underlined-tab filter style — matches the template. The active state shows
   blue text + a 2px blue underline; hover previews the same underline. */
.fin-filter-tabs {
  display: flex;
  gap: 2px;
  align-items: center;
}
.fin-filter-tab {
  padding: 9px 15px;
  font-size: 12.5px;
  font-weight: 500;
  font-family: 'DM Sans', sans-serif;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  transition: all 0.18s;
}
.fin-filter-tab:hover { color: var(--blue, var(--dem)); border-bottom-color: rgba(29, 95, 201, 0.4); }
.fin-filter-tab.active {
  color: var(--blue, var(--dem));
  border-bottom-color: var(--blue, var(--dem));
}

/* FEC progress note — gold band below the toolbar. */
@media (max-width: 720px) {
  .fin-toolbar { padding: 12px 16px; }
  .fin-toolbar-search { max-width: 100%; flex-basis: 100%; }
  .fin-sort { margin-left: 0; }
}

/* ---------- Search page (v5 white hero) ---------- */
.search-page-hero {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 32px 36px 28px;
  margin-bottom: 1.5rem;
}
.search-page-hero h1 {
  font-family: var(--font-serif);
  font-size: 1.8rem;
  color: var(--navy);
  margin: 6px 0 4px;
  font-weight: 400;
}
.search-page-hero h1 em { color: var(--gold); font-style: normal; }
.search-hero-sub {
  color: var(--ink-soft);
  font-size: 0.92rem;
  margin: 0 0 18px;
}
.breadcrumb-trail.trail-light {
  color: var(--ink-soft);
}
.breadcrumb-trail.trail-light a { color: var(--blue); }
.breadcrumb-trail.trail-light .sep { color: var(--ink-soft); opacity: 0.5; }
.search-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-2, #f5f3ec);
  border: 2px solid var(--border);
  border-radius: 14px;
  padding: 11px 18px;
  max-width: 680px;
  transition: border-color 0.18s, box-shadow 0.18s;
}
.search-bar:focus-within {
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(28, 95, 216, 0.1);
}
.search-bar-icon { font-size: 18px; }
.search-bar input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
}
.search-suggest {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 14px;
}
.search-suggest-label {
  font-size: 0.78rem;
  color: var(--ink-soft);
  font-weight: 600;
  margin-right: 4px;
}
.search-suggest button {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px;
  font: inherit;
  font-size: 0.82rem;
  color: var(--blue);
  cursor: pointer;
  font-weight: 500;
  transition: border-color 0.15s, background 0.15s;
}
.search-suggest button:hover {
  border-color: var(--blue);
  background: var(--blue-pale, #eaf2ff);
}
.search-results { padding-top: 0.25rem; }

/* ---------- MyReps hero / page-hero hybrid ---------- */
.page-hero.accent-myreps .myreps-eyebrow {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
  margin-bottom: 8px;
  font-weight: 600;
}
.page-hero.accent-myreps .myreps-addr {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.18);
  display: inline-block;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 0.85rem;
  margin-top: 10px;
  color: rgba(255, 255, 255, 0.92);
}

/* ---------- Auth modal: v5 polish ---------- */
.auth-card {
  padding: 2rem 1.85rem 1.85rem;
  position: relative;
}
.auth-card::before {
  content: 'PoliticSource';
  display: block;
  text-align: center;
  font-family: var(--font-serif);
  font-size: 1.6rem;
  color: var(--navy);
  margin-bottom: 4px;
  letter-spacing: 0.01em;
}
.auth-card::after {
  content: 'Track your representatives. Follow legislation that affects you.';
  display: block;
  text-align: center;
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin-bottom: 1.25rem;
  line-height: 1.45;
}
.auth-tabs {
  background: var(--surface-2, #f5f3ec);
  padding: 5px;
  border-radius: 999px;
}
.auth-tabs button {
  border-radius: 999px;
  padding: 0.55rem 0.5rem;
  font-size: 0.88rem;
  letter-spacing: 0.01em;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
.auth-tabs button.active {
  background: var(--white);
  box-shadow: 0 1px 3px rgba(11, 37, 69, 0.1);
}
.auth-card .btn.btn-primary {
  margin-top: 0.4rem;
  height: 44px;
  font-weight: 600;
  letter-spacing: 0.01em;
  background: var(--navy);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.15s, transform 0.1s;
}
.auth-card .btn.btn-primary:hover {
  background: #07223f;
  transform: translateY(-1px);
}
.auth-card .btn.btn-primary:active { transform: translateY(0); }

/* ---------- Search input default outline (3 unlabeled inputs labelled via aria-label) ---------- */
input[type='search']:focus-visible {
  outline: none;
}

/* ---------- Profile hero accent helpers used by Historical profile ---------- */
.profile-hero.accent-history .exec-avatar {
  background: linear-gradient(135deg, #34563f 0%, #5a8769 100%) !important;
}

/* ---------- States page ---------- */
.page-hero.accent-blue {
  background: linear-gradient(135deg, #14233f 0%, #1a365d 55%, #21477b 100%);
}

.state-hero-abbr {
  display: inline-block;
  margin-left: 0.5rem;
  font-size: 0.6em;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.7);
  font-weight: 500;
  vertical-align: middle;
}

/* Index: 50-state directory grid */
.state-index-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
  margin: 24px 0 60px;
}

.state-index-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.state-index-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(20, 35, 63, 0.08);
  border-color: #b9c4d6;
}
.state-index-card:hover .state-index-shape-svg path {
  fill: var(--dem);
  opacity: 1;
}

.state-index-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.state-index-abbr {
  font-family: 'DM Serif Display', serif;
  font-size: 1.6rem;
  color: var(--dem);
  letter-spacing: 0.04em;
  line-height: 1;
}
.state-index-name {
  font-size: 0.95rem;
  color: var(--text, #1d2330);
  font-weight: 500;
}

.state-index-shape {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.state-index-shape-svg {
  width: 100%;
  height: 100%;
  overflow: visible; /* islands (e.g. HI, AK Aleutians) sometimes nudge outside the bbox */
}
.state-index-shape-svg path {
  fill: #14233f;
  opacity: 0.18;
  transition: fill 0.12s ease, opacity 0.12s ease;
}

/* Per-state view: section + card grid */
.state-section {
  margin: 32px 0;
}
.state-section-title {
  font-family: 'DM Serif Display', serif;
  font-size: 1.5rem;
  margin: 0 0 6px;
  color: #14233f;
}
.state-section-note {
  margin: 0 0 14px;
  font-size: 0.85rem;
  color: var(--muted, #6c7689);
}
.state-section-empty {
  padding: 18px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  color: var(--muted, #6c7689);
  font-size: 0.9rem;
  background: #fafbfd;
}

.state-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

/* Card baseline (used for both federal-button and exec-anchor variants) */
.state-card {
  display: grid;
  grid-template-columns: 48px 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 4px solid var(--border);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.state-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(20, 35, 63, 0.08);
  border-color: #b9c4d6;
}
.state-card:focus-visible {
  outline: 2px solid var(--dem);
  outline-offset: 2px;
}
.state-card.dem { border-left-color: var(--dem); }
.state-card.rep { border-left-color: var(--rep); }
.state-card.ind { border-left-color: var(--gold, #b88a2c); }

.state-card-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--blue-pale, #e3eafd);
  color: var(--dem);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.95rem;
  overflow: hidden;
  flex-shrink: 0;
}
.state-card.rep .state-card-avatar { background: var(--red-pale, #fde6e5); color: var(--rep); }
.state-card.ind .state-card-avatar { background: #fbf2dc; color: #8a6a1f; }
.state-card-avatar img {
  width: 100%; height: 100%; object-fit: cover;
}

.state-card-body {
  min-width: 0;
}
.state-card-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text, #1d2330);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.state-card-role {
  margin-top: 2px;
  font-size: 0.8rem;
  color: var(--muted, #6c7689);
}

.state-card-ext {
  font-size: 0.95rem;
  color: var(--muted, #6c7689);
  margin-left: 4px;
}

.state-page-footer {
  margin: 24px 0 60px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: 0.78rem;
  color: var(--muted, #6c7689);
  text-align: center;
}

/* Per-state district map (118th-Congress shapes from ArcGIS Living Atlas).
   Each <path> is a single congressional district; .dem/.rep/.ind/.vac come
   from the colored chamber palette so the map matches the cards below. */
.state-district-map-wrap {
  position: relative;
  background: #f5f7fb;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
}
.state-district-map {
  position: relative;
  width: 100%;
  min-height: 240px;
}
.state-district-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 240px;
  color: var(--muted, #6c7689);
  font-size: 0.9rem;
}
.state-district-svg {
  width: 100%;
  height: auto;
  display: block;
}
.state-district-path {
  transition: opacity 0.12s ease, stroke-width 0.12s ease;
}
.state-district-path.clickable {
  cursor: pointer;
}
.state-district-path.clickable:hover {
  opacity: 0.85;
  stroke-width: 1.6;
}
.state-district-path.vac {
  fill: #c9d0dc;
}
.state-district-tooltip {
  position: absolute;
  pointer-events: none;
  background: #14233f;
  color: #fff;
  font-size: 0.78rem;
  padding: 5px 10px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 0.1s ease;
  box-shadow: 0 4px 12px rgba(20, 35, 63, 0.18);
  z-index: 5;
}
.state-district-tooltip.visible {
  opacity: 1;
}
.state-district-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  font-size: 0.78rem;
  color: var(--muted, #6c7689);
}
.state-district-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.state-district-legend .swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.05);
}
.state-district-legend .swatch.dem { background: var(--dem); }
.state-district-legend .swatch.rep { background: var(--rep); }
.state-district-legend .swatch.ind { background: #7b4f9e; }
.state-district-legend .swatch.vac { background: #c9d0dc; }
.state-district-legend .swatch.pin {
  background: #ffba1f;
  border: 2px solid #c98a00;
  box-shadow: 0 0 0 1.5px #fff inset;
}

/* "You are here" pin used by the My HQ district map. Three layers:
     - .state-district-pin-pulse  outer animated ring, attention-grab
     - .state-district-pin-halo   solid white disc, contrast against any
                                   underlying party color (red/blue/etc.)
     - .state-district-pin-dot    bright amber center, anchor + theme tie
   Using SVG <circle> elements means the pin scales with the SVG viewBox
   automatically. */
.state-district-pin {
  pointer-events: none;
}
.state-district-pin-pulse {
  fill: #ffba1f;
  fill-opacity: 0.55;
  animation: state-district-pin-pulse 1.8s ease-out infinite;
  transform-origin: center;
  transform-box: fill-box;
}
.state-district-pin-halo {
  fill: #ffffff;
}
.state-district-pin-dot {
  fill: #f59e0b;          /* deeper amber — reads as "warning/attention" */
  stroke: #7a4f00;        /* dark brown ring keeps definition over halo */
  stroke-width: 1.6;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}
@keyframes state-district-pin-pulse {
  0%   { transform: scale(0.45); fill-opacity: 0.7; }
  70%  { transform: scale(1.6); fill-opacity: 0; }
  100% { transform: scale(1.6); fill-opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .state-district-pin-pulse { animation: none; }
}

/* The pinned district itself gets a thicker amber outline so it reads even
   if the centroid pin happens to render off the silhouette (concave shapes). */
.state-district-path.is-pinned {
  stroke: #c98a00;
  stroke-width: 2.4;
}

@media (max-width: 600px) {
  .state-cards-grid { grid-template-columns: 1fr; }
  .state-index-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .state-index-card { padding: 12px; gap: 8px; }
  .state-index-shape { width: 44px; height: 44px; }
  .state-index-abbr { font-size: 1.35rem; }
  .state-index-name { font-size: 0.85rem; }
  .state-card { grid-template-columns: 40px 1fr auto; }
  .state-card-ext { display: none; }
  .state-district-map { min-height: 200px; }
  .state-district-legend { gap: 10px; font-size: 0.72rem; }
}

/* ─────────────────────────────────────────────────────────────────────
 * Vote detail page (/votes/:voteId)
 *
 * Shares the bill-detail-hero base styling so the two pages read as
 * siblings; adds a tally summary card + per-member breakdown grouped
 * by party. Position dot (Y/N/P/—) is the rightmost column on each
 * member tile so the eye scans the chamber's vote pattern at a glance.
 * ───────────────────────────────────────────────────────────────────── */
.vote-detail-hero { /* inherit bill-detail-hero, no override needed */ }
.vote-description {
  margin: 12px 0 0 0;
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.55;
  max-width: 880px;
}
.vote-meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 0.85rem;
  color: var(--ink);
  text-decoration: none;
}
.vote-meta-chip strong { color: var(--ink-strong, var(--ink)); }
.vote-bill-chip { transition: background 0.15s, border-color 0.15s; }
.vote-bill-chip:hover { background: rgba(45, 108, 223, 0.08); border-color: var(--blue); }
.vote-result-chip.good { background: rgba(34, 154, 92, 0.12); border-color: rgba(34, 154, 92, 0.4); color: #167a45; }
.vote-result-chip.bad { background: rgba(204, 60, 80, 0.12); border-color: rgba(204, 60, 80, 0.4); color: #a82a3e; }
.vote-result-chip.pending { background: rgba(245, 166, 35, 0.14); border-color: rgba(245, 166, 35, 0.4); color: #8c5c12; }

.vote-tally-card,
.vote-members-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 28px;
  margin: 20px 40px;
}
.vote-section-title {
  margin: 0 0 16px 0;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--ink);
}

.vote-tally-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.vote-tally-cell {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  text-align: center;
}
.vote-tally-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); margin-bottom: 6px; }
.vote-tally-num { font-size: 2rem; font-weight: 700; line-height: 1; color: var(--ink); }
.vote-tally-pct { font-size: 0.85rem; color: var(--ink-soft); margin-top: 4px; }
.vote-tally-yea { background: rgba(34, 154, 92, 0.08); border-color: rgba(34, 154, 92, 0.25); }
.vote-tally-yea .vote-tally-num { color: #167a45; }
.vote-tally-nay { background: rgba(204, 60, 80, 0.08); border-color: rgba(204, 60, 80, 0.25); }
.vote-tally-nay .vote-tally-num { color: #a82a3e; }
.vote-tally-present { background: rgba(245, 166, 35, 0.08); border-color: rgba(245, 166, 35, 0.25); }
.vote-tally-nv { background: var(--surface); }

.vote-tally-bar {
  display: flex;
  height: 12px;
  border-radius: 6px;
  overflow: hidden;
  margin-top: 8px;
  background: var(--border);
}
.vote-tally-bar-yea { background: #229a5c; }
.vote-tally-bar-nay { background: #cc3c50; }
.vote-tally-bar-present { background: #f5a623; }
.vote-tally-bar-nv { background: #c8c8c8; }

.vote-source-link {
  display: inline-block;
  margin-top: 14px;
  font-size: 0.88rem;
  color: var(--blue);
  text-decoration: none;
}
.vote-source-link:hover { text-decoration: underline; }

.vote-party-section { margin-bottom: 22px; }
.vote-party-section:last-child { margin-bottom: 0; }
.vote-party-heading {
  margin: 0 0 10px 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
  padding: 6px 12px;
  border-radius: 8px;
  display: inline-block;
}
.vote-party-d .vote-party-heading { background: rgba(45, 108, 223, 0.12); color: #1a4ba8; }
.vote-party-r .vote-party-heading { background: rgba(204, 60, 80, 0.12); color: #a82a3e; }
.vote-party-i .vote-party-heading { background: rgba(123, 79, 158, 0.12); color: #5e3679; }
.vote-party-other .vote-party-heading { background: var(--surface); color: var(--ink-soft); }

.vote-member-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}
.vote-member-cell {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto;
  gap: 0 8px;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--white);
  text-decoration: none;
  color: var(--ink);
  font-size: 0.82rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.vote-member-cell:hover {
  border-color: var(--blue);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.vote-member-name {
  grid-column: 1;
  grid-row: 1;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vote-member-state {
  grid-column: 1;
  grid-row: 2;
  font-size: 0.72rem;
  color: var(--ink-soft);
}
.vote-member-pos {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-weight: 700;
  font-size: 0.95rem;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
}
.vote-member-cell.pos-yea .vote-member-pos { background: #229a5c; }
.vote-member-cell.pos-nay .vote-member-pos { background: #cc3c50; }
.vote-member-cell.pos-present .vote-member-pos { background: #f5a623; }
.vote-member-cell.pos-nv .vote-member-pos { background: #c8c8c8; color: var(--ink); }

.vote-members-pending {
  padding: 18px;
  background: rgba(245, 166, 35, 0.08);
  border: 1px dashed rgba(245, 166, 35, 0.4);
  border-radius: 10px;
  color: var(--ink-soft);
  font-size: 0.92rem;
}
.vote-members-pending p { margin: 0; }

@media (max-width: 720px) {
  .vote-tally-card,
  .vote-members-card { margin: 16px 16px; padding: 18px 16px; }
  .vote-member-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

/* ─────────────────────────────────────────────────────────────────────
 * Pro subscription page (/pro) + Pro badge in user menu
 *
 * The Pro page borrows the donate page's card pattern but adds a
 * monthly/yearly plan toggle, a trial pill, and a member-only state
 * card. Body class .user-is-pro drives the menu badge + link swap.
 * ───────────────────────────────────────────────────────────────────── */
.pro-hero { /* inherits page-hero */ }
.pro-test-banner {
  background: rgba(245, 166, 35, 0.14);
  border: 1px solid rgba(245, 166, 35, 0.4);
  color: #6a4506;
  border-radius: 10px;
  padding: 12px 16px;
  margin: 16px 40px 0;
  font-size: 0.92rem;
}
.pro-test-banner code {
  background: rgba(255, 255, 255, 0.5);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.88em;
}

.pro-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 32px;
  margin: 20px 40px;
  max-width: 720px;
}
.pro-card-member { background: linear-gradient(135deg, rgba(245, 166, 35, 0.06), rgba(255, 255, 255, 1)); }

.pro-trial-pill {
  display: inline-block;
  background: rgba(34, 154, 92, 0.14);
  color: #167a45;
  border: 1px solid rgba(34, 154, 92, 0.35);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 18px;
}

.pro-plan-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 18px;
}
.pro-plan-btn {
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  font-family: inherit;
  transition: all 0.15s;
}
.pro-plan-btn:hover { border-color: var(--ink-soft); }
.pro-plan-btn.active {
  border-color: var(--gold);
  background: rgba(245, 166, 35, 0.06);
  box-shadow: 0 0 0 3px rgba(245, 166, 35, 0.15);
}
.pro-plan-name { font-weight: 700; color: var(--ink); font-size: 0.95rem; }
.pro-plan-price { font-size: 1.05rem; font-weight: 600; color: var(--ink); }
.pro-plan-savings {
  display: inline-block;
  font-size: 0.78rem;
  color: #167a45;
  font-weight: 600;
  margin-top: 4px;
}

.pro-subscribe-btn { width: 100%; padding: 14px; font-size: 1rem; font-weight: 700; }
.pro-portal-btn { padding: 12px 24px; font-weight: 600; }

.pro-error { color: #a82a3e; font-size: 0.9rem; min-height: 18px; margin-bottom: 8px; }
.pro-foot { color: var(--ink-soft); font-size: 0.85rem; line-height: 1.5; margin: 12px 0 0; }
.pro-foot a { color: var(--blue); }

.pro-member-badge {
  display: inline-block;
  background: rgba(245, 166, 35, 0.2);
  color: #8c5c12;
  border: 1px solid rgba(245, 166, 35, 0.4);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 14px;
}
.pro-member-meta {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.92rem;
  color: var(--ink);
  margin-bottom: 18px;
}
.pro-member-meta strong { color: var(--ink); }

.pro-features-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 32px;
  margin: 20px 40px;
  max-width: 720px;
}
.pro-section-title { margin: 0 0 16px 0; font-size: 1.15rem; font-weight: 700; color: var(--ink); }
.pro-features-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.pro-features-list li {
  display: grid;
  grid-template-columns: minmax(160px, 220px) 1fr;
  gap: 14px;
  padding: 12px 14px;
  background: var(--surface);
  border-radius: 10px;
  font-size: 0.92rem;
  line-height: 1.5;
}
.pro-features-list strong { color: var(--ink); font-weight: 700; }
.pro-features-list span { color: var(--ink); }
.pro-features-foot { color: var(--ink-soft); font-size: 0.88rem; line-height: 1.55; margin: 16px 0 0; }
.pro-features-foot a { color: var(--blue); }

.pro-thanks-line { margin: 8px 0; color: var(--ink); font-size: 0.95rem; }
.pro-thanks-status { color: var(--ink-soft); font-size: 0.85rem; margin-top: 12px; }
.pro-thanks-actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
  flex-wrap: wrap;
}
.pro-thanks-actions .btn { padding: 10px 18px; }

@media (max-width: 720px) {
  .pro-card,
  .pro-features-card,
  .pro-test-banner { margin-left: 16px; margin-right: 16px; padding: 18px 16px; }
  .pro-plan-toggle { grid-template-columns: 1fr; }
  .pro-features-list li { grid-template-columns: 1fr; gap: 4px; }
}

/* (Removed: .user-menu-pro-badge — Pro indicator now lives on the
 * avatar itself as a gold ring + ⭐ corner overlay; see .avatar-face
 * + .avatar-pro-star above. The user-menu Pro link still toggles
 * label between "Upgrade to Pro" and "Manage Pro".) */

/* ─────────────────────────────────────────────────────────────────────
 * Watch button (Pro: Bill-watch + Vote-watch)
 *
 * Three visual states driven by classes set in public/js/watches.js:
 *   .watch-btn               default — Pro user not yet watching
 *   .watch-btn.is-watching   Pro user actively watching (filled star)
 *   .watch-btn.is-locked     Free / unauthed user — shows "Pro" pill,
 *                             click navigates to /pro
 * ───────────────────────────────────────────────────────────────────── */
.watch-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: 'DM Sans', sans-serif;
  color: var(--ink);
  cursor: pointer;
  transition: all 0.15s;
  margin-top: 10px;
}
.watch-btn:hover { border-color: var(--gold); color: #8c5c12; }
.watch-btn:disabled { opacity: 0.6; cursor: wait; }
.watch-btn .watch-star {
  font-size: 1.05rem;
  line-height: 1;
}
.watch-btn.is-watching {
  background: rgba(245, 166, 35, 0.16);
  border-color: var(--gold);
  color: #8c5c12;
}
.watch-btn.is-watching .watch-star { color: var(--gold); }
.watch-btn.is-watching:hover {
  background: rgba(245, 166, 35, 0.24);
}
.watch-btn.is-locked {
  cursor: pointer;
  opacity: 1;
}
.watch-btn .watch-pro-pill {
  display: inline-block;
  background: var(--gold);
  color: var(--white);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 2px 7px;
  border-radius: 999px;
  margin-left: 4px;
  text-transform: uppercase;
}

/* Slot wrappers — pinned to the top-right of their hero card.
 * z-index 2 so they sit above the .profile-hero::before glow.
 * Inner .watch-btn keeps its existing pill styling; we just override
 * the now-irrelevant top margin so the absolute position is clean. */
.bill-detail-watch-slot,
.profile-watch-slot {
  position: absolute;
  top: 20px;
  right: 24px;
  z-index: 2;
}
.bill-detail-watch-slot .watch-btn,
.profile-watch-slot .watch-btn { margin-top: 0; }
/* Profile hero is on a dark navy background — adjust the button's
 * default colors so it reads correctly against the gradient. */
.profile-watch-slot .watch-btn {
  background: rgba(255, 255, 255, 0.92);
  border-color: rgba(255, 255, 255, 0.5);
  color: var(--navy);
}
.profile-watch-slot .watch-btn:hover {
  background: var(--white);
  border-color: var(--gold);
  color: #8c5c12;
}
.profile-watch-slot .watch-btn.is-watching {
  background: rgba(245, 166, 35, 0.95);
  border-color: var(--gold);
  color: #4a2f06;
}
.profile-watch-slot .watch-btn.is-watching .watch-star { color: #4a2f06; }
.profile-watch-slot .watch-btn.is-watching:hover { background: var(--gold); }

@media (max-width: 600px) {
  /* On phones the absolute pin can overlap the title; flow it back
   * into the hero below the title text. */
  .bill-detail-watch-slot,
  .profile-watch-slot {
    position: static;
    top: auto;
    right: auto;
    margin-top: 0;
  }

  /* Mobile profile-hero rebuild (2026-05-20). The desktop layout
   * (avatar left, text right, actions pinned top-right) crammed up
   * on a 375px viewport — avatar wrapped to its own row, action
   * chips overlapped the title. Mobile gets a vertical, centered
   * column instead: breadcrumb (tight) → avatar (smaller) → name →
   * title → party badge → actions row. Cleaner hierarchy,
   * scannable at a glance. */
  .profile-hero {
    padding: 18px 16px 16px;
    border-radius: 14px;
  }
  .profile-hero .breadcrumb-trail {
    font-size: 10.5px;
    margin-bottom: 12px;
    /* Allow the long breadcrumb chain to wrap gracefully on narrow
     * viewports rather than overflow. */
    line-height: 1.5;
  }
  .profile-hero-row {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 12px;
  }
  .profile-hero .profile-avatar {
    width: 92px;
    height: 92px;
    font-size: 1.5rem;
  }
  .profile-hero-text {
    flex: 1 1 auto;
    width: 100%;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
  }
  .profile-hero-text .party-badge {
    /* Reorder: badge sits BELOW the title on mobile (under name +
     * sub-line) so the title is the visual anchor. */
    order: 3;
    margin-bottom: 0;
  }
  .profile-hero-text .profile-name {
    order: 1;
    font-size: 24px;
    line-height: 1.15;
    margin: 0;
  }
  .profile-hero-text .profile-title {
    order: 2;
    font-size: 13px;
  }
  /* Actions row: flow inline below the avatar/text column, centered. */
  .profile-actions {
    position: static;
    top: auto;
    right: auto;
    margin-top: 14px;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px;
  }

  /* Tabs row: 3 equal-width tabs that fit any phone, no h-scroll. */
  .profile-tabs {
    overflow-x: visible;
    padding: 4px;
    gap: 0;
  }
  .profile-tabs .tab {
    flex: 1 1 0;
    padding: 10px 8px;
    font-size: 12.5px;
    text-align: center;
    /* Slightly smaller font + tighter padding keeps "Voting Record"
     * and "Campaign Finance" on a single line each within ~115px. */
  }
}

/* My HQ "My Watch" tab — two groups (Members / Bills), each with a
 * heading + count badge. Sections sit on the same plain background as
 * the rest of the My HQ tab content. */
.myreps-watches-group { margin-bottom: 28px; }
.myreps-watches-group:last-child { margin-bottom: 0; }
.myreps-watches-group-title {
  margin: 0 0 12px 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 10px;
}
.myreps-watches-group-icon { font-size: 1.2rem; }
.myreps-watches-group-count {
  display: inline-block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-left: auto;
}
.myreps-watches-group-empty {
  padding: 14px 16px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 10px;
  color: var(--ink-soft);
  font-size: 0.88rem;
  line-height: 1.5;
}

/* My HQ — "My Watches" section */
.myreps-watches-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.myreps-watches-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.myreps-watches-row:hover {
  border-color: var(--gold);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.myreps-watches-link {
  flex: 1;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
  min-width: 0;          /* lets the text column truncate */
}
.myreps-watches-icon { font-size: 1.4rem; line-height: 1; }
.myreps-watches-icon-photo,
.myreps-watches-icon-fallback {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--navy);
  color: var(--white);
}
.myreps-watches-icon-photo { background: #e9ecf3; }
.myreps-watches-icon-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.myreps-watches-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.myreps-watches-primary {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.myreps-watches-secondary {
  font-size: 0.82rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.myreps-watches-meta {
  font-size: 0.78rem;
  color: var(--ink-soft);
  white-space: nowrap;
}
.myreps-watches-remove {
  background: transparent;
  border: 0;
  color: var(--ink-soft);
  font-size: 1.1rem;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.15s;
}
.myreps-watches-remove:hover {
  background: rgba(204, 60, 80, 0.14);
  color: #a82a3e;
}
.myreps-watches-remove:disabled { opacity: 0.5; cursor: wait; }

.myreps-watches-empty {
  padding: 18px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 10px;
  text-align: center;
  color: var(--ink);
}
.myreps-watches-empty-sub {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-top: 6px;
}
.myreps-watches-empty-sub a { color: var(--blue); }

.myreps-watches-upsell {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px;
  background: linear-gradient(135deg, rgba(245, 166, 35, 0.08), rgba(255, 255, 255, 1));
  border: 1px solid rgba(245, 166, 35, 0.4);
  border-radius: 12px;
  flex-wrap: wrap;
}
.myreps-watches-upsell-text {
  flex: 1;
  min-width: 240px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--ink);
}
.myreps-watches-upsell-text strong { color: #8c5c12; }

@media (max-width: 600px) {
  .myreps-watches-link { grid-template-columns: auto 1fr; }
  .myreps-watches-meta { grid-column: 1 / -1; padding-left: 36px; }
  .myreps-watches-upsell { flex-direction: column; align-items: stretch; }
}

/* ─────────────────────────────────────────────────────────────────────
 * Voting Record sub-tabs (Analysis + Votes) + Analysis dashboard
 *
 * Sub-tab strip mirrors the My HQ tab visual but smaller. Analysis
 * panel uses a card-based layout: 4-up stat grid, horizontal bars
 * for position breakdown, vertical bars for activity timeline,
 * stacked bar for outcomes, horizontal bars for bill-type breakdown.
 *
 * All visualizations are pure HTML/CSS — no chart library. Keeps the
 * bundle small and the markup screen-reader-friendly (counts are
 * always plain text, bars are decorative).
 * ─────────────────────────────────────────────────────────────────── */
.vr-subtabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
  padding-bottom: 0;
}
.vr-subtab {
  background: transparent;
  border: 0;
  padding: 10px 18px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s;
}
.vr-subtab:hover { color: var(--ink); }
.vr-subtab.active {
  color: var(--ink);
  border-bottom-color: var(--gold);
}
.vr-panel { display: none; }
.vr-panel.active { display: block; }
.vr-panel[hidden] { display: none !important; }

/* Analysis dashboard cards */
.vr-analysis-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 22px;
  margin-bottom: 16px;
}
.vr-section-title {
  margin: 0 0 14px;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
}
.vr-section-sub {
  font-weight: 400;
  color: var(--ink-soft);
  font-size: 0.82rem;
  margin-left: 6px;
}
.vr-analysis-foot {
  font-size: 0.82rem;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 8px 0 0;
}
.vr-empty-mini {
  padding: 16px;
  background: var(--surface);
  border-radius: 8px;
  color: var(--ink-soft);
  font-size: 0.88rem;
  text-align: center;
}

/* Filter row */
.vr-filter-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  padding: 14px 18px;
}
.vr-filter-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
}
.vr-filter-buttons {
  display: inline-flex;
  gap: 4px;
  background: var(--surface);
  border-radius: 8px;
  padding: 3px;
}
.vr-filter-btn {
  background: transparent;
  border: 0;
  padding: 6px 12px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-soft);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s;
}
.vr-filter-btn:hover { color: var(--ink); }
.vr-filter-btn.active {
  background: var(--white);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.vr-filter-summary {
  margin-left: auto;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* 4-up stat grid */
.vr-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.vr-stat-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
}
.vr-stat-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  margin-bottom: 6px;
  font-weight: 600;
}
.vr-stat-value {
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.1;
}
.vr-stat-hint {
  font-size: 0.74rem;
  color: var(--ink-soft);
  margin-top: 4px;
}
.vr-stat-good { background: rgba(34, 154, 92, 0.06); border-color: rgba(34, 154, 92, 0.25); }
.vr-stat-good .vr-stat-value { color: #167a45; }
.vr-stat-mid { background: rgba(245, 166, 35, 0.06); border-color: rgba(245, 166, 35, 0.25); }
.vr-stat-mid .vr-stat-value { color: #8c5c12; }
.vr-stat-low { background: rgba(204, 60, 80, 0.06); border-color: rgba(204, 60, 80, 0.25); }
.vr-stat-low .vr-stat-value { color: #a82a3e; }

/* Position bars (also reused for bill-type breakdown) */
.vr-position-bars { display: flex; flex-direction: column; gap: 10px; }
.vr-position-row {
  display: grid;
  grid-template-columns: 180px 1fr 90px;
  align-items: center;
  gap: 12px;
}
.vr-position-label {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink);
}
.vr-position-bar-track {
  background: var(--surface);
  border-radius: 6px;
  height: 18px;
  overflow: hidden;
}
.vr-position-bar-fill {
  height: 100%;
  border-radius: 6px;
  transition: width 0.3s ease;
  min-width: 2px;
}
.vr-position-num {
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: right;
}
.vr-position-num strong { color: var(--ink); font-weight: 700; }

.vr-pos-yea { background: #229a5c; }
.vr-pos-nay { background: #cc3c50; }
.vr-pos-mid { background: #f5a623; }
.vr-pos-other { background: #b0b8c5; }
.vr-pos-neutral { background: #2d6cdf; }

/* Activity timeline (vertical bars, one per month) */
.vr-timeline {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 140px;
  padding-bottom: 28px;
  position: relative;
  border-bottom: 1px solid var(--border);
}
.vr-timeline-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  position: relative;
}
.vr-timeline-bar {
  width: 100%;
  max-width: 32px;
  background: var(--gold);
  border-radius: 4px 4px 0 0;
  margin-top: auto;
  transition: height 0.3s ease;
}
.vr-timeline-col:hover .vr-timeline-bar { background: #d18712; }
.vr-timeline-label {
  position: absolute;
  bottom: -26px;
  font-size: 0.7rem;
  color: var(--ink-soft);
  text-align: center;
  line-height: 1.2;
  white-space: nowrap;
}
.vr-timeline-label span {
  color: var(--ink);
  font-weight: 600;
}

/* Stacked outcome bar */
.vr-stack-bar {
  display: flex;
  height: 24px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface);
  margin-bottom: 12px;
}
.vr-stack-seg { height: 100%; transition: width 0.3s ease; }
.vr-stack-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.vr-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.vr-legend-item strong { color: var(--ink); font-weight: 700; margin-left: 2px; }
.vr-legend-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

/* Pro upsell variant */
.vr-analysis-locked {
  position: relative;
  min-height: 380px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.vr-analysis-locked-blur {
  filter: blur(6px);
  opacity: 0.5;
  padding: 18px;
  pointer-events: none;
  user-select: none;
}
.vr-analysis-locked-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.95) 60%);
  z-index: 2;
}
.vr-analysis-locked-icon { font-size: 3rem; margin-bottom: 6px; }
.vr-analysis-locked-title {
  margin: 0 0 8px;
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--ink);
}
.vr-analysis-locked-sub {
  max-width: 480px;
  font-size: 0.95rem;
  color: var(--ink-soft);
  line-height: 1.55;
  margin: 0 0 20px;
}
.vr-analysis-locked-cta { font-size: 0.95rem; font-weight: 600; padding: 12px 24px; }
.vr-analysis-locked-foot {
  margin-top: 8px;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

/* Pro upsell — Campaign Finance variant. Same chrome as the Voting
 * Analysis upsell above but with a slightly taller min-height (the
 * blurred Finance preview is two summary cards instead of a stat
 * grid) and a full-page mode for the /finance directory landing. */
.fin-locked {
  position: relative;
  min-height: 320px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.fin-locked-page { min-height: 460px; margin-top: 16px; }
.fin-locked-blur {
  filter: blur(6px);
  opacity: 0.55;
  padding: 18px;
  pointer-events: none;
  user-select: none;
}
.fin-locked-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(255, 255, 255, 0.96) 60%);
  z-index: 2;
}
.fin-locked-icon { font-size: 3rem; margin-bottom: 6px; }
.fin-locked-title {
  margin: 0 0 8px;
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--ink);
}
.fin-locked-sub {
  max-width: 520px;
  font-size: 0.95rem;
  color: var(--ink-soft);
  line-height: 1.55;
  margin: 0 0 20px;
}
.fin-locked-cta { font-size: 0.95rem; font-weight: 600; padding: 12px 24px; }
.fin-locked-foot {
  margin-top: 8px;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

@media (max-width: 600px) {
  .vr-position-row { grid-template-columns: 100px 1fr 70px; gap: 8px; }
  .vr-position-label { font-size: 0.8rem; }
  .vr-filter-row { flex-direction: column; align-items: flex-start; }
  .vr-filter-summary { margin-left: 0; }
}

/* (Removed: .save-search-btn — saved-search feature retired in
 * favor of localStorage-backed Recent Searches on My HQ.) */

/* ─────────────────────────────────────────────────────────────────────
 * Local elections — state legislature + state legislator profile
 * (Phase 1 styles. Tile + grid layouts piggyback on the existing
 * .member-tile + .members-grid styles for federal members.)
 * ───────────────────────────────────────────────────────────────────── */

.state-leg-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0;
}

.state-leg-summary-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
  box-shadow: var(--shadow-sm);
}
.state-leg-summary-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
  border-color: var(--blue);
}
.state-leg-summary-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.4rem;
}
.state-leg-summary-count {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.6rem;
}
.state-leg-summary-split {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin-bottom: 0.8rem;
}
.state-leg-summary-cta {
  font-size: 0.9rem;
  color: var(--blue);
  font-weight: 500;
}

.party-dem-pill, .party-rep-pill, .party-other-pill {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
}
.party-dem-pill { background: rgba(45, 108, 223, 0.12); color: #1d4f99; }
.party-rep-pill { background: rgba(214, 55, 55, 0.12); color: #962727; }
.party-other-pill { background: rgba(120, 120, 130, 0.14); color: #555; }

/* Member tile party stripe — local-elections variant
 * (party-dem / party-rep / party-other class names from
 * state-legislature.js). Federal tiles use .dem/.rep/.ind. */
.member-tile.party-dem { border-left: 4px solid var(--blue); }
.member-tile.party-rep { border-left: 4px solid var(--rep); }
.member-tile.party-other { border-left: 4px solid var(--gold); }

.member-tile-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  background: #e6e9ef;
  display: inline-block;
  vertical-align: middle;
}
.member-tile-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  color: #5a6478;
  font-size: 0.9rem;
}
.member-tile-body {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.75rem;
  max-width: calc(100% - 75px);
}
.member-tile-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text-primary);
  margin-bottom: 0.2rem;
}
.member-tile-meta {
  font-size: 0.8rem;
  color: var(--text-secondary);
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.member-tile-party { font-weight: 600; }

/* State legislator profile — offices block + votes table */
.member-offices h3 {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.6rem;
  color: var(--text-primary);
}
.member-office {
  background: var(--bg-soft, #f8f9fb);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  margin-bottom: 0.6rem;
}
.member-office-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text-primary);
  margin-bottom: 0.3rem;
}
.member-office-line {
  font-size: 0.85rem;
  color: var(--text-secondary);
  margin-bottom: 0.15rem;
}

.state-votes-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin-top: 0.75rem;
}
.state-votes-table th {
  text-align: left;
  padding: 0.6rem 0.75rem;
  border-bottom: 2px solid var(--border);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-secondary);
}
.state-votes-table td {
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  vertical-align: top;
}
.state-votes-table tr:hover { background: rgba(45, 108, 223, 0.03); }
.vote-tally { color: var(--text-secondary); font-size: 0.82rem; margin-left: 0.3rem; }

.pos-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.pos-yea { background: #e7f5ec; color: #0f6a44; }
.pos-nay { background: #fdecea; color: #a8201a; }
.pos-absent { background: #fff4d6; color: #7a5c00; }
.pos-other { background: #eef0f4; color: #5a6478; }

.profile-hero-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.15);
}
.profile-hero-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.6rem;
  color: rgba(255, 255, 255, 0.85);
}

.hero-sub-secondary {
  margin-top: 0.4rem;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.78);
}
.hero-sub-secondary a { color: rgba(255, 255, 255, 0.95); text-decoration: underline; }

@media (max-width: 600px) {
  .state-leg-summary-grid { grid-template-columns: 1fr; }
  .state-votes-table { font-size: 0.82rem; }
  .state-votes-table th, .state-votes-table td { padding: 0.45rem 0.5rem; }
}

/* ─────────────────────────────────────────────────────────────────────
 * State page tabs (Federal / State Legislature / Executive).
 * Sits below the page hero, above the active tab pane. The strip is
 * horizontal-scrollable on small screens so all three tabs are always
 * reachable even on a narrow phone.
 * ───────────────────────────────────────────────────────────────────── */

.state-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin: 1.5rem 0 0;
  overflow-x: auto;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.state-tab {
  flex: 0 0 auto;
  padding: 0.85rem 1.5rem;
  text-decoration: none;
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 0.95rem;
  border-bottom: 3px solid transparent;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
  white-space: nowrap;
}
.state-tab:hover {
  color: var(--text-primary);
  background: rgba(45, 108, 223, 0.04);
}
.state-tab.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
  background: rgba(45, 108, 223, 0.04);
}

.state-subtabs {
  display: flex;
  gap: 0;
  margin: 1.25rem 0 0.5rem;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  overflow-x: auto;
  scrollbar-width: thin;
}
.state-subtab {
  flex: 0 0 auto;
  padding: 0.55rem 1.1rem;
  text-decoration: none;
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 0.88rem;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.state-subtab:hover { color: var(--text-primary); }
.state-subtab.active {
  color: var(--blue);
  border-bottom-color: var(--blue);
}

.state-tab-pane {
  /* Padding-top so the active pane breathes from the tab strip; no
   * other framing — sections inside still own their own spacing. */
  padding-top: 0.75rem;
}

@media (max-width: 600px) {
  .state-tab { padding: 0.65rem 1rem; font-size: 0.88rem; }
  .state-subtab { padding: 0.45rem 0.85rem; font-size: 0.84rem; }
}

/* Governor hero card on the Executive tab. Larger than the secondary
 * exec cards because the governor is the headline office; photo +
 * party-colored top stripe + term + contact in one block. */
.governor-hero {
  margin: 1rem 0 0.5rem;
}
.governor-hero-card {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
  padding: 1.5rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
.governor-hero-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
  border-color: var(--blue);
}
.governor-hero-cta {
  margin-top: 0.6rem;
  font-size: 0.88rem;
  color: var(--blue);
  font-weight: 600;
}
.governor-hero-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: var(--border);
}
.governor-hero-card.party-dem::before { background: var(--dem); }
.governor-hero-card.party-rep::before { background: var(--rep); }
.governor-hero-card.party-other::before { background: var(--gold); }

.governor-hero-photo {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  background: #e6e9ef;
  flex: 0 0 auto;
}
.governor-hero-photo-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.6rem;
  color: #5a6478;
  background: #e6e9ef;
}

.governor-hero-body {
  flex: 1 1 auto;
  min-width: 0;
}
.governor-hero-name {
  margin: 0 0 0.3rem;
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text-primary);
}
.governor-hero-meta {
  font-size: 0.95rem;
  color: var(--text-secondary);
  margin-bottom: 0.7rem;
}
.governor-office {
  font-size: 0.86rem;
  color: var(--text-secondary);
  margin-bottom: 0.6rem;
  line-height: 1.5;
}
.governor-hero-links {
  font-size: 0.88rem;
  color: var(--text-secondary);
}
.governor-hero-links a { color: var(--blue); text-decoration: none; }
.governor-hero-links a:hover { text-decoration: underline; }

.governor-hero-fallback {
  flex-direction: column;
  align-items: stretch;
  padding: 1rem;
}
.governor-hero-note {
  margin: 0.6rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--border);
  font-size: 0.78rem;
  color: var(--text-secondary);
  font-style: italic;
}

@media (max-width: 600px) {
  .governor-hero-card { flex-direction: column; padding: 1.2rem; gap: 1rem; }
  .governor-hero-photo, .governor-hero-photo-fallback { width: 80px; height: 80px; }
  .governor-hero-name { font-size: 1.2rem; }
}

/* Statewide executive profile page (/states/:state/executive/:role).
 * Same visual language as the governor hero card on the Executive
 * tab — same party-colored top stripe, same circular photo — but
 * a permanent page rather than a teaser. Used for governor + 4
 * other roles, with graceful degradation when only minimal data
 * (Ballotpedia link) is available. */
.exec-profile-card {
  display: flex;
  align-items: flex-start;
  gap: 1.75rem;
  padding: 1.75rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}
.exec-profile-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: var(--border);
}
.exec-profile-card.party-dem::before { background: var(--dem); }
.exec-profile-card.party-rep::before { background: var(--rep); }
.exec-profile-card.party-other::before { background: var(--gold); }

.exec-profile-photo {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  object-fit: cover;
  background: #e6e9ef;
  flex: 0 0 auto;
}
.exec-profile-photo-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 2rem;
  color: #5a6478;
  background: #e6e9ef;
}

.exec-profile-body {
  flex: 1 1 auto;
  min-width: 0;
}
.exec-profile-body h3 {
  margin: 0 0 0.5rem;
  font-size: 0.92rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-secondary);
}
.exec-profile-body h3:not(:first-child) { margin-top: 1.2rem; }

.exec-profile-office {
  background: var(--bg-soft, #f8f9fb);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-secondary);
}
.exec-profile-office-name {
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.25rem;
  font-size: 0.85rem;
}

.exec-profile-links {
  font-size: 0.92rem;
  color: var(--text-secondary);
  line-height: 1.8;
}
.exec-profile-links a {
  color: var(--blue);
  text-decoration: none;
  margin-right: 0.4rem;
}
.exec-profile-links a:hover { text-decoration: underline; }

.exec-profile-bio {
  margin-top: 1rem;
  font-size: 0.88rem;
  color: var(--text-secondary);
}

.exec-profile-note {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
  font-size: 0.82rem;
  color: var(--text-secondary);
  font-style: italic;
  line-height: 1.5;
}

@media (max-width: 600px) {
  .exec-profile-card { flex-direction: column; padding: 1.25rem; gap: 1rem; }
  .exec-profile-photo, .exec-profile-photo-fallback { width: 96px; height: 96px; }
  .exec-profile-photo-fallback { font-size: 1.6rem; }
}

/* ─────────────────────────────────────────────────────────────────────
 * Statewide executive profile — rich Wikipedia-enriched view
 * (the page that opens when a user clicks any tile on /states/:state/executive).
 *
 * Two-column layout on desktop: main column has bio + career timeline,
 * sidebar has education + contact + links. Single column on mobile.
 *
 * Class names are prefixed `exec-pro-` (executive profile) to avoid
 * clashing with the smaller `.exec-profile-*` legacy classes that the
 * minimal-fallback card still uses.
 * ───────────────────────────────────────────────────────────────────── */

.exec-pro-hero {
  background: linear-gradient(135deg, #0b2545 0%, #14365f 60%, #1d4f99 100%);
  color: #fff;
  padding: 2.5rem 2rem 2rem;
  border-radius: var(--radius);
  position: relative;
  overflow: hidden;
  margin-bottom: 1.5rem;
}
.exec-pro-hero::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: rgba(255, 255, 255, 0.25);
}
.exec-pro-hero.party-dem::before { background: var(--dem); }
.exec-pro-hero.party-rep::before { background: var(--rep); }
.exec-pro-hero.party-other::before { background: var(--gold); }
.exec-pro-hero .breadcrumb-trail {
  margin-bottom: 1.25rem;
  color: rgba(255, 255, 255, 0.75);
}
.exec-pro-hero .breadcrumb-trail a {
  color: rgba(255, 255, 255, 0.92);
  text-decoration: none;
}
.exec-pro-hero .breadcrumb-trail a:hover { text-decoration: underline; }
.exec-pro-hero .breadcrumb-trail .sep { color: rgba(255, 255, 255, 0.4); }

.exec-pro-hero-row {
  display: flex;
  align-items: center;
  gap: 2rem;
  flex-wrap: wrap;
}
.exec-pro-photo {
  width: 140px;
  height: 140px;
  border-radius: 50%;
  object-fit: cover;
  border: 4px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.08);
  flex: 0 0 auto;
}
.exec-pro-photo-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 2.4rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.7);
}

.exec-pro-hero-body { flex: 1 1 320px; min-width: 0; }
.exec-pro-role {
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: 0.4rem;
}
/* Explicit white — global `.page-hero h1` sets a dark color that wins
 * via specificity if we just rely on `color: inherit` from the hero. */
.exec-pro-name, .exec-pro-hero h1 {
  margin: 0 0 0.85rem;
  font-size: 2.4rem;
  font-weight: 700;
  line-height: 1.1;
  color: #ffffff;
}
.exec-pro-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.exec-pro-fact {
  background: rgba(255, 255, 255, 0.15);
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 500;
}
.exec-pro-fact-party.party-dem { background: rgba(45, 108, 223, 0.32); }
.exec-pro-fact-party.party-rep { background: rgba(214, 55, 55, 0.32); }
.exec-pro-fact-party.party-other { background: rgba(243, 156, 18, 0.3); }
.exec-pro-hero .profile-watch-slot { margin-top: 0.35rem; }

/* Two-column body. The main column is wider (60%) so the bio doesn't
 * feel cramped; the sidebar takes the remaining ~40%. */
.exec-pro-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr);
  gap: 2rem;
  margin-bottom: 2rem;
}
.exec-pro-main, .exec-pro-side {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.exec-pro-section {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  position: relative;
}

/* Collapsible long-section state. The prose is given a max-height +
 * overflow-hidden so the bottom of the content is hidden behind a
 * gradient fade; the toggle button hangs at the bottom-center.
 *
 * Threshold (~2500c HTML) chosen so short bios don't get a useless
 * toggle, but Newsom's 60KB Governor section does. Click handler
 * removes .is-collapsed and the prose expands to full height. */
.exec-pro-section-collapsible {
  padding-bottom: 4rem; /* leave room under the fade for the button */
}
.exec-pro-section-collapsible.is-collapsed .exec-pro-prose {
  max-height: 18rem;
  overflow: hidden;
  position: relative;
  /* Mask out the bottom edge so the cut-off text fades smoothly into
   * the card background — same colors so the gradient feels natural. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 75%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0, #000 75%, transparent 100%);
}
.exec-pro-expand-btn {
  position: absolute;
  bottom: 0.85rem;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1.1rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--blue);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.exec-pro-expand-btn:hover {
  background: rgba(45, 108, 223, 0.06);
  border-color: var(--blue);
  transform: translateX(-50%) translateY(-1px);
}
.exec-pro-expand-arrow {
  font-size: 0.95rem;
  line-height: 1;
}
.exec-pro-section-title {
  margin: 0 0 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-secondary);
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
}

/* Bio prose */
.exec-pro-bio {
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--text-primary);
  font-weight: 400;
}
.exec-pro-attr {
  margin: 1rem 0 0;
  font-size: 0.8rem;
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: 0.75rem 1rem;
  background: var(--bg-soft, #f8f9fb);
  border-radius: var(--radius);
  line-height: 1.5;
}
.exec-pro-attr a { color: var(--blue); text-decoration: none; }
.exec-pro-attr a:hover { text-decoration: underline; }

/* Wikipedia-section prose. The HTML inside has already been sanitized
 * server-side (script/style/table/figure/sup all stripped). Style only
 * the prose primitives that survived: <p>, <a>, <ul>, <ol>, <li>,
 * <h3>, <h4>, <blockquote>, inline emphasis. */
.exec-pro-prose {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--text-primary);
}
.exec-pro-prose p {
  margin: 0 0 1rem;
}
.exec-pro-prose p:last-child { margin-bottom: 0; }
.exec-pro-prose a {
  color: var(--blue);
  text-decoration: underline;
  text-decoration-color: rgba(45, 108, 223, 0.35);
  text-underline-offset: 2px;
  transition: text-decoration-color 0.15s;
}
.exec-pro-prose a:hover {
  text-decoration-color: var(--blue);
}
.exec-pro-prose strong, .exec-pro-prose b { font-weight: 600; }
.exec-pro-prose ul, .exec-pro-prose ol {
  margin: 0 0 1rem 1.5rem;
  padding: 0;
}
.exec-pro-prose li {
  margin-bottom: 0.4rem;
  line-height: 1.65;
}
.exec-pro-prose h3, .exec-pro-prose h4 {
  margin: 1.25rem 0 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
}
.exec-pro-prose h4 { font-size: 0.92rem; }
.exec-pro-prose blockquote {
  margin: 1rem 0;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--blue);
  background: var(--bg-soft, #f8f9fb);
  color: var(--text-secondary);
  font-style: italic;
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* Quick-facts <dl> in the sidebar */
.exec-pro-facts-list {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.exec-pro-fact-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.88rem;
}
.exec-pro-fact-row:last-child { border-bottom: none; }
.exec-pro-fact-row dt {
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  font-size: 0.74rem;
  padding-top: 0.15rem;
}
.exec-pro-fact-row dd {
  margin: 0;
  color: var(--text-primary);
  line-height: 1.4;
  word-break: break-word;
}

.exec-pro-awards {
  list-style: none;
  padding: 0;
  margin: 0;
}
.exec-pro-awards li {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.88rem;
  color: var(--text-primary);
}
.exec-pro-awards li:last-child { border-bottom: none; }
.exec-pro-awards li::before { content: '🏆 '; margin-right: 0.4rem; }

/* Career timeline */
.exec-pro-timeline {
  list-style: none;
  padding: 0;
  margin: 0;
}
.exec-pro-timeline-item {
  position: relative;
  padding: 0.6rem 0 0.6rem 1.25rem;
  border-left: 2px solid var(--border-soft, #eef0f4);
}
.exec-pro-timeline-item::before {
  content: '';
  position: absolute;
  left: -6px;
  top: 1.1rem;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--blue);
}
.exec-pro-timeline-item:first-child::before { background: var(--blue); box-shadow: 0 0 0 3px rgba(45, 108, 223, 0.18); }
.exec-pro-timeline-item:not(:first-child)::before { background: var(--text-secondary); }
.exec-pro-timeline-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-primary);
}
.exec-pro-timeline-dates {
  font-size: 0.82rem;
  color: var(--text-secondary);
  margin-top: 0.2rem;
}

/* Education list */
.exec-pro-edu {
  list-style: none;
  padding: 0;
  margin: 0;
}
.exec-pro-edu li {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.92rem;
  color: var(--text-primary);
}
.exec-pro-edu li:last-child { border-bottom: none; }
.exec-pro-edu li::before {
  content: '🎓 ';
  margin-right: 0.4rem;
}

/* Offices in the sidebar */
.exec-pro-office {
  background: var(--bg-soft, #f8f9fb);
  border-radius: var(--radius);
  padding: 0.75rem 0.85rem;
  margin-bottom: 0.6rem;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--text-secondary);
}
.exec-pro-office-name {
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.25rem;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

/* Links list */
.exec-pro-links {
  list-style: none;
  padding: 0;
  margin: 0;
}
.exec-pro-link {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft, #eef0f4);
  font-size: 0.92rem;
}
.exec-pro-link:last-child { border-bottom: none; }
.exec-pro-link a {
  color: var(--blue);
  text-decoration: none;
}
.exec-pro-link a:hover { text-decoration: underline; }
.exec-pro-link-official::before { content: '🏛️ '; margin-right: 0.4rem; }
.exec-pro-link-wiki::before { content: '📖 '; margin-right: 0.4rem; }
.exec-pro-link-ballotpedia::before { content: '🗳️ '; margin-right: 0.4rem; }
.exec-pro-link-email::before { content: '✉️ '; margin-right: 0.4rem; }
.exec-pro-link-social::before { content: '💬 '; margin-right: 0.4rem; }
.exec-pro-link-misc::before { content: '🔗 '; margin-right: 0.4rem; }

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

/* ─────────────────────────────────────────────────────────────────────
 * "Other Statewide Executives" tile grid on the Executive tab.
 * Designed to fit 4 in a row on desktop, matching the governor card's
 * visual language at a more compact scale: photo + party-color stripe
 * + role + name + term. Clickable; navigates to the per-role profile.
 * ───────────────────────────────────────────────────────────────────── */

.exec-tile-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 0.5rem;
}
.exec-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
  padding: 1.25rem 1rem;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  position: relative;
  overflow: hidden;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
  cursor: pointer;
}
.exec-tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
  border-color: var(--blue);
}
.exec-tile::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--border);
}
.exec-tile.party-dem::before { background: var(--dem); }
.exec-tile.party-rep::before { background: var(--rep); }
.exec-tile.party-other::before { background: var(--gold); }

.exec-tile-photo {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
  background: #e6e9ef;
  flex: 0 0 auto;
  margin-top: 0.3rem;
}
.exec-tile-photo-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.4rem;
  color: #5a6478;
  background: #e6e9ef;
}
.exec-tile-body {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
}
.exec-tile-role {
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-secondary);
  margin-bottom: 0.25rem;
}
.exec-tile-name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.4rem;
  line-height: 1.25;
  /* 2-line clamp so long names don't blow out tile height */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.exec-tile-meta {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.78rem;
  color: var(--text-secondary);
}
.exec-tile-party { font-weight: 600; color: var(--text-primary); }
.exec-tile-term { color: var(--text-secondary); }

.exec-tile-minimal .exec-tile-photo-fallback { opacity: 0.85; }

.exec-tile-empty {
  background: var(--bg-soft, #f8f9fb);
  border-style: dashed;
  cursor: default;
}
.exec-tile-empty:hover { transform: none; box-shadow: var(--shadow-sm); border-color: var(--border); }
.exec-tile-empty-label { color: var(--text-secondary); font-style: italic; font-weight: 400; }

@media (max-width: 900px) {
  .exec-tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .exec-tile-grid { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .exec-pro-hero { padding: 2rem 1.25rem 1.5rem; }
  .exec-pro-photo, .exec-pro-photo-fallback { width: 100px; height: 100px; }
  .exec-pro-photo-fallback { font-size: 1.8rem; }
  .exec-pro-name { font-size: 1.7rem; }
  .exec-pro-section { padding: 1.1rem; }
}
