/* Franklin SA live results: election-night desk in the Weight campaign identity.
   Navy drench, campaign red for Weight, silver for Lavoie, amber for "still open". */
:root {
  /* Brand anchors (zachweight.com): navy #002147, red #BB133E */
  --bg: oklch(0.2 0.075 257);          /* #001a3a: deeper than brand navy, for the page */
  --surface: oklch(0.255 0.082 258);   /* #002147: brand navy */
  --surface-2: oklch(0.3 0.08 258);
  --surface-3: oklch(0.35 0.075 258);
  --line: oklch(0.4 0.06 258);
  --line-soft: oklch(0.33 0.06 258);
  --ink: oklch(0.99 0.003 258);
  --ink-2: oklch(0.89 0.02 258);
  --ink-3: oklch(0.76 0.035 258);

  --hero: #bb133e;                     /* Weight: campaign red (fills; white text 5.9:1) */
  --on-hero: #ffffff;                  /* text on red fills */
  --scrim: rgb(0 8 20 / 0.6);          /* behind modal sheets */
  --hero-hi: oklch(0.72 0.17 12);      /* red for text/lines on navy */
  --opp: oklch(0.82 0.03 255);         /* Lavoie: silver (fills; navy text) */
  --opp-ink: oklch(0.24 0.06 258);
  --amber: oklch(0.83 0.14 80);        /* close / counting: still open */
  --amber-ink: oklch(0.25 0.05 70);
  --live: oklch(0.82 0.17 155);

  --radius: 12px;
  --radius-sm: 8px;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1); /* ease-out-quint */
  --font-sans: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-serif: "Merriweather", Georgia, "Times New Roman", serif;

  /* z-index scale */
  --z-bar: 10;
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* `hidden` must win over component display rules (e.g. .alerts is display:flex). */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 1rem/1.45 var(--font-sans); /* rem, not px, so browser text-size settings apply */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--ink); text-underline-offset: 2px; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
button { font: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 3px solid var(--hero-hi); outline-offset: 2px; border-radius: 4px; }

/* ---------- Top bar ---------- */
.bar {
  position: sticky; top: 0; z-index: var(--z-bar);
  background: var(--bg);
  padding-top: env(safe-area-inset-top);
}
/* Header bottom border = progress toward the next scheduled check. */
.next-bar { position: relative; height: 3px; background: var(--line-soft); overflow: hidden; }
.next-bar > span {
  position: absolute; inset: 0; background: var(--hero-hi);
  transform-origin: left; transform: scaleX(0);
  transition: transform 1s linear;
}
.next-bar.reset > span { transition: none; }
/* Due now: we're checking / waiting on the state to publish. */
.next-bar.due > span { transform: scaleX(1); animation: due 1.2s ease-in-out infinite alternate; }
@keyframes due { from { opacity: 1; } to { opacity: 0.35; } }
.next-bar.done > span { background: var(--ink-3); transform: scaleX(1); animation: none; }
.next-bar.idle > span { transform: scaleX(0); animation: none; } /* polls still open: no checks yet */
.next-bar.stale > span { background: var(--amber); }
.live-next { display: none; color: var(--ink-3); }
@media (min-width: 480px) { .live-next { display: inline; } }
.bar-inner {
  max-width: 1080px; margin: 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 8px max(16px, env(safe-area-inset-right)) 8px max(16px, env(safe-area-inset-left));
  min-height: 56px;
}
.brand { display: flex; flex: none; }
.brand img { display: block; height: 34px; width: auto; }
.bar-mid { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bar-title { font-weight: 800; font-size: 0.8rem; letter-spacing: 0.08em; text-transform: uppercase; }
.live { display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); flex: none; }
.live.on .live-dot { background: var(--live); }
.live.on.blip .live-dot { animation: blip 900ms var(--ease-out); }
.live.stale .live-dot { background: var(--amber); }
.live.final .live-dot { background: var(--ink); }
@keyframes blip { 0% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--live) 70%, transparent); } 100% { box-shadow: 0 0 0 9px transparent; } }

