/*
  CaucusIQ stylesheet

  1. Settings: colors and sizes. Change these first; everything below uses them.
  2. Base: page, text, links
  3. Layout: top bar, cards, grids
  4. Forms and buttons
  5. Tables
  6. Badges, tags, counts, messages
  7. Search page
  8. Voter page
  9. Review queue
  10. Small screens and printing

  Readability rules: body text is 16px or larger, secondary text keeps at least 7:1 contrast on white,
  form labels are dark and semibold, and sizes use rem so browser zoom works.

  Brand: each committee sets its names, logo, four colors and font on Admin > Branding (branding/).
  brand.css, loaded after this file, sets the --brand-* colors and --font; the values here are the
  defaults. They follow the Troy Democratic Committee Design Foundations style guide: Democratic Blue,
  Deep Navy, Troy Red for action and urgency only, Gold as a single highlight, Montserrat (ExtraBold
  standing in for Franklin Gothic in headings), and WCAG AA contrast on all text. Party colors, the
  neutrals and the dark-mode surfaces are fixed: they mean the same thing for every committee.
*/

/* 1. Settings ------------------------------------------------------------------------------------- */
:root {
  --font: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --text-size: 1rem;          /* 16px */
  --text-small: .9375rem;     /* 15px: the smallest text on the site */
  --line: 1.55;

  /* Brand colors (Admin > Branding; brand.css replaces these). The shades are worked out from the four
     colors in branding/colors.py; these defaults are the hand-tuned TDC ones. */
  --brand-primary: #1a3a6b;            /* Democratic Blue: links, buttons, headings */
  --brand-primary-light: #2a5298;      /* Blue Light: hover, secondary */
  --brand-primary-mid: #3d6bc4;        /* dark mode: table headers, search bar */
  --brand-primary-tint: #9fbbea;       /* dark mode: links and buttons */
  --brand-primary-tint-hover: #c9d8f4;
  --brand-header: #0f2244;             /* Deep Navy: top bar, table headers */
  --brand-header-dark: #08142a;        /* dark mode top bar */
  --brand-action: #c8102e;             /* Troy Red: action and urgency only */
  --brand-action-bright: #e22643;      /* dark mode action (white text 4.6:1) */
  --brand-highlight: #c8a400;          /* Gold: one highlight (frequent voters) */

  /* Fixed colors, the same for every committee */
  --party-dem: #1a3a6b;
  --party-rep: #c8102e;
  --no-red: #a00c24;          /* errors and "no" answers */
  --theme-navy: #0f2244;      /* dark mode surfaces */
  --near-black: #1f2937;      /* body text */
  --charcoal: #2D3748;        /* softer text */
  --slate: #6b7280;           /* secondary marks, dividers */
  --light-gray: #e5e7eb;      /* backgrounds only */
  --off-white: #f4f6f9;       /* page background */
  --warm-white: #FAFAF7;

  --bg: var(--off-white);
  --surface: #ffffff;                   /* cards, tables, inputs */
  --surface-alt: var(--warm-white); /* striped table rows, table headers */
  --hover: var(--light-gray);       /* table row under the mouse */
  --text: var(--near-black);
  --heading: var(--brand-primary);
  --muted: var(--charcoal);         /* secondary text: 12:1 on white */
  --faint: #586070;                     /* de-emphasized marks, e.g. elections not voted in (4.5:1 on tints) */
  --border: var(--light-gray);
  --input-border: var(--slate);
  --accent: var(--brand-primary);            /* links, primary buttons */
  --accent-hover: var(--brand-header);
  --accent-text: #ffffff;
  --focus: var(--brand-primary-light);
  --action: var(--brand-action);             /* counts that need attention */
  --action-text: #ffffff;
  --header-bg: var(--brand-header);
  --header-text: #ffffff;
  --warn-bg: #ffffff;                   /* pending / open: white with a gold edge */
  --warn-border: var(--brand-highlight);
  --warn-text: var(--near-black);
  --highlight-bg: var(--brand-highlight);      /* frequent voters: near-black on gold, 7:1 */
  --highlight-text: var(--near-black);
  --error: var(--no-red);
  --success: var(--brand-primary);
  --yes: var(--brand-primary);
  --role-bg: var(--brand-primary-light);
  --role-text: #ffffff;
  --dem: var(--party-dem);
  --rep: var(--party-rep);
  --dem-bg: #dbe5f5;  --dem-text: #1a3a6b;   /* Democratic: blue */
  --rep-bg: #f9dde1;  --rep-text: #a00c24;   /* Republican: red */
  --wor-bg: #dcf0e1;  --wor-text: #1d6b33;   /* Working Families: green */
  --con-bg: #fdeba0;  --con-text: #5a4300;   /* Conservative: yellow */
  --badge-bg: var(--light-gray);
  --table-head-bg: var(--brand-header);     /* table style B1: header color, action-color rule, striped rows */
  --table-head-text: #ffffff;
  --table-sort-arrow: var(--brand-highlight);
  --search-border: var(--brand-header);     /* the joined-pill search bar and its button */
  --search-button-text: #ffffff;
  --filter-bg: #eef2f8;                 /* search filters: soft blue-gray panels */
  --filter-input-border: #c7d2e3;
  --table-rule: var(--brand-action);
  --table-stripe: #eef2f8;

  --radius: 8px;
  --gap: 1rem;
  --pad: 1.25rem;
}

/* Dark mode: the palette's navy as the background, with lighter tints where text needs contrast. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b1830;
    --surface: var(--theme-navy);
    --surface-alt: #132a52;
    --hover: var(--party-dem);
    --text: var(--off-white);
    --heading: #ffffff;
    --muted: var(--light-gray);
    --faint: #9aa3b2;
    --border: #23406e;
    --input-border: #7d8aa3;
    --accent: var(--brand-primary-tint);
    --accent-hover: var(--brand-primary-tint-hover);
    --accent-text: var(--theme-navy);
    --focus: var(--brand-primary-tint);
    --action: var(--brand-action-bright);
    --header-bg: var(--brand-header-dark);
    --warn-bg: var(--theme-navy);
    --warn-text: var(--off-white);
    --error: #ff8a99;
    --success: var(--brand-primary-tint);
    --yes: var(--brand-primary-tint);
    --role-bg: var(--brand-primary-tint);
    --role-text: var(--theme-navy);
    --dem: #9fbbea;
    --rep: #ff8a99;
    --dem-bg: #2f5aa6;  --dem-text: #ffffff;   /* brighter than the navy rows, so it doesn't blend in */
    --rep-bg: #5c1722;  --rep-text: #ffb8c1;
    --wor-bg: #1e4a2b;  --wor-text: #a6e8b7;
    --con-bg: #4a3c06;  --con-text: #ffe27a;
    --badge-bg: #1d3560;
    /* Rows are navy here, so the header goes darker (like the top bar) and stripes go lighter. */
    --search-border: var(--brand-primary-mid);           /* mid blue: a navy border would vanish on the navy page */
    --search-button-text: #ffffff;
    --filter-bg: #132a52;
    --filter-input-border: #2f4f82;
    /* Table headers match the Search button: mid blue with white text, as in light mode they're both navy. */
    --table-head-bg: var(--search-border);
    --table-head-text: var(--search-button-text);
    --table-sort-arrow: var(--brand-highlight);
    --table-rule: var(--brand-action-bright);
    --table-stripe: #132a52;
  }
}

