/*
 * Civic: the one stylesheet for the prerendered static pages (state, race,
 * county, "How we research", the state list and the 404 page). Built by
 * src/civic/prerender/ into dist-civic/assets/civic-static-<hash>.css.
 *
 * Every color, gradient, radius, shadow and font size is a custom property.
 * The values below are PLACEHOLDERS matching the app's current palette; they
 * sit in :where(:root) (zero specificity), so a design token file wins
 * whatever its order. To use one, add at the very top of this file:
 *
 *     /*
 * Civic design tokens: the single source for Civic's colors, gradients,
 * type, shape and depth. Read by
 *   - src/civic/design/civicTheme.js (the app's MUI theme parses this file),
 *   - src/civic/static/civic-static.css (the prerendered pages @import it).
 * See src/civic/design/DESIGN.md for the reasoning and contrast table.
 *
 * Rules for this file: only custom properties, on :root or on a "chrome"
 * scope. Values are literal hex / rgba or var() references to other tokens
 * in this file, so the theme parser can resolve them.
 */

:root {
  /* ─── Navy: the frame ─────────────────────────────────────────────────── */
  --civic-navy-950: #0a1529;
  --civic-navy-900: #0f1f3d; /* midnight: chrome, hero */
  --civic-navy-800: #14284d; /* ink blue: hero mid, sidebar */
  --civic-navy-700: #1b3563;
  --civic-navy-600: #22457f; /* interactive blue on eggshell */
  --civic-navy-500: #3a5f9e;
  --civic-navy-300: #a9c0e6; /* interactive blue on navy */
  --civic-navy-100: #e3e9f4; /* tint for selected states */

  /* ─── Garnet: the accent edge ─────────────────────────────────────────── */
  --civic-red-900: #5c0f1a;
  --civic-red-800: #74151f;
  --civic-red-700: #8f1d2c; /* garnet: rules, emblem ring, errors */
  --civic-red-600: #a3202f;
  --civic-red-300: #eba3ab; /* garnet on navy */
  --civic-red-100: #f5e1e3;

  /* ─── Eggshell: the page ──────────────────────────────────────────────── */
  --civic-ivory: #fbf8f1; /* raised surfaces: cards, dialogs */
  --civic-eggshell-050: #fffdf8; /* card highlight, inputs */
  --civic-eggshell-100: #f5efe2; /* "eagle egg": the page */
  --civic-parchment: #ece3cf; /* deeper surface, section bands */
  --civic-parchment-deep: #e1d5b9;
  --civic-line: #d6c9ab; /* hairlines and card borders */
  --civic-line-strong: #8c8470; /* input borders (3:1 on the page) */

  /* ─── Ink ─────────────────────────────────────────────────────────────── */
  --civic-ink-900: #121725; /* body text */
  --civic-ink-700: #262c3c; /* secondary text, still AAA */
  --civic-ink-500: #4a5063; /* tertiary text, AA on every light surface */
  --civic-on-navy: #f5efe2; /* text on navy */
  --civic-on-navy-soft: #d6dbe5; /* secondary text on navy */
  --civic-on-navy-faint: #b7c0d0; /* small print on navy, AA */

  /* ─── Brass: hairlines only, never text ───────────────────────────────── */
  --civic-brass: #b08d43;

  /* ─── Status (light surfaces / navy surfaces) ─────────────────────────── */
  --civic-green: #2d6a3e;
  --civic-green-on-navy: #8fd3a0;
  --civic-amber: #8a5a00;
  --civic-amber-on-navy: #f0c674;
  --civic-error: var(--civic-red-600);

  /* ─── Party markers: never the brand red or blue (DESIGN.md §Neutrality) */
  --civic-party-d: #4a7fc1;
  --civic-party-r: #d0463f;
  --civic-party-i: #8a63b8;
  --civic-party-l: #d4a52c;
  --civic-party-g: #4c9a5b;
  --civic-party-other: #8b8f99;

  /* ─── Names the static pages use ──────────────────────────────────────── */
  --civic-navy: var(--civic-navy-900);
  --civic-navy-deep: var(--civic-navy-950);
  --civic-red: var(--civic-red-700);
  --civic-eggshell: var(--civic-eggshell-100);
  --civic-gold: var(--civic-brass);
  --civic-gold-soft: var(--civic-brass);
  --civic-sky: var(--civic-navy-300);

  --civic-bg: var(--civic-eggshell-100);
  /* --civic-surface* and --civic-chrome are `background` values (gradients
     included); use the raw palette above where a plain color is needed. */
  --civic-surface: var(--civic-grad-card);
  --civic-surface-raised: var(--civic-grad-card-raised);
  --civic-surface-sunk: var(--civic-parchment);
  --civic-chrome: var(--civic-grad-chrome);
  --civic-ink: var(--civic-ink-900);
  --civic-ink-muted: var(--civic-ink-700);
  --civic-ink-subtle: var(--civic-ink-500);
  --civic-accent: var(--civic-red-700);
  --civic-link: var(--civic-navy-600);
  --civic-link-hover: var(--civic-navy-800);
  --civic-info: var(--civic-navy-600);
  --civic-border: var(--civic-line);
  --civic-border-strong: var(--civic-line-strong);
  --civic-info-border: rgba(34, 69, 127, 0.28);
  --civic-info-bg: rgba(34, 69, 127, 0.06);
  --civic-warn-border: rgba(138, 90, 0, 0.35);
  --civic-warn-bg: rgba(138, 90, 0, 0.07);
  --civic-cta-bg: var(--civic-navy-800);
  --civic-cta-ink: var(--civic-on-navy);
  --civic-cta-bg-hover: var(--civic-navy-900);
  --civic-focus: var(--civic-red-700);
  --civic-focus-on-navy: var(--civic-on-navy);
  --civic-color-scheme: light;

  /* ─── Gradients: depth, not decoration ────────────────────────────────── */
  --civic-grad-chrome: linear-gradient(180deg, #13264a 0%, #0c1a35 100%);
  --civic-grad-hero:
    radial-gradient(120% 140% at 0% 0%, rgba(58, 95, 158, 0.38) 0%, rgba(58, 95, 158, 0) 55%),
    radial-gradient(90% 120% at 100% 100%, rgba(143, 29, 44, 0.22) 0%, rgba(143, 29, 44, 0) 50%),
    linear-gradient(160deg, #1b3563 0%, #12244a 48%, #0a1529 100%);
  --civic-grad-page: linear-gradient(180deg, #efe7d5 0%, #f5efe2 360px);
  --civic-grad-card: linear-gradient(180deg, #fffdf8 0%, #f8f2e6 100%);
  --civic-grad-card-raised: linear-gradient(180deg, #ffffff 0%, #faf6ee 55%, #f3ecdd 100%);
  --civic-grad-band: linear-gradient(90deg, #e9dfc8 0%, rgba(233, 223, 200, 0.55) 55%, rgba(233, 223, 200, 0) 100%);
  --civic-grad-selected: linear-gradient(180deg, #f1f4fa 0%, #e3e9f4 100%);
  --civic-grad-cta: linear-gradient(180deg, #1f3c6f 0%, #14284d 100%);
  --civic-grad-emblem: radial-gradient(circle at 32% 26%, #2f5594 0%, #14284d 58%, #0a1529 100%);
  --civic-rule-edge: linear-gradient(90deg, var(--civic-red-700) 0%, var(--civic-red-600) 100%);

  /* ─── Shape and depth ─────────────────────────────────────────────────── */
  --civic-radius: 12px;
  --civic-radius-sm: 8px;
  --civic-radius-lg: 18px;
  --civic-radius-pill: 999px;
  --civic-border-width: 1px;
  --civic-shadow: 0 1px 2px rgba(15, 31, 61, 0.06), 0 6px 18px rgba(15, 31, 61, 0.07);
  --civic-shadow-raised: 0 1px 2px rgba(15, 31, 61, 0.08), 0 10px 28px rgba(15, 31, 61, 0.12);
  --civic-shadow-hero: 0 2px 6px rgba(10, 21, 41, 0.18), 0 22px 48px rgba(10, 21, 41, 0.22);

  /* ─── Type ────────────────────────────────────────────────────────────── */
  --civic-font-body: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --civic-font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --civic-fs-lede: 1.3125rem; /* 21px: the sentence that opens a section */
  --civic-fs-body: 1.125rem; /* 18px */
  --civic-fs-read: 1.0625rem; /* 17px: bulleted running text, long lists */
  --civic-fs-small: 1rem; /* 16px */
  --civic-fs-caption: 0.9375rem; /* 15px: the smallest text Civic sets */
  --civic-fs-label: 0.8125rem; /* 13px: tracked caps labels only, never prose */
  --civic-fs-h1: clamp(2rem, 1.5rem + 2.2vw, 3rem);
  --civic-fs-h2: clamp(1.5rem, 1.3rem + 0.9vw, 1.875rem);
  --civic-fs-h3: 1.25rem;
  --civic-fs-h4: 1.0625rem; /* the label that opens a block inside a card */
  --civic-fs-name: 1.375rem; /* a candidate's name: the biggest thing on a card */
  --civic-fs-brand: 1.625rem;
  --civic-lh-body: 1.6;
  --civic-lh-heading: 1.2;
  --civic-tracking-label: 0.12em;

  /* ─── Layout ──────────────────────────────────────────────────────────── */
  --civic-max: 52rem;
  --civic-measure: 70ch;
  --civic-gutter: 16px;
}

/*
 * Chrome scopes: navy surfaces re-point the semantic tokens, so text,
 * links and borders inside them read on navy without new rules. Used by the
 * static pages' header, hero and footer, and by the app via
 * data-civic-surface="chrome".
 */
[data-civic-surface="chrome"],
.site-header,
.site-footer,
.hero {
  --civic-ink: var(--civic-on-navy);
  --civic-ink-muted: var(--civic-on-navy-soft);
  --civic-ink-subtle: var(--civic-on-navy-faint);
  --civic-accent: var(--civic-on-navy);
  --civic-link: var(--civic-navy-300);
  --civic-link-hover: var(--civic-on-navy);
  --civic-border: rgba(169, 192, 230, 0.22);
  --civic-border-strong: rgba(169, 192, 230, 0.45);
  --civic-surface: rgba(255, 255, 255, 0.04);
  --civic-surface-raised: rgba(255, 255, 255, 0.07);
  --civic-cta-bg: var(--civic-on-navy);
  --civic-cta-ink: var(--civic-navy-900);
  --civic-cta-bg-hover: #ffffff;
  --civic-focus: var(--civic-focus-on-navy);
  --civic-info-border: rgba(169, 192, 230, 0.35);
  --civic-info-bg: rgba(169, 192, 230, 0.08);
}

 *
 * The build inlines relative @imports, so the page still loads one CSS file.
 * Font files are referenced relative to this file and rewritten to their
 * hashed /assets/ names at build time. HTML templates set no colors.
 */


@font-face {
  font-family: "DM Sans";
  src: url("/assets/DMSans-VariableFont_opsz_wght-D_B5dL4R.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("/assets/dm-sans-latin-C1bDR5vi.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/assets/PlayfairDisplay-VariableFont_wght-Cl-XvBsO.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/assets/playfair-display-latin-Bxn9kp8D.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ─── Tokens (placeholders) ─────────────────────────────────────────────── */
:where(:root) {
  /* Raw palette */
  --civic-navy: #0f1729;
  --civic-navy-deep: #0d1321;
  --civic-red: #b3261e;
  --civic-eggshell: #f4f1e8;
  --civic-gold: #c9a961;
  --civic-gold-soft: #bea959;
  --civic-sky: #5a9bd4;

  /* Semantic */
  --civic-bg: var(--civic-navy);
  --civic-surface: #141d33;
  --civic-surface-raised: #1a2035;
  --civic-chrome: var(--civic-navy-deep);
  --civic-ink: #ffffff;
  --civic-ink-muted: #a0aec0;
  --civic-ink-subtle: #8a9bb4;
  --civic-accent: var(--civic-gold);
  --civic-link: var(--civic-gold-soft);
  --civic-link-hover: #d9c27a;
  --civic-info: var(--civic-sky);
  --civic-border: rgba(201, 169, 97, 0.25);
  --civic-border-strong: rgba(201, 169, 97, 0.5);
  --civic-info-border: rgba(90, 155, 212, 0.45);
  --civic-info-bg: rgba(90, 155, 212, 0.07);
  --civic-warn-border: rgba(217, 165, 32, 0.45);
  --civic-warn-bg: rgba(217, 165, 32, 0.07);
  --civic-cta-bg: var(--civic-gold);
  --civic-cta-ink: #0d1321;
  --civic-cta-bg-hover: #d9bd7c;
  --civic-focus: #ffd966;
  --civic-grad-hero: linear-gradient(180deg, rgba(201, 169, 97, 0.08) 0%, rgba(15, 23, 41, 0) 100%);

  /* Shape */
  --civic-radius: 10px;
  --civic-radius-sm: 6px;
  --civic-radius-pill: 999px;
  --civic-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  --civic-border-width: 1px;

  /* Type */
  --civic-font-body: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --civic-font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --civic-fs-body: 1rem;
  --civic-fs-small: 0.875rem;
  --civic-fs-caption: 0.8125rem;
  --civic-fs-h1: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  --civic-fs-h2: clamp(1.3rem, 1.15rem + 0.8vw, 1.6rem);
  --civic-fs-h3: 1.125rem;
  --civic-fs-brand: 1.5rem;
  --civic-lh-body: 1.6;

  /* Layout */
  --civic-max: 52rem;
  --civic-gutter: 16px;
}

/* ─── Base ──────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  color-scheme: var(--civic-color-scheme, dark);
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--civic-bg);
  color: var(--civic-ink);
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-body);
  line-height: var(--civic-lh-body);
  overflow-wrap: break-word;
}
a {
  color: var(--civic-link);
  text-underline-offset: 0.15em;
}
a:hover {
  color: var(--civic-link-hover);
}
a:focus-visible,
.cta:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--civic-focus);
  outline-offset: 2px;
}
h1,
h2,
h3 {
  font-family: var(--civic-font-display);
  font-weight: 500;
  line-height: 1.25;
  margin: 0;
}
h1 {
  font-size: var(--civic-fs-h1);
  font-weight: 400;
}
h2 {
  font-size: var(--civic-fs-h2);
}
h3 {
  font-size: var(--civic-fs-h3);
  font-family: var(--civic-font-body);
  font-weight: 600;
}
p {
  margin: 0;
}
ul,
ol {
  margin: 0;
  padding-left: 1.25rem;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.5rem 0.75rem;
  background: var(--civic-cta-bg);
  color: var(--civic-cta-ink);
  border-radius: var(--civic-radius-sm);
  z-index: 10;
}
.skip:focus {
  left: var(--civic-gutter);
  top: 0.5rem;
}
/* The contents rail.
 *
 * A long race page had no shape a reader could see: no sense of how many
 * parts there are, which one they are in, or how to get back to one they
 * passed. The rail puts the page's own headings in the right gutter, marks
 * the one being read and makes each a link.
 *
 * It is a list against a hairline, not a panel. The page already carries
 * parchment bands and bordered cards; a third surface floating beside them
 * would read as a second page rather than as a map of this one. It appears
 * only where there is gutter to hold it without squeezing the measure.
 */
.toc {
  display: none;
}
@media (min-width: 1340px) {
  .toc {
    display: block;
    position: fixed;
    top: 7rem;
    left: calc(50% + 26rem + 1.75rem);
    width: 12rem;
    max-height: calc(100vh - 10rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-left: var(--civic-border-width) solid var(--civic-border);
    padding-left: 0.9rem;
  }
  .toc-h {
    font-family: var(--civic-font-body);
    font-size: var(--civic-fs-label);
    font-weight: 700;
    letter-spacing: var(--civic-tracking-label);
    text-transform: uppercase;
    color: var(--civic-ink-subtle);
    margin: 0 0 0.6rem;
  }
  .toc ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .toc li + li {
    margin-top: 0.1rem;
  }
  .toc a {
    display: block;
    /* The rail is navigation, not prose, so it keeps the small tracked size
     * the rest of the type scale reserves for labels. */
    font-size: var(--civic-fs-caption);
    line-height: 1.35;
    color: var(--civic-ink-muted);
    text-decoration: none;
    padding: 0.3rem 0 0.3rem 0.7rem;
    /* The marker sits in the rail's own hairline, so the active item reads as
     * a position on the page rather than as a selected button. */
    border-left: 3px solid transparent;
    margin-left: -0.9rem;
    padding-left: calc(0.9rem - 3px + 0.7rem);
  }
  .toc a:hover,
  .toc a:focus-visible {
    color: var(--civic-ink);
    text-decoration: underline;
  }
  .toc a.is-here {
    color: var(--civic-navy-600);
    font-weight: 700;
    border-left-color: var(--civic-red-700);
  }
}
/* A heading the rail jumps to should land clear of the top of the window. */
.section > h2[id] {
  scroll-margin-top: 1.5rem;
}
.wrap {
  width: 100%;
  max-width: var(--civic-max);
  margin: 0 auto;
  padding: 0 var(--civic-gutter);
}
.muted {
  color: var(--civic-ink-muted);
}
.small {
  font-size: var(--civic-fs-small);
}
.caption {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
.mt-sm {
  margin-top: 0.5rem;
}
.mt {
  margin-top: 0.75rem;
}
.mt-lg {
  margin-top: 1.25rem;
}
.stack {
  display: grid;
  gap: 0.5rem;
}
blockquote {
  margin: 0;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ─── Header / footer ───────────────────────────────────────────────────── */
.site-header {
  position: relative;
  color: var(--civic-ink);
  background: var(--civic-chrome);
  border-bottom: var(--civic-border-width) solid var(--civic-border);
}
/* Garnet edge under the navy header, matching the app header. */
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: var(--civic-rule-edge);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--civic-ink);
  text-decoration: none;
  min-width: 0;
}
.brand:hover {
  color: var(--civic-ink);
}
.brand-mark {
  flex-shrink: 0;
  display: block;
}
.brand-mark rect {
  fill: var(--civic-surface-raised);
  stroke: var(--civic-accent);
}
.brand-mark path {
  stroke: var(--civic-accent);
}
.brand-name {
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-brand);
  line-height: 1;
}
.brand-tag {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
  line-height: 1.3;
}
.header-link {
  font-size: var(--civic-fs-caption);
  white-space: nowrap;
}
.site-footer {
  margin-top: auto;
  background: var(--civic-chrome);
  border-top: var(--civic-border-width) solid var(--civic-border);
  padding: 1.75rem 0;
  font-size: var(--civic-fs-small);
  color: var(--civic-ink-muted);
}
.site-footer .wrap {
  display: grid;
  gap: 0.6rem;
}
.footer-name {
  font-family: var(--civic-font-display);
  color: var(--civic-ink);
  font-size: var(--civic-fs-h3);
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-size: var(--civic-fs-caption);
}

/* ─── Page ──────────────────────────────────────────────────────────────── */
main {
  flex: 1;
  padding-bottom: 2.5rem;
}
.hero {
  /* Re-resolve the ink token: chrome scopes (tokens.css) re-point it. */
  color: var(--civic-ink);
  background: var(--civic-grad-hero);
  padding: 1.25rem 0 1.5rem;
}
.crumbs ol {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
.crumbs li + li::before {
  content: "/";
  margin-right: 0.25rem;
  color: var(--civic-ink-subtle);
}
.eyebrow {
  margin-top: 0.75rem;
  font-size: var(--civic-fs-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--civic-accent);
}
.hero h1 {
  margin-top: 0.25rem;
}
.lede {
  margin-top: 0.6rem;
  color: var(--civic-ink-muted);
  max-width: 44rem;
}
.cta-row {
  margin-top: 1.1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
}
.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.7rem 1.4rem;
  border-radius: var(--civic-radius-pill);
  background: var(--civic-cta-bg);
  color: var(--civic-cta-ink);
  font-weight: 700;
  text-decoration: none;
  box-shadow: var(--civic-shadow);
}
.cta:hover {
  background: var(--civic-cta-bg-hover);
  color: var(--civic-cta-ink);
}
.section {
  margin-top: 3rem;
}
.section > h2 {
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--civic-red-700);
}
.section > h2 + * {
  margin-top: 1.1rem;
}
.note {
  margin-top: 1.25rem;
  padding: 1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-info-border);
  background: var(--civic-info-bg);
  display: grid;
  gap: 0.5rem;
  font-size: var(--civic-fs-small);
}
/* The coverage block: labelled rows, with the one sentence that can cost
 * someone their vote given its own garnet-edged line rather than being the
 * fifth grey paragraph in a row. */
.coverage {
  gap: 0;
}
.coverage .facts {
  border: 0;
  background: none;
  padding: 0;
  gap: 0.55rem;
}
.coverage .facts dd {
  font-size: var(--civic-fs-small);
  max-width: 78ch;
}
.coverage-warn {
  margin-top: 0.9rem;
  padding: 0.6rem 0.85rem;
  border-left: 3px solid var(--civic-red-700);
  border-radius: 0 var(--civic-radius-sm) var(--civic-radius-sm) 0;
  background: var(--civic-red-100);
  color: var(--civic-ink);
  font-size: var(--civic-fs-small);
}
.note--warn {
  border-color: var(--civic-warn-border);
  background: var(--civic-warn-bg);
}
.note strong {
  color: var(--civic-ink);
}

/* Race and measure lists */
.cards {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}
/* Uniform, short cards — one district each — tile two abreast rather than
 * running 125 deep in a single column. */
.cards--grid {
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1rem;
  align-items: start;
}
.card {
  padding: 0.9rem 1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
  box-shadow: var(--civic-shadow);
  display: grid;
  gap: 0.4rem;
}
.card h3 a {
  color: var(--civic-ink);
  text-decoration-color: var(--civic-border-strong);
}
.card h3 a:hover {
  color: var(--civic-link-hover);
}
.card .where {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
/* A race in a list of races.
 *
 * A ballot is long, and a column of identical paragraphs is where a reader
 * gives up. Each race is a unit: a header band carrying the office and the
 * shape of the contest, then one row per candidate — marker, name, party,
 * and what marks them out. The point is that "who is up against whom, and for
 * what" is answerable at a glance, without reading. */
.race-card {
  padding: 0;
  overflow: hidden;
  gap: 0;
}
.race-card-head {
  padding: 0.85rem 1rem 0.7rem;
  background: var(--civic-grad-band);
  border-bottom: var(--civic-border-width) solid var(--civic-border);
  display: grid;
  gap: 0.15rem;
}
.race-card-head h3 {
  font-size: 1.125rem;
  line-height: 1.3;
}
.race-shape {
  font-size: var(--civic-fs-caption);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--civic-red-800);
}
/* A row of figures: four counts at the head of a long index, so the page
 * opens with something a reader can take in at a glance instead of a
 * paragraph of numbers. Navy gradient and a garnet top edge, like the
 * candidate cards, so it reads as the same family of object. */
.tally {
  position: relative;
  overflow: hidden;
  margin: 0 0 1.5rem;
  padding: 1.1rem 1.25rem;
  border-radius: var(--civic-radius-lg);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-grad-cta);
  box-shadow: var(--civic-shadow);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 1rem 1.5rem;
}
.tally::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--civic-rule-edge);
}
.tally > div {
  display: grid;
  gap: 0.15rem;
}
.tally dt {
  order: 2;
  font-size: var(--civic-fs-caption);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(245, 239, 226, 0.82);
  line-height: 1.3;
}
.tally dd {
  order: 1;
  margin: 0;
  font-family: var(--civic-font-display);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1;
  color: var(--civic-gold);
}

/* "About this race": how the seat is elected, who is leaving it, how the
 * district has voted. Each line is its own fact, so each gets its own rule
 * and a garnet tick rather than running together as a paragraph. */
/* Bulleted running text.
 *
 * These lists used to carry a hairline between every item, which made a
 * three-line list read as a three-row table and gave a long page one flat
 * texture. Space separates them now, and the text sits a step above the
 * caption size so a reader can stay in it. */
.context {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.7rem;
  font-size: var(--civic-fs-read);
  line-height: 1.62;
}
.context li {
  position: relative;
  padding-left: 1.15rem;
  max-width: 70ch;
}
.context li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--civic-red-700);
}
.names {
  list-style: none;
  padding: 0.6rem 1rem 0.85rem;
  display: grid;
  gap: 0.1rem;
  font-size: var(--civic-fs-small);
}
/* marker · name · party · markers-out */
.cand-row {
  display: grid;
  grid-template-columns: 0.6rem 1fr auto;
  align-items: baseline;
  column-gap: 0.6rem;
  padding: 0.3rem 0;
  border-top: 1px solid transparent;
}
.cand-row + .cand-row {
  border-top-color: var(--civic-border);
}
.cand-row-name {
  font-weight: 600;
  color: var(--civic-ink);
}
/* Keep the row one line: the markers sit with the name, so the right column
 * stays a clean column of parties a reader can scan straight down. */
.cand-row-name .tag {
  margin-left: 0.5rem;
  vertical-align: 1px;
}
.cand-row-party {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
  white-space: nowrap;
}
/* The dot is a conventional party hue, never a brand colour, and the party is
 * always written out next to it. It is decoration for the word, not a
 * replacement for it. */
.pdot {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--civic-party-other);
  align-self: center;
}
.pdot[data-party="d"] { background: var(--civic-party-d); }
.pdot[data-party="r"] { background: var(--civic-party-r); }
.pdot[data-party="i"] { background: var(--civic-party-i); }
.pdot[data-party="l"] { background: var(--civic-party-l); }
.pdot[data-party="g"] { background: var(--civic-party-g); }
@media (max-width: 520px) {
  .cand-row {
    grid-template-columns: 0.6rem 1fr;
  }
  .cand-row-party {
    grid-column: 2;
  }
}
.cand .party {
  color: var(--civic-ink-muted);
}
.tag {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0 0.45rem;
  border-radius: var(--civic-radius-pill);
  border: var(--civic-border-width) solid var(--civic-border-strong);
  font-size: var(--civic-fs-caption);
  line-height: 1.5;
  color: var(--civic-ink);
  white-space: nowrap;
}
/* Incumbency and write-in status are the two things that change how a vote
 * works, so they are marked — in ink weight, not in a party colour. */
.tag--inc {
  font-weight: 600;
  border-color: var(--civic-navy-600);
  color: var(--civic-navy-900);
  background: var(--civic-navy-100);
}
.tag--wi {
  color: var(--civic-amber);
  border-color: var(--civic-amber);
}
.grid-2 {
  display: grid;
  gap: 0.75rem;
}
@media (min-width: 720px) {
  .grid-2 {
    grid-template-columns: 1fr 1fr;
  }
}

/* Candidates on a race page.
 *
 * One candidate is a card, and the card is a hierarchy, not a stack of
 * same-sized paragraphs: a header carrying the name and the emblem, a row of
 * labelled facts (what they do now), the summary in reading-size prose, then
 * labelled blocks. Every block is headed with the candidate's family name, so
 * a reader landing mid-page always knows who is being described. */
/* A record set as a timeline: the date in its own column, so a reader can
 * follow the sequence without reading every line of every entry. */
.context.timeline {
  gap: 0.95rem;
}
.context.timeline li {
  display: grid;
  grid-template-columns: 9.75rem 1fr;
  gap: 0 1rem;
  padding-left: 0;
  max-width: 76ch;
}
.context.timeline li::before {
  display: none;
}
.context.timeline .when {
  font-size: var(--civic-fs-caption);
  font-weight: 700;
  line-height: 1.6;
  color: var(--civic-navy-800);
  padding-top: 0.08em;
  border-right: 2px solid var(--civic-line);
  padding-right: 0.9rem;
  margin-right: -0.1rem;
  text-align: right;
}
.context.timeline li.undated {
  grid-template-columns: 1fr;
}
.context.timeline li.undated .what {
  padding-left: 1.15rem;
  position: relative;
}
.context.timeline li.undated .what::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--civic-red-700);
}
@media (max-width: 36rem) {
  .context.timeline li {
    grid-template-columns: 1fr;
    gap: 0.15rem;
  }
  .context.timeline .when {
    text-align: left;
    border-right: 0;
    padding-right: 0;
    border-bottom: 0;
  }
}

/* Jump links across a long stack of candidate cards. */
.cand-jump {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.85rem;
  margin-bottom: 1.5rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--civic-radius-sm);
  background: var(--civic-surface-sunk);
}
.cand-jump-label {
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
}
.cand-jump ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.85rem;
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: var(--civic-fs-small);
}
.cand-jump a {
  font-weight: 600;
}
.cands {
  display: grid;
  gap: 2rem;
}
/* A card is long; landing on one from a jump link should not put its name
 * under the sticky header. */