.icon-btn {
  position: relative; flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--ink); border: 1px solid var(--line);
  cursor: pointer; transition: background 150ms, border-color 150ms;
}
.icon-btn:hover { background: var(--surface-3); }
.icon-btn:active { transform: scale(0.96); }
.bell-on { position: absolute; top: 9px; right: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 2px var(--bg); display: none; }
.icon-btn.alerts-on .bell-on { display: block; }
/* Unseen updates */
.badge {
  position: absolute; top: -3px; right: -3px; min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 99px; background: var(--hero); color: var(--on-hero); box-shadow: 0 0 0 2px var(--bg);
  font-size: 0.7rem; font-weight: 800; line-height: 20px; text-align: center;
}
.badge.bump { animation: bump 600ms var(--ease-out); }
@keyframes bump { 0% { transform: scale(1.5); } 100% { transform: scale(1); } }

/* ---------- Updates drawer ---------- */
.drawer {
  margin: 0 0 0 auto; padding: 0; border: 0;
  /* Leave a strip of page visible on phones: it reads as an overlay and gives a tap-to-close area. */
  width: min(420px, calc(100% - 36px)); height: 100dvh; max-height: none; max-width: none;
  background: var(--surface); color: var(--ink);
  border-left: 1px solid var(--line);
  transform: translateX(100%);
  transition: transform 280ms var(--ease-out);
}
.drawer.shown { transform: none; }
.drawer::backdrop { background: rgb(0 8 20 / 0); transition: background 280ms var(--ease-out); }
.drawer.shown::backdrop { background: rgb(0 8 20 / 0.55); }
.drawer-inner {
  height: 100%; overflow-y: auto; overscroll-behavior: contain;
  padding: calc(12px + env(safe-area-inset-top)) max(18px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) 18px;
}
/* Title and close stay put while long content scrolls. */
.drawer-top {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px;
  position: sticky; top: calc(-12px - env(safe-area-inset-top)); z-index: 1;
  margin-top: calc(-12px - env(safe-area-inset-top)); padding: calc(12px + env(safe-area-inset-top)) 0 10px;
  background: var(--surface); border-bottom: 1px solid var(--line-soft);
}
.drawer-top h2 { margin: 0; font-size: 1.3rem; font-weight: 800; }
.drawer-close { position: static; }
.drawer-alerts {
  display: flex; align-items: center; justify-content: space-between; gap: 10px 14px; flex-wrap: wrap;
  padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px solid var(--line);
}
.drawer-alerts p { margin: 0; font-size: 0.92rem; color: var(--ink-2); flex: 1 1 180px; }
.drawer-alerts p b { color: var(--ink); }
.drawer-note { margin: 16px 0 10px; font-size: 0.82rem; color: var(--ink-3); }

/* ---------- Layout ---------- */
.wrap {
  max-width: 1080px; margin: 0 auto;
  padding: 16px max(16px, env(safe-area-inset-right)) calc(40px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  display: flex; flex-direction: column; gap: 14px;
}
.cols { display: grid; gap: 14px; }
/* Desktop: the map stays pinned beside the town-by-town list. */
@media (min-width: 900px) {
  .cols { grid-template-columns: 1fr 1.15fr; align-items: start; }
  .map-panel { position: sticky; top: 76px; }
}
.panel { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 16px; }
.panel-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; margin-bottom: 12px; }
.panel-head h2 { margin: 0; font-size: 1.15rem; font-weight: 800; }
.panel-note { margin: 0; font-size: 0.82rem; color: var(--ink-3); }

/* ---------- 1. The call ---------- */
.call {
  position: relative;
  padding: 18px 18px 20px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  overflow: hidden;
  transition: background 400ms var(--ease-out), color 400ms var(--ease-out), border-color 400ms;
}
/* The logo's open red frame, echoed in the corner. */
.call::after {
  content: ""; position: absolute; right: 14px; top: 14px; width: 54px; height: 30px;
  border-top: 2px solid var(--hero-hi); border-right: 2px solid var(--hero-hi);
  opacity: 0.85; pointer-events: none;
}
.call-race { margin: 0 0 10px; font-size: 0.82rem; font-weight: 700; color: var(--ink-2); padding-bottom: 10px; border-bottom: 2px solid var(--hero); width: fit-content; padding-right: 8px; }
.call-head {
  margin: 0; font-family: var(--font-serif); font-weight: 900;
  font-size: 1.9rem; line-height: 1.12; letter-spacing: -0.01em; max-width: 22ch;
}
.call-sub { margin: 10px 0 0; font-size: 1rem; color: var(--ink-2); max-width: 60ch; }
.call-sub b { color: var(--ink); }
.countdown { font-family: var(--font-sans); font-weight: 800; letter-spacing: -0.02em; }