/* 2. Base ----------------------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--text-size);
  line-height: var(--line);
}
h1, h2 { font-weight: 800; color: var(--heading); letter-spacing: -.01em; }
h1 { font-size: 1.75rem; line-height: 1.2; margin: 0 0 .35rem; }
h2 { font-size: 1.15rem; line-height: 1.3; margin: 0 0 .85rem; }
p { margin: 0 0 .75rem; }
a { color: var(--accent); text-underline-offset: .15em; }
a:hover { color: var(--accent-hover); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.muted { color: var(--muted); }
.small { font-size: var(--text-small); }
.error { color: var(--error); font-weight: 600; }

/* 3. Layout --------------------------------------------------------------------------------------- */
main { padding: 1.25rem; max-width: 1440px; margin: 0 auto; }

.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: .6rem 1.25rem; background: var(--header-bg); color: var(--header-text);
  border-bottom: 4px solid var(--brand-action);
}
.topbar .brand { display: flex; align-items: center; gap: .6rem; font-size: 1.15rem; font-weight: 800; text-decoration: none; color: var(--header-text); }
.topbar .brand img { width: 40px; height: 40px; border-radius: 50%; background: #fff; flex: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-org { font-size: .82rem; font-weight: 600; letter-spacing: .02em; opacity: .9; }
.brand-app { font-size: 1.15rem; font-weight: 800; }
.topbar { position: relative; }
.topbar-tools { display: flex; align-items: center; gap: .75rem; }
.quick-search input { width: 15rem; padding: .45rem .7rem; border-radius: 999px; border: 0; }
.menu-button { display: inline-flex; align-items: center; gap: .5rem; background: transparent; color: var(--header-text);
  border: 2px solid rgba(255,255,255,.55); border-radius: var(--radius); padding: .45rem .9rem; font-weight: 700; }
.menu-button:hover, .menu-button[aria-expanded="true"] { background: rgba(255,255,255,.12); color: var(--header-text); }
.menu-icon, .menu-icon::before, .menu-icon::after { display: block; width: 1.1rem; height: 2px; background: currentColor; border-radius: 2px; position: relative; }
.menu-icon::before, .menu-icon::after { content: ""; position: absolute; left: 0; }
.menu-icon::before { top: -6px; }
.menu-icon::after { top: 6px; }
.site-menu { position: absolute; top: 100%; right: 1.25rem; z-index: 1000; margin-top: 4px;
  display: grid; grid-template-columns: 1fr; gap: .55rem; width: 17rem;
  max-height: calc(100vh - 5rem); overflow-y: auto;
  background: var(--surface); color: var(--text); border: 1px solid var(--border); border-top: 4px solid var(--brand-action);
  border-radius: 0 0 var(--radius) var(--radius); box-shadow: 0 12px 28px rgba(15,34,68,.25); padding: .8rem 1rem; }
.site-menu[hidden] { display: none; }
.site-menu h2 { font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin: 0 0 .2rem; }
.site-menu section { display: grid; gap: .1rem; align-content: start; }
.site-menu section + section { border-top: 1px solid var(--border); padding-top: .5rem; }
.site-menu a, .site-menu button.link { display: block; padding: .28rem .5rem; border-radius: 6px; color: var(--heading); font-weight: 600; text-decoration: none; text-align: left; }
.site-menu a:hover, .site-menu button.link:hover { background: var(--hover); color: var(--heading); text-decoration: none; }
.site-menu a[aria-current="page"] { background: var(--badge-bg); box-shadow: inset 3px 0 0 var(--brand-action); }
.site-menu form { margin: 0; }
@media (max-width: 700px) {
  .quick-search { display: none; }
  .topbar { flex-wrap: nowrap; padding: .5rem .75rem; gap: .5rem; }
  .topbar .brand { gap: .45rem; min-width: 0; }
  .topbar .brand img { width: 34px; height: 34px; }
  .brand-org { font-size: .68rem; }
  .brand-app { font-size: 1rem; }
  .menu-button { padding: .4rem .6rem; flex: none; }
  .site-menu { right: 0; left: 0; width: auto; border-radius: 0; }
}

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--pad); margin-bottom: var(--gap);
}
.card.narrow { max-width: 400px; margin: 3rem auto; }
.row { display: flex; gap: .6rem; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.row input { flex: 1; }
.stack { display: grid; gap: .9rem; }
.inline { display: inline; margin: 0; }
ul.plain { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }

/* 4. Forms and buttons ---------------------------------------------------------------------------- */
label { display: grid; gap: .3rem; font-weight: 600; color: var(--text); }
input, select, textarea {
  font: inherit; font-weight: 400; color: var(--text); background: var(--surface);
  border: 1px solid var(--input-border); border-radius: 6px; padding: .55rem .7rem; width: 100%;
}
textarea { resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 3px solid var(--focus); outline-offset: 0; border-color: var(--focus); }
input[type="checkbox"], input[type="radio"] { width: 1.15rem; height: 1.15rem; padding: 0; margin: 0; accent-color: var(--accent); flex: none; }
label.check { display: flex; align-items: center; gap: .55rem; font-weight: 400; cursor: pointer; }

button, .button {
  font: inherit; font-weight: 600; border: 1px solid var(--input-border); border-radius: 6px;
  padding: .55rem 1rem; background: var(--surface); color: var(--text); cursor: pointer;
  text-decoration: none; display: inline-block; line-height: 1.3;
}
button:hover, .button:hover { background: var(--surface-alt); }
button.primary { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
button.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
button.link {
  background: none; border: 0; padding: 0; color: var(--accent); font-weight: 500;
  text-decoration: underline; text-underline-offset: .15em;
}

/* 5. Tables --------------------------------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.card .table-wrap { border: 0; border-radius: 0; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: .65rem .8rem; border-bottom: 1px solid var(--border); vertical-align: top; }
/* Table style B1 (decided 2026-10-23): navy header with a Troy Red rule, like the top bar; striped rows. */
thead th {
  font-weight: 700; color: var(--table-head-text); background: var(--table-head-bg);
  border-bottom: 3px solid var(--table-rule); white-space: nowrap;
}
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
tbody tr:nth-child(even) { background: var(--table-stripe); }
table.voters tbody tr:hover { background: var(--hover); }
/* One line per voter: on narrow screens the table scrolls sideways inside .table-wrap instead. */
table.voters td, table.voters th { white-space: nowrap; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td a { font-weight: 600; text-decoration: none; }
td a:hover { text-decoration: underline; }

/* 6. Badges, tags, counts, messages --------------------------------------------------------------- */
.badge, .party {
  display: inline-block; padding: .15rem .6rem; border-radius: 999px; font-size: var(--text-small);
  background: var(--badge-bg); color: var(--text); white-space: nowrap; line-height: 1.4;
}
.badge.warn { background: var(--warn-bg); color: var(--warn-text); box-shadow: inset 0 0 0 2px var(--warn-border); font-weight: 600; text-decoration: none; }
.party { font-weight: 700; }
/* Party pills: each party's color as a tint, with dark text of the same color. BLK stays gray. */
.party-dem { background: var(--dem-bg); color: var(--dem-text); }
.party-rep { background: var(--rep-bg); color: var(--rep-text); }
.party-wor { background: var(--wor-bg); color: var(--wor-text); }
.party-con { background: var(--con-bg); color: var(--con-text); }
.badges { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: .65rem; }
.tag {
  display: inline-block; padding: .1rem .6rem; border-radius: 4px; font-size: var(--text-small);
  border: 1px solid var(--accent); color: var(--accent); white-space: nowrap; line-height: 1.4;
}
.count {
  display: inline-block; min-width: 1.6em; padding: 0 .45em; border-radius: 999px; text-align: center;
  background: var(--action); color: var(--action-text); font-size: .875rem; font-weight: 700; line-height: 1.5;
}
.messages { list-style: none; padding: 0; margin: 0 0 var(--gap); display: grid; gap: .5rem; }
.message {
  padding: .7rem 1rem; border-radius: 6px; background: var(--surface);
  border: 1px solid var(--border); border-left-width: 5px; font-weight: 500;
}
.message.success { border-left-color: var(--success); }
.message.info { border-left-color: var(--accent); }
.message.error { border-left-color: var(--error); color: var(--error); }

/* 7. Search page ---------------------------------------------------------------------------------- */
/* Search on top (basic fields in a row, Advanced search folded away), results below. */
.search-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.search-layout > * { min-width: 0; }
.filters { display: grid; gap: .9rem; }
/* The big search box: one field for a name, Voter Id or address, with its own Search button. */
/* Joined pill (decided 2026-10-23): the box and button are one rounded bar with a thick navy border. */
.search-box {
  display: flex; border: 3px solid var(--search-border); border-radius: 999px; overflow: hidden;
  background: var(--surface);
}
.search-box:focus-within { box-shadow: 0 0 0 3px var(--focus); }
.search-box input[type="search"] {
  flex: 1; min-width: 0; font-size: 1.15rem; padding: .85rem 1rem .85rem 3rem; border: 0; border-radius: 0;
  background: var(--surface) no-repeat 1.2rem center / 1.2rem 1.2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-4-4'/%3E%3C/svg%3E");
}
.search-box input[type="search"]:focus { outline: none; box-shadow: none; }
.search-box button.primary {
  font-size: 1.05rem; padding: .85rem 1.8rem; border: 0; border-radius: 0;
  background: var(--search-border); color: var(--search-button-text);
}
.search-box button.primary:hover { background: var(--accent-hover); color: var(--accent-text); }
@media (max-width: 600px) { .search-box button.primary { padding: .85rem 1.1rem; } }
/* Apply filters and Clear all (button option 2): a solid pill like the Search button, and a light outlined pill. */
.search-actions { align-items: center; gap: .75rem; }
button.pill-button, a.pill-link {
  border-radius: 999px; padding: .55rem 1.4rem; font-weight: 700; text-decoration: none; display: inline-block;
}
button.pill-button { border: 2px solid var(--search-border); background: var(--search-border); color: var(--search-button-text); }
button.pill-button:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-text); }
a.pill-link { border: 2px solid var(--border); color: var(--text); background: transparent; }
a.pill-link:hover { border-color: var(--search-border); background: var(--surface-alt); }
.search-basic { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .9rem; align-items: start; }
.search-advanced { border-top: 1px solid var(--border); padding-top: .75rem; }
.search-advanced > summary { cursor: pointer; font-weight: 700; color: var(--heading); }
.search-advanced > summary .muted { font-weight: 400; margin-left: .4rem; }
.search-group { margin-top: 1rem; }
.search-group h3 { font-size: 1rem; margin: 0 0 .5rem; color: var(--heading); }

/* Filter style C (decided 2026-10-23): soft tinted panels, small uppercase labels, rounded white inputs,
   and party checkboxes in each party's color. */
.search-basic, .search-group { background: var(--filter-bg); border-radius: var(--radius); padding: .9rem 1rem; }
.search-basic > label, .search-basic legend, .search-grid > label, .search-grid legend, .search-grid .stack > label,
.search-grid fieldset > label:not(.check) {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading);
}
.search-basic > label > *, .search-grid > label > *, .search-grid .stack > label > *,
.search-grid fieldset > label:not(.check) > * {
  font-size: 1rem; font-weight: 400; text-transform: none; letter-spacing: normal; margin-top: .3rem;
}
.search-basic label.check, .search-grid label.check { font-size: var(--text-small); font-weight: 600; text-transform: none; letter-spacing: normal; }
.search-basic select, .search-basic input:not([type="checkbox"]), .search-grid select,
.search-grid input:not([type="checkbox"]):not([type="radio"]) {
  background: var(--surface); border: 1px solid var(--filter-input-border); border-radius: var(--radius);
}
.search-grid .checklist-box { background: var(--surface); border-color: var(--filter-input-border); }
.party-check-dem input { accent-color: var(--dem); }
.party-check-rep input { accent-color: var(--party-rep); }
.party-check-wor input { accent-color: var(--wor-text); }
.party-check-con input { accent-color: #b08a00; }
.party-check-blk input { accent-color: var(--slate); }
.party-check-dem { color: var(--dem); }
.party-check-rep { color: var(--rep-text); }
.party-check-wor { color: var(--wor-text); }
.party-check-con { color: var(--con-text); }
.search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: .9rem; align-items: start; }
/* No wrapped labels (2026-10-23): long items get a full row, and lists of checkboxes lay out in columns
   across it, instead of squeezing into one narrow cell. */