.cand {
  scroll-margin-top: 1.5rem;
}
.cand {
  position: relative;
  overflow: hidden;
  padding: 0 0 1.5rem;
  border-radius: var(--civic-radius-lg);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface-raised);
  box-shadow: var(--civic-shadow);
  display: grid;
  gap: 1.35rem;
}
/* Everything but the header band is inset; the band runs edge to edge, so a
 * card opens with a person rather than with a paragraph. */
.cand > *:not(.cand-head) {
  margin-inline: 1.4rem;
}
/* A garnet edge along the top: the same rule the header carries, so a
 * candidate card reads as part of the same object as the page. */
.cand::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--civic-rule-edge);
}
/* The header is a band, not a line of text: a candidate's name is the
 * biggest thing on their card, and the identity is plainly separate from the
 * evidence underneath it. Without portraits this is what makes one card
 * distinguishable from the next at a glance. */
.cand-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1.25rem 1.4rem;
  background: linear-gradient(180deg, var(--civic-parchment) 0%, #e6dcc6 100%);
  border-bottom: var(--civic-border-width) solid var(--civic-border);
}
.cand-id {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}
.emblem {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--civic-grad-emblem);
  color: var(--civic-eggshell-100);
  font-family: var(--civic-font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  box-shadow:
    0 0 0 2px var(--civic-ivory),
    0 0 0 3px var(--civic-brass),
    0 1px 3px rgba(15, 31, 61, 0.25);
}
.cand h3 {
  font-size: var(--civic-fs-name);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.cand-party {
  font-size: var(--civic-fs-small);
  color: var(--civic-ink-muted);
}
.emblem {
  width: 3.25rem;
  height: 3.25rem;
  font-size: 1.0625rem;
}
/* Labelled facts: the answer to "what do they actually do?" without making
 * the reader find it inside a paragraph. */
.facts {
  margin: 0;
  display: grid;
  gap: 0.4rem;
  padding: 0.7rem 0.85rem;
  border-radius: var(--civic-radius-sm);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-grad-band);
}
/* A fixed label column, not max-content: each row is its own grid, so a
 * content-sized column would leave the labels ragged down the list. */