.call[data-tone="hero"] { background: var(--hero); border-color: var(--hero); }
.call[data-tone="hero"] .call-race { color: var(--ink); border-color: var(--ink); }
.call[data-tone="hero"] .call-sub { color: var(--ink); }
.call[data-tone="hero"]::after { border-color: var(--ink); }
.call[data-tone="opp"] { background: var(--opp); color: var(--opp-ink); border-color: var(--opp); }
.call[data-tone="opp"] .call-race, .call[data-tone="opp"] .call-sub, .call[data-tone="opp"] .call-sub b { color: var(--opp-ink); border-color: var(--opp-ink); }
.call[data-tone="opp"]::after { border-color: var(--opp-ink); }
.call[data-tone="open"] { border-color: var(--amber); }
.call[data-tone="open"] .call-head { color: var(--amber); }
.call.news { animation: news 1.4s var(--ease-out); }
@keyframes news { 0% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--ink) 50%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }

/* ---------- 2. Scoreboard ---------- */
.score { container: score / inline-size; background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 16px; }
.score-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; gap: 8px; }
.vs { align-self: center; margin-top: 18px; font-size: 0.75rem; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.08em; padding-bottom: 28px; }
.cand { min-width: 0; }
.cand.opp { text-align: right; }
.cand-name { font-family: var(--font-serif); font-weight: 900; font-size: 1.15rem; line-height: 1.15; }
.cand-party { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin-top: 2px; }
.cand-pct { font-weight: 800; font-size: 2.75rem; line-height: 1; letter-spacing: -0.03em; margin-top: 10px; }
.cand.hero .cand-pct { color: var(--hero-hi); }
.cand.opp .cand-pct { color: var(--opp); }
.cand .cand-pct.empty { color: var(--ink-3); font-weight: 600; }
.cand-votes { font-size: 0.95rem; color: var(--ink-2); margin-top: 4px; }
.cand-votes b { color: var(--ink); font-weight: 700; }
.cand-party { display: flex; align-items: center; gap: 6px; min-height: 18px; }
.cand.opp .cand-party { justify-content: flex-end; }
.lead-tag { font-family: var(--font-sans); font-size: 0.62rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; padding: 1px 6px; border-radius: 4px; line-height: 1.5; white-space: nowrap; }
.cand.hero .lead-tag { background: var(--hero); color: var(--on-hero); }
.cand.opp .lead-tag { background: var(--opp); color: var(--opp-ink); }

.cand-votes { margin-bottom: 0; }
/* 2022 for the same towns: directly under tonight's numbers, same side, faded (like the town rows). */
.cand-prev { margin-top: 6px; font-size: 0.82rem; font-weight: 500; color: var(--ink-3); letter-spacing: -0.005em; }
.cand-prev > span { white-space: nowrap; }
.cand-prev .y { font-size: 0.68rem; font-weight: 700; }

.split-pair { display: grid; gap: 4px; margin: 16px 0 10px; }
.split { position: relative; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.split.now { height: 16px; }
.split.then { height: 5px; opacity: 0.45; }
.split > span { position: absolute; top: 0; bottom: 0; width: 100%; transition: transform 700ms var(--ease-out); }
.split-hero { left: 0; background: var(--hero); transform-origin: left; transform: scaleX(0); }
.split-opp { right: 0; background: var(--opp); transform-origin: right; transform: scaleX(0); }
.split-mid { left: calc(50% - 1px); width: 2px !important; background: var(--bg); }

/* Margin: 2026 (bright, leader colour) with 2022 for the same towns directly beneath, swing on the right */
.score-margin { display: grid; grid-template-columns: auto 1fr auto; grid-template-areas: "label now swing" ". then then"; align-items: baseline; gap: 2px 12px; }
.sm-label { grid-area: label; }
.sm-now { grid-area: now; }
.sm-then { grid-area: then; }
.sm-swing { grid-area: swing; }
.sm-label { font-size: 0.72rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); }
.sm-now { font-size: 1.15rem; font-weight: 800; color: var(--ink); }
.sm-now.hero { color: var(--hero-hi); }
.sm-now.opp { color: var(--opp); }
.sm-then { font-size: 0.86rem; font-weight: 500; color: var(--ink-3); }
.sm-then .y { font-size: 0.72rem; font-weight: 700; }
.sm-swing { justify-self: end; font-size: 0.86rem; font-weight: 700; cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; text-decoration-thickness: 1px; position: relative; }
.sm-swing::before { content: ""; position: absolute; inset: -8px -3px; }
.sm-swing.up { color: var(--hero-hi); }
.sm-swing.down { color: var(--opp); }

