/* Ranked market views. Now four TABS inside the midterms hub rather than four pages; the
   standalone pages were retired 2026-09-02 and 301 to /midterms/. One implementation, one
   place, one set of numbers -- a live tab and a snapshot page showing different figures for
   the same ranking at the same moment is one fact written twice and disagreeing.

   DENSE ON PURPOSE — this is a scan surface, not an article. Our pages
   are generously spaced and read as prose even where they are tables; these do not. */
/* The retired standalone pages' chrome -- .mv container, .mv-head, .mv-eyebrow, the old
   .mv-tabs (an inter-PAGE nav) and .vt link styles -- was removed 2026-09-02 with the
   pages. It is called out rather than silently dropped because .mv-tabs now means the
   TABLIST inside the hub: two rules for one class name with different meanings, where
   the later one silently won on the properties they shared. */
.mv h1{font-family:"Syne",sans-serif;font-weight:800;font-size:1.5rem;color:var(--navy);letter-spacing:-.02em;margin:0 0 6px}
/* The ranking rule. Stated, not decorative — it is the thing that makes the ordering checkable. */
.mv-rule{font-size:.86rem;line-height:1.55;color:var(--text-mid);margin:0 0 8px;max-width:78ch}
.mv-pop{font-size:.76rem;line-height:1.5;color:var(--text-light);margin:0 0 14px;max-width:88ch}
.mv-t{width:100%;border-collapse:collapse;font-size:.82rem}
.mv-t thead th{text-align:left;font-size:.64rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-light);border-bottom:1.5px solid var(--border);padding:0 8px 6px}
/* FIGURES ARE THE BODY FACE, NOT A MONOSPACE. DM Sans's lining figures are already uniform
   width -- measured at 20px across all ten digits -- so the columns align without the code
   texture a monospace brings to a table nobody reads as code. tabular-nums is a guard, not
   the fix, and must stay for any face substituted later. */
.mv-t th.n,.mv-t td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;
  font-family:"DM Sans",system-ui,sans-serif;font-weight:500}