.facts > div {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 0.15rem 0.75rem;
  align-items: baseline;
}
.facts dt {
  font-size: var(--civic-fs-caption);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--civic-red-800);
}
.facts dd {
  margin: 0;
  font-size: var(--civic-fs-small);
  color: var(--civic-ink);
}
.facts-wide > div {
  grid-template-columns: 11.5rem 1fr;
}
@media (max-width: 520px) {
  .facts > div,
  .facts-wide > div {
    grid-template-columns: 1fr;
  }
}
/* Prose keeps a comfortable measure even when the card is wide: past about
 * 70 characters the eye loses the start of the next line. */
/* On a card, facts are one or two rows, not a table. The page-level slab
 * left a label stranded a third of a card away from its own value. */
.cand .facts {
  padding: 0;
  border: 0;
  background: none;
  gap: 0.3rem;
}
.cand .facts > div {
  display: block;
}
.cand .facts dt {
  display: inline;
  font-size: var(--civic-fs-label);
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
}
.cand .facts dt::after {
  content: " ";
}
.cand .facts dd {
  display: inline;
  font-size: var(--civic-fs-read);
}
.cand-lede {
  font-size: var(--civic-fs-lede);
  line-height: 1.5;
  color: var(--civic-ink);
  max-width: 60ch;
}
.cand-block li,
.topic li,
.duties li {
  max-width: 72ch;
}
.cand-prose {
  color: var(--civic-ink-muted);
}
/* Each block names its subject, and is separated by a rule rather than by
 * more white space between identical paragraphs. */