.progress { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.progress-row { display: flex; justify-content: space-between; gap: 12px; font-size: 0.88rem; color: var(--ink-2); }
.progress-row b { color: var(--ink); }
.meter { height: 6px; background: var(--surface-3); border-radius: 99px; overflow: hidden; margin-top: 8px; }
.meter > span { display: block; height: 100%; width: 100%; background: var(--ink); transform-origin: left; transform: scaleX(0); transition: transform 700ms var(--ease-out); }

@container score (max-width: 15em) {
  .score-row { grid-template-columns: 1fr; gap: 14px; }
  .vs { display: none; }
  .cand.opp { text-align: left; }
  .cand.opp .cand-party { justify-content: flex-start; flex-direction: row-reverse; }
  .cand-pct { font-size: min(2.75rem, 24cqi); }
  .progress-row { flex-direction: column; gap: 2px; }
  .score-margin { grid-template-areas: "label now now" ". then then" ". swing swing"; }
  .sm-swing { justify-self: start; }
}

/* ---------- Alerts prompt ---------- */
.alerts {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--line);
}
.alerts { position: relative; padding-right: 56px; }
.dismiss {
  position: absolute; top: 4px; right: 4px; width: 44px; height: 44px;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-3); cursor: pointer; transition: background 150ms, color 150ms;
}
.dismiss:hover { background: var(--surface-3); color: var(--ink); }
.alerts h2 { margin: 0; font-size: 1rem; font-weight: 800; }
.alerts p { margin: 2px 0 0; font-size: 0.88rem; color: var(--ink-2); }
.alerts-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.btn {
  min-height: 44px; padding: 10px 18px; border-radius: 10px;
  font-weight: 700; font-size: 0.95rem; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-3); color: var(--ink);
  transition: background 150ms, transform 150ms;
}
.btn:hover { background: var(--line); }
.btn:active { transform: scale(0.98); }
.btn.primary { background: var(--hero); border-color: var(--hero); color: var(--on-hero); }
.btn.primary:hover { background: color-mix(in oklch, var(--hero) 88%, white); }
.btn.ghost { background: transparent; }
.btn[disabled] { opacity: 0.6; cursor: default; }

/* ---------- 3. Tile map ---------- */
.tally { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.tally li { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 6px; border-radius: 99px; background: var(--surface-2); font-size: 0.8rem; color: var(--ink-2); }
.tally b { color: var(--ink); font-weight: 800; }
.sw { width: 14px; height: 14px; border-radius: 4px; flex: none; }
.sw.hero { background: var(--hero); }
.sw.opp { background: var(--opp); }
.sw.close { background: repeating-linear-gradient(135deg, var(--amber) 0 3px, transparent 3px 6px); box-shadow: inset 0 0 0 1.5px var(--amber); }
.sw.counting { box-shadow: inset 0 0 0 1.5px var(--amber); background: linear-gradient(to top, color-mix(in srgb, var(--amber) 55%, transparent) 50%, transparent 50%); }
.sw.waiting { box-shadow: inset 0 0 0 1.5px var(--line); }

.map-panel { container: towns / inline-size; }
.list-panel { container: townlist / inline-size; }
/* minmax(0, 1fr): tiles may shrink below their text's natural width (text clips inside the tile). */
.map { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.tile {
  position: relative; min-height: 76px; padding: 8px 7px 7px;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2);
  display: flex; flex-direction: column; justify-content: space-between; gap: 4px;
  text-align: left; cursor: pointer; overflow: hidden;
  transition: background 400ms var(--ease-out), border-color 400ms, color 400ms, transform 150ms;
}
.tile:active { transform: scale(0.97); }
.tile[aria-pressed="true"] { outline: 2px solid var(--ink); outline-offset: 2px; }
.tile-name { font-size: 0.72rem; font-weight: 700; line-height: 1.15; }
.tile-val { font-size: 0.95rem; font-weight: 800; line-height: 1; letter-spacing: -0.01em; }
.tile-state { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.85; }
.tile.waiting { background: transparent; border-style: dashed; color: var(--ink-3); }
.tile.waiting .tile-val { font-weight: 600; font-size: 0.74rem; white-space: nowrap; letter-spacing: 0; }
.tile.won.hero, .tile.called.hero { background: var(--hero); border-color: var(--hero); color: var(--on-hero); }
.tile.won.opp, .tile.called.opp { background: var(--opp); border-color: var(--opp); color: var(--opp-ink); }
/* Called early (split town, rest can't flip it): a folded corner marks it apart from fully reported. */
.tile.called.hero, .tile.called.opp { background-image: linear-gradient(135deg, transparent 0 78%, color-mix(in oklch, currentColor 30%, transparent) 78%); }
.tile.close { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--amber) 30%, var(--surface-2)) 0 7px, var(--surface-2) 7px 14px); border-color: var(--amber); color: var(--ink); }
.tile.counting { border-color: var(--amber); color: var(--ink); }
.tile.counting::before { content: ""; position: absolute; inset: auto 0 0 0; height: var(--fill, 50%); background: color-mix(in srgb, var(--amber) 24%, transparent); pointer-events: none; }
.tile > * { position: relative; }
.flip { display: inline-block; font-size: 0.58rem; font-weight: 800; letter-spacing: 0.06em; padding: 1px 4px; border-radius: 3px; background: var(--ink); color: var(--bg); margin-left: 4px; vertical-align: 1px; opacity: 1; }
.tile.won.opp .flip, .tile.called.opp .flip { background: var(--opp-ink); color: var(--opp); }
.tile.fresh { animation: fresh 1.6s var(--ease-out); }
@keyframes fresh { 0% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--ink) 80%, transparent); transform: scale(1.04); } 100% { box-shadow: 0 0 0 12px transparent; transform: scale(1); } }