.mv-t tbody td{padding:6px 8px;border-bottom:1px solid var(--border);vertical-align:top;line-height:1.35}
.mv-t tbody tr:nth-child(even){background:#fbfcfe}
.mv-t td.ev{max-width:470px}
.mv-t td.ev a{color:var(--navy);font-weight:700;text-decoration:none}
.mv-t td.ev a:hover{text-decoration:underline}
.lead{display:block;font-size:.72rem;color:var(--text-light);font-weight:500;margin-top:1px}

/* ── THE IDENTITY SLOT ───────────────────────────────────────────────────────────────
   A mark on every outcome, because a ranked view is otherwise a wall of text. WHICH mark
   and WHY -- including the licensing position on flags and portraits, and why compound
   outcomes are deliberately left blank -- is in scripts/lib/outcome-mark.js. Do not infer
   the rules from this stylesheet; it only draws them.

   PARTY COLOUR IS THE ONLY HUE HERE ON PURPOSE. On an election table the party is the
   information, so nothing else competes for colour. */
.outs{display:block;margin-top:3px}
.oleg{display:flex;align-items:center;gap:7px;padding:1.5px 0;font-size:.74rem;color:var(--text-mid)}
.onm{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500}
.omk{width:26px;height:26px;border-radius:50%;flex:0 0 26px;display:grid;place-items:center;
  font-size:9.5px;font-weight:800;color:#fff;background:#94a0bc;letter-spacing:.01em}
.omk-flag{border-radius:0;background:url(/assets/midterms-flagmaps.webp) no-repeat;
  background-size:208.0px 156.0px}
.omk-face{background:url(/assets/midterms-portraits.webp) no-repeat;background-size:208.0px 130.0px}
/* A blank slot is a DECISION on a compound outcome, not a missing asset. Dashed rather than
   filled so nobody completes it for consistency; the title attribute carries the reason. */
.omk-none{background:transparent;border:1px dashed var(--border)}
.omk.is-r,.otag.is-r{--pc:#b3282d}
.omk.is-d,.otag.is-d{--pc:#1f5fa8}
.omk-ini.is-r,.omk-pty.is-r,.omk-ini.is-d,.omk-pty.is-d{background:var(--pc)}
.omk-pty{font-size:11px}
.otag{font-size:8.5px;font-weight:800;color:var(--pc);border:1px solid var(--pc);border-radius:3px;
  padding:0 3px;margin-left:5px;vertical-align:1px}
/* 30 days of daily closes. The SHAPE of a move, which an arrow and a number cannot show. */
.ospk{flex:0 0 74px;display:block;color:#94a0bc}
.ospk.is-r{color:#b3282d}
.ospk.is-d{color:#1f5fa8}
/* No line at all where we hold no series. A FLAT line would claim the price did not move. */
.ospk-na{flex:0 0 74px;height:20px;border-bottom:1px dotted var(--border);align-self:center}
@media(max-width:720px){.ospk,.ospk-na{display:none}}
.small{font-size:.76rem;color:var(--text-mid)}
.muted{color:#b6c0d0}
/* CHANGE IDIOM: up, down, or a dot. A flat marker is a dot rather than "0.0%" because zero
   movement is the common case and printing it as a number gives it a real move's weight. */
.ch{font-weight:800;font-size:.78rem}
.ch-up{color:#0f7a4d}
.ch-dn{color:#b3261e}
.ch-flat{color:#c2cad6;font-weight:900}
.ch-na{color:#d5dbe4}
.mv-note{font-size:.76rem;color:var(--text-light);margin:10px 0 0}
.mv-disc{margin-top:22px;padding-top:12px;border-top:1px solid var(--border);font-size:.74rem;
  line-height:1.6;color:var(--text-light);max-width:92ch}
@media(max-width:720px){.mv-t td.ev{max-width:210px}.mv-t{font-size:.76rem}}
/* A finding, not a caveat — so it is stated above the population line and given weight. */
.mv-finding{background:var(--off-white);border-left:4px solid var(--navy);border-radius:0 9px 9px 0;
  padding:11px 15px;font-size:.8rem;line-height:1.6;color:var(--text-mid);margin:0 0 12px;max-width:92ch}


/* ── THE TABS ────────────────────────────────────────────────────────────────────────
   Every panel is already in the HTML. The switcher shows and hides; it fetches nothing.
   So all four rankings are readable with JavaScript off -- the panels are simply all
   visible -- and none of it is invisible to a crawler. */
.mv-views{margin-top:6px}
.mv-views-head{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap}
.mv-views-h{font-family:"Syne",sans-serif;font-weight:800;font-size:1.12rem;color:var(--navy);margin:0}
/* THE FRESHNESS LINE. The time here is when the PRICES were fetched, stamped by the job that
   fetched them -- never the page's build time. A deploy carrying three-hour-old data must not
   print the deploy's clock. The cadence is stated beside it so the number has a bound. */
.mv-views-fresh{font-size:.74rem;color:var(--text-light);margin:0}
.mv-views-fresh time{font-variant-numeric:tabular-nums}
.mv-tabs{display:flex;gap:3px;flex-wrap:wrap;margin:12px 0 4px;border-bottom:1.5px solid var(--border)}
.mv-tab{appearance:none;background:none;border:0;cursor:pointer;font:inherit;font-size:.8rem;
  font-weight:700;color:var(--text-mid);padding:8px 13px;border-radius:8px 8px 0 0;
  border-bottom:2px solid transparent;margin-bottom:-1.5px}
.mv-tab:hover{background:var(--off-white)}
.mv-tab.on{color:var(--navy);border-bottom-color:var(--navy)}
.mv-tab:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.mv-panel{padding-top:12px}
.mv-panel[hidden]{display:none}
/* No JS: nothing sets [hidden] beyond the first paint, so every panel stays readable rather
   than the page collapsing to one tab's worth of content. */
@media(max-width:720px){.mv-tab{font-size:.74rem;padding:7px 9px}}

/* ── RACE-TYPE CHIPS ─────────────────────────────────────────────────────────────────
   These FILTER; they do not re-rank. The rule sits above them and stays true under any
   filter, which is why the order is rule -> chips -> table and not the reverse.

   A count of 0 is shown, not hidden, and its chip is disabled: a dead end that is visible
   before it is clicked. What must never appear is a stale number -- counts are computed at
   render from the rows the panel is about to draw, so "Governor 0" on Newly listed is a
   reading rather than a guess. */
.mv-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:0 0 12px}
.mv-chip{appearance:none;cursor:pointer;font:inherit;font-size:.74rem;font-weight:700;
  color:var(--text-mid);background:var(--paper,#fff);border:1px solid var(--border);
  border-radius:999px;padding:4px 11px;line-height:1.5}
.mv-chip:hover:not(:disabled){background:var(--off-white)}
.mv-chip.on{background:var(--navy);border-color:var(--navy);color:#fff}
.mv-chip:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.mv-chip-n{font-variant-numeric:tabular-nums;opacity:.72;margin-left:4px}
/* Disabled rather than absent: removing the chip would hide that the category exists. */
.mv-chip:disabled{opacity:.45;cursor:not-allowed}
.mv-chip.is-empty{border-style:dashed}
/* The untyped remainder, stated so the three type chips summing to less than All is
   visible rather than a silent narrowing of the population. */
.mv-chip-rest{font-size:.7rem;color:var(--text-light);margin-left:2px}

/* ── RACES-BY-STATE HEADING, which now carries the race switch ───────────────────────
   Moved here from a section of its own at the top of the page. It was reading as a
   page-level control and is not one: it governs this map and this table only. */
.mt-races-head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.mt-back-to-views{font-size:.82rem;color:var(--text-mid);margin:6px 0 0}
.mt-back-to-views a{color:var(--navy);font-weight:700}