.search-grid > fieldset.checklist, .search-grid > label.check, .search-grid > .stack { grid-column: 1 / -1; }
.search-grid > label.check { flex-wrap: wrap; column-gap: .55rem; }
.search-grid .checklist-box { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); column-gap: 1.25rem; }
.search-grid .check-columns { columns: 3 15rem; width: 100%; }
.search-grid > .stack { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr)); gap: .9rem; }
.search-grid > fieldset.checklist:not(.wide-field) { display: flex; flex-wrap: wrap; gap: .4rem 1.25rem; }
.search-grid > fieldset.checklist:not(.wide-field) legend { width: 100%; }
.search-grid label.check, .search-basic label.check { white-space: nowrap; }
.search-advanced > summary .muted { display: block; margin: .2rem 0 0 1.15rem; }
/* On phones, give the labels more room by trimming the panels' side padding. */
@media (max-width: 600px) {
  .filters.card { padding-left: .75rem; padding-right: .75rem; }
  .search-basic, .search-group { padding-left: .7rem; padding-right: .7rem; }
}
.filters h2 { margin-bottom: .25rem; }
.filters .helptext { display: none; }
.summary { margin: 0 0 .85rem; font-size: 1.05rem; }

/* Sortable column headings: click to sort, click again to reverse. */
thead th a.sort { color: inherit; font-weight: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: .3rem; }
thead th a.sort:hover { color: var(--table-head-text); text-decoration: underline; }
.sort-arrow { font-size: .8em; color: var(--faint); }
thead .sort-arrow { color: var(--table-head-text); opacity: .65; }
thead th[aria-sort] .sort-arrow { color: var(--table-sort-arrow); opacity: 1; }
thead th[aria-sort] { color: var(--table-head-text); }
.summary strong { font-size: 1.2rem; }