.town-detail { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.town-detail:focus { outline: none; }
.town-detail h3 { margin: 0 0 6px; font-size: 1.05rem; font-weight: 800; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.td-grid { display: grid; grid-template-columns: auto 1fr auto; gap: 4px 10px; font-size: 0.92rem; align-items: center; }
.td-grid .k { color: var(--ink-3); }
.td-grid .n { text-align: right; font-weight: 700; }
.td-note { margin: 8px 0 0; font-size: 0.86rem; color: var(--ink-2); }

/* ---------- 4. Feed ---------- */
.feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.feed li { display: grid; grid-template-columns: 4.6em 1fr; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line-soft); }
.feed li:first-child { border-top: 0; padding-top: 0; }
.feed time { font-size: 0.78rem; color: var(--ink-3); padding-top: 2px; white-space: nowrap; }
.feed .f-title { font-weight: 700; font-size: 0.95rem; }
.feed .f-body { font-size: 0.88rem; color: var(--ink-2); margin-top: 2px; }
.feed li.call-event .f-title { color: var(--hero-hi); }
.feed li.new { animation: feed-in 500ms var(--ease-out); }
@keyframes feed-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.feed .empty { display: block; color: var(--ink-3); font-size: 0.9rem; border: 0; padding: 0; }

/* ---------- 5. Town list ---------- */
.group + .group:not([hidden]) { margin-top: 24px; }
/* The flat (non-status) list has no group heading; column headings still apply. */
.group[data-group="all"] .group-head { display: none; }

/* Sort control in the "Town by town" header */
.sort { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; max-width: 100%; font-size: 0.82rem; font-weight: 700; color: var(--ink-3); }
.sort select {
  max-width: 100%; min-width: 0;
  appearance: none; -webkit-appearance: none;
  min-height: 36px; padding: 6px 30px 6px 12px; border-radius: 8px;
  border: 1px solid var(--line); background-color: var(--surface-2); color: var(--ink);
  font: inherit; font-weight: 700; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
  transition: border-color 150ms, background-color 150ms;
}
.sort select:hover { border-color: var(--ink-3); }
.sort select:focus-visible { outline: 3px solid var(--hero-hi); outline-offset: 2px; }
.sort select option { background: var(--surface); color: var(--ink); }
.list-note { flex-basis: 100%; }
.group + .group { margin-top: 24px; }
.group-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.group-head h3 { margin: 0; font-size: 0.82rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.group-head span { font-size: 0.82rem; font-weight: 800; color: var(--ink-3); }

/* Shared column grid: year · Weight · Lavoie · margin. Headings, 2026 and 2022 all use it, so each
   number sits directly above its 2022 counterpart. */
.tgrid { display: grid; grid-template-columns: 2.9rem 1fr 1fr 1.15fr; column-gap: 10px; align-items: baseline; }
.tgrid > :not(.y) { text-align: right; white-space: nowrap; }
.t-cols { font-size: 0.7rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-3); padding-bottom: 6px; border-bottom: 1px solid var(--line-soft); }

.trow { padding: 12px 0 14px; border-top: 1px solid var(--line-soft); }
.group-rows > .trow:first-child { border-top: 0; }
.t-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin-bottom: 8px; }
.t-name { font-weight: 800; font-size: 1rem; }
.t-swing { margin-left: auto; font-size: 0.8rem; font-weight: 700; white-space: nowrap; }
.t-swing.up { color: var(--hero-hi); }
.t-swing.down { color: var(--opp); }