.cand-block {
  display: grid;
  gap: 0.6rem;
  padding-top: 1.1rem;
  border-top: var(--civic-border-width) solid var(--civic-border);
}
.cand-block > h4 {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-h4);
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--civic-navy-900);
}
.cand-block ul {
  display: grid;
  gap: 0.6rem;
  font-size: var(--civic-fs-read);
  line-height: 1.62;
}
.topics {
  display: grid;
  gap: 0.6rem;
}
/* Where they stand, topic by topic.
 *
 * The same positions as on the cards, turned ninety degrees: topic down the
 * page, candidates across it. This is the layout that answers the question a
 * voter arrives with, which is not "what does this one think" but "how do
 * these people differ" — a question the card stack makes you hold in your
 * head while you scroll.
 *
 * auto-fit with a 15rem floor means two candidates get two wide columns,
 * five get as many as fit and then wrap, and a phone gets one column with
 * each name above its own answer. No party colour anywhere: the cells are
 * identical and only the name changes (DESIGN.md §Neutrality).
 */
.stand {
  display: grid;
  gap: 1.1rem;
}
.stand-topic {
  padding-top: 0.85rem;
  border-top: var(--civic-border-width) solid var(--civic-border);
}
.stand-topic:first-child {
  padding-top: 0;
  border-top: 0;
}
.stand-h {
  font-size: var(--civic-fs-h3);
  color: var(--civic-navy-900);
  margin-bottom: 0.55rem;
}
.stand-row {
  display: grid;
  gap: 0.7rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  align-items: start;
}
/* The page caps prose at 52rem, which is right for reading and wrong for
 * comparing: at that width a fourth candidate drops to a row of their own and
 * the comparison stops being one. So this section, and only this section,
 * steps outside the measure. Each column stays narrow, so no line of text
 * gets longer than it would have been — the extra width buys columns, not
 * longer lines. */