fieldset.checklist { border: 0; padding: 0; margin: 0; display: grid; gap: .5rem; min-width: 0; }
fieldset.checklist legend { font-weight: 600; padding: 0; margin-bottom: .3rem; }
.checklist-box {
  max-height: 15rem; overflow-y: auto; border: 1px solid var(--input-border); border-radius: 6px;
  padding: .35rem .6rem; background: var(--surface); display: grid; gap: .1rem;
}
.checklist-box label.check { padding: .25rem 0; }

.pager { display: flex; gap: 1.25rem; align-items: center; justify-content: center; margin: 1.25rem 0; }
.pager a { font-weight: 600; }

/* 8. Voter page ----------------------------------------------------------------------------------- */
.voter-head h1 { font-size: 2rem; }
.address { margin: 0; color: var(--muted); font-size: 1.1rem; }
.committee-grid, .detail-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap); margin-bottom: var(--gap);
}
.committee-grid .card, .detail-grid .card { margin-bottom: 0; }
dl { display: grid; grid-template-columns: max-content 1fr; gap: .45rem 1.25rem; margin: 0; }
dt { color: var(--muted); }
dd { margin: 0; overflow-wrap: anywhere; font-weight: 500; }

.tag-list { list-style: none; padding: 0; margin: 0 0 .9rem; display: flex; flex-wrap: wrap; gap: .5rem 1rem; }
.tag-list li { display: flex; align-items: center; gap: .4rem; }
td .tag { margin: 0 .25rem .25rem 0; }
.note-list { list-style: none; padding: 0; margin: 1rem 0 0; display: grid; gap: .75rem; max-height: 24rem; overflow-y: auto; }
.note-list li { border-top: 1px solid var(--border); padding-top: .65rem; }
.note-list p { margin: 0 0 .25rem; }

table.history td { white-space: nowrap; }
.vote { display: inline-block; margin-right: .75rem; font-variant-numeric: tabular-nums; }
.vote.yes { color: var(--yes); font-weight: 700; }
.vote.no { color: var(--faint); }

