:root {
  /* The top bar and its buttons, the same on every page: a 36px button with 14px
     above and below it makes a 64px bar (Orbit's floating buttons sit at the same spot). */
  --nav-h: 36px;
  --nav-gap: 14px;
  --bar-h: calc(var(--nav-h) + 2 * var(--nav-gap));
  /* Static half-circle colors: left edge → right edge. Change these to match your reference. */
  --arc-fill: linear-gradient(90deg, #0022ff 0%, #ff0000 100%);

  --bg: #ffffff;
  --ink: #111111;
  --muted: #666666;
  --line: #d9d9d9;
  --panel: #fafafa;
  --accent: #111111;
  --danger: #c0392b;

  /* Party border colors (sheet column I) */
  --party-democrat: #0022ff;
  --party-republican: #ff0000;
  --party-other: #8a2be2;

  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
}

* { box-sizing: border-box; }
/* Every scrollbar on the site: a grey thumb with no track behind it, so
   whatever's underneath (the page's background, a panel) shows through. */
* { scrollbar-color: rgba(0, 0, 0, .35) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; background: transparent; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(0, 0, 0, .35); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: rgba(0, 0, 0, .5); }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); }

/* ---------- home: stage ---------- */

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  transition: right .25s ease;
}

.hover-info {
  /* A pill like the other controls at the top, centred, sized to its text. */
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  box-sizing: border-box;
  max-width: calc(100% - 1180px);   /* js/main.js (fitInfo) puts it in line with the Power slider, in the gap beside it */
  margin: 0;
  padding: 7px 18px;
  border: 0;
  border-radius: 18px;   /* (a pill on one line; a soft rounded box on two) */
  background: #fff;
  color: var(--btn-ink);
  box-shadow: 0 4px 14px rgba(38, 27, 143, .14);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.3;
  text-align: center;
  display: -webkit-box;   /* up to two lines (js/main.js fitInfo) */
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  pointer-events: none;
  z-index: 500;
}
.hover-info:empty { display: none; }
.hover-info b { font-weight: 700; }
.hover-info .hover-pos { opacity: .7; }
.hover-info .hover-pos::before { content: "·"; margin-right: .35em; }
/* (the party, as a dot in its colour before the name) */
.hover-dot { display: inline-block; width: .55em; height: .55em; margin: 0 .45em .08em 0; border-radius: 50%; background: #9a93c9; vertical-align: middle; }
.hover-dot[data-party="democrat"] { background: var(--party-democrat); }
.hover-dot[data-party="republican"] { background: var(--party-republican); }

.arc {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  border-radius: 9999px 9999px 0 0;
  background: var(--arc-fill);
  /* Hollow out the middle to make a ring; --hole (inner radius) is set by main.js. */
  -webkit-mask: radial-gradient(circle at 50% 100%, transparent var(--hole, 0), #000 calc(var(--hole, 0px) + 1px));
          mask: radial-gradient(circle at 50% 100%, transparent var(--hole, 0), #000 calc(var(--hole, 0px) + 1px));
  pointer-events: none;
}

.circle {
  --s: 1;
  position: absolute;
  display: grid;
  place-items: center;
  border: 3px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  overflow: hidden;
  /* --pop shrinks a circle to nothing when a filter hides it (see .filtered-out). */
  transform: translate(-50%, -50%) scale(calc(var(--s) * var(--pop, 1)));
  /* --grow is set per circle by main.js: small circles that grow a lot take longer. */
  transition: transform var(--grow, .18s) cubic-bezier(.45, 0, .25, 1), left .3s ease, top .3s ease, width .3s ease, height .3s ease, opacity .25s ease, visibility .25s, filter .25s ease;
  cursor: pointer;
}
/* Party border: a colored ring just outside the black outline. */
.circle {
  --party: var(--party-other);
  /* Outline and party ring are divided by the hover scale so they stay the same
     thickness while the circle itself grows. */
  --party-ring: calc(4px / var(--s));
  border-width: calc(3px / var(--s));
  box-shadow: 0 0 0 var(--party-ring) var(--party);
}
.circle[data-party="democrat"] { --party: var(--party-democrat); }
.circle[data-party="republican"] { --party: var(--party-republican); }

/* main.js adds .hovered (on mouse hover or keyboard focus), sets --s to how much it
   grows (small circles grow more), and nudges neighbours away. */
.circle:focus-visible { outline: none; box-shadow: 0 0 0 var(--party-ring) var(--party), 0 0 0 calc(var(--party-ring) + 2px) #fff, 0 0 0 calc(var(--party-ring) + 5px) #111; }
.circle img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 25%;   /* headshots: keep faces in frame */
}
.circle .initials { font-weight: 600; letter-spacing: .02em; user-select: none; }
.circle.has-image .initials,
.circle.tiny .initials { visibility: hidden; }

/* Top right: Reset, then Swap. */
.view-bar {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 8px;
}
.reset-button {
  box-sizing: border-box;
  height: 36px;
  padding: 0 16px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.reset-button:hover { background: var(--ink); color: #fff; }
.reset-button:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
.view-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  font: inherit;
  font-size: 14px;
  padding: 5px 5px 5px 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  cursor: pointer;
}
.view-swap {
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-weight: 600;
  white-space: nowrap;
}
.view-toggle:hover .view-swap { background: #0022ff; }
.view-toggle:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }

/* Search bar, top left */
.search {
  position: fixed;
  top: var(--nav-gap);
  left: 14px;
  z-index: 1001;
  width: 280px;
}
.search-input {
  box-sizing: border-box;
  width: 100%;
  font: inherit;
  font-size: 14px;
  height: var(--nav-h);   /* the same height as the buttons beside it */
  padding: 0 14px 0 36px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23111' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='7' cy='7' r='5'/%3E%3Cpath d='m11 11 4 4'/%3E%3C/svg%3E") 13px 50% no-repeat;
  color: var(--ink);
}
.search-input:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
/* The address filter (js/main.js): under the search box, which address it is and how many represent it */
.search-addr { position: absolute; left: calc(100% + 10px); top: 0; height: var(--nav-h); box-sizing: border-box; width: max-content; max-width: 340px; display: flex; align-items: center; gap: 8px; padding: 0 5px 0 12px; background: #fff; border: 2px solid var(--ink, #111); border-radius: 999px; font-size: 13px; font-weight: 700; line-height: 1.2; white-space: nowrap; }
.search-addr[hidden] { display: none; }   /* (no address: no chip) */
.search-addr-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.search-addr-count { flex: none; padding: 2px 8px; border-radius: 999px; background: #111; color: #fff; font-size: 12px; }
.search-addr.is-under { left: 0; top: calc(100% + 6px); height: 34px; max-width: max(100%, 260px); font-size: 12px; box-shadow: 0 2px 0 var(--ink, #111); }   /* (no room beside the box) */
@media (max-width: 700px) {   /* phones: a line under the search box */
  .search-addr.is-under { max-width: calc(100vw - 120px); }
}
.search-addr span { flex: 1; min-width: 0; }
.search-addr.is-busy { color: #555; font-weight: 600; }
.search-addr-x { flex: none; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--ink, #111); background: #fff; font: inherit; font-weight: 800; cursor: pointer; padding: 0; }
.search-results {
  list-style: none;
  margin: 6px 0 0;
  padding: 6px;
  max-height: min(420px, 70vh);
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .15);
}
.search-results[hidden] { display: none; }
.search-result {
  --party: var(--party-other);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
}
.search-result[data-party="democrat"] { --party: var(--party-democrat); }
.search-result[data-party="republican"] { --party: var(--party-republican); }
.search-result.active,
.search-result:hover { background: var(--panel); }
.search-photo {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 2px var(--party);
  background: #fff 50% 25% / cover no-repeat;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
}
.search-photo.is-position { border-radius: 8px; box-shadow: none; font-size: 16px; }
.search-text { min-width: 0; display: grid; }
.search-name { font-weight: 600; font-size: 14px; }
.search-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-result mark { background: #ffe58a; color: inherit; border-radius: 2px; }
.search-empty { padding: 8px 10px; color: var(--muted); font-size: 14px; }
/* While searching, circles that don't match fade back. */
.circle.search-dim { opacity: .18; }

/* Select multiple and Connect the dots, under the search bar */
.group-filter {
  position: fixed;
  top: 60px;
  left: 14px;
  z-index: 1000;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  font-size: 14px;
}

/* The groups on Orbit: one pill top middle with the mix's name; it opens out into a bubble of the
   groups (× takes one off, ＋ grows open the bank). Bubbly: everything springs (it overshoots a
   little and settles). */
:root { --spring: cubic-bezier(.34, 1.56, .64, 1); }
.group-bar {
  position: fixed;
  top: 14px;   /* (placeControls: the top row, or the second, or under them) */
  left: 50%;
  translate: -50% 0;
  z-index: 1500;   /* (its bubble covers the other controls) */
  width: max-content;
  font-size: 13px;
}
/* the bubble: over the pill, grown out of its outline */
.group-pop {
  position: absolute; top: 0; left: 50%; translate: -50% 0;
  width: min(560px, calc(100vw - 28px)); box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 12px 16px 14px; border-radius: 26px; background: #fff;
  box-shadow: 0 16px 40px rgba(38, 27, 143, .22);
}
.group-pop[hidden] { display: none; }
/* (the bubbles' faint glint, top left) */
.group-pop::before { content: ""; position: absolute; top: 13px; left: 24px; width: 30px; height: 12px; border-radius: 50%; background: rgba(211, 205, 251, .28); rotate: -30deg; pointer-events: none; }
.group-pop.is-opening { animation: pop-grow .55s var(--spring) both; }
.group-pop.is-closing { animation: pop-shrink .26s ease-in both; pointer-events: none; }
@keyframes pop-grow {
  from { clip-path: inset(0 calc(50% - var(--pw) / 2) calc(100% - var(--ph)) round 999px); }
  to { clip-path: inset(-40px round 60px); }
}
@keyframes pop-shrink {
  from { clip-path: inset(-40px round 60px); }
  to { clip-path: inset(0 calc(50% - var(--pw) / 2) calc(100% - var(--ph)) round 999px); opacity: .4; }
}
.group-pop.is-opening .pop-head, .group-pop.is-opening .group-chips > *, .group-pop.is-opening .group-bank > *, .group-pop.is-opening .pop-pick { animation: pop-in .45s var(--spring) both; animation-delay: calc(90ms + var(--k, 0) * 30ms); }
.pop-head { position: relative; display: flex; justify-content: center; align-items: center; width: 100%; min-height: 26px; }
.pop-name { font-size: 15px; color: var(--btn-ink); }
.pop-close {
  position: absolute; right: -4px; top: 50%; translate: 0 -50%; display: grid; place-items: center;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: var(--btn-tint); color: var(--btn-ink); cursor: pointer;
  transition: transform .3s var(--spring);
}
.pop-close .icon { width: 11px; height: 11px; }
.pop-close:hover { transform: rotate(90deg) scale(1.1); }
.pop-pick {
  padding: 4px 10px; border: 0; border-radius: 999px; background: none; color: var(--btn-ink);
  font: inherit; font-size: 13px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; opacity: .75; cursor: pointer;
}
.pop-pick:hover { opacity: 1; }
.pop-close:focus-visible, .pop-pick:focus-visible, .empty-add:focus-visible { outline: 3px solid var(--btn-ring); outline-offset: 2px; }
.group-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px; }
.group-chips { display: contents; }
.icon { display: inline-grid; place-items: center; flex: none; }
.icon svg { display: block; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.mix-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; line-height: 1;
  height: 36px; padding: 0 12px 0 16px; box-sizing: border-box; border: 0; border-radius: 999px;
  background: #fff; color: var(--btn-ink); font: inherit; font-size: 14px; cursor: pointer; white-space: nowrap;
  box-shadow: 0 4px 14px rgba(38, 27, 143, .14);
  transition: transform .3s var(--spring), box-shadow .2s;
}
.mix-count {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; box-sizing: border-box;
  border-radius: 999px; background: var(--btn-go); color: #fff; font-size: 11px; font-weight: 700; line-height: 1;
}
.mix-count:empty { display: none; }
.mix-down { transition: rotate .3s var(--spring); }
.mix-button[aria-expanded="true"] .mix-down { rotate: 180deg; }
.mix-button:hover { transform: scale(1.05); box-shadow: 0 4px 14px rgba(38, 27, 143, .15); }
.mix-down { width: 12px; height: 12px; }
.group-pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; line-height: 1;
  padding: 7px 12px; border: 0; border-radius: 999px;
  background: var(--btn-tint); color: var(--btn-ink); font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: transform .3s var(--spring), background .2s, opacity .18s;
}
.group-pill:hover { transform: scale(1.06); background: var(--btn-tint-hover); }
.group-pill.is-on { background: var(--btn-go); color: #fff; }
.group-pill.is-on:hover { background: var(--btn-go-hover); }
.group-pill > span { line-height: 1; }
/* (a font's capitals sit a little above the middle of its line: nudged down to the true centre) */
/* (each part's ink centred in the pill, measured: a font's capitals sit a little high in their line,
   the smaller count a little less so; the drawn ＋ and × sit at the true middle and come up to meet them) */
.group-pill .group-name, #mixLabel { translate: 0 .095em; }
.group-pill .group-count { translate: 0 .045em; }
.group-pill .group-lead, .group-pill .group-x { translate: 0 -.5px; }
.group-pill .group-count { font-size: 11px; font-weight: 700; opacity: .65; }
.group-pill:has(.group-x) { padding-left: 11px; padding-right: 9px; }
.group-pill:has(.group-lead) { padding-left: 11px; padding-right: 11px; }
.group-pill .group-lead { width: 10px; height: 10px; margin-right: -1px; }
.group-pill .group-x { width: 10px; height: 10px; opacity: .75; transition: transform .3s var(--spring), opacity .2s; }
.group-pill.is-on:hover .group-x { transform: rotate(90deg) scale(1.2); opacity: 1; }
.group-pill.is-leaving { transform: scale(0); opacity: 0; transition: transform .18s ease-in, opacity .18s ease-in; }
.group-pill.is-new, .group-bar.is-arriving .mix-button { animation: pop-in .5s var(--spring) both; animation-delay: calc(var(--k, 0) * 40ms); }
.group-pill:focus-visible, .mix-button:focus-visible { outline: 3px solid var(--btn-ring); outline-offset: 2px; }
@keyframes pop-in { from { transform: scale(0); opacity: 0; } 60% { opacity: 1; } to { transform: scale(1); opacity: 1; } }
/* the bank: every group not on Orbit, in a box under the ones that are */
.group-bank {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px;
  width: 100%; max-height: 50vh; overflow-y: auto; box-sizing: border-box;
  padding: 12px; border-radius: 20px; background: var(--surf-tint);
}
.bank-empty { margin: 0; color: var(--muted); font-size: 13px; }

/* Nobody on Orbit (every group off) */
.orbit-empty {
  position: fixed; top: 45%; left: 50%; translate: -50% -50%; z-index: 900; margin: 0;
  display: flex; align-items: center; gap: 12px; white-space: nowrap;
  padding: 8px 8px 8px 20px; border-radius: 999px; background: #fff; color: var(--btn-ink); font-size: 15px;
  box-shadow: 0 8px 24px rgba(38, 27, 143, .12); animation: pop-in .5s var(--spring) both; text-align: center;
}
.orbit-empty[hidden] { display: none; }

/* Opening Orbit: white bubbles floating on a soft wash, each a ready-made mix */
.chooser {
  position: fixed; inset: 0; z-index: 3000;
  display: flex; flex-direction: column; align-items: center; justify-content: safe center;
  padding: 24px 16px; box-sizing: border-box; overflow-y: auto;
  /* (solid, not a blur of Orbit behind it: that blur was redone every frame, over 100+ photos) */
  background: radial-gradient(circle at 30% 20%, #dad5fc, #f1effe 60%) #f1effe;
  animation: chooser-in .35s ease both;
}
/* Orbit isn't drawn while the bubbles cover it (once they've faded in); it comes back as it grows
   out of the picked one */
body.choosing .stage { visibility: hidden; transition: visibility 0s .35s; }
/* (a mix picked: Orbit drawn again under the bubbles, its circles placed without sliding, ready to be revealed) */
body.choosing.orbit-prep .stage { visibility: visible; transition: none; }
body.orbit-prep .circle { transition: none !important; }
.chooser[hidden] { display: none; }
/* (opening Orbit: the bubbles are there from the first frame, Orbit hidden under them; no fade-in) */
html.start-choosing .chooser[hidden] { display: flex; }
html.start-choosing .stage { visibility: hidden; }
html.start-choosing .chooser, .chooser.is-instant { animation: none; }
.chooser:focus { outline: none; }
.chooser.is-fading { animation: chooser-out .4s ease .1s both; }
@keyframes chooser-in { from { opacity: 0; } }
@keyframes chooser-out { to { opacity: 0; } }
body.choosing { overflow: hidden; }
.chooser-title { margin: 0 0 4px; font-size: 30px; color: var(--btn-ink); animation: pop-in .5s var(--spring) both; }
.chooser-sub { margin: 0 0 22px; color: var(--btn-ink); opacity: .75; font-size: 15px; text-align: center; }
.chooser-bubbles { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px 30px; max-width: 1120px; }
/* each one: a rounded square (gently bobbing), its name inside at the top */
.mix-bubble {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 0; border: 0; background: none; color: var(--btn-ink); font: inherit; cursor: pointer;
  animation: pop-in .6s var(--spring) both, bob 5s ease-in-out infinite;
  animation-delay: calc(var(--k) * 70ms), calc(var(--k) * -1.3s + .6s);
}
.mix-name { font-size: 17px; line-height: 1.15; text-align: center; }
.mix-blob {
  position: relative; width: 224px; height: 270px; box-sizing: border-box; padding: 28px 22px 30px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  border-radius: var(--ra); background: #fff;
  box-shadow: 0 10px 28px rgba(38, 27, 143, .14), inset 0 -6px 14px rgba(38, 27, 143, .05);
  transition: box-shadow .25s;
}
/* (a faint glint, like a soap bubble) */
.mix-blob::before { content: ""; position: absolute; top: 3.5%; left: 7%; width: 12%; height: 4.5%; border-radius: 50%; background: rgba(211, 205, 251, .28); rotate: -30deg; pointer-events: none; }
@keyframes bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -7px; } }
/* (grows a little on hover: with scale, as the pop-in animation holds transform) */
.mix-bubble { scale: 1; transition: scale .35s var(--spring); }
.mix-bubble:hover, .mix-bubble:focus-visible { scale: 1.05; outline: none; }
.mix-bubble:hover .mix-blob { box-shadow: 0 16px 36px rgba(38, 27, 143, .22); }
.mix-bubble:focus-visible .mix-blob { box-shadow: 0 0 0 4px var(--btn-ring), 0 16px 36px rgba(38, 27, 143, .22); }
.mix-faces { position: relative; display: block; width: 100%; flex: none; margin: auto 0; }
.mix-faces::before { content: ""; display: block; padding-top: 62%; }   /* (the scatter's 200 × 124 box) */
.mix-face {
  position: absolute; aspect-ratio: 1; border-radius: 50%; box-sizing: border-box; border: 2.5px solid #888;
  background: #888 center / cover no-repeat; color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center;
  box-shadow: 0 2px 6px rgba(38, 27, 143, .18);
}
.mix-face[data-party="democrat"] { border-color: var(--party-democrat); background-color: var(--party-democrat); }
.mix-face[data-party="republican"] { border-color: var(--party-republican); background-color: var(--party-republican); }
/* the mix's groups along the bottom */
.mix-pills { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 6px; max-width: 100%; }
.mix-pill { display: block; padding: 5px 9px 3px; line-height: 1.15; text-align: center; border-radius: 999px; background: var(--btn-tint); font-size: 11px; font-weight: 600; white-space: nowrap; max-width: 172px; overflow: hidden; text-overflow: ellipsis; }
.mix-pill.is-exec { background: var(--btn-go); color: #fff; }
.mix-pill.is-more { background: none; border: 1px dashed var(--hairline); }
.mix-bubble.is-own .mix-blob { justify-content: center; gap: 14px; background: rgba(255, 255, 255, .5); border: 2.5px dashed var(--hairline); box-shadow: none; }
.mix-bubble.is-own:hover .mix-blob { background: #fff; }
.mix-plus { display: grid; place-items: center; width: 64px; height: 64px; padding: 20px; box-sizing: border-box; border-radius: 50%; background: var(--btn-go); color: #fff; transition: transform .45s var(--spring); }
.mix-plus svg { stroke-width: 2.4; }
.mix-bubble.is-own:hover .mix-plus { transform: rotate(90deg); }
/* picked: it swells, the rest pop away */
.chooser.is-leaving .mix-bubble:not(.is-picked) { animation: pop-out .26s ease-in both; animation-delay: calc(var(--k) * 20ms); }
.chooser.is-leaving .mix-bubble.is-picked { animation-play-state: paused; scale: 1.05; }   /* (it stays put: Orbit opens out of it) */
.chooser.is-leaving.is-fading .mix-bubble.is-picked { animation: swell .45s ease-in both; }
/* Orbit growing out of the picked card: the new view is revealed from the card's outline outward,
   over the bubbles (which stay put underneath until it covers them). */
html.orbit-growing::view-transition-group(root) { animation-duration: .6s; }
/* the bubbles behind sink back and fade as Orbit grows over them */
html.orbit-growing::view-transition-old(root) { animation: orbit-behind .6s cubic-bezier(.32, .72, 0, 1) both; }
/* Orbit: from the card's outline, its rounded corners kept the whole way (it grows a little past
   the screen's edges, so the curves sweep off it rather than flattening into a square) */
html.orbit-growing::view-transition-new(root) { animation: orbit-grow .6s cubic-bezier(.32, .72, 0, 1) both; }
@keyframes orbit-grow {
  from { clip-path: inset(var(--grow-t) var(--grow-r) var(--grow-b) var(--grow-l) round 42px); }
  to { clip-path: inset(-90px round 42px); }
}
@keyframes orbit-behind {
  to { scale: .94; opacity: .55; }   /* (no blur: a blur of the whole screen is redrawn every frame) */
}

@keyframes pop-out { to { transform: scale(0); opacity: 0; } }
@keyframes swell { 40% { transform: scale(1.15); opacity: 1; } to { transform: scale(1.6); opacity: 0; } }
@media (max-width: 700px) {
  .chooser { justify-content: flex-start; padding-top: 28px; }
  .chooser-title { font-size: 24px; }
  .chooser-bubbles { gap: 12px; }
  .mix-bubble { gap: 5px; }
  .mix-name { font-size: 14px; }
  .mix-blob { width: min(43vw, 170px); height: min(53vw, 208px); padding: 19px 12px 20px; gap: 6px; }
  .mix-face { border-width: 2px; font-size: 9px; }
  .mix-pill { font-size: 9.5px; padding: 4px 7px 2px; max-width: 118px; }
  .mix-plus { width: 48px; height: 48px; padding: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .mix-bubble, .mix-blob, .group-pill, .group-bank, .group-pop, .group-pop *, .chooser, .orbit-empty { animation: none !important; transition: none !important; }
}
.multi-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .85);
  cursor: pointer;
  user-select: none;
}
.multi-toggle input { width: 16px; height: 16px; margin: 0; accent-color: var(--ink); cursor: pointer; }
/* Circles outside the chosen groups fade out. */
/* Circles hidden by a filter shrink away where they stand... */
.circle.filtered-out {
  --pop: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: transform .28s cubic-bezier(.55, 0, 1, .45), opacity .22s ease-in .06s, visibility 0s .28s;
}
/* ...and ones coming back jump to their place, then pop in with a slight overshoot. */
.circle.popping-in {
  transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), opacity .2s ease, visibility 0s;
}

/* Size slider, under the view toggle (top right) */
.size-filter {
  position: fixed;
  top: 60px;
  right: 14px;
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 5px 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  font-size: 14px;
  cursor: pointer;
}
.size-cut-label { min-width: 11.5em; font-weight: 600; white-space: nowrap; }
.size-filter input[type="range"] { width: 150px; margin: 0; accent-color: var(--ink); cursor: pointer; }
.size-filter:focus-within { outline: 3px solid #0022ff; outline-offset: 2px; }

@media (max-width: 700px) {
  /* phones: the size slider gets its own row, under the search bar and group filter */
  .size-filter { top: 100px; left: 14px; right: 14px; justify-content: space-between; }
  .size-filter input[type="range"] { flex: 1; width: auto; }
  .size-cut-label { min-width: 0; }
  .search { width: calc(100vw - 244px); min-width: 120px; }
  .view-sep, .view-height { display: none; }   /* phones: just "Size: Weight  ⇄ Swap" */
}

/* Phones: no hover readout at all (there's no hover; tapping opens the page). */
@media (max-width: 700px) {
  .hover-info { display: none; }
}

/* ---------- internal page ---------- */

.person { min-height: 100%; }
.person-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  min-height: var(--bar-h);
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  height: var(--nav-h);
  padding: 0 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--bg, #fff);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  flex: none;   /* never squeezed narrower than its label */
}
.nav-btn:hover { background: var(--ink); color: #fff; }
.nav-btn:focus-visible { outline: 3px solid var(--party-democrat); outline-offset: 2px; }

.sheet {
  /* Image column is 25vw and ends left of the page's center line. */
  --img-w: 25vw;
  display: grid;
  grid-template-columns: var(--img-w) minmax(0, 1fr);
  /* Photo and map on the left; bio, stances, controversies, then allies and
     opponents on the right. The last row takes any spare height, so the
     allies sit right under the controversies even when the left column is taller. */
  grid-template-areas:
    "top  top"
    "img  side"
    "img  rel"
    "news news"
    "stand stand"
    "soc  soc";
  grid-template-rows: auto auto 1fr auto auto auto;
  gap: 16px 24px;
  width: min(100% - 32px, calc(var(--img-w) + 52vw));
  margin: 24px 0 48px 12vw;
  align-items: start;
}
.sheet-top { grid-area: top; }
.sheet-img { grid-area: img; }
.sheet-side { grid-area: side; }
.relations { grid-area: rel; }

/* ---------- allies / opponents ---------- */

.relations {
  margin-bottom: 40px;   /* room for the readout bar at the bottom of the screen */
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}
.relation-col { min-width: 0; }
.relation-title { margin: 0 0 12px; font-size: 24px; text-align: center; }
.lump { position: relative; width: 100%; min-height: 60px; }
.lump .circle { transition: transform .18s ease; }
.lump .circle:hover,
.lump .circle:focus-visible { --s: 1.1; z-index: 5; }
.lump-empty { margin: 16px 0; text-align: center; color: var(--muted); }

.rel-readout {
  position: fixed;
  left: 50%;
  bottom: max(16px, var(--tray-space, 0px));   /* just above the Compare button or box (js/compare-tray.js) */
  transform: translateX(-50%);
  margin: 0;
  max-width: calc(100% - 32px);
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: 16px;
  text-align: center;
  pointer-events: none;
  z-index: 1000;
}
.rel-readout:empty { display: none; }

.page-heading,
.page-subheading {
  margin: 0;
  padding: 2px 4px;
  border-radius: 6px;
  outline: none;
  overflow-wrap: anywhere;
}
.page-heading { font-size: clamp(28px, 3.2vw, 42px); line-height: 1.15; }
.name-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0 10px; }
.party-tag { font-size: clamp(24px, 2.6vw, 34px); font-weight: 700; color: var(--party); user-select: none; }

/* Party color on the person page, matching the circle borders. */
.sheet { --party: var(--party-other); }
.sheet[data-party="democrat"] { --party: var(--party-democrat); }
.sheet[data-party="republican"] { --party: var(--party-republican); }
.page-subheading { margin-top: 4px; font-size: clamp(18px, 1.8vw, 24px); font-weight: 500; color: var(--muted); }

.position-link { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.position-link:hover { color: var(--ink); }
.secondary-role[hidden] { display: none; }

/* ---------- position page ---------- */

/* Blue→red gradient photo behind the whole page; fixed so it doesn't scroll away. */
body.position-bg {
  background: #fff url("../images/backgrounds/position.jpg") center / cover no-repeat fixed;
  min-height: 100vh;
}
.position-bg .person-bar { border-bottom-color: transparent; }

.position-page {
  width: min(100% - 32px, 900px);
  margin: 24px auto 48px;
  display: grid;
  gap: 24px;
}
.holders { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 12px; }
.holder {
  --party: var(--party-other);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px 8px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  background: #fff;
}
.holder[data-party="democrat"] { --party: var(--party-democrat); }
.holder[data-party="republican"] { --party: var(--party-republican); }
.holder:hover { border-color: var(--ink); }
.holder-photo {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 3px var(--party);
  background: #eee 50% 25% / cover no-repeat;
  flex: none;
}
.holder-name { font-size: 18px; font-weight: 600; }

.sheet-side { display: grid; gap: 16px; }
.text-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  padding: 12px 14px;
}
.card-title { margin: 0 0 6px; font-size: 17px; font-weight: 700; }
.card-text {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;        /* keep the sheet's line breaks and bullets */
  overflow-wrap: anywhere;
}
.card-text.is-empty::before { content: "—"; color: var(--muted); }
.box-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
}

.img-box {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 3 / 4;
  border: 4px solid var(--party);
  border-radius: 8px;
  background: var(--panel);
  overflow: hidden;
}
/* No photo yet: large initials in the box. */
.img-initials { font-size: clamp(40px, 6vw, 96px); font-weight: 700; color: var(--muted); }
.img-box.filled { aspect-ratio: auto; background: #fff; }
.img-box img { display: block; width: 100%; height: auto; }

.not-found { padding: 48px 16px; text-align: center; }

@media (max-width: 700px) {
  .sheet {
    --img-w: 100%;
    grid-template-columns: 1fr;
    grid-template-areas: "top" "img" "side" "rel" "news" "stand" "soc";
    grid-template-rows: none;
    width: auto;
    margin: 16px;
  }
  .img-box { width: 70%; }
  .box-pair { grid-template-columns: 1fr; }
  .relations { grid-template-columns: 1fr; }
}


/* ---------- site index (left edge, every page; js/index.js) ---------- */

/* The Index button: top left, left of the search bar (home page) or of Back (other pages). */
.index-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  height: var(--nav-h);
  padding: 0 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  flex: none;
}
.index-tab:hover { background: var(--ink); color: #fff; }
.index-tab:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
/* Home page: fixed in the corner; the search bar starts to its right. */
.index-tab.is-fixed { position: fixed; top: var(--nav-gap); left: 16px; z-index: 1001; }   /* lines up with the other pages' bars */
.has-index-tab .search { left: 116px; }
/* Orbit: Home sits between the Index button and the search bar. */
.orbit-home { position: fixed; top: var(--nav-gap); left: 116px; z-index: 1001; }
.has-index-tab:has(.orbit-home) .search { left: 220px; }
@media (max-width: 700px) {
  /* phones: just the ☰ icon, so the search bar keeps its room */
  .index-tab.is-fixed { width: 36px; padding: 0; justify-content: center; }
  .index-tab.is-fixed .index-tab-label { display: none; }
  .has-index-tab .search { left: 60px; width: calc(100vw - 290px); min-width: 100px; }
  .orbit-home { left: 60px; width: 36px; padding: 0; justify-content: center; }
  .has-index-tab:has(.orbit-home) .search { left: 104px; }
  /* every page's bar: Index and Home shrink to their icons, so the bar stays one row */
  .person-bar .index-tab, .land-bar .index-tab, .nav-home, .nav-back { width: var(--nav-h); padding: 0; justify-content: center; }
  .person-bar .index-tab-label, .land-bar .index-tab-label, .nav-home .nav-label, .nav-back .nav-label { display: none; }
}

.index-scrim {
  position: fixed;
  inset: 0;
  z-index: 1600;
  background: rgba(0, 0, 0, .25);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.site-index {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 1700;
  width: min(340px, 88vw);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 14px 0;
  border-right: 2px solid var(--ink);
  background: #fff;
  box-shadow: 8px 0 30px rgba(0, 0, 0, .18);
  transform: translateX(calc(-100% - 48px));   /* far enough that the shadow doesn't show */
  visibility: hidden;
  transition: transform .25s cubic-bezier(.3, 0, .2, 1), visibility 0s .25s;
}
body.index-open .site-index { transform: none; visibility: visible; transition-delay: 0s; }
body.index-open .index-scrim { opacity: 1; pointer-events: auto; }

.index-head { display: flex; align-items: center; justify-content: space-between; }
.index-title { margin: 0; font-size: 20px; }
.index-close {
  width: 34px; height: 34px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.index-close:hover { background: var(--ink); color: #fff; }
.index-filter {
  box-sizing: border-box;
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 7px 14px;
  border: 2px solid var(--ink);
  border-radius: 999px;
}
.index-filter:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
.index-tabs { display: flex; gap: 6px; }
.index-tabs button {
  flex: 1;
  padding: 6px 4px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.index-tabs button[aria-selected="true"] { background: var(--ink); color: #fff; }

.index-list { flex: 1; overflow-y: auto; margin: 0 -14px; padding: 0 8px 16px; overscroll-behavior: contain; }
.index-letter {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 8px 8px 4px;
  background: #fff;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}
.index-item {
  --party: var(--party-other);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
}
.index-item:hover, .index-item:focus-visible { background: var(--panel); outline: none; }
.index-item.here { background: #eef1ff; box-shadow: inset 3px 0 0 #0022ff; }
.index-photo {
  --party: var(--party-other);
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 2px var(--party);
  background: #fff 50% 25% / cover no-repeat;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
}
.index-photo[data-party="democrat"] { --party: var(--party-democrat); }
.index-photo[data-party="republican"] { --party: var(--party-republican); }
.index-photo.is-icon { border-radius: 8px; box-shadow: none; font-size: 15px; }
.index-text { min-width: 0; display: grid; }
.index-name { font-size: 14px; font-weight: 600; }
.index-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.index-empty { padding: 12px 8px; color: var(--muted); }
.index-tabs .index-fav-tab { flex: none; padding: 6px 10px; }
@media (max-width: 420px) { .index-tabs { gap: 4px; } .index-tabs button { font-size: 11px; padding: 6px 2px; } .index-tabs .index-fav-tab { padding: 6px 7px; } }
.index-star { color: #b38600; }
.index-row { display: flex; align-items: center; gap: 6px; padding-right: 6px; }
.index-row .index-item { flex: 1; min-width: 0; }
.index-row .fav-btn { width: 30px; height: 30px; font-size: 22px; flex: none; }
.index-guide { display: block; margin: 10px 8px 0; padding: 8px 12px; border: 2px solid var(--ink); border-radius: 999px;
  color: var(--ink); font-size: 14px; font-weight: 600; text-align: center; text-decoration: none; }
.index-guide:hover { background: var(--ink); color: #fff; }

/* Filter button: phones only. Swap, the group filter and the size slider stay
   hidden until it's tapped, then stack in rows under the search bar. */
.filter-toggle { display: none; }
@media (max-width: 700px) {
  .search-input::placeholder { color: transparent; }   /* just the magnifying glass */
  .has-index-tab .search { width: auto; right: 126px; min-width: 0; }
  .filter-toggle {
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 1001;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    box-sizing: border-box;
    height: 36px;
    width: 104px;
    justify-content: center;
    padding: 0;
    border: 2px solid var(--ink);
    border-radius: 999px;
    background: #fff;
    color: var(--ink);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
  }
  .filter-toggle::after { content: "▾"; font-size: 12px; transition: rotate .2s ease; }
  .filter-toggle[aria-expanded="true"]::after { rotate: 180deg; }
  .filter-toggle[aria-expanded="true"] { background: var(--ink); color: #fff; }
  .filter-toggle.is-active::before {   /* a filter is hiding people */
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #0022ff;
  }
  body:not(.filters-open) .view-bar,
  body:not(.filters-open) .group-filter,
  body:not(.filters-open) .size-filter { display: none; }
  .view-bar { top: 60px; left: 14px; right: auto; }
  .size-filter { top: 106px; }
  .group-filter { top: 148px; right: 14px; }   /* (placed under the slider by placeControls) */
  /* phones: the mix's pill under the top row */
  .group-bar { top: 60px; }
  .mix-button { height: 34px; font-size: 13px; }
}

/* The wheel (phones): drag from the top of the ring down to scroll the
   zoomed-in page sideways; the ring grows while zoomed and turns like a
   record. Its middle goes back to the main view. Desktop keeps the plain ring. */
.wheel-center, .wheel-zone { display: none; }
@media (max-width: 700px) {
  .arc {
    background: conic-gradient(from calc(-90deg + var(--spin, 0deg)) at 50% 100%,
      #0022ff 0deg, #ff0000 180deg, #0022ff 360deg);
    transform: none;
    translate: -50% 0;   /* (not transform: it would be scaled with the ring and push it off centre) */
    transform-origin: 50% 100%;
    scale: var(--wheel-scale, 1);
    transition: scale .35s ease;
  }
  /* The page of circles: slides sideways when zoomed. */
  #circles { position: absolute; top: 0; left: 0; width: 100%; height: 0; }
  .wheel-moving #circles { transition: transform .35s ease; }
  .wheel-zone {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
  }
  .wheel-center {
    position: absolute;
    left: 50%;
    bottom: 0;
    z-index: 5;
    translate: -50% 0;
    transform-origin: 50% 100%;
    scale: var(--wheel-scale, 1);
    transition: scale .35s ease;
    display: grid;
    place-items: end center;
    padding: 0 0 10px;
    border: 0;
    border-radius: 9999px 9999px 0 0;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
    pointer-events: none;   /* taps land on the touch area underneath */
  }
  .wheel-center > span { grid-area: 1 / 1; transition: opacity .2s ease; }
  .wheel-all { opacity: 0; font-size: 11px; }   /* shown 1.4x bigger with the ring */
  .zoomed .wheel-center { color: var(--ink); }
  .zoomed .wheel-hint { opacity: 0; }
  .zoomed .wheel-all { opacity: 1; }
  .wheel-all::before { content: "⤢ "; }
  .wheel-center:focus-visible { outline: 3px solid #0022ff; outline-offset: -3px; }
}

/* Position page: the title on the left, the Compare / Orbit / About switch on the right. */
.position-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 12px 24px;
}
.position-main { display: grid; gap: 6px; }
.view-switch { display: flex; }
.seg-btn[aria-selected="true"] { background: var(--ink); color: #fff; }
.view-dot { display: inline-block; width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: #e00; vertical-align: 2px; }
.view-dot[hidden] { display: none; }
.position-view[hidden], .nobody-note[hidden] { display: none; }
.nobody-note { margin: 24px 0; text-align: center; font-weight: 600; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }
/* About: tiles like the person page's. */
.position-tiles { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.position-tile { padding: 16px 18px; border-radius: 12px; }
.position-tile .card-title { padding-right: 0; }
.position-tile .news-list { margin-top: 4px; }
.tile-more { display: inline-block; margin-top: 12px; font-size: 14px; font-weight: 700; color: var(--ink); }
.tile-more[hidden] { display: none; }
.position-about-text { margin: 0; font-size: 15px; line-height: 1.55; white-space: pre-line; }
.position-about-text.is-empty { color: var(--muted); }
/* About and News down the left; the power diagram large on the right (the page widens for it). */
.position-tiles:has(.position-side:not([hidden])) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); grid-template-rows: auto 1fr; }
.position-tiles .position-side { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.position-tiles .position-side[hidden], .position-tiles .position-powers[hidden] { display: none; }
.position-page:has(#viewAbout:not([hidden]) .position-side:not([hidden])) { width: min(100% - 32px, 1200px); }
/* The map of the seat's area, under the powers. */
.position-side .position-area { margin-top: 0; padding: 14px 18px 10px; border: 1px solid var(--line); border-radius: 12px; }
.position-side .position-area .area-mini-label { font-size: 15px; }
.position-area .area-mini-map { height: 260px; }
.position-powers .gen-diagram { margin-top: 14px; gap: 0 56px; }
.position-powers .gen-d-list { gap: 10px; }
.position-powers .gen-d-card { padding: 8px 12px; }
.position-powers .gen-d-card b { font-size: 15px; }
.position-powers .gen-d-card small { font-size: 12.5px; }
.position-powers .gen-d-head { font-size: 12px; }
.position-powers .gen-d-name { font-size: 15px; }
@media (max-width: 700px) {
  .position-tiles, .position-tiles:has(.position-side:not([hidden])) { grid-template-columns: 1fr; grid-template-rows: none; }
  .position-tiles .position-side { grid-column: auto; grid-row: auto; order: 1; }
  .position-area .area-mini-map { height: 200px; }
  .position-tiles .position-news { order: 2; }
}

/* Phones: the position page is white, and the colorful background sits only
   behind the shown view (Compare or About) under the title, edge to edge, reaching the
   bottom of the screen. */
@media (max-width: 700px) {
  body.position-bg {
    background: #fff;
    display: flex;
    flex-direction: column;
  }
  .position-bg .position-page {
    flex: 1;
    margin-bottom: 0;
    grid-template-rows: auto 1fr;
  }
  .position-bg .position-view {
    margin: 0 -16px;   /* out to the screen edges (the page has 16px gutters) */
    padding: 20px 16px 40px;
    background: url("../images/backgrounds/position.jpg") center / cover no-repeat;
  }
}

/* "Show more" on the person page's text boxes: appears in the top right corner
   when the box is hovered (always shown on touch screens) and swaps the short
   version for the full text. */
.text-card { position: relative; }
.show-more {
  position: absolute;
  top: 10px;
  right: 10px;
  padding: 3px 10px;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s ease;
}
.show-more[hidden] { display: none; }
.text-card:hover .show-more,
.text-card:focus-within .show-more,
.show-more[aria-expanded="true"] { opacity: 1; }
.show-more:hover { background: var(--ink); color: #fff; }
.show-more:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; opacity: 1; }
.text-card .card-title { padding-right: 96px; }   /* room for the button */
@media (hover: none) { .show-more { opacity: 1; } }

/* Position page: a "Previously" button in the top bar (after Home) with a
   dropdown listing people who held or ran for this position but no longer do. */
.previously { position: relative; }
.previously[hidden] { display: none; }
.previously-btn { font-family: inherit; font-size: 14px; font-weight: 600; cursor: pointer; }
.previously-btn[aria-expanded="true"] { background: var(--ink); color: #fff; }
.previously-count { font-weight: 500; }
.prev-short { display: none; }
@media (max-width: 700px) { .prev-long { display: none; } .prev-short { display: inline; } }
.previously-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 1500;
  width: 280px;
  max-width: calc(100vw - 32px);
  max-height: 60vh;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .15);
}
.previously-panel[hidden] { display: none; }
.previously-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.previous-person { width: 100%; box-sizing: border-box; padding: 6px 12px 6px 6px; }
.previous-person .holder-photo { width: 40px; height: 40px; display: grid; place-items: center; font-size: 13px; font-weight: 700; }
.previous-person .holder-name { font-size: 15px; }
@media (max-width: 700px) {
  .person-bar { position: relative; }
  .previously { position: static; }   /* dropdown spans the bar on phones */
  .previously-panel { left: 16px; right: 16px; width: auto; top: calc(100% + 4px); }
}

/* Position page, "Compared": a column per person (3 or fewer), each a
   miniature of their person page; or, for more, a miniature home-page ring. */
.compare-cols {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 320px));
  justify-content: center;
  gap: 16px;
  align-items: stretch;
}
.compare-cols[hidden] { display: none; }
.mini-person {
  --party: var(--party-other);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5em;
  padding: 1.2em 1.1em 1.1em;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #fff;
  text-align: center;
}
.mini-person[data-party="democrat"] { --party: var(--party-democrat); }
.mini-person[data-party="republican"] { --party: var(--party-republican); }
.mini-photo {
  width: 3.5em;    /* 7× the card's text size (its own font-size is 2em, for the initials) */
  height: 3.5em;
  border-radius: 50%;
  border: 3px solid var(--ink);
  box-shadow: 0 0 0 4px var(--party);
  background: #eee 50% 25% / cover no-repeat;
  display: grid;
  place-items: center;
  color: var(--ink);
  font-size: 2em;
  font-weight: 700;
  text-decoration: none;
  margin-bottom: 6px;
}
.mini-person.is-holder .mini-photo {
  box-shadow: 0 0 0 4px var(--party), 0 0 0 6px #fff, 0 0 0 10px #f2b600;
}
.mini-name { margin: 4px 0 0; font-size: 1.19em; line-height: 1.25; }
.mini-bio { margin: 4px 0 0; font-size: .875em; line-height: 1.45; }
.mini-head { display: flex; flex-direction: column; align-items: center; gap: .5em; }
.mini-body { width: 100%; display: flex; flex-direction: column; gap: .5em; }
.mini-section { width: 100%; text-align: left; }
.mini-heading { margin: 8px 0 4px; font-size: .8125em; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.mini-list { margin: 0; padding-left: 18px; font-size: .875em; line-height: 1.45; }

/* Phones: one person per row. */
@media (max-width: 700px) {
  .compare-cols { grid-template-columns: minmax(0, 1fr); }
}

/* Position page: shown under the title only when no one holds the seat. */
.vacant-note { margin: 8px 0 0; font-size: 15px; color: var(--muted); }
.vacant-note[hidden] { display: none; }

/* Home page: the blue→red photo behind everything. Desktop has no ring (the
   photo's left-blue / right-red does that job); phones keep the wheel, outlined
   in white so it stands out from the photo, with white text in its middle. */
body.home { background: #fff url("../images/backgrounds/position.jpg") center / cover no-repeat fixed; min-height: 100vh; }
.arc-outline { position: absolute; inset: 0; pointer-events: none; }
@media (min-width: 701px) {
  .home .arc { display: none; }
}
@media (max-width: 700px) {
  .arc-outline {
    filter: drop-shadow(3px 0 0 #fff) drop-shadow(-3px 0 0 #fff) drop-shadow(0 3px 0 #fff) drop-shadow(0 -3px 0 #fff);
  }
  .wheel-center, .zoomed .wheel-center { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .55); }
}

/* "Connect the dots": lines between allies, behind the circles. Each is a
   thin div from one centre, rotated towards the other; darker = stronger ally.
   Lines stay invisible until someone is hovered, then only theirs show. */
.links { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 0; pointer-events: none; }
.links[hidden] { display: none; }
.link {
  position: absolute;
  height: 1.5px;
  margin-top: -.75px;
  transform-origin: 0 50%;
  background: #111;
  opacity: 0;
  transition: left .3s ease, top .3s ease, width .3s ease, transform .3s ease, opacity .2s ease;
}
/* Only the hovered person's lines show. */
.link.lit { opacity: calc(.4 + var(--strength, 1) * .1); height: 2.5px; margin-top: -1.25px; }

/* ---------- Compare (home page, js/compare-tray.js) ---------- */

/* Closed: a pill at the bottom centre. Open: it grows into a small box. */
.compare-tray {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: 1050;
  transform: translateX(-50%);
}
.compare-open {
  box-sizing: border-box;
  height: 40px;
  padding: 0 22px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .18);
}
.compare-open:hover { background: var(--ink); color: #fff; }
.compare-open:focus-visible, .compare-go:focus-visible, .compare-close:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
.compare-box {
  display: none;
  box-sizing: border-box;
  width: min(460px, calc(100vw - 32px));
  padding: 10px 12px 12px;
  border: 2px solid var(--ink);
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .22);
  transform-origin: 50% 100%;
}
.compare-tray.open .compare-open { display: none; }
.compare-tray.open .compare-box { display: block; animation: compare-grow .22s cubic-bezier(.3, 1.3, .6, 1); }
@keyframes compare-grow { from { transform: scale(.3, .25); opacity: .4; } to { transform: none; opacity: 1; } }
.compare-tray.drop-hover .compare-box { border-color: #0022ff; box-shadow: 0 0 0 4px rgba(0, 34, 255, .2), 0 8px 30px rgba(0, 0, 0, .22); }
.compare-tray.dragging .compare-slot:not(.filled) { border-color: #0022ff; }
.compare-tray.refuse .compare-box { animation: compare-shake .4s ease; }
@keyframes compare-shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }
.compare-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.compare-title { flex: 1; font-size: 15px; font-weight: 700; }
.compare-hint { margin-left: 6px; font-size: 12px; font-weight: 500; color: var(--muted); }
.compare-close {
  width: 28px; height: 28px; padding: 0;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.compare-close:hover { background: var(--panel, #f0f0f0); }
.compare-go {
  padding: 6px 16px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.compare-go:hover:not(:disabled) { background: #0022ff; border-color: #0022ff; }
.compare-go:disabled { background: #e4e4e4; border-color: #cfcfcf; color: #9a9a9a; cursor: not-allowed; }
.compare-slots { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.compare-slot {
  --party: var(--party-other);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-height: 74px;
  padding-top: 4px;
  border: 2px dashed #cfcfcf;
  border-radius: 12px;
  transition: border-color .15s ease;
}
.compare-slot.filled { border-style: solid; border-color: var(--line); }
.compare-slot[data-party="democrat"] { --party: var(--party-democrat); }
.compare-slot[data-party="republican"] { --party: var(--party-republican); }
.compare-face {
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 2px var(--party);
  background: #eee 50% 25% / cover no-repeat;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
}
.compare-name { max-width: 100%; padding: 0 4px; box-sizing: border-box; font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.compare-remove {
  position: absolute; top: 2px; right: 2px;
  width: 20px; height: 20px; padding: 0;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 16px; line-height: 1; cursor: pointer;
}
.compare-remove:hover { background: var(--ink); color: #fff; }

/* The circle being dragged: a copy that follows the pointer. */
.comparing .compare-draggable .circle[data-id] { cursor: grab; touch-action: none; }
.circle.compare-source { opacity: .3; }
.circle.compare-ghost {
  position: fixed;
  z-index: 2000;
  margin: 0;
  pointer-events: none;
  cursor: grabbing;
  transition: none;
  box-shadow: 0 0 0 var(--party-ring) var(--party), 0 12px 28px rgba(0, 0, 0, .35);
}
.circle.compare-ghost.returning { transition: left .45s cubic-bezier(.34, 1.56, .64, 1), top .45s cubic-bezier(.34, 1.56, .64, 1); }
.circle.compare-ghost.landing { transition: left .3s ease, top .3s ease, transform .3s ease, opacity .3s ease; }

/* Phones: the wheel owns the bottom centre, so the button sits bottom right;
   opened, the box spans the bottom of the screen. */
@media (max-width: 700px) {
  .compare-tray { left: auto; right: 12px; bottom: 12px; transform: none; }
  .compare-tray.open { left: 12px; }
  .compare-box { width: 100%; }
  .compare-open { height: 36px; padding: 0 14px; font-size: 14px; }
}

/* ---------- compare page (compare.html) ---------- */
.compare-main { width: min(100% - 32px, 1200px); margin: 16px auto 48px; }
.compare-grid { display: grid; gap: 18px; align-items: stretch; }
.compare-grid[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 900px; margin: 0 auto; }
.compare-grid[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.compare-grid[data-count="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 900px; margin: 0 auto; }
.mini-person.is-link { color: var(--ink); text-decoration: none; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.mini-person.is-link:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(0, 0, 0, .18); }
.mini-person.is-link:focus-visible { outline: 3px solid #0022ff; outline-offset: 3px; }
@media (max-width: 700px) {
  .compare-grid[data-count] { grid-template-columns: minmax(0, 1fr); }
}
.compare-main > .page-heading { text-align: center; margin-bottom: 18px; }

/* While the Compare box is open, the circles move up out of its way (js/main.js
   leaves room at the bottom); on phones the wheel is hidden. */
@media (max-width: 700px) {
  .comparing .arc-outline, .comparing .wheel-center, .comparing .wheel-zone { display: none; }
}

/* Compare on the person page: the page's own person can't be removed, and
   the page gets room at the bottom so the open box doesn't hide the circles. */
.compare-slot.pinned { border-color: var(--ink); }
.compare-tray[hidden] { display: none; }
body.person.comparing::after { content: ""; display: block; height: 180px; }

/* A slot just filled by clicking a circle pops in. */
.compare-slot.just-added { animation: compare-pop .35s cubic-bezier(.3, 1.6, .6, 1); }
@keyframes compare-pop { from { transform: scale(.6); } to { transform: none; } }

/* Meters at the bottom of each mini card (js/cards.js): Popularity and Power,
   grey (low) to gold (high), and left/right, blue to red. A white thumb marks
   the person's score. The card's text scales with how many meters are shown:
   fewer meters, a little larger. */
.mini-person { font-size: var(--fit, 17px); }
.mini-meters { width: 100%; display: grid; gap: 7px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.mini-meter { display: grid; grid-template-columns: 6.6em 1fr; align-items: center; gap: 8px; font-size: .8em; }
.meter-label { font-weight: 700; text-align: left; color: var(--muted); white-space: nowrap; }
.meter-track {
  position: relative;
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, #111, #f2b600);
}
.meter-politics .meter-track { background: linear-gradient(90deg, var(--party-democrat), #8a2be2 50%, var(--party-republican)); }
.meter-thumb {
  position: absolute;
  top: 50%;
  left: calc(var(--v) * 1%);
  width: 14px;
  height: 14px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}


/* Segmented buttons (one joined pill), e.g. the bar chart's metric switch. */
.seg-btn {
  padding: 6px 18px;
  border: 2px solid var(--ink);
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.seg-btn + .seg-btn { margin-left: -2px; }
.seg-btn:first-child { border-radius: 999px 0 0 999px; }
.seg-btn:last-child { border-radius: 0 999px 999px 0; }
.seg-btn[aria-pressed="true"] { background: var(--ink); color: #fff; }
.seg-btn:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; position: relative; }
.compare-grid[hidden] { display: none; }
.line-plot { position: relative; width: 100%; }
.line-track {
  position: absolute;
  height: 10px;
  margin-top: -5px;
  border-radius: 999px;
  background: linear-gradient(90deg, #111, #f2b600);
}
.line-plot[data-kind="politics"] .line-track { background: linear-gradient(90deg, var(--party-democrat), #8a2be2 50%, var(--party-republican)); }
.line-end { position: absolute; font-size: 12px; font-weight: 700; color: var(--muted); white-space: nowrap; }
.line-end.low { left: 0; }
.line-end.high { right: 0; }
.line-dot {
  position: absolute;
  width: 12px; height: 12px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  z-index: 2;
}
.line-stem { position: absolute; width: 2px; margin-left: -1px; background: var(--ink); opacity: .5; }
.line-person {
  --party: var(--party-other);
  position: absolute;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translate(-50%, calc(var(--d) / -2));
  color: var(--ink);
  text-decoration: none;
}
.line-person[data-party="democrat"] { --party: var(--party-democrat); }
.line-person[data-party="republican"] { --party: var(--party-republican); }
.line-face {
  width: var(--d); height: var(--d);
  border-radius: 50%;
  border: 3px solid var(--ink);
  box-shadow: 0 0 0 4px var(--party);
  background: #eee 50% 25% / cover no-repeat;
  display: grid; place-items: center;
  font-size: calc(var(--d) * .3); font-weight: 700;
  transition: transform .15s ease;
}
.line-person:hover .line-face { transform: scale(1.08); }
.line-person:focus-visible .line-face { outline: 3px solid #0022ff; outline-offset: 6px; }
.line-note { margin: 12px 0 0; font-size: 13px; color: var(--muted); text-align: center; }

/* Desktop: the compare and position pages fit the window without scrolling.
   The page is a column (top bar, header, then the cards or ring filling what's
   left); js/cards.js shrinks the card text to fit, and the position page's
   ring takes the remaining height. Phones scroll as usual. */
@media (min-width: 701px) {
  body.compare-page, body.position-bg { height: 100vh; display: flex; flex-direction: column; }
  .compare-page .person-bar, .position-bg .person-bar { flex: none; }
  .compare-main { flex: 1; min-height: 0; margin: 8px auto 12px; display: flex; flex-direction: column; }
  .compare-main > .page-heading { margin: 0 0 8px; font-size: 32px; }
  .compare-grid[data-count="4"] { max-width: 1200px; }
  .position-bg .position-page { flex: 1; min-height: 0; margin: 12px auto 12px; gap: 14px; grid-template-rows: auto 1fr; }
  .position-bg .position-page .page-heading { font-size: 34px; }
  .position-bg .position-page { grid-template-rows: auto 1fr; }
  /* About can run longer than the window: the whole page scrolls (not the
     column of tiles), so the scrollbar sits at the far right, over the
     background. */
  html:has(body.position-bg #viewAbout:not([hidden])) { overflow: hidden; }
  body.position-bg:has(#viewAbout:not([hidden])) { overflow-y: auto; }
  body.position-bg:has(#viewAbout:not([hidden])) .position-page { flex: none; }
}


/* The bar on the compare page: spans the grid, below the cards (2–3 people)
   or between the two rows (4). */
.compare-bar {
  grid-column: 1 / -1;
  padding: 8px 14px 6px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #fff;
}
.bar-head { display: flex; justify-content: center; margin-bottom: 4px; }
.bar-head .seg-btn { font-size: 12px; padding: 3px 12px; }
.compare-bar .line-end { transform: translateY(-50%); max-width: 58px; white-space: normal; line-height: 1.15; font-size: 11px; }
.compare-bar .line-end.high { text-align: right; }
.compare-bar .line-note { margin: 2px 0 0; font-size: 12px; }
.compare-bar .line-note[hidden] { display: none; }
/* On the compare page the whole card is the link, so its button is dropped to save room. */
.compare-bar .line-face { border-width: 2px; box-shadow: 0 0 0 3px var(--party); }
/* Four people: the top three stances and controversies each, to save room. */

/* Person page: the meters to the right of the name and position. */
.sheet-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name meters" "pos meters"; column-gap: 24px; align-items: center; }
.sheet-top .name-row { grid-area: name; }
.sheet-top .page-subheading { grid-area: pos; }
.person-meters { grid-area: meters; width: min(320px, 34vw); font-size: 16px; }
.person-meters .mini-meters { margin: 0; padding: 0; border: 0; }
@media (max-width: 700px) {
  .sheet-top { grid-template-columns: 1fr; grid-template-areas: "name" "pos" "meters"; }
  .person-meters { width: 100%; margin-top: 10px; }
}
/* Position page: the bar spans the card columns. */
.compare-cols > .compare-bar { grid-column: 1 / -1; }

/* Mini cards, consolidated: photo on the left with the name and status beside
   it, then the text at full width. The whole card links to the person's page
   (arrow in the corner, lift on hover). */
.mini-person { position: relative; align-items: stretch; text-align: left; padding: 1em 1.1em 1.1em; }
.mini-head { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: .9em; }
.mini-head .mini-photo { width: 2.4em; height: 2.4em; font-size: 1.6em; margin: 0; border-width: 2px; box-shadow: 0 0 0 3px var(--party); }
.mini-person.is-holder .mini-head .mini-photo { box-shadow: 0 0 0 3px var(--party), 0 0 0 5px #fff, 0 0 0 8px #f2b600; }
.mini-who { display: flex; flex-direction: column; align-items: flex-start; gap: .3em; min-width: 0; padding-right: 1.4em; }
.mini-name { margin: 0; font-size: 1.25em; line-height: 1.2; }
.mini-bio { text-align: left; font-size: .95em; margin: .2em 0 0; }
.mini-list { font-size: .95em; }
.mini-go {
  position: absolute; top: .7em; right: .8em;
  font-size: 1.2em; font-weight: 700; color: var(--muted);
  transition: transform .15s ease, color .15s ease;
}
.mini-person.is-link:hover .mini-go { color: var(--ink); transform: translateX(3px); }
.mini-person.is-link:hover { border-color: var(--ink); }
/* Four people (wide, short cards on desktop): stances and controversies side by side. */
@media (min-width: 701px) {
  .compare-grid[data-count="4"] .mini-body { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1.2em; }
}
/* Secondary information on the cards: the bio stays small. */
.mini-person .mini-bio { font-size: .78em; color: #333; }

/* Cards side by side line up section by section: each card spans one shared
   grid row per section (header, bio, stances, controversies), so every
   section starts at the same height in every card of the row. */
@supports (grid-template-rows: subgrid) {
  .compare-grid > .mini-person, .compare-cols > .mini-person {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: .55em;
    align-content: start;
  }
  .compare-grid > .mini-person .mini-body, .compare-cols > .mini-person .mini-body { display: contents; }
  .mini-person .mini-bio { margin: 0; }
  .mini-person .mini-head { align-self: start; }
  @media (min-width: 701px) {
    /* Four people: stances and controversies share one row, side by side. */
    .compare-grid[data-count="4"] > .mini-person { grid-row: span 3; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 1.2em; }
    .compare-grid[data-count="4"] > .mini-person .mini-head { grid-column: 1 / -1; }
  }
}
.mini-section.is-empty { min-height: 0; }

/* Person page: a text box with more to show is clickable as a whole. */
.text-card:has(.show-more:not([hidden])) { cursor: pointer; }
.text-card:has(.show-more:not([hidden])):hover { border-color: #bbb; }

/* Card header: the photo sits at the top, so it lines up across cards even
   when a neighbour's name wraps onto more lines. */
.mini-head { align-items: start; }
.mini-who { padding-top: .15em; }
/* Under the header: the bio in a shaded box (left half) beside a box with the
   person's status, e.g. Holds this seat / Running (right half). */
.mini-info { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .5em; align-items: start; }
.mini-info:has(.mini-bio:only-child) { grid-template-columns: 1fr; }
/* Narrow cards (three across): the bio gets more of the width. */
.compare-cols[style*="--cols: 3"] .mini-info, .compare-grid[data-count="3"] .mini-info { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.mini-person .mini-info .mini-bio { margin: 0; padding: .55em .7em; border-radius: 10px; background: #f3f3f5; font-size: .78em; line-height: 1.4; }
@supports (grid-template-rows: subgrid) {
  @media (min-width: 701px) {
    .compare-grid[data-count="4"] > .mini-person .mini-info { grid-column: 1 / -1; }
  }
}

/* Names: clear of the corner arrow; a little smaller on narrow (three-across) cards. */
.mini-who { padding-right: 1.6em; }
.compare-cols[style*="--cols: 3"] .mini-name, .compare-grid[data-count="3"] .mini-name { font-size: 1.12em; }
.mini-head { padding-right: 1.5em; }
.mini-who { padding-right: 0; }
.mini-name { overflow-wrap: normal; }
.mini-name { min-width: 0; max-width: 100%; }
/* Position page with four people: the compare page's 2 × 2 layout. */
.compare-cols.compare-grid[data-count="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); justify-content: stretch; max-width: none; }
.position-page.is-wide { width: min(100% - 32px, 1200px); }
/* (No card has a status box any more, so the bio always takes the full width.) */
.mini-info:not(:has(.mini-status)) { grid-template-columns: 1fr !important; }

/* Compare page: chips for the people compared (× to remove) and + to add. */
.compare-people { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; margin: -2px auto 12px; }
.person-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 3px 4px 3px 4px;
  border: 1px solid var(--line); border-radius: 999px; background: #fff;
  font-size: 13px; font-weight: 600;
}
.chip-face {
  --party: var(--party-other);
  width: 24px; height: 24px; border-radius: 50%;
  border: 1.5px solid var(--ink); box-shadow: 0 0 0 2px var(--party);
  background: #eee 50% 25% / cover no-repeat;
  display: grid; place-items: center; font-size: 9px; font-weight: 700; flex: none;
}
.chip-face[data-party="democrat"] { --party: var(--party-democrat); }
.chip-face[data-party="republican"] { --party: var(--party-republican); }
.chip-x, .chip-plus {
  width: 24px; height: 24px; padding: 0;
  border: 0; border-radius: 50%; background: transparent;
  color: var(--muted); font: inherit; font-size: 17px; line-height: 1; cursor: pointer;
}
.chip-x:hover { background: var(--ink); color: #fff; }
.chip-plus { width: 32px; height: 32px; border: 2px dashed #9a9a9a; background: #fff; color: var(--ink); font-size: 20px; font-weight: 700; }
.chip-plus:hover { border-style: solid; border-color: var(--ink); }
.chip-x:focus-visible, .chip-plus:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
.chip-add { position: relative; }
.chip-search {
  width: 220px; box-sizing: border-box;
  padding: 6px 12px; border: 2px solid var(--ink); border-radius: 999px;
  font: inherit; font-size: 13px; background: #fff;
}
.chip-results {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  width: 280px; max-height: 320px; overflow-y: auto;
  margin: 0; padding: 6px; list-style: none;
  border: 1px solid var(--line); border-radius: 12px; background: #fff;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .15);
}
.chip-results[hidden] { display: none; }
.chip-result { display: flex; align-items: center; gap: 9px; padding: 6px 8px; border-radius: 8px; cursor: pointer; }
.chip-result.active, .chip-result:hover { background: var(--panel, #f1f1f1); }
.chip-result-text { display: flex; flex-direction: column; min-width: 0; }
.chip-result-text b { font-size: 13px; }
.chip-result-text small { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Bio box: a touch smaller. */
.mini-person .mini-info .mini-bio { font-size: .72em; padding: .45em .65em; line-height: 1.35; }

/* Four people (compare page and four-candidate position pages): the page scrolls. */
@media (min-width: 701px) {
  body.compare-page:has(.compare-grid[data-count="4"]),
  body.position-bg:has(#viewCompare:not([hidden]) .compare-cols[data-count="4"]) { height: auto; min-height: 100vh; }
  .compare-main:has(.compare-grid[data-count="4"]) { flex: none; }
  .position-bg .position-page:has(#viewCompare:not([hidden]) .compare-cols[data-count="4"]) { flex: none; }
}
/* Scrolling pages keep the photo fixed behind them, edge to edge. */
html:has(body.position-bg) { background: #fff url("../images/backgrounds/position.jpg") center / cover no-repeat fixed; }

/* The position held or sought, under the name on compare cards. */
.mini-who .mini-role { margin: 0; font-size: .7em; font-weight: 600; color: #555; line-height: 1.25; }
.mini-person.is-holder .mini-who .mini-role { color: #7a5a00; }

/* "Select multiple": a selected circle stays a little bigger (js/main.js) and
   gets a white halo outside its party ring. */
.circle.selected {
  box-shadow: 0 0 0 var(--party-ring) var(--party), 0 0 0 calc(8px / var(--s)) #fff, 0 2px 12px calc(8px / var(--s)) rgba(0, 0, 0, .25);
}

/* One person on a position page: a wider card, so the bar under it has room. */
@media (min-width: 701px) {
  .compare-cols[data-count="1"] { grid-template-columns: minmax(0, 560px); }
}

/* ---------- Fact check mode (js/factcheck.js) ---------- */

/* Tints: what the last fact check found about each piece of text. */
.fact-mode [data-fc-status] {
  --fc: 120, 120, 140;
  cursor: help;
  border-radius: 6px;
  background-color: rgba(var(--fc), .13);
  box-shadow: inset 0 0 0 1.5px rgba(var(--fc), .55);
  transition: background-color .15s ease, box-shadow .15s ease;
}
.fact-mode [data-fc-status="key"] { --fc: 220, 38, 38; }
.fact-mode [data-fc-status="unsure"] { --fc: 217, 140, 0; }
.fact-mode [data-fc-status="fixed"] { --fc: 37, 99, 235; }
.fact-mode [data-fc-status="ok"] { --fc: 22, 163, 74; }
.fact-mode [data-fc-status]:hover,
.fact-mode [data-fc-status].fc-active { background-color: rgba(var(--fc), .24); box-shadow: inset 0 0 0 2px rgba(var(--fc), .9); }
/* Inline text gets a little breathing room; boxes keep their own padding. */
.fact-mode .page-heading[data-fc-status], .fact-mode .page-subheading[data-fc-status],
.fact-mode .party-tag[data-fc-status], .fact-mode .mini-name[data-fc-status],
.fact-mode .mini-role[data-fc-status] { padding: 0 .2em; margin-left: -.2em; }
.fact-mode .mini-section[data-fc-status], .fact-mode .card-text[data-fc-status],
.fact-mode .mini-meter[data-fc-status] { padding: .25em .4em; margin: -.25em -.4em; }
/* Faces on the bar: a colored ring instead of a tint. */
.fact-mode .line-person[data-fc-status] { background-color: transparent; box-shadow: none; }
.fact-mode .line-person[data-fc-status] .line-face { box-shadow: 0 0 0 4px rgb(var(--fc)); }
.fact-mode .jr-face[data-fc-status], .fact-mode .jr-face[data-fc-status]:hover, .fact-mode .jr-face[data-fc-status].fc-active { border-radius: 50%; background-color: #fff; box-shadow: 0 0 0 4px rgb(var(--fc)); }   /* the Learn journey's faces: a ring in the check's color */

/* The toggle: a nav button beside Index, filled while on. */
.fc-toggle[aria-pressed="true"] { background: var(--ink); color: #fff; }

/* The popup with the notes. */
.fc-pop {
  position: fixed;
  z-index: 3000;
  width: min(400px, calc(100vw - 16px));
  max-height: min(60vh, 520px);
  overflow-y: auto;
  padding: 12px 14px 10px;
  background: #fff;
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 14px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .25);
  font-size: 13px;
  line-height: 1.42;
  text-align: left;
}
.fc-pop[hidden] { display: none; }
.fc-pop.is-pinned { border-width: 2px; }
.fc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.fc-title { font-weight: 800; font-size: 14px; }
.fc-date { color: #666; font-size: 11.5px; white-space: nowrap; }
.fc-caveat { margin: 0 0 8px; padding: 6px 8px; border-radius: 8px; background: #f3f3f5; color: #444; font-size: 12px; }
.fc-field + .fc-field { margin-top: 10px; padding-top: 8px; border-top: 1px solid #e6e6ea; }
.fc-field-title { margin: 0 0 6px; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: #666; }
.fc-item + .fc-item { margin-top: 10px; }
.fc-item-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fc-chip {
  --fc: 120, 120, 140;
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(var(--fc), .14);
  color: rgb(var(--fc));
  font-size: 11px;
  font-weight: 700;
  filter: saturate(1.2) brightness(.8);
}
.fc-chip.is-key { --fc: 220, 38, 38; }
.fc-chip.is-unsure { --fc: 217, 140, 0; }
.fc-chip.is-fixed { --fc: 37, 99, 235; }
.fc-chip.is-ok { --fc: 22, 163, 74; }
.fc-chance { color: #555; font-size: 11.5px; }
.fc-pop p { margin: 4px 0 0; }
.fc-old { color: #777; text-decoration: line-through; text-decoration-color: rgba(0, 0, 0, .35); }
.fc-old b, .fc-new b { text-decoration: none; display: inline-block; }
.fc-why, .fc-hint { color: #555; font-size: 12px; }
.fc-reason { white-space: pre-line; }
.fc-none { color: #555; }
.fc-none.is-ok { color: #157a3c; font-weight: 600; }
.fc-sources { margin: 5px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 2px; }
.fc-sources li::before { content: "↗ "; color: #888; }
.fc-sources a { color: #1d4ed8; font-size: 12px; word-break: break-all; }

/* Legend (bottom left while the mode is on). */
.fc-legend {
  position: fixed;
  left: 12px;
  bottom: 12px;
  z-index: 1200;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  max-width: calc(100vw - 24px);
  padding: 6px 12px;
  background: rgba(255, 255, 255, .94);
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  font-size: 11.5px;
  pointer-events: none;
}
.fc-legend[hidden] { display: none; }
.fc-legend span { display: inline-flex; align-items: center; gap: 4px; }
.fc-legend i { width: 10px; height: 10px; border-radius: 3px; background: rgb(120, 120, 140); }
.fc-legend i.is-key { background: rgb(220, 38, 38); }
.fc-legend i.is-unsure { background: rgb(217, 140, 0); }
.fc-legend i.is-fixed { background: rgb(37, 99, 235); }
.fc-legend i.is-ok { background: rgb(22, 163, 74); }
/* Phones: above the Compare button, smaller. */
@media (max-width: 700px) {
  .fc-legend { bottom: auto; top: auto; left: 8px; right: 8px; bottom: 64px; border-radius: 12px; justify-content: center; font-size: 10.5px; }
}
.fc-toggle-short { display: none; }
@media (max-width: 700px) { .fc-toggle-long { display: none; } .fc-toggle-short { display: inline; } }

/* Connect the dots, hovering someone: people not joined to them grey out (js/main.js). */
.circle.unlinked { filter: grayscale(1) contrast(.5) brightness(1.3); }   /* solid, so lines stay behind */

/* Fact check mode, allies and opponents on a person page: a grey ring when the
   reason is recorded (hover for it); the circle keeps its party ring. */
.fact-mode .lump .circle { cursor: help; }
.fact-mode .lump .circle[data-fc-status] {
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 var(--party-ring) var(--party), 0 0 0 calc(9px / var(--s)) rgba(var(--fc), .85);
}

/* ---------- Maps (js/areas.js, js/map.js) ---------- */

/* Person page: the area they represent, under the photo. */
.area-mini {
  display: grid;
  gap: 6px;
  margin-top: 16px;
  padding: 10px 10px 8px;
  border: 1.5px solid var(--ink);
  border-radius: 14px;
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease;
}
.area-mini[hidden] { display: none; }
.area-mini:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0, 0, 0, .12); }
.area-mini-label { font-size: 14px; line-height: 1.3; }
.area-mini-verb { color: var(--muted); }
.area-mini-map { display: block; height: 190px; border-radius: 9px; overflow: hidden; background: #eef0f3; }
.area-mini-map.is-failed::after { content: "Map unavailable"; display: grid; place-items: center; height: 100%; color: var(--muted); font-size: 13px; }
.area-mini-canvas { width: 100%; height: 100%; }
.area-mini-go { justify-self: end; font-size: 12px; font-weight: 700; color: var(--muted); }
.area-mini:hover .area-mini-go { color: var(--ink); }
.area-mini .maplibregl-ctrl-attrib { font-size: 9px; }

/* Map page (map.html): the map fills the window under the top bar; controls
   float top left; the details panel slides in on the right (bottom on phones). */
body.map-page { height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
.map-page .person-bar { flex: none; background: #fff; }
.map-main { position: relative; flex: 1; min-height: 0; }
.map-canvas, .map-canvas.maplibregl-map { position: absolute; inset: 0; background: #eef0f3; }
.map-error { margin: 40px auto; max-width: 420px; text-align: center; color: var(--muted); }

.map-controls {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  display: grid; gap: 10px; width: min(380px, calc(100% - 24px));
  padding: 12px 14px; background: rgba(255, 255, 255, .96);
  border: 1.5px solid var(--ink); border-radius: 16px; box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  font-size: 13px;
}
.map-where { display: grid; gap: 6px; margin: 0; }
.map-where-label { font-weight: 800; font-size: 14px; }
.map-where-row { display: flex; gap: 6px; }
.map-where-row input { flex: 1; min-width: 0; padding: 7px 12px; border: 1.5px solid var(--ink); border-radius: 999px; font: inherit; }
.map-btn { padding: 6px 12px; border: 1.5px solid var(--ink); border-radius: 999px; background: var(--ink); color: #fff; font: inherit; font-weight: 700; cursor: pointer; }
.map-btn + .map-btn { background: #fff; color: var(--ink); }
.map-where-note { margin: 0; color: var(--muted); font-size: 12px; }
.map-where-note[hidden] { display: none; }
.map-row { display: grid; grid-template-columns: 52px 1fr; align-items: center; gap: 8px; }
.map-row-label { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.map-seg { display: flex; flex-wrap: wrap; gap: 4px; }
.map-seg button { padding: 3px 9px; border: 1.5px solid var(--ink); border-radius: 999px; background: #fff; color: var(--ink); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.map-seg button[aria-pressed="true"] { background: var(--ink); color: #fff; }
.map-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: #333; }
.map-legend span { display: inline-flex; align-items: center; gap: 5px; }
.map-legend i { width: 12px; height: 12px; border-radius: 3px; opacity: .75; }
.map-legend-scale i { width: 110px; height: 8px; border-radius: 99px; opacity: 1; }
.map-legend-scale b { font-weight: 600; font-size: 11px; color: var(--muted); }
.map-legend i.is-leftRight { background: linear-gradient(90deg, #0022ff, #8a2be2 50%, #ff0000); }
.map-legend i.is-popularity, .map-legend i.is-weight { background: linear-gradient(90deg, #111, #f2b600); }
.map-legend-note { width: 100%; color: var(--muted); font-size: 11px; }

.map-label {
  padding: 1px 7px; border-radius: 999px; background: rgba(255, 255, 255, .92); border: 1.5px solid var(--ink);
  font-size: 12px; font-weight: 800; color: var(--ink); pointer-events: none;
}
.map-hover .maplibregl-popup-content { padding: 6px 10px; border: 1.5px solid var(--ink); border-radius: 10px; font-size: 13px; line-height: 1.35; box-shadow: 0 4px 14px rgba(0, 0, 0, .15); }
.map-hover .maplibregl-popup-tip { display: none; }
.map-hover div { color: #444; }

.map-panel {
  position: absolute; top: 12px; right: 12px; bottom: 12px; z-index: 3;
  width: min(360px, calc(100% - 24px)); overflow-y: auto;
  padding: 16px 16px 12px; background: #fff;
  border: 1.5px solid var(--ink); border-radius: 16px; box-shadow: 0 8px 28px rgba(0, 0, 0, .18);
}
.map-panel[hidden] { display: none; }
.map-panel-close { position: absolute; top: 8px; right: 10px; border: 0; background: none; font-size: 24px; line-height: 1; cursor: pointer; color: var(--ink); }
.map-panel-title { margin: 0 24px 8px 0; font-size: 18px; }
.map-area + .map-area { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line, #e3e3e8); }
.map-area h3 { margin: 0 24px 8px 0; font-size: 15px; }
.map-person { display: flex; align-items: center; gap: 10px; padding: 5px 6px; margin: 0 -6px; border-radius: 10px; color: var(--ink); text-decoration: none; }
.map-person:hover { background: #f3f3f5; }
.map-person { --party: var(--party-other); }
.map-person[data-party="democrat"] { --party: var(--party-democrat); }
.map-person[data-party="republican"] { --party: var(--party-republican); }
.map-face {
  flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  border: 2px solid var(--ink); box-shadow: 0 0 0 3px var(--party); background: #eee 50% 25% / cover no-repeat;
  font-size: 13px; font-weight: 700; margin: 3px;
}
.map-person-text { display: grid; line-height: 1.25; min-width: 0; }
.map-person-text b { font-size: 14px; }
.map-person-text span { font-size: 12px; color: var(--muted); }
.map-none { margin: 4px 0; color: var(--muted); font-size: 13px; }
.map-compare, .map-spot {
  display: inline-block; margin-top: 8px; padding: 4px 12px; border: 1.5px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink); font: inherit; font-size: 12px; font-weight: 700; text-decoration: none; cursor: pointer;
}
.map-spot { display: block; margin-top: 12px; }

@media (max-width: 700px) {
  .map-controls { top: 8px; left: 8px; width: calc(100% - 16px); padding: 10px 12px; gap: 8px; }
  .map-panel { top: auto; left: 8px; right: 8px; bottom: 8px; width: auto; max-height: 52%; }
}
.map-link { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
@media (max-width: 700px) { .map-link-label { display: none; } }
.map-more { display: none; }
@media (max-width: 700px) {
  .map-more { display: block; justify-self: start; padding: 2px 0; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 700; color: var(--muted); cursor: pointer; }
  .map-controls:not(.is-open) .map-row, .map-controls:not(.is-open) .map-legend { display: none; }
}
.map-where-in { margin: 0 0 10px; color: var(--muted); font-size: 13px; }
.map-select {
  justify-self: start; padding: 4px 30px 4px 12px; border: 1.5px solid var(--ink); border-radius: 999px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23111'/%3E%3C/svg%3E") no-repeat right 12px center;
  color: var(--ink); font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; appearance: none; -webkit-appearance: none;
}

/* Map page: layer buttons take their layer's color when on; several can be on. */
.map-seg button[data-layer][aria-pressed="true"] { background: var(--layer, var(--ink)); border-color: var(--layer, var(--ink)); color: #fff; }
.map-legend i.map-legend-line { width: 16px; height: 0; border-radius: 0; border-top-width: 3px; opacity: 1; background: none; }
.map-hover-row { padding-left: 7px; border-left: 3px solid transparent; }
.map-hover-row + .map-hover-row { margin-top: 5px; }
.map-area h3 { padding-left: 8px; border-left: 4px solid transparent; }

/* "Put people on the map": search, results, chips. */
.map-pick { display: grid; gap: 6px; }
.map-pick-search { position: relative; }
.map-pick-search input { width: 100%; box-sizing: border-box; padding: 7px 12px; border: 1.5px solid var(--ink); border-radius: 999px; font: inherit; }
.map-pick-results {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 5; max-height: 320px; overflow-y: auto;
  margin: 0; padding: 4px; list-style: none; background: #fff; border: 1.5px solid var(--ink); border-radius: 12px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .16);
}
.map-pick-results[hidden] { display: none; }
.map-pick-results li { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 8px; cursor: pointer; }
.map-pick-results li:hover, .map-pick-results li.is-active { background: #f0f0f3; }
.map-pick-results li { --party: var(--party-other); }
.map-pick-results li[data-party="democrat"], .map-chip[data-party="democrat"], .map-pin[data-party="democrat"] { --party: var(--party-democrat); }
.map-pick-results li[data-party="republican"], .map-chip[data-party="republican"], .map-pin[data-party="republican"] { --party: var(--party-republican); }
.map-pick-results .map-face { width: 28px; height: 28px; font-size: 11px; border-width: 1.5px; box-shadow: 0 0 0 2px var(--party); }
.map-pick-icon { width: 34px; text-align: center; font-size: 18px; }
.map-pick-empty { color: var(--muted); cursor: default !important; }
.map-pick-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.map-pick-chips[hidden] { display: none; }
.map-chip { --party: var(--party-other); display: inline-flex; align-items: center; border: 1.5px solid var(--ink); border-radius: 999px; background: #fff; }
.map-chip-label { display: inline-flex; align-items: center; gap: 5px; padding: 2px 4px 2px 3px; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; color: var(--ink); }
.map-chip-label .map-face { width: 20px; height: 20px; margin: 1px; font-size: 9px; border-width: 1px; box-shadow: 0 0 0 2px var(--party); }
.map-chip-x { padding: 0 8px 0 2px; border: 0; background: none; font-size: 16px; line-height: 1; cursor: pointer; color: var(--muted); }
.map-chip-x:hover { color: var(--ink); }
.map-pick-chips .map-compare { margin-top: 0; }
.map-chip-clear { padding: 2px 8px; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 700; color: var(--muted); text-decoration: underline; cursor: pointer; }

/* Pinned people: their photo on their area, name below. */
.map-pin { --party: var(--party-other); display: grid; justify-items: center; gap: 2px; text-decoration: none; color: var(--ink); }
.map-pin .map-face { width: 44px; height: 44px; margin: 0; box-shadow: 0 0 0 4px var(--party), 0 3px 10px rgba(0, 0, 0, .3); }
.map-pin:hover .map-face { transform: scale(1.08); }
.map-pin-name { padding: 0 6px; border-radius: 999px; background: rgba(255, 255, 255, .92); font-size: 11px; font-weight: 800; white-space: nowrap; }
.map-pin-pos { padding: 2px 9px; border: 1.5px solid var(--ink); border-radius: 999px; background: #fff; font-size: 12px; font-weight: 800; white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, .2); }
.map-pin-name { max-width: 68px; overflow: hidden; text-overflow: ellipsis; }

/* Map panel: each person has a pin button on the right (adds them to the map). */
.map-person-row { display: flex; align-items: center; gap: 6px; }
.map-person-row .map-person { flex: 1; min-width: 0; }
.map-pin-btn {
  flex: none; width: 30px; height: 30px; border: 1.5px solid var(--ink); border-radius: 50%;
  background: #fff; color: var(--ink); font: inherit; font-size: 17px; font-weight: 800; line-height: 1; cursor: pointer;
}
.map-pin-btn:hover { background: #f0f0f3; }
.map-pin-btn.is-on { background: var(--ink); color: #fff; }

/* Person page: X and Instagram logo links at the bottom (js/person.js). */
.person-social { grid-area: soc; display: flex; justify-content: center; gap: 14px; padding: 18px 0 24px; border-top: 1px solid var(--line, #e3e3e8); }
.person-social[hidden] { display: none; }
.social-link {
  display: grid; place-items: center; width: 44px; height: 44px; border: 2px solid var(--ink); border-radius: 50%;
  color: var(--ink); background: #fff; transition: transform .15s ease, background .15s ease, color .15s ease;
}
.social-link svg { width: 20px; height: 20px; }
.social-link:hover { transform: translateY(-2px); background: var(--ink); color: #fff; }
.social-link:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }

/* ---------- News (js/news.js) ---------- */

/* Lists of headlines (person page, position page). */
.news-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.news-list li { display: grid; gap: 2px; }
.news-list a { color: var(--ink); font-weight: 700; line-height: 1.3; text-decoration: none; }
.news-list a:hover { text-decoration: underline; }
.news-meta { color: var(--muted); font-size: 12px; }
.news-summary { font-size: 13px; color: #333; }
.news-tag {
  justify-self: start; padding: 1px 7px; border-radius: 999px; background: #d50000; color: #fff;
  font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.news-none { margin: 0; color: var(--muted); font-size: 14px; }

/* Person page: "In the news", above the social links. */
.person-news { grid-area: news; padding-top: 18px; border-top: 1px solid var(--line, #e3e3e8); }
.person-news h2 { margin: 0 0 12px; font-size: 20px; }
.person-news .news-list { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px 24px; }

/* Scrolling pages: room at the bottom for the Compare button (js/compare-tray.js
   sets --tray-space), so the last lines can always be scrolled clear of it. */
body:not(.home)::after { content: ""; display: block; flex: none; height: var(--tray-space, 0px); }

/* × and + buttons sitewide: the mark is drawn (not a font character, which
   sits off centre), so it's always dead centre in its button. Its size is
   --glyph; the button's color is the mark's color. */
.glyph-x, .glyph-plus { display: inline-flex; align-items: center; justify-content: center; padding: 0; font-size: 0 !important; }
.glyph-x::before, .glyph-plus::before {
  content: ""; width: var(--glyph, 12px); height: var(--glyph, 12px); background: currentColor;
  -webkit-mask: var(--glyph-shape) center / contain no-repeat; mask: var(--glyph-shape) center / contain no-repeat;
}
.glyph-x { --glyph-shape: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 5L19 19M19 5L5 19' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E"); }
.glyph-plus { --glyph-shape: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3V21M3 12H21' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E"); }
.compare-close { --glyph: 13px; }
.index-close { --glyph: 13px; color: var(--ink); }
.index-close:hover { color: #fff; }
.compare-remove { --glyph: 9px; }
.chip-x { --glyph: 10px; }
.chip-plus { --glyph: 14px; }
.map-pin-btn { --glyph: 13px; }
.map-chip-x { --glyph: 9px; width: 20px; height: 20px; margin-right: 4px; border-radius: 50%; }
.map-chip-x:hover { background: #f0f0f3; }
.map-panel-close { --glyph: 14px; width: 32px; height: 32px; top: 6px; right: 6px; border-radius: 50%; }
.map-panel-close:hover { background: #f0f0f3; }

/* ---------- Powers: who holds power over whom (js/government.js) ----------
   The Genetics page's pop-up card and the position page's "Powers" tile. */

:root {
  --pw-presides: #0d9488; --pw-budget: #d97706; --pw-appoints: #7c3aed;
  --pw-audits: #db2777; --pw-runs: #15803d; --pw-advises: #475569; --pw-elects: #6b7280;
}
.is-presides { --k: var(--pw-presides); } .is-budget { --k: var(--pw-budget); } .is-appoints { --k: var(--pw-appoints); }
.is-audits { --k: var(--pw-audits); } .is-runs { --k: var(--pw-runs); } .is-advises { --k: var(--pw-advises); }
.is-elects { --k: var(--pw-elects); }
.gen-p-lede { margin: 16px 0 0; font-size: 14px; line-height: 1.5; }
.gen-p-sec { margin-top: 18px; }
.gen-p-sec h3 { margin: 0 0 8px; font-size: 12px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.gen-p-sec ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.gen-p-item { padding-left: 10px; border-left: 3px solid var(--k, var(--line)); font-size: 14px; }
.gen-p-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 6px; }
.gen-p-kind { font-weight: 700; color: var(--k); font-size: 13px; }
.gen-p-other { padding: 0; border: 0; background: none; font: inherit; font-weight: 800; color: var(--ink); text-decoration: underline; text-decoration-color: var(--line); cursor: pointer; }
.gen-p-other:hover { text-decoration-color: var(--ink); }
.gen-p-why { margin: 3px 0 0; line-height: 1.45; color: #333; }
.gen-p-src { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); }
.gen-p-src a { color: var(--muted); }
a.gen-p-other { font-weight: 800; }
.gen-p-other.is-plain { text-decoration: none; cursor: default; }

/* A seat's circle: the holder's photo in their party's ring, or plain. */
.gen-disc { display: grid; place-items: center; flex: none; border-radius: 50%; border: 2px solid var(--ink); background: #eee 50% 25% / cover no-repeat;
  box-shadow: 0 0 0 3px var(--party-other); font-weight: 800; color: #555; }
.gen-disc[data-party="democrat"] { box-shadow: 0 0 0 3px var(--party-democrat); }
.gen-disc[data-party="republican"] { box-shadow: 0 0 0 3px var(--party-republican); }
.gen-disc.is-plain {   /* people hidden (or no holder): a grey person silhouette, no one in particular */
  background: #f2f2f4 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Ccircle cx='20' cy='15' r='7.5' fill='%23a3a3ad'/%3E%3Cpath d='M5 40c0-9 6.7-15 15-15s15 6 15 15z' fill='%23a3a3ad'/%3E%3C/svg%3E") center bottom / 100% 100% no-repeat;
  box-shadow: none; border: 2.5px solid var(--ink); }

.gen-p-photo { flex: none; border-radius: 50%; transition: transform .12s; }
.gen-p-photo:hover { transform: scale(1.06); }
.gen-p-photo:focus-visible { outline: 3px solid #0022ff; outline-offset: 3px; }

/* ---------- the power diagram (js/government.js diagram) ----------
   On the Genetics card and the position page's Powers tile.
   What holds power over the seat | the seat | what it holds power over,
   an arrow per box in the power's color; stacked top to bottom when narrow. */
/* Both columns start at the top, their headings on one line of a set height; the seat sits midway. */
.gen-diagram { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: start; gap: 0 44px; margin-top: 16px; }
.gen-d-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; position: relative; z-index: 1; }
.gen-d-head { height: 16px; margin: 0; line-height: 16px; white-space: nowrap; font-size: 11px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.gen-d-col.is-out .gen-d-head { text-align: right; }
.gen-d-list { display: flex; flex-direction: column; gap: 8px; }
.gen-d-card { display: block; width: 100%; padding: 6px 9px; border: 1.5px solid #ccc; border-left: 4px solid var(--k); border-radius: 9px; background: #fff;
  color: var(--ink); font: inherit; text-align: left; cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.gen-d-card:hover { border-color: var(--ink); border-left-color: var(--k); box-shadow: 0 2px 8px rgba(0, 0, 0, .1); }
.gen-d-card:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; }
.gen-d-card b { display: block; font-size: 13px; line-height: 1.25; }
.gen-d-card small { display: block; color: var(--k); font-size: 11.5px; font-weight: 700; line-height: 1.3; }
.gen-d-card.is-multi { --k: #333; }
.gen-d-none { margin: 0; padding: 6px 9px; border: 1.5px dashed #ddd; border-radius: 9px; color: #999; font-size: 12px; font-weight: 600; }
.gen-d-hub { align-self: center; display: flex; flex-direction: column; align-items: center; gap: 6px; max-width: 120px; text-align: center; position: relative; z-index: 1; }
.gen-d-hub .gen-d-disc { box-shadow: 0 0 0 3px var(--ink); }
.gen-d-hub .gen-d-disc[data-party="democrat"] { box-shadow: 0 0 0 3px var(--party-democrat); }
.gen-d-hub .gen-d-disc[data-party="republican"] { box-shadow: 0 0 0 3px var(--party-republican); }
.gen-d-name { font-size: 13px; line-height: 1.2; }
.gen-d-note { grid-column: 1 / -1; margin: 10px 0 0; color: var(--muted); font-size: 12px; }
.gen-d-box { display: block; padding: 10px 12px; border: 2px solid var(--ink); border-radius: 12px; background: #fff; font-weight: 800; font-size: 13px; }
.gen-d-box.is-extra { border-color: #999; background: #fafafa; }
.gen-d-lines { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; z-index: 0; }
.gen-d-line { fill: none; stroke: var(--k); stroke-width: 2.2; }
.gen-d-line.is-elects { stroke-dasharray: 5 4; }
.gen-d-line.is-multi, .gen-d-lines .is-multi { --k: #333; }
.gen-d-lines marker path { fill: var(--k); }
/* Narrow (phones, small windows): above, the seat, below. */
.gen-diagram.is-stacked { grid-template-columns: minmax(0, 1fr); gap: 30px 0; }
.gen-diagram.is-stacked .gen-d-hub { justify-self: center; max-width: none; }
.gen-diagram.is-stacked .gen-d-list { flex-direction: row; flex-wrap: wrap; justify-content: center; }
.gen-diagram.is-stacked .gen-d-card, .gen-diagram.is-stacked .gen-d-none { width: auto; max-width: 100%; }
.gen-diagram.is-stacked .gen-d-head, .gen-diagram.is-stacked .gen-d-col.is-out .gen-d-head { text-align: center; }
/* The explanations behind the arrows, folded under the diagram. */
.gen-p-more { margin-top: 18px; }
.gen-p-more > summary { cursor: pointer; font-size: 13px; font-weight: 800; color: var(--muted); }
.gen-p-more > summary:hover { color: var(--ink); }
.gen-d-card.is-static { cursor: default; }
.gen-d-card.is-static:hover { border-color: #ccc; border-left-color: var(--k); box-shadow: none; }
a.gen-d-card { text-decoration: none; }

/* Favorites: ☆ / ★ beside a person's name and in the voter guide (js/favorites.js). */
.fav-btn { display: inline-grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; background: none;
  font-size: 28px; line-height: 1; color: #9a9a9a; cursor: pointer; transition: color .15s, transform .15s; }
.fav-btn:hover { color: #e0b100; transform: scale(1.12); }
.fav-btn.is-on { color: #ffcc00; -webkit-text-stroke: 1px #e0a800; }
.fav-btn.is-on:hover { color: #ffcc00; }
.fav-btn:focus-visible { outline: 3px solid #0022ff; outline-offset: 2px; border-radius: 6px; }
.fav-slot { display: inline-flex; align-self: center; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* "Nobody on Orbit yet" opens the bubble with the bank */
.empty-add {
  display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border: 0; border-radius: 999px;
  background: var(--btn-go); color: #fff; font: inherit; font-size: 14px; font-weight: 600; line-height: 1; cursor: pointer;
  transition: transform .3s var(--spring);
}
.empty-add .icon { width: 11px; height: 11px; }
.empty-add .icon svg { stroke-width: 2.6; }
.empty-add:hover { transform: scale(1.06); }

/* ---------- Contact (person page, js/contact.js): the button at the top bar's right end, and its panel ---------- */
.contact-slot { display: inline-flex; margin-left: auto; }   /* (the right end of the page's top bar) */
.contact-slot[hidden] { display: none; }
@media (max-width: 380px) {   /* the smallest phones: just the ✉, so the bar stays one row */
  .contact-btn { width: var(--nav-h); padding: 0; justify-content: center; }
  .contact-btn .nav-label { display: none; }
}
.contact-dialog { width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); box-sizing: border-box; padding: 0; border: 0; border-radius: 22px;
  background: #fff; color: #150e5e; box-shadow: 0 18px 50px rgba(38, 27, 143, .28); overflow: hidden; }
.contact-dialog[open] { display: flex; flex-direction: column; }
/* Only the body scrolls, so the bar sits inside the box: a thin rounded thumb, kept clear of the corners. */
.contact-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 8px 18px 22px; margin-right: 6px;
  scrollbar-gutter: stable; scrollbar-color: auto; scrollbar-width: auto; }   /* (auto: the page's own scrollbar colors would switch off the styling below) */
@supports not selector(::-webkit-scrollbar) { .contact-body { scrollbar-width: thin; scrollbar-color: #b9b1f5 transparent; } }   /* (Firefox) */
.contact-body::-webkit-scrollbar { width: 8px; }
.contact-body::-webkit-scrollbar-button { display: none; height: 0; }
.contact-body::-webkit-scrollbar-track { background: transparent; margin: 4px 0 16px; }
.contact-body::-webkit-scrollbar-thumb { background: #b9b1f5; border-radius: 8px; }
.contact-body::-webkit-scrollbar-thumb:hover { background: #8f84ee; }
.contact-dialog::backdrop { background: rgba(21, 14, 94, .35); }
.contact-head { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 20px 22px 14px; }
.contact-title { margin: 0; font-size: 20px; line-height: 1.25; }
.contact-close { flex: none; width: 34px; height: 34px; border: 0; border-radius: 10px; background: var(--btn-tint, #d3cdfb); color: var(--btn-ink, #150e5e); font-size: 22px; line-height: 1; cursor: pointer; }
.contact-ways { display: grid; gap: 8px; margin-bottom: 16px; }
.contact-way { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 14px; background: #f1effe; color: inherit; text-decoration: none; }
.contact-way:hover { background: #e6e2fd; }
.contact-way-icon { flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: #21167c; color: #fff; font-size: 16px; }
.contact-way-text { display: grid; min-width: 0; }
.contact-way-text b { font-size: 13px; color: #4e4a7a; font-weight: 700; }
.contact-way-text span { font-size: 16px; font-weight: 700; overflow-wrap: anywhere; }
.contact-write { display: grid; gap: 10px; padding: 14px; border-radius: 16px; background: #f7f6ff; }
.contact-write[hidden] { display: none; }
.contact-sub { margin: 0; font-size: 16px; }
.contact-field { display: grid; gap: 4px; }
.contact-label { font-size: 13px; font-weight: 700; color: #4e4a7a; }
.contact-field input, .contact-field textarea { box-sizing: border-box; width: 100%; padding: 10px 12px; border: 0; border-radius: 12px; background: var(--field, #d3cdfb);
  color: #150e5e; font: inherit; font-size: 15px; resize: vertical; }
.contact-field input:focus, .contact-field textarea:focus { outline: 3px solid var(--btn-ring, #4232d4); outline-offset: 1px; }
.contact-hint { font-size: 12px; color: #6a6596; }
.contact-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.contact-go, .contact-plain { padding: 10px 16px; border: 0; border-radius: var(--btn-radius, 14px); font: inherit; font-size: 15px; font-weight: 700; cursor: pointer; }
.contact-go { background: var(--btn-go, #21167c); color: #fff; }
.contact-go:hover { background: var(--btn-go-hover, #180f5c); }
.contact-plain { background: var(--btn-tint, #d3cdfb); color: var(--btn-ink, #150e5e); }
.contact-plain:hover { background: var(--btn-tint-hover, #c4bcf8); }
.contact-note { min-height: 1.2em; margin: 0; font-size: 13px; color: #21167c; }
.contact-body > .contact-note { min-height: 0; margin: 0 0 12px; font-size: 14px; }
.contact-source, .contact-privacy { margin: 12px 0 0; font-size: 12px; color: #6a6596; }
.contact-privacy { margin-top: 4px; }
.contact-source a { color: #4232d4; }

/* ---------- Where they stand (person pages; js/person.js, js/ballot.js) ---------- */
.person-stands { grid-area: stand; padding-top: 18px; border-top: 1px solid var(--line, #e3e3e8); }
.person-stands[hidden] { display: none; }
.person-stands h2 { margin: 0 0 12px; font-size: 20px; }
.stand-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: 12px; }
.stand-item { display: grid; align-content: start; gap: 6px; padding: 12px 14px; border-radius: 16px; background: #f5f4ff; color: inherit; text-decoration: none; }
.stand-tag { justify-self: start; padding: 3px 7px; border-radius: 7px; font-size: 11px; font-weight: 800; letter-spacing: .04em; }
.stand-tag.is-for { background: #dff3ea; color: #13795b; } .stand-tag.is-against { background: #fbe3e1; color: #b3261e; }
.stand-tag.is-bills { background: #e9e6fd; color: #21167c; }
.stand-title { font-weight: 700; font-size: 14px; line-height: 1.3; color: #150e5e; }
.stand-item small { font-size: 12px; line-height: 1.35; color: #5d5890; }
.stand-src { justify-self: start; font-size: 11px; font-weight: 700; color: #4232d4; }
a.stand-bills:hover { background: #ece9fd; }

/* An address outside the area being shown (js/areas.js: Areas.outsideNote) */
.area-outside { margin: 6px 0; padding: 10px 14px; border-radius: 12px; background: #fff7d6; color: #5c4a00; font-size: 14px; line-height: 1.45; }
.area-outside a { font-weight: 700; color: #21167c; }