@media (min-width: 62rem) {
  .stand {
    --stand-w: min(74rem, calc(100vw - 2 * var(--civic-gutter)));
    width: var(--stand-w);
    margin-inline: calc((100% - var(--stand-w)) / 2);
  }
}
.stand-cell {
  padding: 0.65rem 0.8rem 0.7rem;
  border-radius: var(--civic-radius-sm);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
}
/* A candidate who has not been found addressing the topic gets the same cell,
 * recessed rather than removed. A blank would read as "no opinion"; the point
 * is that the gap is in our research, and the words in it say so. */
.stand-cell--none {
  background: var(--civic-surface-sunk);
  border-style: dashed;
}
.stand-who {
  font-weight: 600;
  font-size: var(--civic-fs-small);
  color: var(--civic-navy-900);
  margin-bottom: 0.3rem;
}
.stand-who a {
  color: inherit;
}
.stand-cell ul {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding-left: 1.05rem;
  font-size: var(--civic-fs-caption);
  line-height: 1.55;
}
.stand-none {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
  font-style: italic;
}
.topic {
  padding: 0.6rem 0.75rem;
  border-radius: var(--civic-radius-sm);
  background: var(--civic-surface-sunk);
  border-left: 3px solid var(--civic-navy-600);
}
/* Inside a candidate card the topic boxes were a third tinted surface stacked
 * inside the second. Four of them in a row read as a wall. In the card they
 * become a label on a rule; the tinted box stays where it earns its keep, in
 * the side-by-side comparison grid. */
.cand .topics {
  gap: 1.1rem;
}
.cand .topic {
  padding: 0;
  border-radius: 0;
  background: none;
  border-left: 0;
  border-top: var(--civic-border-width) dashed var(--civic-border);
  padding-top: 0.7rem;
}
.cand .topic:first-child {
  border-top: 0;
  padding-top: 0;
}
.cand .topic-name {
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
}
.topic-name {
  font-weight: 600;
  font-size: var(--civic-fs-small);
  color: var(--civic-navy-900);
  margin-bottom: 0.25rem;
}
.topic ul {
  display: grid;
  gap: 0.35rem;
  font-size: var(--civic-fs-small);
}
/* What we looked for and did not find. A blank space tells a reader nothing;
 * a list of where we looked tells them the silence is the record, not an
 * oversight — and tells them where to send a correction. */
/* A candidate's own words, lifted from an official voters' pamphlet. It is
 * the one passage on the page that is not ours, so it does not look like the
 * rest: a navy gradient panel with a garnet edge down the left and the
 * attribution under it, never an unmarked paragraph among our sentences. */
.quote {
  position: relative;
  margin: 0;
  padding: 1rem 1.15rem 0.9rem 1.4rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-grad-band);
  overflow: hidden;
}
.quote::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--civic-rule-edge);
}
.quote p {
  font-size: var(--civic-fs-body);
  line-height: 1.6;
  max-width: 68ch;
}
.quote-cite {
  margin-top: 0.55rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
/* A question a reader could put to a candidate, under the point that raises
 * it. It is ours, not anyone's answer, so it sits apart from the sourced
 * sentence above it. */
.ask {
  margin-top: 0.4rem;
  padding-left: 0.75rem;
  border-left: 3px solid var(--civic-navy-600);
  font-size: var(--civic-fs-small);
  color: var(--civic-ink-muted);
}

/* A dated list of changes in the law. The date is the thing to scan for, so
 * it sits in its own column with a garnet tick, and each entry gets a rule
 * rather than another paragraph of the same grey. */
.timeline {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0;
  max-width: 74ch;
}
.timeline li {
  position: relative;
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: 0 1rem;
  padding: 0.7rem 0 0.7rem 1.1rem;
  font-size: var(--civic-fs-small);
  line-height: 1.55;
  border-top: var(--civic-border-width) solid var(--civic-border);
}
.timeline li:first-child {
  border-top: 0;
}
.timeline li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.15rem;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--civic-red-600);
}
/* An entry with no date in front of it still spans the full width. */
.timeline .undated {
  grid-column: 1 / -1;
}
.timeline .when {
  font-weight: 650;
  color: var(--civic-navy-900);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 34rem) {
  .timeline li {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }
}

/* A stat tile: one current figure with its history under it. The figure is
 * the headline, so it carries no decoration and wears the body face — a
 * display serif on a number reads as ornament, not as data. */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
  align-items: start;
  margin-bottom: 1rem;
}
.stat {
  padding: 1rem 1.15rem 1.1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-grad-card-raised);
  box-shadow: var(--civic-shadow);
}
.stat-label {
  font-size: var(--civic-fs-caption);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--civic-ink-muted);
}
.stat-value {
  margin-top: 0.15rem;
  font-family: var(--civic-font-body);
  font-size: 2rem;
  font-weight: 650;
  line-height: 1.1;
  color: var(--civic-navy-900);
}
.stat-value--sm {
  font-size: 1.5rem;
  margin: 0.2rem 0 0.35rem;
}
.stat-sub {
  margin-top: 0.3rem;
  font-size: var(--civic-fs-small);
  color: var(--civic-ink-muted);
}
/* One series, so one hue and no legend; the ends are labelled and every
 * figure is in the table below, so nothing is reachable only by hovering. */
.spark {
  margin: 0.75rem 0 0;
}
.spark svg {
  display: block;
  width: 100%;
  height: 52px;
}
.spark-area {
  fill: rgba(34, 69, 127, 0.14);
}
.spark-line {
  fill: none;
  stroke: var(--civic-navy-600);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.spark-dot {
  fill: var(--civic-navy-600);
  stroke: var(--civic-eggshell-050);
  stroke-width: 2;
}
.spark-ends {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.3rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
  font-variant-numeric: tabular-nums;
}

/* An incumbent's record in office. It carries more structure than the other
 * blocks — counts, committees, votes — so it gets a tinted field of its own
 * rather than another run of rules in the same card. */
.record {
  margin-top: 0.4rem;
  padding: 1rem 1.1rem 1.1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface-sunk);
  border-top-width: var(--civic-border-width);
}
.record > h4 {
  color: var(--civic-red-800);
}
.rec-label {
  margin-top: 0.4rem;
  font-size: var(--civic-fs-caption);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--civic-ink-muted);
}
.rec-details > summary {
  cursor: pointer;
  padding: 0.5rem 0;
  font-size: var(--civic-fs-small);
  font-weight: 600;
  color: var(--civic-navy-600);
}
/* The compact variant of the figure row, inside a candidate card. */
.tally--sm {
  margin: 0.3rem 0 0.5rem;
  padding: 0.75rem 0.85rem;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 0.75rem 1rem;
}
.tally--sm dd {
  font-size: 1.5rem;
}
.tally--sm .tally-sub {
  order: 3;
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-caption);
  font-weight: 400;
  color: rgba(245, 239, 226, 0.78);
}
.tag--vote[data-vote="yea"] {
  border-color: var(--civic-navy-600);
  color: var(--civic-navy-900);
}
.tag--vote[data-vote="nay"] {
  border-color: var(--civic-red-600);
  color: var(--civic-red-800);
}

/* Committee seats: a dozen short names read as a row of labels, not as a
 * bulleted column of near-identical lines. */
/* `.cand-block ul` sets a grid below, so the chip row names both. */
.cand-block ul.chips,
.chips {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.chip {
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-grad-band);
  font-size: var(--civic-fs-caption);
  line-height: 1.3;
}