/* 9. Review queue --------------------------------------------------------------------------------- */
.tabs { display: flex; gap: .25rem; margin: .5rem 0 1.25rem; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.tabs a {
  padding: .55rem 1rem; text-decoration: none; color: var(--muted); font-weight: 500;
  border-bottom: 3px solid transparent; margin-bottom: -1px;
}
.tabs a[aria-current="page"] { color: var(--text); border-bottom-color: var(--accent); font-weight: 700; }
.kind-link {
  display: flex; justify-content: space-between; align-items: center; gap: .75rem;
  padding: .5rem .65rem; border-radius: 6px; text-decoration: none; color: var(--text);
}
.kind-link:hover { background: var(--hover); color: var(--text); }
.kind-link.current { background: var(--badge-bg); font-weight: 700; }

/* 10. Small screens and printing ------------------------------------------------------------------ */
@media (max-width: 800px) {
  main { padding: 1rem 16px; }
  .voter-head h1 { font-size: 1.6rem; }
}

@media print {
  body { background: #fff; color: #000; font-size: 11pt; }
  .topbar, .filters, .pager, .messages, form, button { display: none !important; }
  .search-layout { display: block; }
  .card, .table-wrap { border: 0; padding: 0; }
  a { color: #000; text-decoration: none; }
  /* On paper: a light header (no solid navy ink), tighter rows, faint stripes. */
  thead th { background: #e5e7eb !important; color: #000 !important; border-bottom: 2px solid #000 !important; box-shadow: none !important; }
  th, td { padding: .3rem .45rem; }
  tbody tr:nth-child(even) { background: #f2f2f2; }
}

/* One-click actions in the review queue, and the kept record in a duplicate pair. */
.action-cell { white-space: nowrap; }
button.small-button { padding: .35rem .8rem; }
.card.keeper { border: 2px solid var(--success); }
.banner {
  padding: .8rem 1rem; border-radius: var(--radius); margin-bottom: var(--gap);
  background: var(--warn-bg); color: var(--warn-text); border: 1px solid var(--border); border-left: 5px solid var(--warn-border);
  display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; justify-content: space-between;
}
.banner a { color: inherit; font-weight: 700; }

/* --- Two-step login, imports --- */
.card.narrow.wide { max-width: 560px; }
ol.steps { padding-left: 1.4rem; display: grid; gap: 1.1rem; margin: 1rem 0 0; }
.qr { margin: .75rem 0; width: 220px; max-width: 100%; background: #fff; padding: .5rem; border-radius: var(--radius); border: 1px solid var(--border); }
.qr svg { display: block; width: 100%; height: auto; }
code.secret { display: inline-block; font-size: 1rem; letter-spacing: .05em; padding: .15rem .4rem; background: var(--badge-bg); border-radius: 4px; word-break: break-all; }
.backup-codes { list-style: none; padding: 0; margin: 1rem 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
.backup-codes code { display: block; font-size: 1.15rem; letter-spacing: .08em; padding: .45rem .6rem; background: var(--badge-bg); border-radius: 6px; text-align: center; }
a.primary-link { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
a.primary-link:hover { background: var(--accent-hover); color: var(--accent-text); }
.upload-form input[type="file"] { padding: .45rem; }
@media print { .backup-codes code { border: 1px solid #000; } }

/* --- Likely-voter score and roles --- */
.role {
  display: inline-block; padding: .1rem .6rem; border-radius: 4px; font-size: var(--text-small);
  background: var(--role-bg); color: var(--role-text); white-space: nowrap; line-height: 1.4; margin: 0 .25rem .25rem 0;
}
.star { display: inline-block; background: var(--highlight-bg); color: var(--highlight-text); border-radius: 4px; padding: 0 .25rem; font-size: .85em; line-height: 1.4; }
.score-badge { text-decoration: none; font-weight: 600; }
.score-badge.frequent { background: var(--highlight-bg); color: var(--highlight-text); }
.score-list { list-style: none; padding: 0; margin: .5rem 0; columns: 2 18rem; column-gap: 2rem; }
.score-list li { padding: .15rem 0; break-inside: avoid; }
.score-list li.yes { color: var(--yes); font-weight: 600; }
.score-list li.no { color: var(--faint); }
.roles-table th[scope="row"] { font-weight: 600; white-space: nowrap; }
.roles-table input[type="date"] { min-width: 10rem; }
.roles-table td { vertical-align: middle; }
strong.yes { color: var(--yes); }
.sr-label { font-weight: 400; color: var(--muted); font-size: var(--text-small); }
.lede { font-size: 1.05rem; max-width: 60rem; }
.settings-form fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; margin: 0 0 1rem; display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.settings-form legend { font-weight: 700; padding: 0 .4rem; }
.settings-form input[type="number"] { max-width: 8rem; }

/* Branding page: the settings beside a live preview. The preview uses the --brand-* properties set on it,
   so it shows unsaved colors; its light and dark panels use fixed page colors like the real site. */
.branding-layout { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr) minmax(0, 24rem); align-items: start; }
@media (max-width: 960px) { .branding-layout { grid-template-columns: minmax(0, 1fr); } }
.branding-fields .card { margin-bottom: 1rem; }
.branding-current { grid-column: 1 / -1; display: flex; align-items: center; gap: 1rem; }
.branding-current img { border: 1px solid var(--border); }
.branding-current p { margin: 0; }
/* Committee settings: the map that sets where every map opens, with a crosshair on its center. */
.map-settings .map-intro, .settings-form .fieldset-intro { grid-column: 1 / -1; margin: 0; }
/* Each field takes three rows of its fieldset (name, box, notes), so boxes in a row line up even when a name wraps. */
.settings-form label.field { grid-row: span 3; grid-template-rows: subgrid; row-gap: .3rem; align-content: start; }
/* A section's only field (voter file layout, reply-to) gets room for its long choices and notes. */
.settings-form label.field.wide { grid-column: 1 / -1; max-width: 34rem; }
main .settings-form label.field > .field-name { font: inherit; text-transform: inherit; letter-spacing: inherit; color: inherit; align-self: end; }
main .settings-form label.field > .field-notes { display: grid; gap: .2rem; align-content: start; }
.area-map { grid-column: 1 / -1; height: 340px; border-radius: var(--radius); border: 1px solid var(--border); position: relative; }
.area-map::after { content: ""; position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
  border: 3px solid var(--brand-action); border-radius: 50%; z-index: 500; pointer-events: none; box-shadow: 0 0 0 2px #fff; }
.color-pick { display: flex; align-items: center; gap: .6rem; }
.color-pick input[type="color"] { width: 3.25rem; height: 2.5rem; padding: .15rem; flex: none; cursor: pointer; }
.color-hex { font-family: ui-monospace, Consolas, monospace; font-weight: 600; }
.contrast-checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.contrast-checks li { display: grid; grid-template-columns: 2.6rem minmax(0, 1fr) auto; gap: .6rem; align-items: center; }
.contrast-checks .swatch { display: inline-block; text-align: center; font-weight: 800; border-radius: 6px; padding: .15rem 0; border: 1px solid var(--border); }
.contrast-checks li.fail strong { color: var(--error); }
.branding-preview { position: sticky; top: 1rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--pad); display: grid; gap: .8rem; }
.branding-preview h2 { font-family: var(--font); }
.bp { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.bp-mode { margin: 0; padding: .25rem .6rem; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; background: var(--badge-bg); color: var(--muted); }
.bp-topbar { display: flex; align-items: center; gap: .5rem; padding: .45rem .6rem; color: #fff; background: var(--brand-header); border-bottom: 3px solid var(--brand-action); }
.bp-logo { border-radius: 50%; background: #fff; flex: none; object-fit: contain; }
.bp-name { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; flex: 1; }
.bp-org { font-size: .68rem; font-weight: 600; opacity: .9; }
.bp-app { font-weight: 800; }
.bp-count { background: var(--brand-action); color: #fff; font-weight: 700; font-size: .8rem; padding: 0 .45rem; border-radius: 999px; }
.bp-page { padding: .6rem; background: #f4f6f9; color: #1f2937; display: grid; gap: .45rem; justify-items: start; }
.bp-page p { margin: 0; }
.bp-heading { font-weight: 800; font-size: 1.05rem; color: var(--brand-primary); }
.bp-link { color: var(--brand-primary); text-decoration: underline; font-weight: 600; }
.bp-highlight { background: var(--brand-highlight); color: #1f2937; font-weight: 700; font-size: .8rem; padding: .05rem .45rem; border-radius: 999px; }
.bp-button { background: var(--brand-primary); color: #fff; font-weight: 700; padding: .3rem .9rem; border-radius: 6px; }
.bp-table { border-collapse: collapse; width: 100%; font-size: .85rem; background: #fff; }
.bp-table th { background: var(--brand-header); color: #fff; text-align: left; padding: .25rem .5rem; border-bottom: 2px solid var(--brand-action); }
.bp-table td { padding: .25rem .5rem; border-bottom: 1px solid #e5e7eb; }
.bp-table tbody tr:nth-child(even) { background: #eef2f8; }
.bp-dark .bp-topbar { background: var(--brand-header-dark); border-bottom-color: var(--brand-action-bright); }
.bp-dark .bp-count { background: var(--brand-action-bright); }
.bp-dark .bp-page { background: #0b1830; color: #f4f6f9; }
.bp-dark .bp-heading { color: #fff; }
.bp-dark .bp-link { color: var(--brand-primary-tint); }
.bp-dark .bp-button { background: var(--brand-primary-tint); color: #0f2244; }
.bp-dark .bp-table { background: #0f2244; }
.bp-dark .bp-table th { background: var(--brand-primary-mid); border-bottom-color: var(--brand-action-bright); }
.bp-dark .bp-table td { border-bottom-color: #23406e; }
.bp-dark .bp-table tbody tr:nth-child(even) { background: #132a52; }
.bp-pair { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.bp-login { background: #fff; color: #1f2937; border: 1px solid #e5e7eb; border-top: 5px solid var(--brand-primary); border-radius: var(--radius); padding: .7rem; text-align: center; display: grid; justify-items: center; gap: .2rem; }
.bp-login p { margin: 0; }
.bp-login .bp-org { font-size: .7rem; }
.bp-login .bp-app { color: var(--brand-primary); font-size: .9rem; }
.bp-phone { border: 1px solid var(--border); border-radius: 14px; overflow: hidden; background: #f4f6f9; color: #1f2937; align-self: start; }
.bp-phone-bar { display: flex; align-items: center; gap: .4rem; padding: .4rem .5rem; background: var(--brand-header); color: #fff; font-weight: 700; font-size: .85rem; border-bottom: 3px solid var(--brand-action); }
.bp-phone-name { margin: 0; padding: .5rem; font-size: .8rem; font-weight: 600; }
/* On narrow screens each role becomes a small stacked card, so the Add/Save buttons stay in view. */
@media (max-width: 900px) {
  .roles-table thead { display: none; }
  .roles-table, .roles-table tbody, .roles-table tr, .roles-table th, .roles-table td { display: block; width: 100%; }
  .roles-table tr { border-bottom: 1px solid var(--border); padding: .6rem 0; }
  .roles-table th[scope="row"], .roles-table td { border: 0; padding: .25rem .2rem; }
  .roles-table th[scope="row"] { white-space: normal; }
  .roles-table input[type="date"], .roles-table input[type="text"] { width: 100%; }
}

/* --- Reports --- */
.report-filters .filter-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .9rem; margin-bottom: 1rem; }
.report-totals dl { gap: .3rem 1rem; }
.report-totals dd { text-align: right; font-variant-numeric: tabular-nums; }
@media print {
  .report-filters, .print-only-hide, .print-note { display: none !important; }
  .report-totals { grid-template-columns: repeat(4, 1fr); gap: .5rem; }
  .report-totals .card { border: 1px solid #999; padding: .4rem; }
  table.voters td, table.voters th { padding: .2rem .35rem; font-size: 9.5pt; }
}
.role.past { background: var(--badge-bg); color: var(--muted); border: 1px solid var(--border); }
.roles-table tr.role-continued th, .roles-table tr.role-continued td { border-top: 0; }
.roles-table tr.role-past input[type="text"] { color: var(--muted); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* --- Sign-in screens (password and two-step): the TDC seal above the form, on phones and desktops --- */
.auth-brand { text-align: center; margin-bottom: 1.25rem; }
.auth-brand img { width: 140px; height: 140px; display: block; margin: 0 auto .75rem; }
.auth-brand .org { font-weight: 800; color: var(--heading); font-size: 1.05rem; line-height: 1.3; margin: 0; }
.auth-brand .app { color: var(--muted); margin: .15rem 0 0; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; font-size: .85rem; }
.card.auth { max-width: 420px; margin: 2.5rem auto; padding: 2rem 1.75rem; border-top: 6px solid var(--brand-primary); }
.card.auth h1 { text-align: center; font-size: 1.4rem; }
.card.auth button.primary { width: 100%; padding: .75rem 1rem; font-size: 1.05rem; }
@media (max-width: 480px) {
  .card.auth { margin: 1rem auto; padding: 1.5rem 1.1rem; }
  .auth-brand img { width: 112px; height: 112px; }
}
.card.auth.wide { max-width: 560px; }
/* "Powered by CaucusIQ" (branding/product.py): the product's name, kept small under the committee's. */
.auth-brand .powered { color: var(--muted); font-size: .8rem; margin: .5rem 0 0; }
.site-foot { max-width: 1440px; margin: 0 auto; padding: .5rem 1.25rem 1.5rem; color: var(--muted); font-size: .8rem; text-align: center; }
/* Terms of use (accounts/terms.py). */
.terms-text h2 { font-size: 1.05rem; margin: 1.25rem 0 .4rem; }
.terms-text ul { padding-left: 1.25rem; }
.terms-text li { margin: .3rem 0; }
.card.auth .terms-decline { display: block; margin: .75rem auto 0; }
.card.auth.wide h1 { text-align: center; }

/* Collapsible cards (roles on the voter page): the heading is the button. */
details.collapsible > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem; }
details.collapsible > summary::-webkit-details-marker { display: none; }
details.collapsible > summary::before { content: "▸"; color: var(--accent); font-size: 1.1rem; transition: transform .15s; }
details.collapsible[open] > summary::before { transform: rotate(90deg); }
details.collapsible > summary h2 { margin: 0; }
details.collapsible[open] > summary { margin-bottom: .85rem; }
.login-badge { background: var(--brand-header); color: #fff; }
.login-actions { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; margin-top: .75rem; }
.banner.reset-link { margin-top: .9rem; align-items: flex-end; }
.banner.reset-link > div { flex: 1; min-width: 14rem; }
.banner.reset-link p { margin: .2rem 0 .5rem; }
.banner.reset-link input { font-family: ui-monospace, Consolas, monospace; font-size: .9rem; }

/* --- Canvassing (Phase 3) --- */
.canvass-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.5rem; }
.canvass-grid h3 { font-size: 1rem; font-weight: 800; color: var(--heading); margin: 0 0 .6rem; }
.canvass-grid h3 + p, .canvass-grid ul + h3 { margin-top: 1.1rem; }
.contact-form .two-up > label { flex: 1; min-width: 10rem; }
.support-fields { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; margin: 0; display: grid; gap: .6rem; }
.support-fields legend { font-weight: 700; padding: 0 .3rem; }
.support-fields.dimmed { opacity: .5; }
.support { display: inline-block; padding: .1rem .55rem; border-radius: 999px; font-size: var(--text-small); font-weight: 700; white-space: nowrap; }
.support.tiny { font-size: .8rem; padding: 0 .45rem; margin: .15rem .25rem 0 0; }
.support-1 { background: var(--brand-primary); color: #fff; }          /* Strong yes */
.support-2 { background: var(--brand-primary-light); color: #fff; }    /* Lean yes */
.support-3 { background: var(--light-gray); color: var(--near-black); } /* Undecided */
.support-4 { background: #fbe4e7; color: var(--no-red); }  /* Lean no */
.support-5 { background: var(--no-red); color: #fff; }      /* Strong no */
.support-list li, .contact-list li { padding: .35rem 0; border-bottom: 1px solid var(--border); }
.contact-list { max-height: 22rem; overflow-y: auto; }
.sign-list li { padding: .5rem 0; border-bottom: 1px solid var(--border); }
.sign-list form { margin-top: .35rem; }
details.add-sign { margin-top: .75rem; }
details.add-sign summary { cursor: pointer; font-weight: 700; color: var(--accent); }
details.add-sign form { margin-top: .75rem; }
@media (max-width: 800px) { .canvass-grid { grid-template-columns: minmax(0, 1fr); } }
.count-plain { color: var(--faint); font-weight: 500; }
tr.sub-row td { padding-top: .25rem; padding-bottom: .25rem; border-bottom-style: dashed; }

/* --- Map and turfs ------------------------------------------------------------------------------ */
.map-layout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.map-side h2 { margin-top: 1.25rem; }
.map { height: calc(100vh - 13rem); min-height: 420px; border: 1px solid var(--border); border-radius: var(--radius); z-index: 0; }
.map.short { height: 420px; margin-top: .9rem; }
.map-legend { list-style: none; padding: 0; margin: .9rem 0 0; display: flex; flex-wrap: wrap; gap: .35rem 1rem; font-size: var(--text-small); }
.dot { display: inline-block; width: .8rem; height: .8rem; border-radius: 50%; margin-right: .35rem; vertical-align: -1px; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
ul.map-popup { margin: .35rem 0 0; padding-left: 1.1rem; }
.summary-actions { display: inline-flex; gap: .5rem; flex-wrap: wrap; margin-left: .75rem; vertical-align: middle; }
a.button.small-button, .summary-actions button.small-button { padding: .3rem .75rem; font-size: var(--text-small); }
.check-row { display: flex; flex-wrap: wrap; gap: .35rem 1rem; }
.meter { height: .7rem; background: var(--surface-alt); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.meter span { display: block; height: 100%; background: var(--success); }
.progress-line { font-size: 1.1rem; margin-bottom: .4rem; }
tr.street-row th { background: var(--badge-bg); font-weight: 700; }
@media (max-width: 900px) { .map-layout { grid-template-columns: 1fr; } .map { height: 70vh; } }
@media print {
  .topbar, .no-print, .messages { display: none !important; }
  .walk-list { border: 0; padding: 0; }
  table.voters td, table.voters th { padding: .25rem .4rem; }
}
dl.signup-record { background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; }
.leaflet-container path.turf-shape { cursor: move; }
.leaflet-marker-icon.shape-handle { display: flex; align-items: center; justify-content: center; border-radius: 50%; background: #fff; color: var(--brand-primary); border: 2px solid var(--brand-primary); font-size: 15px; font-weight: 700; line-height: 1; box-shadow: 0 1px 4px rgba(0,0,0,.35); cursor: grab; }
.leaflet-marker-icon.shape-handle-size { cursor: nwse-resize; }

/* --- About section (voter page) --------------------------------------------------------------- */
.about { margin: 1.25rem 0; }
.about .section-heading { margin-bottom: .2rem; }
.about-grid { margin-top: .75rem; }
.about-grid h3 { margin: 0 0 .6rem; font-size: 1.05rem; }
.about-list li { padding: .5rem 0; border-bottom: 1px solid var(--border); display: grid; gap: .2rem; }
.about-list li.row { display: flex; justify-content: space-between; }
.about-list .small-form { margin-top: .2rem; gap: .9rem; }
.add-form { margin-top: .75rem; }
.add-form summary { cursor: pointer; font-weight: 600; color: var(--accent); }
.add-form[open] summary { margin-bottom: .6rem; }
.about-fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; margin: 0; display: grid; gap: .6rem; }
.about-fieldset legend { font-weight: 700; padding: 0 .3rem; }
.check-columns { columns: 2 12rem; column-gap: 1.25rem; }
.check-columns label.check { padding: .2rem 0; break-inside: avoid; }
input.short-input { max-width: 11rem; }
.preferred-name { font-weight: 600; color: var(--muted); }
.about-grid .two-up > label { flex: 1; min-width: 10rem; }

/* --- List imports ------------------------------------------------------------------------------ */
.columns-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: .9rem; }
.inline-heading { display: inline; margin: 0; }
details > summary { cursor: pointer; }
fieldset.review-row { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; margin: 0 0 .75rem; display: grid; gap: .45rem; }
fieldset.review-row legend { padding: 0 .3rem; }
fieldset.review-row label.check { align-items: flex-start; }

/* --- Buildings --------------------------------------------------------------------------------- */
.filters-inline label { display: flex; align-items: center; gap: .45rem; }
table.buildings td { vertical-align: middle; white-space: normal; }
.building-form { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.building-form input[name="name"] { width: 14rem; }
.building-form .wide-input { flex: 1; min-width: 16rem; }
.building-name { font-weight: 700; color: var(--heading); }
.building-note { color: var(--muted); font-size: var(--text-small); }
tr.building-row th { background: var(--surface-alt); font-weight: 600; }
.contact-pick { display: flex; flex-wrap: wrap; gap: .4rem; width: 100%; }
.contact-pick select { max-width: 22rem; }
.badge.contact-badge { background: var(--brand-primary-light); color: #fff; text-decoration: none; }

/* --- Committee members ------------------------------------------------------------------------- */
table.seats-table td, table.seats-table th { white-space: normal; vertical-align: top; }
table.seats-table td.seat { width: 40%; }
td.seat.open { background: var(--warn-bg); box-shadow: inset 3px 0 0 var(--warn-border); }
.open-seat { font-weight: 700; color: var(--muted); }
tr.over-row td { background: #fbe4e7; color: var(--no-red); font-size: var(--text-small); }
table.committee-table td { white-space: normal; }
.seat-fill { margin-top: .35rem; gap: .35rem; }
.seat-fill input { min-width: 0; flex: 1; padding: .35rem .5rem; }
.seat-action { margin-top: .3rem; }
.registered-as { margin: 0 0 .2rem; color: var(--muted); font-size: var(--text-small); }
.tenure { color: var(--heading); font-weight: 600; margin: .2rem 0; }
table.officers-table td, table.officers-table th { white-space: normal; vertical-align: top; }
table.officers-table tr.vacant th { color: var(--muted); }
.officer-actions { min-width: 18rem; }
.badge.officer-badge { background: var(--search-border); color: var(--search-button-text); text-decoration: none; font-weight: 700; }
.officer-actions .seat-fill { flex-wrap: wrap; }
.officer-actions .seat-fill input[name=q] { flex: 1 1 100%; }
.seat-fill .date-input { flex: 1; min-width: 8.5rem; }

/* Help articles (Menu › Help). */
.help-list { gap: 1rem; }
.help-list .card p { margin: 0 0 .35rem; }
.help-article { max-width: 52rem; display: grid; gap: 1rem; }
.help-article > h1, .help-article > p { margin-bottom: 0; }
.help-article .card > p:last-child { margin-bottom: 0; }
.help-article dd { margin: 0; }
.help-article ol.steps + p { margin-top: 1.1rem; }
.help-article dt { font-weight: 600; }
table.help-table td, table.help-table th { white-space: normal; }

/* Committee members list: the Seats heading, and printing (Print, or Save as PDF). */
.seats-heading { margin-top: 1.25rem; }
@media print {
  /* Officers on the first page; the seats start on a fresh page. */
  section.officers { break-after: page; page-break-after: always; }
  .seats-heading { margin-top: 0; }
  h2.seats-heading, tr.street-row { break-after: avoid; page-break-after: avoid; }
  /* Never split one member (or officer) across two pages: the whole row moves to the next page. */
  table.seats-table tr, table.officers-table tr, table.committee-table tr { break-inside: avoid; page-break-inside: avoid; }
}

/* Every desktop page (decided 2026-10-23, first on the voter page): the same style as search. A red top edge on the header card, tinted
   panels with small uppercase labels, rounded white fields, and pill-shaped buttons. */
main .voter-head { border-top: 5px solid var(--table-rule); }
main fieldset.support-fields, main fieldset.about-fieldset, main .settings-form fieldset, main fieldset.review-row {
  border: 0; background: var(--filter-bg); border-radius: var(--radius); padding: .9rem 1rem; display: grid; gap: .8rem;
}
main fieldset.support-fields > legend, main fieldset.about-fieldset > legend, main .settings-form fieldset > legend,
main fieldset.review-row > legend {
  float: left; width: 100%; grid-column: 1 / -1; padding: 0; margin: 0 0 .1rem;
  font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--heading);
}
main form label:not(.check) {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading);
}
main form label:not(.check) > * {
  font-size: 1rem; font-weight: 400; text-transform: none; letter-spacing: normal; color: var(--text);
}
main form label:not(.check) > .muted, main form label:not(.check) > .small { font-size: var(--text-small); color: var(--muted); }
main form input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="search"]), main form select,
main form textarea { border: 1px solid var(--filter-input-border); border-radius: var(--radius); background: var(--surface); }
main fieldset input:not([type="checkbox"]):not([type="radio"]), main fieldset select { background: var(--surface); }
main a.button { border-radius: 999px; border-width: 2px; font-weight: 700; }
main a.button:hover { border-color: var(--search-border); }
main button:not(.link) { border-radius: 999px; border: 2px solid var(--border); font-weight: 700; padding: .5rem 1.25rem; }
main button.small-button:not(.link) { padding: .3rem .9rem; }
main button:not(.link):hover { border-color: var(--search-border); background: var(--surface-alt); }
main button.primary { background: var(--search-border); border-color: var(--search-border); color: var(--search-button-text); }
main button.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-text); }
main fieldset > legend > .muted { text-transform: none; letter-spacing: normal; font-weight: 400; }
main .roles-table label.sr-label {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading);
}
main .roles-table label.sr-label > * { font-size: 1rem; font-weight: 400; text-transform: none; letter-spacing: normal; color: var(--text); }
main .roles-table input:not([type="checkbox"]), main .roles-table select {
  border: 1px solid var(--filter-input-border); border-radius: var(--radius); background: var(--surface);
}
main button.pill-button { border-color: var(--search-border); padding: .55rem 1.4rem; }
main button.pill-button:hover { border-color: var(--accent-hover); background: var(--accent-hover); }

/* Accessibility (WCAG 2.1 AA review, 2026-10-23). */
.skip-link { position: absolute; left: .75rem; top: -3rem; z-index: 100; padding: .6rem 1rem; border-radius: 999px;
  background: var(--search-border); color: var(--search-button-text); font-weight: 700; text-decoration: none; }
.skip-link:focus { top: .6rem; }
/* The joined search bar clips its edges, so the Search button's focus ring sits inside it. */
.search-box button:focus-visible { outline: 3px solid var(--search-button-text); outline-offset: -6px; }
/* Tables that scroll sideways can be scrolled with the keyboard (made focusable in base.html). */
.table-wrap[tabindex]:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.quick-picks { display: flex; flex-wrap: wrap; gap: .4rem; margin: .1rem 0 .5rem; }

/* Elected officials page. */
table.officials-table td, table.officials-table th { white-space: normal; vertical-align: top; }
table.officials-table th[scope="row"] { min-width: 9rem; }
table.officials-table td:nth-child(2) { min-width: 12rem; }
table.officials-table .seat-fill { flex-wrap: wrap; }
table.officials-table .seat-fill input { flex: 1 1 11rem; }
table.officials-table tr.vacant th { color: var(--muted); }
table.officials-table tr.former td { color: var(--muted); }
table.officials-table tr.add-row td { padding-top: .2rem; }
.officials-group { margin-bottom: 1rem; }
@media print { .officials-group { break-inside: auto; } table.officials-table tr { break-inside: avoid; page-break-inside: avoid; } }
.official-add { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .6rem .8rem; align-items: end; margin-top: .5rem; }
.official-add button { justify-self: start; }
.official-actions { display: flex; gap: .4rem; align-items: center; justify-content: flex-end; }
main button.icon-button:not(.link) { padding: .3rem .55rem; line-height: 0; }
main button.icon-button[aria-expanded="true"] { border-color: var(--search-border); background: var(--surface-alt); }
table.officials-table tr.edit-row td { background: var(--filter-bg); }
.official-add .position-picks { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .3rem 1.2rem; border: 0; padding: 0; margin: 0; }
.official-add .position-picks legend {
  padding: 0; margin-bottom: .3rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading);
}
.official-add .position-picks label { display: inline-flex; align-items: center; gap: .35rem; }
table.officials-table td .officer-badge { margin-left: .25rem; }
/* Hidden edit rows and Add rows would throw the stripes out of step here, so this table isn't striped. */
table.officials-table tbody tr:nth-child(even) { background: transparent; }
table.officials-table tbody tr.add-row td, table.officials-table tbody tr.edit-row td { background: var(--filter-bg); }

/* --- Voter page overview (decided 2026-10-24): four stat cards, contact information, then tabs. --- */
.voter-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .75rem; margin: 0 0 var(--gap); }
.stat-card {
  display: flex; flex-direction: column; gap: .25rem; min-width: 0; padding: .85rem 1rem;
  background: var(--surface); border: 1px solid var(--border); border-top: 4px solid var(--search-border);
  border-radius: var(--radius); color: var(--text); text-decoration: none;
}
a.stat-card:hover { border-color: var(--search-border); color: var(--text); }
.stat-card.frequent { border-top-color: var(--highlight-bg); }
.stat-label { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading); }
.stat-value { font-size: 2rem; font-weight: 800; line-height: 1.15; color: var(--heading); }
.stat-value .party, .stat-value .support { font-size: 1.05rem; padding: .2rem .8rem; vertical-align: middle; white-space: normal; max-width: 100%; }
.stat-note { font-size: var(--text-small); color: var(--muted); overflow-wrap: anywhere; }
@media (max-width: 760px) {
  .voter-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
  .stat-card { padding: .7rem .75rem; }
  .stat-value .party, .stat-value .support { font-size: .95rem; padding: .15rem .6rem; }
}
.contact-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: .5rem 2rem; }
.contact-card h3 { margin-top: .25rem; }
.voter-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin: 1.5rem 0 1rem; padding-bottom: .75rem; border-bottom: 3px solid var(--table-rule); }
main .voter-tabs button[role="tab"] { background: var(--surface); color: var(--heading); }
main .voter-tabs button[role="tab"][aria-selected="true"] { background: var(--search-border); border-color: var(--search-border); color: var(--search-button-text); }
.tab-count { display: inline-block; min-width: 1.4em; margin-left: .3rem; padding: 0 .4rem; border-radius: 999px; background: var(--badge-bg); color: var(--text); font-size: .8em; }
@media (max-width: 640px) {
  .voter-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; }
  main .voter-tabs button[role="tab"] { flex: none; }
}
@media print {
  .voter-tabs { display: none !important; }
  .tab-panel[hidden] { display: block !important; }
}

/* --- Map quick picks (decided 2026-10-24): council district and election district, one click each. --- */
.map-picks { margin-bottom: 1rem; }
.map-picks h2 { margin: 0 0 .4rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--heading); }
.map-picks h2 .muted { text-transform: none; letter-spacing: normal; font-weight: 400; }
.pick-row { display: flex; flex-wrap: wrap; gap: .3rem; }
.pick {
  display: inline-block; min-width: 2.4rem; padding: .25rem .65rem; text-align: center; text-decoration: none;
  border: 2px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--heading);
  font-size: var(--text-small); font-weight: 700;
}
.pick:hover { border-color: var(--search-border); color: var(--heading); }
.pick[aria-current="true"] { background: var(--search-border); border-color: var(--search-border); color: var(--search-button-text); }

/* Not found on the map: a street heading row above each street's addresses. */
table.not-found-table tbody tr.street-row th { background: var(--filter-bg); color: var(--heading); text-align: left; }
table.not-found-table tbody tr:nth-child(even) { background: transparent; }
table.not-found-table td:first-child { white-space: nowrap; }
/* The Map's party key doubles as the party picker. */
.party-pick { display: inline-flex; align-items: center; }
.party-pick .dot { margin-right: .3rem; }
.pick.party-pick[aria-current="true"] .dot { box-shadow: 0 0 0 2px var(--search-button-text); }
.map-legend-note { margin: .5rem 0 0; color: var(--muted); }