.chip { font-size: 0.66rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; padding: 2px 7px; border-radius: 99px; white-space: nowrap; }
.chip.won-hero, .chip.called-hero { background: var(--hero); color: var(--on-hero); }
.chip.won-opp, .chip.called-opp { background: var(--opp); color: var(--opp-ink); }
.chip.close, .chip.counting { background: var(--amber); color: var(--amber-ink); }
.chip.waiting { background: transparent; color: var(--ink-3); box-shadow: inset 0 0 0 1px var(--line); }
.chip.flip { background: var(--ink); color: var(--bg); }

/* 2026: the news. Full ink, heavy, leader in their colour. */
.t-line.now { font-size: 1.05rem; font-weight: 800; color: var(--ink); }
.t-line.now .y { font-size: 0.72rem; font-weight: 800; color: var(--ink-2); }
.t-line.now .n.lead { color: var(--ink); }
.t-line.now .m.hero { color: var(--hero-hi); }
.t-line.now .m.opp { color: var(--opp); }
/* 2022: the reference. Same columns, smaller, lighter, no candidate colour. */
.t-line.then { margin-top: 3px; font-size: 0.86rem; font-weight: 500; color: var(--ink-3); }
.t-line.then .y { font-size: 0.72rem; font-weight: 700; }

.t-bars { display: grid; gap: 3px; margin: 8px 0 0 calc(2.9rem + 10px); }
.t-bar { position: relative; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.t-bar.now { height: 8px; }
.t-bar.then { height: 4px; opacity: 0.45; }
.t-bar > span { position: absolute; top: 0; bottom: 0; width: 100%; transition: transform 700ms var(--ease-out); }
.t-bar .h { left: 0; background: var(--hero); transform-origin: left; }
.t-bar .o { right: 0; background: var(--opp); transform-origin: right; }
.t-bar .mid { left: calc(50% - 1px); width: 2px; background: var(--surface); }

/* Live updates: a changed row glows once; a town that just reported eases its 2026 line in. */
.trow.updated { animation: row-updated 1.8s var(--ease-out); }
@keyframes row-updated { 0%, 25% { background: color-mix(in srgb, var(--ink) 9%, transparent); } 100% { background: transparent; } }
.t-line.appear { animation: line-in 450ms var(--ease-out); }
@keyframes line-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
/* Rows moving between groups (View Transitions). Keep the rest of the page still. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
::view-transition-group(*) { animation-duration: 420ms; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
/* Bleed rows 8px each side so the update glow has room; content stays on the same grid. */
.trow { border-radius: 8px; margin: 0 -8px; padding-left: 8px; padding-right: 8px; }

/* Waiting towns: only last time's line, so open rows read as "nothing yet" at a squint. */
.trow.waiting { padding-top: 10px; padding-bottom: 12px; } /* vertical only: keep the 8px side bleed so columns line up */
.trow.waiting .t-head { margin-bottom: 4px; }
.trow.waiting .t-name { color: var(--ink-2); }

@media (max-width: 379px) {
  .tgrid { grid-template-columns: 2.4rem 1fr 1fr 1.2fr; column-gap: 6px; }
  .t-bars { margin-left: calc(2.4rem + 6px); }
  .t-line.now { font-size: 0.98rem; }
}

/* ---------- 6. Context ---------- */
.context h2 { margin: 0 0 6px; font-size: 1.15rem; font-weight: 800; }
.context p { margin: 0; color: var(--ink-2); max-width: 70ch; }
.method { margin-top: 12px; border-top: 1px solid var(--line-soft); padding-top: 10px; }
.method summary { cursor: pointer; font-weight: 700; min-height: 32px; display: flex; align-items: center; }
.method ul { margin: 8px 0 0; padding-left: 18px; color: var(--ink-2); font-size: 0.92rem; max-width: 70ch; }
.method li { margin-bottom: 6px; }
.method b { color: var(--ink); }

.foot { font-size: 0.82rem; color: var(--ink-3); padding: 4px 2px 0; }
.foot p { margin: 0 0 6px; }
.foot a { color: var(--ink-2); }
.foot-actions { color: var(--ink-2); }
.linkish {
  background: none; border: 0; padding: 6px 0; min-height: 32px; cursor: pointer;
  color: var(--ink); font-weight: 700; text-decoration: underline; text-underline-offset: 3px;
}
.linkish:hover { color: var(--hero-hi); }

/* ---------- Glossary ---------- */
/* Badges double as glossary links: same look, plus a pointer and focus ring. */
button.chip, button.lead-tag { border: 0; font-family: var(--font-sans); cursor: help; }
button.chip, button.lead-tag, .t-swing[data-term] { position: relative; }
button.chip::before, button.lead-tag::before, .t-swing[data-term]::before { content: ""; position: absolute; inset: -8px -3px; }
.t-swing[data-term] { cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; text-decoration-thickness: 1px; }
button.chip:focus-visible, button.lead-tag:focus-visible, [data-term][role="button"]:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.tally li { padding: 0; }
.tally button { all: unset; display: inline-flex; align-items: center; gap: 6px; cursor: help; border-radius: 99px; min-height: 32px; padding: 0 10px 0 7px; box-sizing: border-box; }
.tally li:has(button:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
.term-link { font-size: 0.82rem; padding: 0; min-height: 24px; }

/* Topic tabs, pinned with the title */
.gl-top { flex-wrap: wrap; padding-bottom: 0; }
.gl-tabs { flex-basis: 100%; display: grid; grid-template-columns: repeat(4, auto); justify-content: space-between; margin: 4px -6px 0; }
.gl-tabs [role="tab"] {
  position: relative; min-height: 44px; padding: 8px 6px;
  border: 0; background: none; color: var(--ink-3); cursor: pointer;
  font: inherit; font-size: 0.88rem; font-weight: 700; white-space: nowrap;
  border-radius: 8px 8px 0 0; transition: color 150ms, background 150ms;
}
.gl-tabs [role="tab"]:hover { color: var(--ink); background: var(--surface-2); }
.gl-tabs [role="tab"][aria-selected="true"] { color: var(--ink); }
.gl-tabs [role="tab"][aria-selected="true"]::after {
  content: ""; position: absolute; left: 6px; right: 6px; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0; background: var(--hero-hi);
}
.gl-tabs [role="tab"]:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.gl-section { margin-top: 6px; }
.gl-section:not([hidden]) { animation: gl-in 220ms var(--ease-out); }
@keyframes gl-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.gl-section h3 { margin: 0 0 6px; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.gl { margin: 0; }
.gl-item { padding: 12px 10px; margin: 0 -10px; border-radius: 10px; border-top: 1px solid var(--line-soft); scroll-margin: 80px; }
.gl-item:first-child { border-top: 0; }
.gl-item dt { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 0.95rem; margin-bottom: 4px; }
.gl-item dd { margin: 0; font-size: 0.9rem; color: var(--ink-2); max-width: 60ch; }
.gl-item.spotlight { animation: spotlight 2.4s var(--ease-out); }
@keyframes spotlight { 0%, 35% { background: color-mix(in srgb, var(--ink) 11%, transparent); } 100% { background: transparent; } }
.gl-call { font-family: var(--font-serif); font-weight: 900; font-size: 1.05rem; }
.gl-call.open { color: var(--amber); }
.gl-sample { font-weight: 800; }
.gl-sample.up { color: var(--hero-hi); font-size: 0.85rem; }
.gl-sample.faded { color: var(--ink-3); font-weight: 600; }
.lead-tag.hero { background: var(--hero); color: var(--on-hero); }
.gl-live { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--ink-3); }
.gl-live .live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--live); }