.searched {
  display: grid;
  gap: 0.35rem;
  padding: 0.7rem 0.85rem;
  border-radius: var(--civic-radius-sm);
  border: var(--civic-border-width) dashed var(--civic-border-strong);
  background: var(--civic-surface-sunk);
}
.searched ul {
  display: grid;
  gap: 0.2rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
.cand .about {
  color: var(--civic-ink-muted);
}
.cand .links {
  font-size: var(--civic-fs-caption);
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
}
/* The office section: a summary at reading size, then the statutory duties
 * folded away so the page opens short and the detail is one click deep. */
.lede-sm {
  font-size: var(--civic-fs-lede);
  line-height: 1.5;
  color: var(--civic-ink);
  max-width: 60ch;
}
.section .facts {
  margin-top: 0.9rem;
}
/* The job, at the top of a race page.
 *
 * A voter cannot choose between candidates until they know what they are
 * choosing someone to do, so this section is built to be read rather than
 * skimmed past: the duties are open on the page instead of folded into a
 * disclosure triangle, and what the next officeholder will decide sits
 * beside them. Each part is labelled, and the one that answers "what will
 * this person actually be deciding" is the one given an edge.
 */
/* The process diagram.
 *
 * A property tax bill passes through six hands and names none of them. This
 * draws the chain: a numbered tile per step, the offices that act at each one
 * listed under it, and the office whose page this is marked in every step it
 * appears in.
 *
 * It is drawn rather than written because the thing a reader needs is the
 * shape — how many steps, where this one falls, how much of the chain is not
 * on the ballot at all. A connector runs down the numerals so the tiles read
 * as a sequence and not as six unrelated boxes. At narrow widths it stays one
 * column, which is the same sequence, just taller.
 */
.steps {
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 0;
  counter-reset: none;
}
.step {
  position: relative;
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0.9rem;
  padding: 0 0 1.25rem;
}
/* The thread between the numerals. It stops at the last step rather than
 * trailing off the end of the chain. */
.step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 1.2rem;
  top: 2.4rem;
  bottom: 0.35rem;
  width: 2px;
  background: var(--civic-border);
}
.step-n {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  margin: 0;
  border-radius: 999px;
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h4);
  color: var(--civic-ink-subtle);
}
.step-body {
  min-width: 0;
  padding-bottom: 0.1rem;
}
.step-name {
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h4);
  font-weight: 600;
  color: var(--civic-ink);
  margin: 0.25rem 0 0.3rem;
}
.step-text {
  margin: 0;
  font-size: var(--civic-fs-read);
  color: var(--civic-ink-muted);
}
/* Who acts at this step. Chips, because the answer is a set of offices and a
 * reader is scanning for one of them, not reading a sentence. */
.step-who {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.4rem;
  list-style: none;
  margin: 0.55rem 0 0;
  padding: 0;
}
.step-who li {
  font-size: var(--civic-fs-label);
  letter-spacing: 0.01em;
  color: var(--civic-ink-subtle);
  background: var(--civic-parchment);
  border-radius: 999px;
  padding: 0.14rem 0.6rem;
}
.step-who li.is-here {
  color: var(--civic-eggshell-100);
  background: var(--civic-navy-600);
  font-weight: 700;
}
.step-who-none {
  margin: 0.55rem 0 0;
  font-size: var(--civic-fs-label);
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
}
/* The step the reader's office acts at. The numeral fills and the body sits
 * on parchment: enough to find at a glance down the column, not so much that
 * the other steps read as inactive. */
.step.is-here > .step-n {
  color: var(--civic-eggshell-100);
  background: var(--civic-red-700);
  border-color: var(--civic-red-700);
}
.step.is-here > .step-body {
  background: var(--civic-parchment);
  border-radius: var(--civic-radius);
  padding: 0.5rem 0.9rem 0.8rem;
  margin-top: -0.25rem;
}
.step.is-here .step-text {
  color: var(--civic-ink);
}
.step.is-here .step-who li {
  background: var(--civic-surface);
}
.step.is-here .step-who li.is-here {
  background: var(--civic-navy-600);
}
.step-tag {
  display: inline-block;
  vertical-align: 0.1em;
  margin-left: 0.4rem;
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-red-700);
}
.process > .caption {
  margin-top: 0.25rem;
}

/* Where the office sits in the levels of government.
 *
 * A ballot prints a county auditor, a township trustee and a state auditor in
 * the same type and leaves a reader to guess which government each one is.
 * This is the smallest drawing that answers it: four rungs, the office's own
 * one filled in. Courts, school corporations and special districts are not
 * rungs on that ladder, so they get a single chip and a line saying why,
 * rather than being pressed onto a tier they do not occupy. */
.levels {
  margin-top: 1.1rem;
  padding: 0.85rem 1rem 0.9rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-parchment);
}
.levels-h {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
  margin: 0 0 0.55rem;
}
.levels-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.levels-list li {
  display: flex;
  align-items: center;
}
/* The rungs read as a descent, so each one after the first carries the step
 * down in front of it — outside the pill, where it reads as a connector
 * rather than as part of the label. */
.levels-list li + li::before {
  content: "\203a";
  margin-right: 0.55rem;
  color: var(--civic-ink-subtle);
}
.levels-list .rung {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-subtle);
  padding: 0.18rem 0.6rem;
  border-radius: 999px;
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
  white-space: nowrap;
}
.levels-list .rung.is-here {
  color: var(--civic-eggshell-100);
  background: var(--civic-navy-600);
  border-color: var(--civic-navy-600);
  font-weight: 700;
}
.levels-chip {
  display: inline-block;
  margin: 0;
  font-size: var(--civic-fs-caption);
  font-weight: 700;
  color: var(--civic-eggshell-100);
  background: var(--civic-navy-600);
  border-radius: 999px;
  padding: 0.18rem 0.7rem;
}
.levels > .caption {
  margin: 0.5rem 0 0;
}
.job-part {
  margin-top: 1.1rem;
}
/* The reference half of the job keeps a tracked-caps label: it is a heading
 * for a list of facts, and reads as one. The forward-looking panels below
 * override this with a display heading, because they are the argument for
 * reading the page rather than a label on a list. */
.job-h {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
  margin-bottom: 0.45rem;
}
/* The decisions of the coming term, and the questions that follow from them.
 *
 * This is the half of the job no ballot and no endorsement tells a voter, and
 * it used to sit in the same 13px label and 16px bullets as everything else,
 * where it read as more of the same. It now gets its own heading size, a
 * wider surface and real room, because it is the reason to read the page. */
.job-part--decides,
.job-part--ask {
  margin-top: 1.5rem;
  padding: 1.1rem 1.25rem 1.25rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  border-left: 4px solid var(--civic-red-700);
  background: var(--civic-surface);
  box-shadow: var(--civic-shadow);
}
.job-part--ask {
  border-left-color: var(--civic-navy-600);
}
.job-part--decides > .job-h,
.job-part--ask > .job-h {
  font-family: var(--civic-font-display);
  font-size: 1.3125rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--civic-navy-900);
  margin-bottom: 0.15rem;
}
.job-part--decides > .small,
.job-part--ask > .small {
  max-width: 62ch;
  margin-bottom: 0.9rem;
}
/* The questions are the one place on the page a reader is being handed
 * something to use rather than told something. Numbering them says so, and
 * stops four questions reading as four more facts. */
.job-part--ask .context {
  counter-reset: ask;
  gap: 0.85rem;
}
.job-part--ask .context li {
  counter-increment: ask;
  padding-left: 2.1rem;
  font-size: var(--civic-fs-body);
  line-height: 1.55;
  color: var(--civic-ink);
}
.job-part--ask .context li::before {
  content: counter(ask);
  top: 0;
  left: 0;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--civic-navy-100);
  color: var(--civic-navy-800);
  font-size: var(--civic-fs-caption);
  font-weight: 700;
  display: grid;
  place-items: center;
}
.duties {
  margin-top: 0.9rem;
  padding: 0.7rem 0.85rem;
  border-radius: var(--civic-radius-sm);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
}
.duties > summary {
  cursor: pointer;
  font-weight: 600;
  font-size: var(--civic-fs-small);
  color: var(--civic-navy-900);
}
.duties ul {
  display: grid;
  gap: 0.45rem;
  font-size: var(--civic-fs-small);
  line-height: 1.55;
}
.sources {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
}
.sources ol,
.sources ul {
  display: grid;
  gap: 0.2rem;
  margin-top: 0.3rem;
}
.sources a {
  overflow-wrap: anywhere;
}
sup.cite {
  font-size: 0.7em;
  line-height: 0;
}

/* Facts (voting info, yes/no) */
.facts {
  margin: 0;
  display: grid;
  gap: 0.75rem;
}
.facts dt {
  font-size: var(--civic-fs-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--civic-ink-muted);
}
.facts dd {
  margin: 0.15rem 0 0;
}
.panel {
  padding: 1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
}

/* State and county indexes */
.index {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.35rem 1rem;
}
.index a {
  display: inline-block;
  padding: 0.3rem 0;
}

details {
  margin-top: 0.75rem;
}
summary {
  cursor: pointer;
  color: var(--civic-link);
}

/* A case citation is one long unbreakable token — a docket number, a court
 * abbreviation, a date — and it used to sit inside the link with the case
 * name, pushing retention pages sideways at phone width. It now sits on its
 * own line, and is allowed to break. */
.cite-line {
  overflow-wrap: anywhere;
}
.event-title {
  overflow-wrap: anywhere;
}

/* Who else the opinion names from the same courtroom. It sits above the case
 * rather than under it, because a reader who does not see it before reading
 * the ruling will read the ruling as this judge's. */
.shared-with {
  margin-top: 0.5rem;
  padding: 0.4rem 0.65rem;
  border-radius: var(--civic-radius);
  border-left: 3px solid var(--civic-border-strong, var(--civic-border));
  background: var(--civic-parchment);
  color: var(--civic-ink-subtle);
}