/* ---------- iOS sheet ---------- */
/* Native modal dialog, docked to the bottom like a sheet */
.sheet { margin: auto auto 0; padding: 16px; border: 0; background: transparent; width: 100%; max-width: 492px; max-height: none; color: var(--ink); }
.sheet::backdrop { background: var(--scrim); }
.sheet-card { background: var(--surface-2); color: var(--ink); border: 1px solid var(--line); border-radius: 16px; padding: 20px; max-width: 460px; width: 100%; margin-bottom: env(safe-area-inset-bottom); }
.sheet-card h2 { margin: 0 0 8px; font-size: 1.1rem; }
.sheet-card p { color: var(--ink-2); margin: 0 0 16px; }
.share-ico { width: 1em; height: 1em; vertical-align: -0.12em; }

/* ---------- Loading skeleton ---------- */
.skel { display: inline-block; height: 0.9em; width: 4ch; border-radius: 4px; background: var(--surface-3); vertical-align: middle; }

/* ---------- Larger screens ---------- */
@media (min-width: 600px) {
  .call { padding: 22px 24px 24px; }
  .call-head { font-size: 2.5rem; }
  .cand-name { font-size: 1.4rem; }
  .cand-pct { font-size: 3.5rem; }
  .score, .panel { padding: 20px; }
  .tile { min-height: 86px; padding: 10px 9px 9px; }
  .tile-name { font-size: 0.8rem; }
  .tile-val { font-size: 1.1rem; }
  .map { gap: 8px; }
}