/* A case, in four parts.
 *
 * A case summary used to be one paragraph that had to carry the facts, the
 * legal question, the outcome and the judge's path to it at once, and a reader
 * looking for any one of those had to find it inside the others. The parts are
 * labelled and stacked instead, so "what did the judge actually decide" and
 * "how did they get there" are each one glance away. The labels are tracked
 * caps because they are signposts, not sentences; the prose under them keeps
 * reading size.
 */
.case-parts {
  margin-top: 0.7rem;
}
.case-part + .case-part {
  margin-top: 0.7rem;
}
.case-l {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
  margin: 0 0 0.15rem;
}
.case-part > p + p {
  margin: 0;
  font-size: var(--civic-fs-read);
}

/* A study's table. It holds the counts the prose rests on, so it stays a
 * table; on a phone it scrolls inside its own box rather than pushing the
 * page sideways. */
.table-wrap {
  margin: 1.1rem 0;
  overflow-x: auto;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
}
.study-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--civic-fs-caption);
  background: var(--civic-surface);
}
.study-table th,
.study-table td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  vertical-align: top;
  border-bottom: var(--civic-border-width) solid var(--civic-border);
}
.study-table thead th {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
  background: var(--civic-parchment);
  white-space: nowrap;
}
.study-table tbody th {
  font-weight: 600;
  color: var(--civic-ink);
}
.study-table tbody tr:last-child th,
.study-table tbody tr:last-child td {
  border-bottom: 0;
}
/* A number column reads right-aligned; these tables are label-then-counts. */
.study-table td {
  font-variant-numeric: tabular-nums;
}

/* The fiscal screen on a county page.
 *
 * A screen is a finding about a county, which is a different kind of thing
 * from a figure, so it gets a surface of its own and carries what an official
 * there said in their own words — attributed, dated and linked, because a
 * quote without those is a rumor. The line saying a screen is not a forecast
 * travels with it.
 */
.screen {
  margin-top: 1.4rem;
  padding: 1rem 1.15rem 1.1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  border-left: 4px solid var(--civic-red-700);
  background: var(--civic-surface);
  box-shadow: var(--civic-shadow);
}
.screen-lede {
  margin: 0;
  font-size: var(--civic-fs-read);
}
.screen-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.45rem;
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0;
}
.screen-flags > li {
  font-size: var(--civic-fs-label);
  color: var(--civic-ink-subtle);
  background: var(--civic-parchment);
  border-radius: 999px;
  padding: 0.16rem 0.65rem;
}
.screen-quote {
  margin: 0.9rem 0 0;
  padding-left: 0.9rem;
  border-left: 3px solid var(--civic-border);
}
.screen-quote > p {
  margin: 0;
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h4);
  line-height: 1.45;
  color: var(--civic-ink);
}
.screen-quote > footer {
  margin-top: 0.35rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-subtle);
}
.screen > .caption {
  margin-top: 0.8rem;
}
.money .bars {
  margin-top: 1.4rem;
}

/* A study: a long read, in Civic's own type.
 *
 * These arrive as finished pages with their own stylesheet. Publishing one as
 * it stands would put a second design system inside the site, so the prose is
 * re-set here instead: the same section band and measure as every other page,
 * numbered eyebrows above the headings because the author wrote the piece as a
 * sequence, and a diagram's labelled numbers rendered as the stat tiles the
 * rest of the site already uses.
 *
 * The county pages carry the opening of a study, not the whole thing, so the
 * block there is a section like any other and the rail finds it on its own.
 */
.study-eyebrow {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-red-700);
  margin: 0 0 0.35rem;
}
.study-sec > p {
  font-size: var(--civic-fs-read);
}
.study-h3 {
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h4);
  font-weight: 600;
  color: var(--civic-ink);
  margin: 1.4rem 0 0.35rem;
}
.study-fig {
  margin: 1.2rem 0;
  padding: 1rem 1.1rem 1.1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-parchment);
}
.study-fig .scores {
  margin-top: 0;
}
.study-fig .timeline {
  margin-top: 0;
}
/* A sequence, not a set: each step after the first carries the operation that
 * produced it, sitting above the figure it applies to. */
.scores--flow > li {
  position: relative;
}
.flow-op {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-red-700);
  margin: 0 0 0.3rem;
}
.study-fig > figcaption {
  margin-top: 0.75rem;
}
/* "Led by: Hendricks · Bartholomew · Whitley" — a credit on a play, which
 * belongs with the play and not in the prose above it. */
.study-credit {
  margin: -0.2rem 0 0.5rem;
  font-weight: 700;
  color: var(--civic-navy-600);
}
.study > .note {
  margin-top: 1rem;
}
.study .scores {
  margin-top: 0.6rem;
}
.study > .bars-h {
  margin-top: 1.2rem;
  margin-bottom: 0;
}

/* The judicial scoreboard: stat tiles and one comparison.
 *
 * The research behind a retention vote counted thousands of decisions and
 * published the answer as seven dense sentences. These are the same numbers
 * set as numbers — a figure large enough to read at a glance, its label under
 * it, and the denominator and the court-wide figure in caption type below
 * that, because a count without its denominator is the thing that misleads.
 *
 * The bars carry one series and a reference mark, so there is no categorical
 * palette and nothing to tell apart by hue: the fill is the judge, the upright
 * mark is the same figure for the whole court. Every value and every n is
 * printed beside its bar, so there is nothing a hover could reveal that the
 * page is not already showing.
 */
.scores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  /* Tiles carry different amounts of caption; stretching them to the tallest
   * in the row leaves the short ones mostly empty. */
  align-items: start;
  gap: 0.75rem;
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 0;
}
.scores > li {
  padding: 0.8rem 0.9rem 0.85rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
}
.score-v {
  font-family: var(--civic-font-display);
  font-size: 1.75rem;
  line-height: 1.1;
  color: var(--civic-navy-600);
  margin: 0;
}
.score-l {
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-label);
  font-weight: 700;
  letter-spacing: var(--civic-tracking-label);
  text-transform: uppercase;
  color: var(--civic-ink-subtle);
  margin: 0.25rem 0 0.3rem;
}
.scores .caption {
  margin: 0.15rem 0 0;
}
.bars {
  margin: 1.6rem 0 0;
}
.bars-h {
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h4);
  font-weight: 600;
  color: var(--civic-ink);
  margin-bottom: 0.2rem;
}
.bars-key {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-subtle);
  margin: 0 0 0.75rem;
}
.bars-key-mark {
  display: inline-block;
  width: 2px;
  height: 0.95rem;
  background: var(--civic-ink);
}
.bars ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bar-row {
  display: grid;
  grid-template-columns: minmax(6rem, 10rem) 1fr minmax(7rem, auto);
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding: 0.3rem 0;
}
.bar-label {
  margin: 0;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink);
}
.bar-track {
  position: relative;
  height: 12px;
  border-radius: 6px;
  background: rgba(34, 69, 127, 0.1);
}
.bar-fill {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 0 6px 6px 0;
  background: rgba(34, 69, 127, 0.55);
}
/* A fall is drawn to the left of the zero line, so its rounded end is on the
 * left; garnet marks the direction without becoming a second series. */
.bar-fill.is-down {
  border-radius: 6px 0 0 6px;
  background: rgba(138, 29, 42, 0.5);
}
.bar-zero {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  margin-left: -0.5px;
  background: var(--civic-border-strong, var(--civic-border));
}
/* The whole court, same dates. An upright mark rather than a second bar: it
 * is a reference line, and a second fill would read as a rival series. */
.bar-mark {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  background: var(--civic-ink);
}
.bar-value {
  margin: 0;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink);
  white-space: nowrap;
}
.bars > .caption {
  margin-top: 0.7rem;
}
@media (max-width: 34rem) {
  .bar-row {
    grid-template-columns: 1fr auto;
  }
  .bar-track {
    grid-column: 1 / -1;
    order: 3;
  }
  .bar-value {
    text-align: right;
  }
}
/* The lines that keep a count from being read as a grade. Each is its own
 * reason the figure above is narrower than it looks, so they are set as a
 * list rather than run together into a paragraph nobody finishes. */
.caveat {
  margin-top: 1rem;
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-subtle);
  border-left: 3px solid var(--civic-border);
  padding-left: 0.75rem;
}
ul.caveat {
  list-style: none;
  padding-left: 0.75rem;
  margin-bottom: 0;
}
ul.caveat > li + li {
  margin-top: 0.45rem;
}
/* The full prose behind a summarised block, for a reader who wants it. */
.more > summary {
  font-size: var(--civic-fs-caption);
}

/* Election results (src/civic/prerender/results.mjs). One neutral bar color
   for every candidate; no party hue, no winner marker (DESIGN.md). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.results {
  padding: 1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  background: var(--civic-surface);
}
.results > h2 {
  border-bottom: 0;
  padding-bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}
.results .status {
  display: inline-block;
  margin: 0.4rem 0 0;
  padding: 0.1rem 0.6rem;
  border-radius: var(--civic-radius-pill);
  border: var(--civic-border-width) solid var(--civic-border-strong);
  font-size: var(--civic-fs-caption);
  font-weight: 600;
  color: var(--civic-ink-muted);
}
.results .status--certified {
  color: var(--civic-green);
  border-color: var(--civic-green);
}
.results-table {
  width: 100%;
  margin-top: 0.75rem;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.results-table th,
.results-table td {
  text-align: left;
  padding: 0.45rem 0;
  border-bottom: var(--civic-border-width) solid var(--civic-border);
  vertical-align: top;
}
.results-table thead th {
  font-size: var(--civic-fs-caption);
  color: var(--civic-ink-muted);
  font-weight: 600;
}
.results-table tbody th {
  font-weight: 600;
  width: 100%;
}
.results-table .num {
  text-align: right;
  white-space: nowrap;
  padding-left: 1rem;
}
.results-table .bar {
  display: block;
  margin-top: 0.3rem;
  height: 6px;
  border-radius: 3px;
  background: rgba(34, 69, 127, 0.12);
  overflow: hidden;
}
.results-table .bar > span {
  display: block;
  height: 100%;
  background: rgba(34, 69, 127, 0.55);
}
.results .caption {
  margin-top: 0.6rem;
}
.note--results {
  border-left: 5px solid var(--civic-info);
}
.test-label {
  display: inline-block;
  padding: 0.05rem 0.5rem;
  border: 2px dashed var(--civic-red-600);
  border-radius: var(--civic-radius-sm);
  color: var(--civic-red-600);
  font-family: var(--civic-font-body);
  font-size: var(--civic-fs-caption);
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* "Right now" voting line (filled in the browser from the state's key dates) */
.now {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-radius: var(--civic-radius);
  border-left: 4px solid var(--civic-navy, #1b2f5c);
  background: linear-gradient(90deg, rgba(27, 47, 92, 0.1), rgba(27, 47, 92, 0.02));
}
.now[data-tone="closed"] {
  border-left-color: var(--civic-red, #7a1f2b);
  background: linear-gradient(90deg, rgba(122, 31, 43, 0.08), rgba(122, 31, 43, 0.02));
}
.now-head {
  margin: 0;
  font-family: var(--civic-font-display);
  font-size: var(--civic-fs-h3);
  font-weight: 700;
  color: var(--civic-ink);
}
.now-detail {
  margin: 0.25rem 0 0;
  color: var(--civic-ink);
}
.now-detail:empty {
  display: none;
}
.now-hero {
  margin: 1rem 0 0;
  border-left-color: var(--civic-red, #b3243a);
  background: rgba(255, 255, 255, 0.08);
}
.now-hero a {
  color: inherit;
  text-decoration: none;
}
.now-hero .now-head {
  display: block;
  color: #fff;
}
.now-hero .now-detail {
  display: block;
  margin-top: 0.2rem;
  color: rgba(255, 255, 255, 0.85);
}

/* Forums and debates */
.events {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}
.event {
  /* A case card can hold a docket number or a bare opinion URL, neither of
   * which breaks. In a grid track that sets the column's min-content width
   * and pushes the whole page sideways on a phone, so allow a break where
   * nothing else will fit. Ordinary prose is unaffected. */
  min-width: 0;
  overflow-wrap: anywhere;
  padding: 0.85rem 1rem;
  border-radius: var(--civic-radius);
  border: var(--civic-border-width) solid var(--civic-border);
  border-left: 4px solid var(--civic-navy, #1b2f5c);
  background: var(--civic-surface);
}
.event.past {
  border-left-color: var(--civic-border);
  opacity: 0.85;
}
.event p {
  margin: 0.15rem 0;
}
.event-title {
  font-weight: 600;
}
.event-title .muted {
  font-weight: 400;
}
.event-title,
.event-title a {
  overflow-wrap: anywhere;
}
.header-links {
  display: flex;
  gap: 1rem;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Whose job this is.
   A study ends by naming the offices it was actually about, because that is
   the only part of it a reader can vote on. Each entry is three lines with
   three jobs: the office as a link, what the law puts in it, and the one
   thing this study found about it. They are set at different weights so the
   eye can take the office names alone and stop there. */
.whose { display: grid; gap: 1.1rem; }
.whose > li { padding-left: 0; }
.whose > li::before { content: none; }
.whose-h { margin: 0 0 0.15rem; font-weight: 650; letter-spacing: -0.01em; }
.whose-h .caption { display: inline; margin-left: 0.4rem; font-weight: 400; }
.whose-does { margin: 0 0 0.3rem; }
.whose-found { margin: 0; color: var(--civic-ink-muted); font-size: var(--civic-fs-small, 0.94rem); }

/* Moving between a study's sections when you arrived at one of them from
   somebody else's link, which is the normal way a section page is reached. */
.step-nav { display: grid; gap: 0.35rem; }
.step-nav p { margin: 0; }
/* The same list in its short form, inside a county's study panel: office
   names in a row, between the county's own line and the link into the study.
   It needs air on both sides or it reads as part of whichever one it touches. */
.whose-row { margin: 0.7rem 0 0.7rem; }
.whose { margin-top: 1.1rem; }

/* The tier map.
   A level of government drawn as what it is: offices in bands by what they
   are for, and a curve for every handoff the law requires between them. The
   curves carry numbers rather than words, because a dozen labels inside one
   drawing is a thicket; the words are in the list underneath, in the same
   order, cited. That list is also the whole picture for anyone who cannot
   see it, so it is never decoration and never collapsed. */
.tier-fig { margin: 1.5rem 0 1rem; }
.tier-map {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
/* A row label can land on a curve swinging wide of the middle. It is drawn
   last, over a halo of the page color, so the words win and the line reads as
   passing behind them. */
.tier-row-l {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  fill: var(--civic-ink-subtle);
  stroke: var(--civic-eggshell-100, #f5efe2);
  stroke-width: 5px;
  paint-order: stroke fill;
}
/* --civic-surface and --civic-surface-raised are gradients once the real
   token file loads, and SVG fill cannot take one, so the boxes use the plain
   paper colors behind those gradients. */
.tier-node rect {
  fill: var(--civic-ivory, #fbf8f1);
  stroke: var(--civic-border-strong);
  stroke-width: 1.5;
}
.tier-node text {
  font-size: 16px;
  font-weight: 600;
  text-anchor: middle;
  fill: var(--civic-ink);
}
/* Something nobody elects is drawn, because leaving it out would imply a
   voter controls a step they do not. It is drawn as plainly as that fact:
   no fill, a broken edge. */
.tier-node.is-external rect {
  fill: none;
  stroke: var(--civic-border);
  stroke-dasharray: 5 4;
}
.tier-node.is-external text { fill: var(--civic-ink-muted); font-weight: 500; }
.tier-edge { fill: none; stroke: var(--civic-border-strong); stroke-width: 1.5; }
.tier-arrowhead { fill: var(--civic-border-strong); }
.tier-badge circle { fill: var(--civic-eggshell-100, #f5efe2); stroke: var(--civic-accent); stroke-width: 1.5; }
.tier-badge text {
  font-size: 13px;
  font-weight: 700;
  text-anchor: middle;
  fill: var(--civic-accent);
}

/* The same handoffs in words, numbered to the drawing. */
.tier-edges { counter-reset: tier-edge; display: grid; gap: 1rem; margin: 1.25rem 0 0; padding: 0; list-style: none; }
.tier-edges > li { counter-increment: tier-edge; display: grid; gap: 0.2rem; padding-left: 2.2rem; position: relative; }
.tier-edges > li::before {
  content: counter(tier-edge);
  position: absolute;
  left: 0;
  top: 0.1rem;
  width: 1.55rem;
  height: 1.55rem;
  border: 1.5px solid var(--civic-accent);
  border-radius: 50%;
  color: var(--civic-accent);
  font-size: 0.8rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.tier-edges p { margin: 0; }
.tier-edge-h { font-weight: 650; }
.tier-arrow { color: var(--civic-accent); padding: 0 0.15rem; }
.levels--tier { margin-top: 1.1rem; }

/* Below the width where a thousand units of drawing can hold sixteen-pixel
   type, the picture is a picture of nothing. The list carries it alone. */
@media (max-width: 700px) {
  .tier-fig { display: none; }
}
.tier-edges-h { margin: 1.1rem 0 0; }