/* Large text (browser text size 150%+): reflow instead of scrolling sideways (WCAG 1.4.10).
   Thresholds are in em, so they grow with the text size rather than the screen size. */
@container towns (max-width: 15em) {
  .map:not(.geo) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container townlist (max-width: 14em) {
  .tgrid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "y y" "w l" "m m"; row-gap: 2px; }
  .tgrid > :nth-child(1) { grid-area: y; }
  .tgrid > :nth-child(2) { grid-area: w; }
  .tgrid > :nth-child(3) { grid-area: l; }
  .tgrid > :nth-child(4) { grid-area: m; }
  .t-cols { grid-template-areas: "w l"; }
  .t-cols > :nth-child(1), .t-cols > :nth-child(4) { display: none; }
  .t-bars { margin-left: 0; }
  .t-swing { margin-left: 0; white-space: normal; }
}

/* Smallest phones (iPhone SE and similar): drop the "vs", tighten the scoreboard type. */
@media (max-width: 379px) {
  .score-row { grid-template-columns: 1fr 1fr; gap: 12px; }
  .vs { display: none; }
  .cand-name { font-size: 1rem; }
  .cand-party { flex-wrap: wrap; row-gap: 4px; }
  .cand-pct { font-size: 2.2rem; }
  .cand-votes { font-size: 0.88rem; }
  .progress-row { flex-wrap: wrap; row-gap: 2px; }
  .score-margin { grid-template-areas: "label now now" ". then then" ". swing swing"; }
  .sm-swing { justify-self: start; }
}

/* Narrow phones: four tiles across still fit, with tighter spacing and hyphenated long names. */
@media (max-width: 400px) {
  .cols > .panel:first-child { padding: 14px 12px; }
  .map { gap: 4px; }
  .tile { padding: 7px 5px 6px; min-height: 72px; }
  .tile-name { font-size: 0.68rem; hyphens: manual; }
  .tile-val { font-size: 0.9rem; }
  .tile.waiting .tile-val { font-size: 0.66rem; }
  .tile-state { font-size: 0.58rem; letter-spacing: 0.04em; }
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .tile.close { background: repeating-linear-gradient(135deg, rgb(110 98 74) 0 7px, var(--surface-2) 7px 14px); }
  .tile.counting::before { background: rgb(245 184 61 / 0.24); }
  .sw.counting { background: linear-gradient(to top, rgb(245 184 61 / 0.55) 50%, transparent 50%); }
  .tile.called.hero, .tile.called.opp { background-image: linear-gradient(135deg, transparent 0 78%, rgb(255 255 255 / 0.3) 78%); }
  .btn.primary:hover { background: #c93a5d; }
  @keyframes row-updated { 0%, 25% { background: rgb(255 255 255 / 0.09); } 100% { background: transparent; } }
  @keyframes spotlight { 0%, 35% { background: rgb(255 255 255 / 0.11); } 100% { background: transparent; } }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
}
