/* ============================================================
   UnderWalker — design tokens + dashboard layout
   Ported from the design-handoff prototype.
   ============================================================ */

:root {
  --paper:      #FFFFF1;
  --ink:        #080808;
  --orange:     #DB6200;
  --ink-soft:   #6f6b5e;
  --ink-faint:  #a8a497;
  --line:       rgba(8,8,8,.18);
  --line-soft:  rgba(8,8,8,.10);
  --grotesque:  "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono:       "IBM Plex Mono", ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

body {
  background: #cdcabf;
  font-family: var(--grotesque);
  color: var(--ink);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  display: flex;
  align-items: center;
  justify-content: center;
}

#viewport {
  position: fixed;
  inset: 0;
  overflow: auto;        /* below the stage minimum, scroll instead of crushing */
}

#stage {
  width: 100%;
  height: 100%;
  /* Fill the viewport when there's room; hold a legible floor and let
     #viewport scroll once the window gets smaller than the design needs. */
  min-width: 1080px;
  min-height: 680px;
  background: var(--paper);
  position: relative;
  display: grid;
  grid-template-columns: 240px 1fr 380px;
  grid-template-rows: 72px 1fr 86px;
  grid-template-areas:
    "top top top"
    "left main right"
    "bottom bottom bottom";
}

/* ---------- shared type ---------- */
.meta        { font-size: 11px; letter-spacing: .2em;  text-transform: uppercase; color: var(--ink-soft); }
.meta-strong { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--ink); }
.num         { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ---------- top bar ---------- */
#top {
  grid-area: top;
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--ink);
  position: relative;
  padding: 0 22px;
}
.brand { display: flex; align-items: center; gap: 13px; }
.brand img { height: 30px; width: auto; display: block; }
.brand-stack { display: flex; flex-direction: column; }
.brand .word { font-size: 18px; font-weight: 700; letter-spacing: .26em; line-height: 1; }
/* The tagline — what this IS, everywhere the wordmark goes. Letterspacing chosen
   so the line sits at roughly the wordmark's width (a Rand lockup, not a caption). */
.brand-tag {
  font-family: var(--mono); font-size: 8px; letter-spacing: .155em; text-transform: uppercase;
  color: var(--ink-soft); margin-top: 5px; white-space: nowrap;
}

/* top-level nav (Dashboard | News) — also reused on the /news header */
.topnav { display: flex; align-items: center; gap: 20px; margin-left: 30px; }
.topnav-link {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase; text-decoration: none;
  color: var(--ink-soft); padding: 4px 0; border-bottom: 2px solid transparent; white-space: nowrap;
}
.topnav-link:hover { color: var(--ink); }
.topnav-link.active { color: var(--ink); border-bottom-color: var(--ink); }   /* current page — ink underline, never orange */

/* Editions dropdown in the topnav — pure CSS (hover / focus-within), no JS.
   No vertical gap between button and menu, or the hover chain breaks mid-travel. */
.topnav-drop { position: relative; }
.topnav-drop-btn { background: none; border: none; border-bottom: 2px solid transparent; cursor: pointer; font: inherit; font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); padding: 4px 0; }
.topnav-drop-btn:hover { color: var(--ink); }
.topnav-drop-btn.active { color: var(--ink); border-bottom-color: var(--ink); }
.topnav-menu {
  display: none; position: absolute; right: 0; top: 100%;
  background: var(--paper); border: 1px solid var(--ink);
  min-width: 250px; padding: 5px 0; z-index: 400;
  box-shadow: -3px 3px 0 rgba(8, 8, 8, .08);
}
.topnav-drop:hover .topnav-menu, .topnav-drop:focus-within .topnav-menu { display: block; }
.topnav-menu-item {
  display: block; padding: 8px 14px; text-decoration: none;
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
}
.topnav-menu-item:hover { background: var(--ink); color: var(--paper); }

#clock {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  white-space: nowrap;
}
#clock .num { letter-spacing: .16em; font-size: 12.5px; color: var(--ink); font-weight: 500; }
#clock .sep { color: var(--ink-faint); padding: 0 6px; }

.status { margin-left: auto; display: flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; }
.status .dot { width: 8px; height: 8px; border: 1.4px solid var(--ink); border-radius: 50%; }
.status.drawing .dot { background: var(--orange); border-color: var(--orange); animation: pulse 1s ease-in-out infinite; }
.status.settled .dot { background: transparent; }
.status .label { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; }

@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }

#progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  background: var(--orange);
  width: 0;
}

/* ---------- left rail ---------- */
#left {
  grid-area: left;
  border-right: 1px solid var(--line);
  padding: 20px 18px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-height: 0;
  overflow-y: auto;     /* sources + legend scroll if the column is short */
}
.rail-h { font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 13px; }

/* ---------- collapsible rail sections ---------- */
.sect { display: flex; flex-direction: column; min-height: 0; }
.sect.grow { flex: 1 1 auto; }                 /* feed fills the rest of the rail */
.sect-h {
  font: inherit; background: none; border: none; cursor: pointer; text-align: left; width: 100%;
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--ink-soft);
  padding: 0 0 11px; display: flex; align-items: center; gap: 8px;
}
.sect-h:hover { color: var(--ink); }
.sect-h .chev {                                /* right-pointing triangle; rotates down when open */
  width: 0; height: 0; flex: 0 0 auto;
  border-left: 5px solid currentColor; border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s;
}
.sect:not(.collapsed) > .sect-h .chev { transform: rotate(90deg); }
.sect.collapsed > .sect-body { display: none; }
.sect-body { min-height: 0; }
.sect-body.scroll { overflow-y: auto; }
.rail-ct { font-family: var(--mono); font-size: 10px; letter-spacing: 0; color: var(--ink-faint); text-transform: none; }
/* data-age chip — right-aligned in the section header ("2m", "36m") */
.sect-age { margin-left: auto; font-family: var(--mono); font-size: 9px; letter-spacing: .02em; color: var(--ink-faint); text-transform: none; }

/* right-rail section chrome (brief) */
#right .sect { padding: 15px 20px 13px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
/* brief fills the right rail (alerts moved to the left rail; browse link sits on top) */
/* Brief sizes to content (0 grow) so the Wikipedia-trends mini sits directly under it
   (user call 2026-07-01); still shrinks + scrolls when a long brief would overflow. */
#right .sect[data-sect="brief"] { flex: 0 1 auto; min-height: 0; }
#right .sect[data-sect="brief"] .sect-body { overflow-y: auto; }
/* the moved "browse all news" link, inset to match the section padding, sits above the brief */
.news-archive-link.rail-top { margin: 8px 20px 8px; }

/* "Recently noticed" — the Convergence Ledger rows. The orange ⊕ is the
   sanctioned convergence mark; retired entries read at rest, still-active ones
   slightly bolder. Data-rich but calm: place / what / when on one line. */
.noticed-mini { display: flex; flex-direction: column; gap: 5px; }
.noticed-row { display: flex; align-items: baseline; gap: 7px; font-size: 11px; color: var(--ink-soft); }
.noticed-row.active { color: var(--ink); }
.noticed-row .nr-mark { color: var(--orange); flex: 0 0 auto; }
.noticed-row .nr-place { font-weight: 600; flex: 0 0 auto; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.noticed-row .nr-what { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.noticed-row .nr-time { font-family: var(--mono); font-size: 9.5px; color: var(--ink-faint); flex: 0 0 auto; }

/* Metro briefing chips — tiny calm buttons above the news link, one per anchor
   metro (3-char codes so all five fit one row), opening its slide-over. Ink at
   rest; trailing › is the "opens a panel" cue shared with the map anchors. */
.metro-chips-wrap { margin: 15px 20px 0; }
.metro-chips-h { font-size: 9px; letter-spacing: .22em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 6px; }
.metro-chips { display: flex; flex-wrap: nowrap; gap: 6px; }
.metro-chip {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); background: none; border: 1px solid var(--line); border-radius: 3px;
  padding: 4px 8px; cursor: pointer;
}
.metro-chip:hover { color: var(--ink); border-color: var(--ink); }
/* Left-rail scrolling (reworked 2026-07-02, user call): sections take their NATURAL
   height — no per-section caps or inner scroll squeeze (multiple expanded sections
   used to compress each other into tiny scroll areas). The RAIL scrolls as a whole
   (#left overflow-y above); the floating .rail-more pill signals content below the
   fold. */
#left .sect { flex: 0 0 auto; }
#left .sect-body.scroll { overflow: visible; }

/* Floating "more below" pill — sticky to the rail's bottom edge while overflow
   exists (setupRailMore hides it at scroll end). Ochre = attention without alarm;
   burnt orange stays reserved for convergence. */
.rail-more {
  position: sticky; bottom: 4px; align-self: center; z-index: 5;
  background: var(--sev-moderate); color: var(--paper);
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  padding: 4px 12px; border-radius: 11px; cursor: pointer;
  box-shadow: 0 1px 4px rgba(8,8,8,.18);
  flex: 0 0 auto; margin-top: -14px;   /* overlaps the gap so it doesn't add rail height */
}
.rail-more:hover { background: var(--ink); }

/* legend — button bottom-left of the map, panel expands up on click */
/* /news living pass — rows ink in (first ~30, capped stagger), NEW-since-last-
   visit rows get a fleeting sage edge tick (sage = the "made the dashboard"
   family: novelty is calm information, not an alert), the count line carries a
   soft live dot, wiki sparklines draw themselves. */
body.news-page tbody tr.ink-in-row {
  animation: ink-in .45s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: var(--ink-delay, 0ms);
}
body.news-page tr.fresh-news td:first-child { animation: news-fresh 4s ease-out both; }
@keyframes news-fresh {
  0%   { box-shadow: inset 3px 0 0 rgba(108,128,84,.9); }
  100% { box-shadow: inset 0 0 0 transparent; }
}
.live-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: rgba(108,128,84,.9); margin-right: 8px; vertical-align: 1px;
  animation: awake 9s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  body.news-page tbody tr.ink-in-row, body.news-page tr.fresh-news td:first-child, .live-dot { animation: none; }
}

/* Dusk paper — after Central sunset the cream warms ~2% (ink + data colors
   untouched, so the Rand discipline and severity ramps survive). The map at
   10 PM feels like paper under lamplight, not a screen. Set by JS on <body>. */
body.dusk { --paper: #FDF6E4; }

/* Sheets ink in — content blocks cascade with per-block delays; sparklines
   draw themselves. Set by inkInSheet() on every openSheet. */
.cs-content .ink-in {
  animation: ink-in .5s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: var(--ink-delay, 0ms);
}
@keyframes ink-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
@keyframes spark-draw { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .cs-content .ink-in { animation: none; } }

/* Pulse pass (2026-07-03) — the few things allowed to move at rest, each
   because its urgency is real:
   • Extreme-severity alert polygons breathe at the EDGE (~4.5s) — an Extreme
     warning is an event in progress, not an archive entry.
   • Rising-fast gauges breathe — the "something is coming" glyph.
   • Hovering a converged mark raises its connection trails + brightens them —
     "show me the clues" on demand.
   • One of the never-finished borders occasionally tries to finish (JS nudge).
   • Smoke boundaries smolder (dash drift; the FILL never moves — we don't know
     the wind).
   • The SETTLED status dot blinks softly every ~9s: awake, not asleep. */
.alert-poly.sev-extreme { animation: sev-breathe 4.5s ease-in-out infinite; }
@keyframes sev-breathe {
  0%, 100% { stroke-opacity: 1;   stroke-width: 2.2; }
  50%      { stroke-opacity: .55; stroke-width: 1.4; }
}
.flood-rising .flood-drop { animation: rise-breathe 3.4s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes rise-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}
.conv-trail { transition: opacity .35s, stroke-width .35s; }
#map:has(.converged:hover) .conv-trail, .conv-trail.lit { opacity: .6; stroke-width: 1.5; }
.smoke { animation: smolder 26s linear infinite; }
@keyframes smolder { to { stroke-dashoffset: -70; } }
.status.settled .dot { animation: awake 9s ease-in-out infinite; }
@keyframes awake {
  0%, 92%, 100% { opacity: 1; }
  96%           { opacity: .35; }
}
@media (prefers-reduced-motion: reduce) {
  .alert-poly.sev-extreme, .flood-rising .flood-drop, .smoke,
  .status.settled .dot { animation: none; }
}

/* Change awareness — a NEW mark announces itself once with an expanding ink
   ripple (a drop landing on the paper); a new rail row gets a fleeting edge
   tick. Nothing loops; announcements fire only for keys unseen last load. */
.arrive-ripple {
  fill: none; stroke: var(--ink); stroke-width: 1.4; pointer-events: none;
  animation: arrive 2.2s cubic-bezier(.2,.6,.3,1) both;
}
@keyframes arrive {
  0%   { r: 4;  stroke-opacity: .65; stroke-width: 1.6; }
  100% { r: 34; stroke-opacity: 0;  stroke-width: .4; }
}
#left .a-item.fresh { animation: fresh-tick 3.2s ease-out both; }
@keyframes fresh-tick {
  0%   { box-shadow: inset 3px 0 0 var(--ink); background: rgba(8,8,8,.05); }
  100% { box-shadow: inset 0 0 0 transparent; background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .arrive-ripple, #left .a-item.fresh { animation: none; }
}

/* The rite — fleeting mono whisper during draw-in ("up from under…") and wipe
   ("gone back under."). Bottom-center of the map, fades with the ink. */
.brand { cursor: pointer; }
#rite {
  position: absolute; bottom: 44px; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .34em; text-transform: lowercase;
  color: var(--ink-faint); opacity: 0; transition: opacity 1.1s ease;
  pointer-events: none; z-index: 5; white-space: nowrap;
}
#rite.show { opacity: .85; }

/* Replay the day — dims the live data layers, re-inks the archive over them. */
#replay-btn {
  position: absolute; bottom: 18px; left: 96px; z-index: 6;
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  background: var(--paper); border: 1px solid var(--line); border-radius: 3px;
  padding: 5px 10px; color: var(--ink-soft); cursor: pointer;
}
#replay-btn:hover, #replay-btn.open { background: var(--ink); color: var(--paper); }
#stage.replaying-day .alerts, #stage.replaying-day .alert-cities, #stage.replaying-day .tfrs,
#stage.replaying-day .lsrs, #stage.replaying-day .floods, #stage.replaying-day .tropical,
#stage.replaying-day .air, #stage.replaying-day .outages, #stage.replaying-day .fires,
#stage.replaying-day .conv-trails,
#stage.replaying-day #map > g:not(.replay):not(.counties) .glyph { transition: opacity .8s; }
#stage.replaying-day .alerts, #stage.replaying-day .alert-cities, #stage.replaying-day .tfrs,
#stage.replaying-day .lsrs, #stage.replaying-day .floods, #stage.replaying-day .tropical,
#stage.replaying-day .air, #stage.replaying-day .outages, #stage.replaying-day .fires,
#stage.replaying-day .conv-trails { opacity: .05; }
#stage.replaying-day .glyph { opacity: .05; transition: opacity .8s; }
#replay-clock {
  position: absolute; top: 46px; right: 22px; z-index: 6;
  font-family: var(--mono); font-size: 15px; letter-spacing: .12em; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: 3px; padding: 4px 10px;
}
.rp-mark { animation: rp-bloom .5s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes rp-bloom { from { opacity: 0; transform: translate(var(--x), var(--y)) scale(.1); } }
.rp-mark { transform-box: fill-box; transform-origin: center; }
@keyframes rp-pop { from { opacity: 0; } }
.rp-mark { animation: rp-pop .45s ease-out both; }
.rp-news   { fill: #8A867A; fill-opacity: .75; stroke: var(--ink); stroke-width: .5; }
.rp-lsr    { fill: none; stroke: var(--ink); stroke-width: 1.4; }
.rp-fire   { fill: var(--sev-severe); stroke: var(--ink); stroke-width: .5; }
.rp-civic  { fill: none; stroke: var(--ink); stroke-width: 1.1; }
.rp-tfr    { fill: none; stroke: var(--ink); stroke-width: 1.2; }
.rp-outage { fill: var(--ink); fill-opacity: .25; stroke: var(--ink); stroke-dasharray: 2 2; }
.rp-conv   { fill: none; stroke: var(--orange); stroke-width: 1.8; }
.rp-label  { font-family: var(--mono); font-size: 9px; letter-spacing: .06em; fill: var(--orange); paint-order: stroke; stroke: var(--paper); stroke-width: 3px; }
@media (prefers-reduced-motion: reduce) { .rp-mark { animation: none; } }

#legend-btn {
  position: absolute; left: 14px; bottom: 14px; z-index: 25;
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  background: var(--paper); border: 1px solid var(--ink); color: var(--ink);
  padding: 6px 11px; cursor: pointer;
}
#legend-btn:hover, #legend-btn.open { background: var(--ink); color: var(--paper); }
#legend-box {
  position: absolute; left: 14px; bottom: 44px; z-index: 25;
  width: 282px; max-width: calc(100% - 28px);
  background: var(--paper); border: 1px solid var(--ink);
  box-shadow: 3px 4px 0 rgba(8, 8, 8, .12);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 12px;
}
#legend-box[hidden] { display: none; }
.sources { display: flex; flex-direction: column; gap: 2px; }

.src {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 4px;
  cursor: pointer;
  border: none; background: none;
  font: inherit; text-align: left; width: 100%;
}
.src .box { width: 12px; height: 12px; border: 1.4px solid var(--ink); flex: 0 0 auto; position: relative; }
.src .box::after {
  content: "";
  position: absolute; inset: 2px;
  background: var(--ink);
  opacity: 0;
  transition: opacity .15s;
}
.src.on .box::after { opacity: 1; }
.src .name { font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; flex: 1; }
.src .ct   { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.src.off { opacity: .4; }
.src.off .name { text-decoration: line-through; }
/* not-yet-wired source: greyed, non-interactive, "soon" instead of a count */
.src.disabled { opacity: .38; cursor: not-allowed; }
.src.disabled .box { border-color: var(--ink-soft); }
.src.disabled .name { color: var(--ink-soft); }
.src.disabled .ct { font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }

.legend { display: flex; flex-direction: column; gap: 14px; }
.leg { display: flex; gap: 11px; align-items: flex-start; }
.leg .ico { width: 22px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; padding-top: 1px; }
.leg .lt  { font-size: 11px; letter-spacing: .04em; line-height: 1.32; color: var(--ink); }
.leg .lt b    { font-weight: 700; letter-spacing: .08em; text-transform: uppercase; font-size: 10px; display: block; }
.leg .lt span { color: var(--ink-soft); font-size: 10.5px; }

/* ---------- main / map ---------- */
#main { grid-area: main; position: relative; overflow: hidden; }
#map  { position: absolute; inset: 0; width: 100%; height: 100%; }

.map-tag {
  position: absolute;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--ink-faint);
  text-transform: uppercase;
  white-space: nowrap;
}
#tag-tl { left: 18px; top: 14px; }
#tag-br { right: 18px; bottom: 14px; text-align: right; }

.state   { fill: none; stroke: var(--ink); stroke-width: .7; stroke-linejoin: round; stroke-linecap: round; }
.nation  { fill: none; stroke: var(--ink); stroke-width: 1.1; stroke-linejoin: round; }
.county  { fill: none; stroke: var(--ink); stroke-width: .35; stroke-linejoin: round; opacity: .26; }

/* anchor-city reference labels (regional views) */
/* The label layer is lifted above the data marks (so anchor names aren't buried
   under co-located story glyphs); making the visual elements non-targetable keeps
   the marks underneath clickable. Only each primary anchor's transparent hit rect
   stays interactive (pointer-events:all inline) — it also carries the :hover. */
.city-label, .city-dot, .city-chevron { pointer-events: none; }
.city-dot   { fill: var(--ink); }
.city-label {
  font-family: var(--mono);
  letter-spacing: .08em;
  fill: var(--ink);
  paint-order: stroke;          /* paper halo so the name stays legible over county lines */
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
}
/* primary anchors: prominent, clickable */
.city-primary { cursor: pointer; }
.city-primary .city-label { font-size: 10.5px; font-weight: 600; }
.city-primary .city-dot { fill: var(--ink); }
/* trailing disclosure chevron — persistent "this opens a panel" affordance on the
   clickable metro anchors. Ink at rest (orange stays reserved for convergence on
   the map); hover shifts it orange + nudges it right. Paper halo keeps it legible
   over county lines and data marks. */
.city-chevron {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
  transition: transform .18s ease, fill .18s ease;
}
/* secondary reference towns: small, light, label-only */
.city-secondary .city-label { font-size: 7.5px; letter-spacing: .1em; fill: var(--ink-faint); stroke-width: 2.5px; }
.city-secondary .city-dot { fill: var(--ink-faint); }
.glyph   { cursor: pointer; }
.glyph[data-dim="1"] { pointer-events: none; }
.sel-ring { fill: none; stroke: var(--orange); stroke-width: 1.4; }

/* live NWS alert footprints — severity ramp (grey→ochre→red→crimson). Burnt
   orange (--orange) stays reserved for convergence, so the ramp avoids it.
   --sev carries the per-severity hue; fill + stroke both read from it, severity
   also reads as stroke weight + fill density. pointer-events:all makes the whole
   interior a click target even where the fill is near-transparent (tiny polys). */
:root {
  --sev-minor:    #6f6b5e;
  --sev-moderate: #C99A2E;
  --sev-severe:   #C4361B;
  --sev-extreme:  #8E1209;
}
.alert-poly {
  --sev: var(--ink-soft);
  fill: var(--sev); fill-opacity: .07;
  stroke: var(--sev); stroke-width: 1; stroke-linejoin: round;
  pointer-events: all; cursor: pointer;
  transition: fill-opacity .12s ease, stroke-width .12s ease;
}
.alert-poly.sev-minor    { --sev: var(--sev-minor);    stroke-width: .8;  fill-opacity: .05; }
.alert-poly.sev-moderate { --sev: var(--sev-moderate); stroke-width: 1.0; fill-opacity: .10; }
.alert-poly.sev-severe   { --sev: var(--sev-severe);   stroke-width: 1.3; fill-opacity: .13; }
.alert-poly.sev-extreme  { --sev: var(--sev-extreme);  stroke-width: 1.7; fill-opacity: .17; }
.alert-poly:hover    { fill-opacity: .26; }
.alert-poly.selected { fill-opacity: .30; stroke-width: 2.4; }

/* FAA TFR airspace footprints (broadcast-class, ink — orange stays reserved for
   convergence). A dashed restricted-airspace ring + a centroid marker (▲ hazard /
   ◆ event). A faint fill makes the whole interior clickable (not just the stroke).
   Upcoming (scheduled, not yet in effect) reads dimmer than currently-in-effect. */
.tfr-poly {
  fill: var(--ink); fill-opacity: .035;
  stroke: var(--ink); stroke-width: 1; stroke-dasharray: 4 3; stroke-linejoin: round;
  pointer-events: all; cursor: pointer;
  transition: fill-opacity .12s ease;
}
.tfr-hazard .tfr-poly { stroke-width: 1.3; }
.tfr:hover .tfr-poly  { fill-opacity: .10; }
.tfr-upcoming         { opacity: .62; }
.tfr-icon {
  fill: var(--ink); stroke: var(--paper); stroke-width: 2.5;
  paint-order: stroke; stroke-linejoin: round; pointer-events: all; cursor: pointer;
}
.tfr-mark { pointer-events: all; cursor: pointer; }

/* TFR drilldown (in the fly-over sheet) */
.tfr-detail { margin-top: 16px; }
.td-row { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); }
.td-k { flex: 0 0 84px; font-family: var(--mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }
.td-v { font-size: 13px; color: var(--ink); }
.td-reason { margin-top: 12px; font-size: 13px; line-height: 1.5; color: var(--ink); border-left: 2px solid var(--ink-soft); padding-left: 11px; }
.td-src { margin-top: 12px; font-family: var(--mono); font-size: 8px; letter-spacing: .08em; color: var(--ink-faint); }

/* cities over the population floor inside an active polygon — hollow ink rings,
   distinct from the filled anchor-city reference dots. Clickable: selects the
   most-severe alert covering that city (a second, easier target than tiny polys) */
.alert-city { cursor: pointer; }
.alert-city-dot { fill: var(--paper); stroke: var(--ink); stroke-width: 1.3; }
.alert-city:hover .alert-city-dot { stroke-width: 2; }
/* per-severity hue for the affected-city marker */
.alert-city.sev-minor    { --sev: var(--sev-minor); }
.alert-city.sev-moderate { --sev: var(--sev-moderate); }
.alert-city.sev-severe   { --sev: var(--sev-severe); }
.alert-city.sev-extreme  { --sev: var(--sev-extreme); }
/* prominent = a town ≥ 20k under an active polygon: filled severity-colored
   dot + always-labeled, so it stays visible on the map for the alert's life */
.alert-city.prominent .alert-city-dot   { fill: var(--sev); stroke: var(--sev); }
.alert-city.prominent .alert-city-label { font-weight: 600; }
.alert-city.selected .alert-city-dot    { stroke-width: 2.6; }
.alert-city.selected .alert-city-label  { font-weight: 700; }
.alert-city-label {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .08em;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
}

/* ---------- alert popover (on-map, anchored to the click point) ---------- */
#alert-popover {
  position: absolute;
  z-index: 30;
  width: 268px;
  max-width: calc(100% - 24px);
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 4px 6px 0 rgba(8,8,8,.12);
  padding: 12px 13px 13px;
  font-family: var(--grotesque);
  pointer-events: auto;
}
#alert-popover[hidden] { display: none; }
#alert-popover .pop-sev {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--paper); background: var(--sev, var(--ink-soft));
  padding: 2px 7px; line-height: 1.3;
}
#alert-popover .pop-event {
  margin-top: 8px; font-size: 16px; font-weight: 700; line-height: 1.1; letter-spacing: .01em;
}
#alert-popover .pop-head {
  margin-top: 7px; font-size: 11.5px; line-height: 1.35; color: var(--ink-soft);
}
#alert-popover .pop-meta {
  margin-top: 9px; display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--ink-soft);
}
#alert-popover .pop-meta b { color: var(--ink); font-weight: 600; }
#alert-popover .pop-close {
  position: absolute; top: 6px; right: 8px;
  background: none; border: none; cursor: pointer;
  font-family: var(--mono); font-size: 14px; line-height: 1; color: var(--ink-faint); padding: 2px;
}
#alert-popover .pop-close:hover { color: var(--ink); }

/* per-severity hue for the popover badge */
#alert-popover.sev-minor    { --sev: var(--sev-minor); }
#alert-popover.sev-moderate { --sev: var(--sev-moderate); }
#alert-popover.sev-severe   { --sev: var(--sev-severe); }
#alert-popover.sev-extreme  { --sev: var(--sev-extreme); }

/* ---------- alert detail (right rail) ---------- */
.a-sev {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--paper); background: var(--sev, var(--ink-soft));
  padding: 2px 8px;
}
.a-detail.sev-minor    { --sev: var(--sev-minor); }
.a-detail.sev-moderate { --sev: var(--sev-moderate); }
.a-detail.sev-severe   { --sev: var(--sev-severe); }
.a-detail.sev-extreme  { --sev: var(--sev-extreme); }
.a-head { margin-top: 10px; font-size: 13px; line-height: 1.4; }
.a-meta { margin-top: 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.a-meta .k { font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); }
.a-cell { background: var(--paper); padding: 9px 11px; }
.a-cell .v { font-family: var(--mono); font-size: 12px; margin-top: 3px; color: var(--ink); }
.a-cell .sub { font-family: var(--mono); font-size: 10px; margin-top: 2px; color: var(--ink-soft); }
.a-area { margin-top: 6px; font-size: 11px; line-height: 1.45; color: var(--ink-soft); }
/* NWS statement body — the actual alert text (description / instruction). */
.a-sech { margin-top: 14px; font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); }
.a-body { margin-top: 5px; font-size: 12px; line-height: 1.5; color: var(--ink); white-space: normal; }
.a-instr { color: var(--ink); border-left: 2px solid var(--sev, var(--line)); padding-left: 9px; }
.gd-link {
  display: inline-block; margin-top: 14px; align-self: flex-start;
  font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--line); padding-bottom: 2px;
}
.gd-link:hover { border-color: var(--ink); }
.gd-title { margin-top: 10px; font-size: 13.5px; line-height: 1.3; font-weight: 600; }
.gd-ent { margin-top: 8px; font-size: 11px; line-height: 1.4; color: var(--ink); }
.gd-ent .k { font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-right: 5px; }

/* short-hover tooltip over a news marker (inverted ink chip; non-interactive) */
#hover-tip {
  position: absolute; z-index: 35; pointer-events: none;
  max-width: 260px;
  background: var(--ink); color: var(--paper);
  padding: 7px 9px;
  box-shadow: 2px 3px 0 rgba(8, 8, 8, .18);
  font-family: var(--grotesque);
}
#hover-tip[hidden] { display: none; }
#hover-tip .ht-title { font-size: 12px; line-height: 1.25; font-weight: 600; }
#hover-tip .ht-sum { margin-top: 4px; font-size: 11px; line-height: 1.3; opacity: .92; }
#hover-tip .ht-sub {
  margin-top: 4px; font-family: var(--mono); font-size: 9px;
  letter-spacing: .04em; opacity: .72; text-transform: uppercase;
}
.gd-sum { margin-top: 7px; font-size: 12px; line-height: 1.4; color: var(--ink); }

/* clickable anchor cities */
.anchor-city { cursor: pointer; }
.anchor-city:hover .city-dot { stroke: var(--orange); stroke-width: 2; }
.anchor-city:hover .city-label { fill: var(--orange); }
.anchor-city:hover .city-chevron { fill: var(--orange); transform: translateX(2px); }

/* ---------- city slide-over (metro news digest) ---------- */
#fly-sheet { position: absolute; inset: 0; z-index: 40; pointer-events: none; }
#fly-sheet[hidden] { display: none; }
#fly-sheet .cs-surface {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(520px, 86%);
  background: var(--paper);
  border-left: 1px solid var(--ink);
  box-shadow: -10px 0 28px rgba(8, 8, 8, .16);
  transform: translateX(100%);
  transition: transform .56s cubic-bezier(.22, .61, .36, 1);   /* slow-in (deliberate) */
  pointer-events: auto;
  overflow-y: auto;
  padding: 22px 24px 34px;
}
#fly-sheet.open .cs-surface { transform: translateX(0); }
#fly-sheet.closing .cs-surface { transition: transform .24s ease-in; }  /* fast-out */
/* Labeled close control (user call 2026-07-02 — the bare faint ✕ was hard to find/
   hit): a bordered chip with a verb label and a generous hit area, inverting on
   hover. Per the labeled-affordances rule. */
#fly-sheet .cs-close {
  position: absolute; top: 14px; right: 16px; z-index: 3;
  background: var(--paper); border: 1px solid var(--ink); border-radius: 3px;
  cursor: pointer; padding: 6px 12px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink);
}
#fly-sheet .cs-close:hover { background: var(--ink); color: var(--paper); }
.cs-city { font-size: 26px; font-weight: 700; letter-spacing: .01em; }
.cs-sub { margin-top: 3px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); }
.cs-brief p { margin: 14px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink); border-left: 2px solid var(--orange); padding-left: 11px; }
/* "Place profile" — slow-moving metro context (TRERC housing). Calm Rand: a thin
   keyline card, mono labels, ink figures + a small ink sparkline. No orange. */
.cs-profile { margin-top: 16px; border: 1px solid var(--line); padding: 12px 13px 10px; background: var(--paper); }
.pp-h { display: flex; justify-content: space-between; align-items: baseline; font-family: var(--mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); }
.pp-asof { color: var(--ink-faint); letter-spacing: .1em; }
.pp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 11px; }
.pp-k { font-family: var(--mono); font-size: 8.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }
.pp-v { font-size: 17px; font-weight: 700; line-height: 1.15; margin-top: 3px; }
.pp-yoy { display: inline-block; margin-top: 3px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; color: var(--ink-soft); }
.pp-yoy.dn { color: var(--ink-faint); }
.pp-spark { display: flex; align-items: center; gap: 9px; margin-top: 12px; }
.pp-spark .spark { flex: 0 0 auto; }
.pp-spark .spark-end { fill: var(--ink); }
.pp-spark-cap { font-family: var(--mono); font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.pp-src { margin-top: 10px; font-family: var(--mono); font-size: 8px; letter-spacing: .08em; color: var(--ink-faint); }
.cs-sec-h { margin-top: 22px; display: flex; justify-content: space-between; font-family: var(--mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); border-bottom: 1px solid var(--line); padding-bottom: 5px; }
.cs-list { display: flex; flex-direction: column; }
.cs-node { border-bottom: 1px solid var(--line-soft); }
.cs-item { display: flex; gap: 9px; padding: 11px 2px; cursor: pointer; }
.cs-item:hover { background: rgba(8, 8, 8, .025); }
.cs-twisty { width: 0; height: 0; flex: 0 0 auto; margin-top: 6px;
  border-left: 5px solid var(--ink-soft); border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s; }
.cs-twisty.empty { border: none; width: 5px; }
.cs-item.open .cs-twisty { transform: rotate(90deg); }
.cs-dot { width: 8px; height: 8px; flex: 0 0 auto; margin-top: 4px; background: var(--ink); }
.cs-node.sig5 .cs-dot, .cs-node.sig4 .cs-dot { background: var(--sev-severe); }
.cs-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cs-label { font-size: 13px; font-weight: 600; line-height: 1.25; color: var(--ink); }
.cs-n { font-family: var(--mono); font-size: 9px; color: var(--paper); background: var(--ink-soft); padding: 0 4px; vertical-align: 1px; }
.cs-sum { font-size: 11.5px; line-height: 1.4; color: var(--ink-soft); }
.cs-meta { font-family: var(--mono); font-size: 9px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
/* nested member stories of one event (city sheet) */
.cs-children { display: flex; flex-direction: column; gap: 6px; padding: 2px 0 10px 22px; }
.cs-children[hidden] { display: none; }
.cs-child { font-size: 11px; line-height: 1.35; color: var(--ink-soft); text-decoration: none; }
.cs-child:hover { color: var(--orange); }
.cs-child-host { font-family: var(--mono); font-size: 9px; color: var(--ink-faint); }
.cs-empty { margin-top: 22px; font-size: 12px; color: var(--ink-soft); }
/* stack count badge — ink on a paper halo so it reads over a colored shape */
.gd-count {
  font-family: var(--mono); font-size: 8px; font-weight: 700; fill: var(--ink);
  paint-order: stroke; stroke: var(--paper); stroke-width: 2.4px; stroke-linejoin: round;
}

/* co-located stack popover (hover/click a stack → list every event there) */
#stack-pop {
  position: absolute; z-index: 36; width: 252px; max-width: calc(100% - 16px);
  background: var(--paper); border: 1px solid var(--ink); box-shadow: 3px 4px 0 rgba(8,8,8,.14);
  padding: 7px 0 4px; font-family: var(--grotesque);
}
#stack-pop[hidden] { display: none; }
#stack-pop .sp-head {
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); padding: 0 11px 6px; border-bottom: 1px solid var(--line-soft);
}
#stack-pop .sp-list { max-height: 300px; overflow-y: auto; }
.sp-row { display: flex; gap: 8px; align-items: flex-start; width: 100%; text-align: left;
  background: none; border: none; cursor: pointer; padding: 7px 11px; font: inherit; }
.sp-row:hover { background: rgba(8,8,8,.04); }
.sp-dot { width: 8px; height: 8px; flex: 0 0 auto; margin-top: 3px; border: 1px solid var(--ink); }
.sp-text { display: flex; flex-direction: column; gap: 2px; }
.sp-label { font-size: 11.5px; line-height: 1.25; color: var(--ink); }
.sp-meta { font-family: var(--mono); font-size: 8.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }

/* cluster member articles in the drilldown */
.gd-arts { margin-top: 8px; display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.gd-art { background: var(--paper); padding: 8px 10px; text-decoration: none; display: block; }
.gd-art:hover { background: rgba(8,8,8,.03); }
.gd-art-t { font-size: 11.5px; line-height: 1.3; color: var(--ink); }
.gd-art-s { margin-top: 3px; font-family: var(--mono); font-size: 9px; letter-spacing: .03em; color: var(--ink-soft); }

/* Central TX brief panel (right rail) */
/* hidden attr must beat .sect{display:flex}; brief styles repointed to classes
   now that the section is .sect[data-sect="brief"] (no #brief id after reorg). */
.sect[hidden] { display: none !important; }
.brief-body { font-size: 12.5px; line-height: 1.5; color: var(--ink); }
.brief-foot { margin-top: 8px; font-family: var(--mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }

/* "Also in Central TX" feed — relevant news with no map geocode */
#feed { padding: 14px 20px; border-bottom: 1px solid var(--line); min-height: 0; overflow-y: auto; max-height: 30%; }
.rail-ct { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); font-weight: 400; }
.feed-list { display: flex; flex-direction: column; }
.feed-node { border-bottom: 1px solid var(--line-soft); }
.feed-row { display: flex; gap: 6px; align-items: flex-start; cursor: pointer; padding: 7px 0; }
.feed-row:hover { background: rgba(8,8,8,.025); }
/* twisty for events with nested coverage; .empty is a spacer for singletons */
.feed-twisty { width: 0; height: 0; flex: 0 0 auto; margin-top: 5px;
  border-left: 4px solid var(--ink-soft); border-top: 3px solid transparent; border-bottom: 3px solid transparent;
  transition: transform .15s; }
.feed-twisty.empty { border: none; width: 4px; }
.feed-row.open .feed-twisty { transform: rotate(90deg); }
.feed-dot { width: 7px; height: 7px; flex: 0 0 auto; margin-top: 4px; border: 1px solid var(--ink); }
.feed-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.feed-label { font-size: 11.5px; line-height: 1.3; color: var(--ink); }
.feed-n { font-family: var(--mono); font-size: 8.5px; color: var(--paper); background: var(--ink-soft); padding: 0 4px; vertical-align: 1px; }
.feed-meta { font-family: var(--mono); font-size: 8.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
/* nested member stories of one event */
.feed-children { display: flex; flex-direction: column; gap: 5px; padding: 1px 0 8px 21px; }
.feed-children[hidden] { display: none; }
.feed-child { font-size: 10.5px; line-height: 1.32; color: var(--ink-soft); text-decoration: none; }
.feed-child:hover { color: var(--orange); }

/* shared story-tree child styling (feed + city sheet): host tag, major-source ★/highlight */
.src-host { font-family: var(--mono); font-size: 9px; color: var(--ink-faint); }
.src-star { color: var(--orange); margin-right: 3px; font-size: 9px; vertical-align: 1px; }
/* list-item bullet — the no-star counterpart of .src-star, marking each row of a
   multi-source list as a distinct item so long headlines don't run together. */
.src-bullet { color: var(--ink-faint); margin-right: 5px; font-weight: 700; }
.feed-child.major, .cs-child.major { color: var(--ink); font-weight: 600; }   /* major outlets stand out */
.feed-child.major .src-host, .cs-child.major .src-host { color: var(--ink-soft); }

/* convergence drill tag — the sanctioned orange */
.d-sub .tag.conv { border-color: var(--orange); color: var(--orange); }
.conv-row { cursor: pointer; }
.conv-row .cnt { color: var(--orange); }
.a-cityhead {
  margin-top: 14px; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft);
  display: flex; justify-content: space-between;
}
.a-cities { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 5px; }
.a-cities .chip {
  font-family: var(--mono); font-size: 10.5px;
  border: 1px solid var(--line); padding: 3px 7px; color: var(--ink);
}
.a-cities .chip.none { border: none; color: var(--ink-faint); padding-left: 0; }
/* named in the warning area but not geometrically enclosed by the polygon */
.a-cities .chip.named { border-style: dashed; }

/* ---------- alert list (right-rail default, ordered by severity) ---------- */
.a-list { display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.a-item { background: var(--paper); padding: 9px 11px; cursor: pointer; display: flex; flex-direction: column; gap: 4px; }
.a-item:hover { background: rgba(8,8,8,.03); }
.a-item.sev-minor    { --sev: var(--sev-minor); }
.a-item.sev-moderate { --sev: var(--sev-moderate); }
.a-item.sev-severe   { --sev: var(--sev-severe); }
.a-item.sev-extreme  { --sev: var(--sev-extreme); }
.a-item-top { display: flex; align-items: center; gap: 7px; }
.a-item-top .a-dot { width: 9px; height: 9px; flex: 0 0 auto; background: var(--sev, var(--ink-soft)); }
.a-item-top .a-ev  { font-size: 12.5px; font-weight: 600; line-height: 1.1; }
.a-item-top .a-star { color: var(--ink); font-size: 12px; line-height: 1; }
/* No-fly-zone (TFR) list rows reuse .a-item; ▲ hazard / ◆ event icon in place of the dot */
.a-item-top .tfr-row-icon { flex: 0 0 11px; width: 11px; text-align: center; font-size: 9px; color: var(--ink-soft); line-height: 1; }
.a-item-top .tfr-row-icon.hz { color: var(--ink); font-weight: 700; }
.a-item.tfr-row.upcoming { opacity: .72; }
.a-item-top .tfr-row-conv { margin-left: auto; color: var(--orange); font-size: 12px; line-height: 1; }
/* TFR convergence tag in the fly-over (the sanctioned orange) */
.td-conv { margin-top: 14px; display: inline-block; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--orange); border: 1px solid var(--orange); padding: 4px 9px; }

/* IEM storm reports — small hollow ink "spotter report" rings (ground truth),
   a distinct broadcast-class layer. Subtle family cues, all ink (calm). */
.lsr-ring { fill: var(--paper); fill-opacity: .55; stroke: var(--ink); stroke-width: 1; pointer-events: all; cursor: pointer; }
.lsr-core { fill: var(--ink); pointer-events: none; }
.lsr:hover .lsr-ring { stroke-width: 1.9; }
.lsr-flood .lsr-ring { stroke-dasharray: 2 1.5; }             /* flood reports: dashed ring */
.lsr-hail  .lsr-ring { fill: var(--ink); fill-opacity: .18; } /* hail: faint fill */
/* storm-report rail rows reuse .a-item; a small family-tinted dot in place of .a-dot */
.a-item-top .lsr-row-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--paper); border: 1px solid var(--ink); }
.a-item-top .lsr-row-dot.lsr-tornado, .a-item-top .lsr-row-dot.lsr-waterspout { background: var(--ink); }
.a-item-top .lsr-row-dot.lsr-hail { background: var(--ink-soft); }

/* NWPS river gauges — droplet glyphs, only shown when a gauge is in a flood
   category. Color = category on the sanctioned NWS severity ramp (action=grey,
   minor=ochre, moderate=red, major=crimson — orange stays reserved for
   convergence); ink border keeps the ink grammar. Forecast-only flooding dims
   (advance signal, same grammar as upcoming TFRs). */
.flood-drop { stroke: var(--ink); stroke-width: 1; pointer-events: all; cursor: pointer; }
.flood-cat-action   .flood-drop { fill: var(--sev-minor); }
.flood-cat-minor    .flood-drop { fill: var(--sev-moderate); }
.flood-cat-moderate .flood-drop { fill: var(--sev-severe); }
.flood-cat-major    .flood-drop { fill: var(--sev-extreme); }
.flood-gauge.flood-fcst { opacity: .55; }
.flood-gauge:hover .flood-drop { stroke-width: 1.6; }
.a-item-top .flood-row-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--ink); }
.a-item-top .flood-row-dot.flood-cat-action   { background: var(--sev-minor); }
.a-item-top .flood-row-dot.flood-cat-minor    { background: var(--sev-moderate); }
.a-item-top .flood-row-dot.flood-cat-moderate { background: var(--sev-severe); }
.a-item-top .flood-row-dot.flood-cat-major    { background: var(--sev-extreme); }

/* NHC tropical cyclones — cone of uncertainty (faint dashed wash), forecast track
   (dotted line + points), storm marker. Strength rides the sanctioned severity
   ramp (depression grey → storm ochre → hurricane red → major crimson); orange
   stays reserved for convergence. */
.storm-cone  { fill: var(--sev, #6f6b5e); fill-opacity: .07; stroke: var(--sev, #6f6b5e); stroke-width: 1.1; stroke-dasharray: 6 4; pointer-events: all; cursor: pointer; }
.storm-track { fill: none; stroke: var(--ink); stroke-width: 1; stroke-dasharray: 2 3; pointer-events: none; }
/* footprints along the forecast track — alternating feet, ink with paper halo */
.storm-print { fill: var(--ink); fill-opacity: .8; stroke: var(--paper); stroke-width: .6; pointer-events: none; }
.storm-fpt   { fill: var(--paper); stroke: var(--ink); stroke-width: 1; pointer-events: none; }
.storm-eye   { fill: var(--sev, #6f6b5e); stroke: var(--ink); stroke-width: 1.2; cursor: pointer; }
.storm-label { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; fill: var(--ink); paint-order: stroke; stroke: var(--paper); stroke-width: 3px; }
.storm-depression { --sev: var(--sev-minor); }
.storm-storm      { --sev: var(--sev-moderate); }
.storm-hurricane  { --sev: var(--sev-severe); }
.storm-major      { --sev: var(--sev-extreme); }
.a-item-top .flood-row-dot.storm-dot-depression { background: var(--sev-minor); }
.a-item-top .flood-row-dot.storm-dot-storm      { background: var(--sev-moderate); }
.a-item-top .flood-row-dot.storm-dot-hurricane  { background: var(--sev-severe); }
.a-item-top .flood-row-dot.storm-dot-major      { background: var(--sev-extreme); }

/* Air quality — HMS smoke plumes as a grey wash (opacity by density; literally
   "smoke over the parchment") + AQI area markers ONLY at USG/101+ (sev ramp).
   Rail dots span the full AQI scale for the ambient list. */
/* Smoke is NON-interactive (a frame-covering wash would swallow backdrop clicks —
   the rail's ☁ note opens the smoke detail instead). */
.smoke { fill: #6f6b5e; stroke: #6f6b5e; stroke-width: .8; stroke-dasharray: 3 4; stroke-opacity: .5; pointer-events: none; }
.aqi-dot { stroke: var(--ink); stroke-width: 1; cursor: pointer; }
.aqi-usg .aqi-dot       { fill: var(--sev-moderate); }
.aqi-unhealthy .aqi-dot { fill: var(--sev-severe); }
.aqi-hazardous .aqi-dot { fill: var(--sev-extreme); }
.aqi-num { font-family: var(--mono); font-size: 8px; fill: var(--paper); text-anchor: middle; pointer-events: none; }
.a-item-top .flood-row-dot.aqi-dot-good      { background: none; }
.a-item-top .flood-row-dot.aqi-dot-moderate  { background: var(--sev-minor); }
.a-item-top .flood-row-dot.aqi-dot-usg       { background: var(--sev-moderate); }
.a-item-top .flood-row-dot.aqi-dot-unhealthy { background: var(--sev-severe); }
.a-item-top .flood-row-dot.aqi-dot-hazardous { background: var(--sev-extreme); }
.air-smoke-note {
  font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--ink-soft);
  padding: 2px 2px 8px; background: none; border: none; cursor: pointer; text-align: left; display: block; width: 100%;
}
.air-smoke-note:hover { color: var(--ink); }

/* IODA internet outages — the affected county gets an INK WASH ("gone dark") +
   an OFFLINE label at its centroid. Rare; unmistakable when it happens. */
.outage-county { fill: var(--ink); fill-opacity: .14; stroke: var(--ink); stroke-width: 1; stroke-dasharray: 2 3; pointer-events: all; cursor: pointer; }
.outage:hover .outage-county { fill-opacity: .2; }
.outage-label { font-family: var(--mono); font-size: 8px; letter-spacing: .18em; fill: var(--ink); text-anchor: middle; paint-order: stroke; stroke: var(--paper); stroke-width: 3px; pointer-events: none; }
.a-item-top .flood-row-dot.outage-dot { background: var(--ink); }

/* Acute 311 civic reports — rendered as a compact block inside the AUSTIN metro
   slide-over (not a map layer / rail section; user call 2026-07-02). Rows link to
   the external map. */
.cs-civic { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 14px; }
.cs-civic-row {
  display: flex; align-items: baseline; gap: 8px; text-decoration: none;
  font-size: 11.5px; color: var(--ink); padding: 4px 6px; border-radius: 3px;
}
.cs-civic-row:hover { background: rgba(8,8,8,.05); }
.cs-civic-row .ccr-type { font-weight: 600; flex: 0 0 auto; }
.cs-civic-row .ccr-type.acute { color: var(--sev-severe); }
.cs-civic-row .ccr-addr { color: var(--ink-soft); flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-civic-row .ccr-time { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); flex: 0 0 auto; }

/* Rising-fast gauges — hollow ochre droplet + tags ("water on the way up",
   distinct from in-flood fills). */
.flood-rising .flood-drop { fill: none; stroke: var(--sev-moderate); stroke-width: 1.6; stroke-dasharray: 3 2; }
.flood-rise-tag { font-family: var(--mono); font-size: 9.5px; color: var(--sev-moderate); letter-spacing: .03em; }
.a-item-top .flood-row-dot.flood-dot-rising { background: none; border: 1.5px dashed var(--sev-moderate); }

/* City-sheet attention pulse — weekly news sparkline + AQI, one calm line. */
.cs-pulse { display: flex; align-items: center; gap: 10px; margin: 12px 0 2px; }
.cs-pulse .spark polyline { stroke: var(--ink-soft); }
.cs-pulse-n, .cs-pulse-aqi { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--ink-soft); text-transform: uppercase; }

/* Footer day pulse — one-line "what kind of day" summary before the convergence chips. */
.day-pulse { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; color: var(--ink-soft); margin-right: 16px; white-space: nowrap; }

/* Convergence connection trails — dashes march from the corroborating partner
   to the converged mark once (on draw), then settle faint. Sanctioned orange:
   these lines ARE the convergence. */
.conv-trail {
  fill: none; stroke: var(--orange); stroke-width: 1.1; stroke-linecap: round;
  stroke-dasharray: 2 6; opacity: .18; pointer-events: none;
}
#stage.drawn .conv-trail {
  animation: conv-march 2.2s ease-out both;
}
@keyframes conv-march {
  0%   { stroke-dashoffset: var(--tlen, 200); opacity: .75; }
  80%  { opacity: .55; }
  100% { stroke-dashoffset: 0; opacity: .18; }
}
@media (prefers-reduced-motion: reduce) { #stage.drawn .conv-trail { animation: none; } }

/* Fire — NIFC named incidents (flame glyph + label) + FIRMS thermal dots.
   Small fires = calm ink flame with a paper halo; MAJOR fires (≥100 ac) go
   full color — sev-ramp red body + ochre inner flame + ink border, matching
   the GKG "color = severity, ink border" grammar. Burnt orange stays reserved
   for convergence. FIRMS dots read RED (heat), faint scatter beneath. */
.fire-icon  { fill: var(--ink); stroke: var(--paper); stroke-width: 1.6; paint-order: stroke; stroke-linejoin: round; pointer-events: all; cursor: pointer; }
.fire-inc.major .fire-icon { fill: var(--sev-severe); stroke: var(--ink); stroke-width: 1; }
.fire-icon-inner { fill: var(--sev-moderate); stroke: none; pointer-events: none; }
.fire-label { font-family: var(--mono); font-size: 8.5px; letter-spacing: .06em; fill: var(--ink); paint-order: stroke; stroke: var(--paper); stroke-width: 3px; pointer-events: none; }
.fire-inc:hover .fire-icon { stroke-width: 2.2; }
.fire-inc.major:hover .fire-icon { stroke-width: 1.6; }
.firms { fill: var(--sev-severe); fill-opacity: .45; stroke: none; pointer-events: all; cursor: pointer; }
.firms.conf-h { fill-opacity: .8; }
.firms:hover { fill-opacity: 1; }
.a-item-top .fire-row-icon { flex: 0 0 11px; width: 11px; text-align: center; color: var(--ink); display: flex; align-items: center; justify-content: center; }
.flame-mini .fo { fill: var(--ink); }
.flame-mini.major .fo { fill: var(--sev-severe); stroke: var(--ink); stroke-width: .08; }
.flame-mini.major .fi { fill: var(--sev-moderate); }
.fire-det-note { font-family: var(--mono); font-size: 8.5px; letter-spacing: .06em; color: var(--ink-faint); padding: 7px 2px 2px; }
.td-maps { margin-top: 0; } /* gd-link's stand-alone top margin doesn't apply inside a td-row */
/* Expiring alerts (final 30 min) dim in the rail — a state, readable, not a ramp. */
.a-item.expiring { opacity: .55; }

.a-item-bot {
  font-family: var(--mono); font-size: 10px; letter-spacing: .03em;
  color: var(--ink-soft); display: flex; justify-content: space-between; gap: 8px;
}
.a-back {
  align-self: flex-start;
  background: none; border: none; cursor: pointer; padding: 0; margin-bottom: 10px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft);
}
.a-back:hover { color: var(--ink); }

/* ---------- right rail ---------- */
#right { grid-area: right; border-left: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; }
/* convergence list takes up to ~half the rail, then scrolls; drill gets the rest */
#conv  { padding: 18px 20px 16px; border-bottom: 1px solid var(--ink); flex: 0 1 auto; min-height: 0; max-height: 50%; overflow-y: auto; }

.conv-row {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 8px;
  cursor: pointer;
  border: 1px solid transparent;
}
.conv-row:hover { background: rgba(219,98,0,.06); }
.conv-row.active { border-color: var(--orange); background: rgba(219,98,0,.08); }
.cr-top, .cr-bot { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.conv-row .place { font-size: 12px; font-weight: 700; letter-spacing: .06em; }
.conv-row .srcs  { font-family: var(--mono); font-size: 10px; color: var(--ink-soft); }
.conv-row .cnt   { font-family: var(--mono); font-size: 11px; color: var(--orange); font-weight: 600; white-space: nowrap; }
.conv-row .tm    { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); white-space: nowrap; }

.conv-none { font-size: 12.5px; letter-spacing: .04em; color: var(--ink-soft); padding: 10px 6px 4px; font-style: italic; }

#drill { flex: 1 1 auto; padding: 18px 20px; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
#drill-empty {
  margin: auto;
  color: var(--ink-soft);
  font-size: 14px;
  letter-spacing: .02em;
  text-align: center;
  line-height: 1.5;
  max-width: 200px;
}
#drill-body { display: none; flex-direction: column; height: 100%; min-height: 0; }

.d-place { font-size: 23px; font-weight: 700; letter-spacing: .01em; line-height: 1.05; }
.d-sub   { margin-top: 8px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.d-sub .tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .06em;
  border: 1px solid var(--ink);
  padding: 2px 6px;
  text-transform: uppercase;
  white-space: nowrap;
}
.d-sub .tag.nws { border-color: var(--orange); color: var(--orange); }

.d-grid {
  margin-top: 18px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.d-cell { background: var(--paper); padding: 11px 12px; }
.d-cell .k { font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); }
.d-cell .v {
  font-family: var(--mono);
  font-size: 20px;
  font-weight: 600;
  margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.d-cell .v.accent { color: var(--orange); }
.d-cell .v small { font-size: 11px; color: var(--ink-soft); font-weight: 400; }

.d-samhead {
  margin-top: 20px;
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  justify-content: space-between;
}
.d-samples {
  margin-top: 9px;
  border-top: 1px solid var(--line);
  padding-top: 11px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  overflow: hidden;
}
.sam {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.4;
  color: var(--ink);
  padding-left: 13px;
  position: relative;
}
.sam::before {
  content: "";
  position: absolute; left: 0; top: 6px;
  width: 5px; height: 5px;
  background: var(--ink);
}
.sam.nws::before { background: var(--orange); }
.sam .who { color: var(--ink-faint); }

/* ---------- bottom gutter ---------- */
#bottom {
  grid-area: bottom;
  border-top: 1px solid var(--ink);
  display: flex;
  align-items: center;
  padding: 0 22px;
  gap: 0;
}
/* convergence (NWS × news) — static, left; orange, the rare/bright signal */
.foot-conv {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  max-width: 46%; overflow: hidden;
}
.foot-conv .fc-label {
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--orange); font-weight: 700; white-space: nowrap;
}
.foot-conv .fc-label.muted { color: var(--ink-soft); font-weight: 400; }
.foot-conv .fc-chip {
  font: inherit; font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
  border: 1px solid var(--orange); color: var(--orange); background: var(--paper);
  padding: 4px 9px; cursor: pointer; white-space: nowrap;
}
.foot-conv .fc-chip:hover, .foot-conv .fc-chip.active { background: var(--orange); color: var(--paper); }

/* top-stories marquee — multi-row, fills the rest of the footer */
.foot-marquee {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  flex: 1; min-width: 0;
  border-left: 1px solid var(--line); margin-left: 18px; padding-left: 22px;
  height: 72px; overflow: hidden;
}
.mq-row { display: flex; align-items: center; overflow: hidden; width: 100%; height: 24px; }
.marquee-track { display: flex; align-items: center; gap: 22px; width: max-content; will-change: transform; }
.mq-item {
  font: inherit; background: none; border: none; cursor: pointer;
  display: flex; align-items: center; gap: 7px; flex: 0 0 auto; padding: 0;
}
.mq-item .mq-dot { width: 7px; height: 7px; flex: 0 0 auto; border: 1px solid var(--ink); }
.mq-item .mq-label { font-size: 11.5px; color: var(--ink); white-space: nowrap; }
.mq-item .mq-place { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; color: var(--ink-faint); white-space: nowrap; }
.mq-item:hover .mq-label { color: var(--orange); }
.mq-empty { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); letter-spacing: .1em; text-transform: uppercase; }
@media (prefers-reduced-motion: reduce) {
  .foot-marquee { overflow-x: auto; }
}

/* ---------- draw-in animation ---------- */
.glyph { opacity: 0; }
#stage.drawn .glyph {
  opacity: var(--o, 1);
  transition: opacity .5s ease, transform .5s ease;
}
#stage.wiping .glyph {
  opacity: 0 !important;
  transition: opacity .35s ease;
}
/* During a resize-driven rebuild, snap marks into place — no fade-in replay. */
#stage.relaying .glyph,
#stage.relaying .state,
#stage.relaying .nation,
#stage.relaying .county {
  transition: none !important;
}

/* ---------- Marauder's-Map "alive ink" nods (news marks) ---------- */
/* Ink-bloom: each news mark spreads onto the parchment from a dot, with a slight
   overshoot, longitude-staggered by the same --delay as the opacity fade. */
.gd-bloom { transform: scale(.06); transform-box: fill-box; transform-origin: center; }
#stage.drawn .gd-bloom {
  transform: scale(1);
  transition: transform .6s cubic-bezier(.34, 1.56, .5, 1) var(--delay, 0s);
}
/* Footsteps trail (convergence marks only): dotted dashes march toward the mark, then
   fade — "someone arrived." Driven by dashoffset; gated so it replays with the draw-in. */
@keyframes gd-footsteps {
  0%   { stroke-dashoffset: 22; opacity: 0; }
  20%  { opacity: .5; }
  70%  { stroke-dashoffset: 0;  opacity: .5; }
  100% { stroke-dashoffset: 0;  opacity: 0; }
}
.gd-trail { opacity: 0; }
#stage.drawn .gd-trail { animation: gd-footsteps 1.7s ease var(--delay, 0s) both; }
/* Significant marks keep breathing once settled — a gentle, slow pulse (the parchment
   stays alive). Starts after the entrance (delay + 1s). */
@keyframes gd-breathe {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .68; transform: scale(1.06); }
}
.gd-breathe { transform-box: fill-box; transform-origin: center; }
#stage.drawn .gd-breathe { animation: gd-breathe 3.8s ease-in-out calc(var(--delay, 0s) + 1s) infinite; }
/* Freeze entrance + perpetual animations during resize (snap) and wipe. */
#stage.relaying .gd-bloom { transform: scale(1); }
#stage.relaying .gd-bloom,
#stage.relaying .gd-trail,
#stage.relaying .gd-breathe,
#stage.wiping .gd-breathe,
#stage.wiping .gd-trail { animation: none !important; transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  /* respect reduced-motion: keep marks present, drop the perpetual breathe + march */
  .gd-breathe, .gd-trail { animation: none !important; }
  #stage.drawn .gd-bloom { transition: opacity .4s ease; transform: scale(1); }
}

/* ============================================================
   FLY-OVER SHEET (drilldown deep view)
   Covers everything except the top bar; slides in from the right.
   ============================================================ */

.sheet {
  position: absolute;
  top: 72px;            /* clear of the bucket clock */
  left: 0;
  right: 0;
  bottom: 86px;         /* clear of the unresolved gutter */
  z-index: 20;
  display: block;
  pointer-events: auto; /* backdrop catches clicks for dismissal */
  background: transparent;
}
.sheet[hidden] { display: none; }

.sheet-surface {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  /* Leave ~480px of map visible on the left when there's room, but never let the
     surface get narrower than 560px — past that it covers everything. */
  left: max(0px, min(480px, 100% - 560px));
  background: var(--paper);
  border: 1px solid var(--ink);
  display: flex;
  flex-direction: column;
  transform: translateX(110%);  /* off-screen plus shadow buffer */
  transition: transform .96s cubic-bezier(.22, .68, .26, 1),
              box-shadow .96s ease;
  box-shadow: none;
}
/* faster close — match the previous .72s feel on the way out */
.sheet.is-closing .sheet-surface {
  transition: transform .72s cubic-bezier(.22, .68, .26, 1),
              box-shadow .72s ease;
}
.sheet:not([hidden]) .sheet-surface {
  transform: translateX(0);
  /* paper-on-paper: warm directional shadow, most pronounced on the left edge */
  box-shadow:
    -22px  0   46px -10px rgba(8,8,8,0.24),
      0   14px 32px -14px rgba(8,8,8,0.16),
      0  -10px 26px -14px rgba(8,8,8,0.10);
}

/* header */
.sheet-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 0 22px;
  height: 56px;
  border-bottom: 1px solid var(--ink);
  position: relative;
}
.sheet-crumb {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.sheet-crumb .sep { color: var(--ink-faint); padding: 0 6px; }
.sheet-crumb [data-dashboard-target] { color: var(--ink); }
.sheet-close {
  margin-left: auto;
  background: none;
  border: 1px solid var(--ink);
  width: 28px;
  height: 28px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink);
  padding: 0;
}
.sheet-close:hover { background: var(--ink); color: var(--paper); }

/* body — scrollable region */
.sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 28px 38px 48px;
  display: flex;
  flex-direction: column;
}

/* variant gate */
.sheet-variant { display: none; }
.sheet[data-active-variant="conv"]  .sheet-variant[data-variant="conv"],
.sheet[data-active-variant="spike"] .sheet-variant[data-variant="spike"],
.sheet[data-active-variant="bc"]    .sheet-variant[data-variant="bc"]    { display: block; }

/* sub-variant gate inside broadcast */
.bc-sub { display: none; }
.bc-sub[hidden] { display: none; }
.bc-sub:not([hidden]) { display: block; }
.sheet[data-bc-kind="usgs"]   .bc-sub[data-bc-kind="usgs"],
.sheet[data-bc-kind="nws"]    .bc-sub[data-bc-kind="nws"],
.sheet[data-bc-kind="github"] .bc-sub[data-bc-kind="github"] { display: block; }
.sheet[data-bc-kind="usgs"]   .bc-sub[data-bc-kind="nws"],
.sheet[data-bc-kind="usgs"]   .bc-sub[data-bc-kind="github"],
.sheet[data-bc-kind="nws"]    .bc-sub[data-bc-kind="usgs"],
.sheet[data-bc-kind="nws"]    .bc-sub[data-bc-kind="github"],
.sheet[data-bc-kind="github"] .bc-sub[data-bc-kind="usgs"],
.sheet[data-bc-kind="github"] .bc-sub[data-bc-kind="nws"] { display: none; }

/* title row */
.sheet-title-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 18px;
  margin-bottom: 22px;
}
.sheet-place {
  font-size: 38px;
  font-weight: 700;
  letter-spacing: .015em;
  line-height: 1;
}
.sheet-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sheet-tags .tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .06em;
  border: 1px solid var(--ink);
  padding: 3px 7px;
  text-transform: uppercase;
  white-space: nowrap;
}
.sheet-tags .tag.nws { border-color: var(--orange); color: var(--orange); }

/* metric strip */
.sheet-metric-strip {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-bottom: 22px;
}
.sheet-metric-strip .ms { background: var(--paper); padding: 14px 16px; }
.sheet-metric-strip .k {
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.sheet-metric-strip .v {
  font-family: var(--mono);
  font-size: 26px;
  font-weight: 600;
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}
.sheet-metric-strip .v.accent { color: var(--orange); }

/* section grid */
.sheet-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.sheet-section {
  border: 1px solid var(--line);
  padding: 18px 20px 20px;
  background: var(--paper);
}
.sheet-section--span { grid-column: 1 / -1; }
.sec-h {
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 4px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.sec-h-tail {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .08em;
  font-weight: 400;
  color: var(--ink-faint);
  text-transform: none;
}
.sec-sub {
  font-size: 11px;
  color: var(--ink-soft);
  margin-bottom: 14px;
  line-height: 1.4;
}

/* sparkline */
.sparkline { width: 100%; height: 90px; display: block; }
.sparkline .spark-x {
  font-family: var(--mono);
  font-size: 9px;
  fill: var(--ink-faint);
  letter-spacing: .08em;
}

/* source-contribution bars */
.src-bars { display: flex; flex-direction: column; gap: 9px; }
.src-bar { display: grid; grid-template-columns: 100px 1fr 100px; align-items: center; gap: 12px; }
.src-bar .lbl {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}
.src-bar .track {
  height: 14px;
  background: var(--line-soft);
  position: relative;
}
.src-bar .fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--ink);
}
.src-bar:first-child .fill { background: var(--ink); }
.src-bar .val {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-soft);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* NWS row */
.nws-row { display: grid; grid-template-columns: 180px 1fr; gap: 22px; align-items: flex-start; }
.mini-map { width: 100%; height: auto; display: block; border: 1px solid var(--line); }
.nws-title {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 8px;
}
.nws-line { display: flex; gap: 10px; font-size: 11px; margin-top: 3px; }
.nws-line .k { width: 80px; color: var(--ink-soft); letter-spacing: .12em; text-transform: uppercase; font-size: 9.5px; padding-top: 1px; }
.nws-line .v { font-family: var(--mono); color: var(--ink); }
.nws-body {
  margin-top: 12px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
  color: var(--ink);
  padding-top: 10px;
  border-top: 1px solid var(--line);
  text-wrap: pretty;
}

/* co-occurring tokens */
.tok-list { list-style: none; display: flex; flex-direction: column; gap: 7px; }
.tok-list li { display: grid; grid-template-columns: 120px 1fr 40px; align-items: center; gap: 10px; }
.tok-list .t { font-family: var(--mono); font-size: 11.5px; color: var(--ink); }
.tok-list .bar { height: 8px; background: var(--line-soft); position: relative; }
.tok-list .bar span {
  display: block;
  height: 100%;
  background: var(--ink);
}
.tok-list .n {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-soft);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* disambiguation list */
.dis-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.dis-list li { display: grid; grid-template-columns: 130px 1fr; gap: 12px; font-size: 11px; line-height: 1.35; }
.dis-list .k {
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-top: 2px;
}
.dis-list .v { font-family: var(--mono); color: var(--ink); }
.dis-list .v.accent { color: var(--orange); }

/* aftershock list */
.aft-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
.aft-list li {
  display: grid;
  grid-template-columns: 90px 60px 1fr;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
  padding: 4px 0;
  border-bottom: 1px dashed var(--line-soft);
}
.aft-list .ts { color: var(--ink); }
.aft-list .mag { color: var(--ink); font-weight: 600; }
.aft-list .muted { color: var(--ink-faint); }

/* post stream */
.post-stream {
  margin-top: 6px;
  max-height: 360px;
  overflow-y: auto;
  border-top: 1px solid var(--line);
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.post {
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.42;
  padding-left: 16px;
  position: relative;
}
.post::before {
  content: "";
  position: absolute;
  left: 0; top: 7px;
  width: 6px; height: 6px;
  background: var(--ink);
}
.post.nws::before { background: var(--orange); }
.post-meta { display: flex; gap: 10px; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 2px; }
.post-meta .ts { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.post-meta .who { color: var(--ink-soft); }
.post-body { color: var(--ink); text-wrap: pretty; }
.post-body .post-link {
  color: var(--ink-faint);
  text-decoration: none;
  margin-left: 6px;
  font-size: 11px;
}
.post-body .post-link:hover { color: var(--orange); }
.post-more {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-faint);
  font-style: italic;
  text-align: center;
  padding: 12px 0 0;
}

/* raw provenance */
.prov-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.prov-list li {
  display: grid;
  grid-template-columns: 110px 1fr auto;
  gap: 14px;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px dashed var(--line-soft);
}
.prov-list .lbl {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}
.prov-list .v { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }
.prov-link {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--orange);
  text-decoration: none;
  letter-spacing: .04em;
}
.prov-link:hover { text-decoration: underline; }

/* broadcast headline */
.bc-headline {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 18px 0 22px;
  border-bottom: 1px solid var(--ink);
  margin-bottom: 22px;
}
.bc-mag {
  font-family: var(--mono);
  font-size: 44px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
  line-height: 1;
  border: 1.5px solid var(--ink);
  padding: 10px 18px;
}
.bc-mag--nws { color: var(--orange); border-color: var(--orange); font-size: 32px; }
.bc-mag--gh  { font-size: 36px; }
.bc-meta { font-size: 13px; line-height: 1.42; }
.bc-meta .muted {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-faint);
  margin-top: 4px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* alert body for NWS broadcast */
.alert-body {
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--ink);
  text-wrap: pretty;
  padding-top: 6px;
}

/* drilldown expand affordance — labeled DRILL button next to place name */
.d-place-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.drill-expand {
  flex: 0 0 auto;
  margin-top: 4px;
  font-family: var(--mono);
  background: var(--paper);
  border: 1px solid var(--ink);
  cursor: pointer;
  color: var(--ink);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 5px 9px 4px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: background .15s, color .15s;
}
.drill-expand .arrow {
  font-size: 12px;
  line-height: 1;
  transition: transform .15s;
}
.drill-expand:hover {
  background: var(--ink);
  color: var(--paper);
}
.drill-expand:hover .arrow { transform: translate(1px, -1px); }

/* ============================================================
   NARROW LAYOUT — below the wide 3-column floor, reflow to two
   columns: the map stacked OVER a horizontal sources/legend strip
   on the left, with the convergence + drilldown rail on the right.
   Same partials, regrouped via grid-template-areas — no markup change.
   ============================================================ */
@media (max-width: 1079px) {
  #stage {
    min-width: 720px;
    grid-template-columns: 1fr 360px;
    grid-template-rows: 72px 1fr auto 86px;
    grid-template-areas:
      "top    top"
      "main   right"
      "left   right"
      "bottom bottom";
  }

  /* sources + legend flow into a horizontal strip beneath the map */
  #left {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 16px 44px;
    border-right: none;
    border-top: 1px solid var(--line);
    overflow-x: auto;
  }
  #left > div { min-width: 0; }
  .sources { flex-direction: row; flex-wrap: wrap; gap: 2px 20px; }
  .src     { width: auto; }
  .legend  { flex-direction: row; flex-wrap: wrap; gap: 14px 26px; }
  .leg     { max-width: 220px; }

  /* drop the centered clock into the flow, just right of the always-present
     logo + wordmark, so they never collide at narrow widths */
  #clock {
    position: static;
    transform: none;
    left: auto;
    top: auto;
    margin-left: 24px;
    text-align: left;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ============================================================
   /news — Central TX article archive (browse/search/group)
   A normal scrolling page (NOT the full-screen dashboard stage),
   same Rand palette/tokens. Body class `news-page` undoes the
   dashboard's centered overflow-hidden flex stage.
   ============================================================ */
body.news-page {
  overflow: auto;
  display: block;
  background: var(--paper);
  color: var(--ink);
}
/* Narrower content column + a reserved LEFT GUTTER (padding-left) that always holds the
   vertical date rail (and future side helps) — so the rail is a layout element with room
   at any width, not something squeezed into a vanishing margin. */
.news-page-wrap { max-width: 1180px; margin: 0 auto; padding: 22px 26px 60px 56px; }

/* Full-width site band — SAME geometry as the dashboard #top (72px tall,
   22px side padding, brand left / context centered / nav right, ink rule),
   so the dashboard, Explorer, and Editions share ONE navbar. Reuses the
   global .brand/.word lockup styles from the top-bar section. */
.site-top {
  position: relative; display: flex; align-items: center;
  height: 72px; padding: 0 22px; border-bottom: 1px solid var(--ink);
  background: var(--paper);
}
.site-top-brand { text-decoration: none; color: var(--ink); }
/* centered context, mirroring the dashboard #clock slot */
.site-top-mid {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  text-align: center; white-space: nowrap;
}
.site-top-title { font-size: 12.5px; letter-spacing: .16em; text-transform: uppercase; font-weight: 500; color: var(--ink); }
.site-top-sub { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; color: var(--ink-soft); margin-top: 3px; }
.site-top .topnav { margin-left: auto; }
@media (max-width: 1000px) { .site-top-mid { display: none; } }   /* brand + nav win when narrow */
/* filter bar */
.news-bar { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; margin-bottom: 12px; }
.news-search {
  flex: 1 1 280px; min-width: 220px;
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); padding: 9px 11px;
}
.news-search:focus { outline: none; border-color: var(--ink); }
.news-sel {
  font-family: var(--mono); font-size: 12px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); padding: 8px 9px; cursor: pointer;
}
.news-sel:focus { outline: none; border-color: var(--ink); }
.news-reset, .news-go {
  font-family: var(--mono); font-size: 12px; color: var(--ink-soft); text-decoration: none;
  border: 1px solid var(--line); padding: 8px 11px; background: var(--paper); cursor: pointer;
}
.news-reset:hover, .news-go:hover { color: var(--ink); border-color: var(--ink); }
.news-count { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); margin: 4px 0 14px; }
.news-count strong { color: var(--ink); }

/* facet (group-by) navigator */
/* Stack the two facet groups vertically (sub-region row, then category row) — NOT
   side-by-side-wrapping, so the layout doesn't jump from two rows to one when a
   filter prunes chips. Each group keeps its own row regardless of chip count. */
.news-facets { display: flex; flex-direction: column; gap: 14px; margin-bottom: 18px; }
.facet-h { font-family: var(--mono); font-size: 9px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 7px; }
.facet-row { display: flex; flex-wrap: wrap; gap: 6px; }
.facet {
  display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  font-family: var(--mono); font-size: 11px; color: var(--ink);
  border: 1px solid var(--line); padding: 4px 8px;
}
.facet:hover { border-color: var(--ink); }
/* no matches under the current filter — greyed + non-interactive, but kept in place */
.facet.disabled { opacity: .32; cursor: default; pointer-events: none; }
.facet.on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.facet.on .facet-c { color: var(--paper); }
.facet-c { color: var(--ink-soft); font-size: 10px; }

/* table */
.news-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.news-table thead th {
  text-align: left; font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft); font-weight: 500;
  border-bottom: 1px solid var(--ink); padding: 7px 9px; vertical-align: bottom; white-space: nowrap;
}
.th-sort { color: var(--ink-soft); text-decoration: none; }
.th-sort:hover { color: var(--ink); }
.th-sort.active { color: var(--ink); }
.news-table tbody td { padding: 13px 9px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.news-table tbody tr:hover { background: rgba(8,8,8,.035); }
/* "Made the dashboard" (Regional + pinned on the map): a faint, natural sage wash on
   the whole row — calm, not alarming (deliberately not red/orange). No border accent;
   the shade alone marks rows that reached the map. */
.news-table tbody tr.made-dash { background: rgba(108,128,84,.09); }
.news-table tbody tr.made-dash:hover { background: rgba(108,128,84,.15); }
/* Per-day left-border cue: the color cycles every 5 days, so scrolling past a day
   boundary visibly changes the edge. Muted naturals; box-shadow (not border) so it
   doesn't shift cell layout and coexists with the made-dash wash. */
.news-table tbody tr.news-day-0 td.c-title { box-shadow: inset 3px 0 0 #8a9a7b; }
.news-table tbody tr.news-day-1 td.c-title { box-shadow: inset 3px 0 0 #b0a07a; }
.news-table tbody tr.news-day-2 td.c-title { box-shadow: inset 3px 0 0 #7f97a8; }
.news-table tbody tr.news-day-3 td.c-title { box-shadow: inset 3px 0 0 #b39079; }
.news-table tbody tr.news-day-4 td.c-title { box-shadow: inset 3px 0 0 #9a8aa0; }
/* Headline is the lead, dominant column; Sig + Date are the only compact columns now
   (category/source/location moved into the headline block). */
.c-title { width: auto; }
.c-sig  { white-space: nowrap; width: 96px; }
.c-date { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); white-space: nowrap; text-align: right; width: 120px; }
/* Significance as a 5-dot scale (●●●●○) — quick visual cue; filled ink, empty faint. */
.sig-dots { font-size: 11px; letter-spacing: 1.5px; white-space: nowrap; }
.sig-dots .sig-on { color: var(--ink); }
.sig-dots .sig-off { color: var(--ink-faint); }
.sig-dots.none { color: var(--ink-faint); font-family: var(--mono); }

/* Meta line under the headline+summary: category chip · location · source / N sources. */
.news-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft); letter-spacing: .02em; }
.news-meta .nm-sep { color: var(--ink-faint); }
.news-meta .nm-where { color: var(--ink-soft); }
.news-meta .nm-src { color: var(--ink-soft); }

/* Color-coded category chip — glyph shape + hue = the map's 4-bucket grammar
   (crime ◆ / hazard ▲ / event ● / other ■); the text is the specific category. */
.cat { white-space: nowrap; font-weight: 600; }
.cat .cat-g { font-size: 9px; margin-right: 1px; }
.cat-crime  { color: #C4361B; }   /* crime — crimson */
.cat-hazard { color: #C56A24; }   /* fire/flood/weather — burnt */
.cat-event  { color: #8A867A; }   /* community — warm grey (matches map) */
.cat-other  { color: #3E6E72; }   /* gov/health/edu/business/infra/other — blue-green */
.cat-none   { color: var(--ink-faint); }

.badge {
  display: inline-block; font-family: var(--mono); font-size: 9px; letter-spacing: .08em;
  padding: 2px 6px; border: 1px solid var(--line);
}
.badge.yes { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.badge.no { color: var(--ink-faint); }
/* Regional story that appeared on the map dashboard — orange, the "made it" tag. */
.badge.dash { background: var(--orange); color: var(--paper); border-color: var(--orange); }
/* Headline is the featured element: largest, boldest text on the row. */
.news-link { color: var(--ink); text-decoration: none; font-weight: 600; font-size: 15px; line-height: 1.32; display: block; }
.news-link:hover { text-decoration: underline; }
.news-summ { font-size: 12.5px; color: var(--ink-soft); margin-top: 5px; line-height: 1.45; max-width: 70ch; }
.news-where { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft); margin-top: 7px; letter-spacing: .02em; }

/* pagination */
.news-pager { display: flex; align-items: center; gap: 16px; justify-content: center; margin-top: 22px; }
.pg { font-family: var(--mono); font-size: 12px; color: var(--ink); text-decoration: none; border: 1px solid var(--line); padding: 7px 13px; }
.pg:hover { border-color: var(--ink); }
.pg.disabled { color: var(--ink-faint); border-color: var(--line-soft); }
.pg-at { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }
.news-empty { font-family: var(--mono); font-size: 13px; color: var(--ink-soft); padding: 40px 0; text-align: center; }

/* "← Back" button in the flyover detail (when reached from a stack/metro list). */
.sheet-back {
  font-family: var(--mono); font-size: 11px; letter-spacing: .04em; color: var(--ink-soft);
  background: none; border: none; cursor: pointer; padding: 0 0 12px; display: inline-block;
}
.sheet-back:hover { color: var(--orange); }
/* Prominent bottom back button (clear return to the stack/metro list after reading). */
.sheet-back-btn {
  display: block; width: 100%; margin-top: 20px; cursor: pointer;
  font-family: var(--mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink); padding: 12px;
}
.sheet-back-btn:hover { background: var(--orange); border-color: var(--orange); }

/* Floating vertical "date in view" rail — fixed just left of the centered table,
   updates on scroll across day boundaries (JS: news#updateDateView). Reads bottom-to-top. */
.news-dateview {
  position: fixed; top: 50%;
  /* Sit in the wrap's left gutter: ~11px right of the centered 1180px wrap's left edge
     (half = 590) on wide screens; clamps to 11px when the wrap fills the viewport — so
     it's in the gutter (just left of the table) at every width, never off-screen. */
  left: max(11px, calc(50% - 579px));
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line);
  padding: 13px 5px; white-space: nowrap; z-index: 40; pointer-events: none;
}
/* Only hide on small/phone widths where a vertical rail + gutter isn't practical. */
@media (max-width: 700px) { .news-dateview { display: none; } }

/* Floating back-to-top on /news — hidden until scrolled, then fades in bottom-right. */
.news-totop {
  position: fixed; right: 22px; bottom: 22px; z-index: 50;
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink);
  padding: 9px 13px; cursor: pointer; opacity: 0; pointer-events: none; transition: opacity .18s;
}
.news-totop.show { opacity: 1; pointer-events: auto; }
.news-totop:hover { background: var(--orange); border-color: var(--orange); }

/* Left-rail link out to the full /news archive (replaced the in-rail feed). */
.news-archive-link { display: block; text-decoration: none; border: 1px solid var(--line); padding: 13px 14px; background: var(--paper); }
.news-archive-link:hover { border-color: var(--ink); }
.nal-title { display: block; font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: .01em; }
.nal-sub { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft); margin-top: 6px; line-height: 1.45; }

/* /news — event grouping (cluster expand/collapse) */
.nc-sub { color: var(--ink-faint); font-weight: 400; }
.news-where { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* "N sources" toggle — reveals same-event coverage from other outlets */
.grp-toggle {
  font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--ink-soft);
  background: var(--paper); border: 1px solid var(--line); padding: 2px 7px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
}
.grp-toggle:hover { border-color: var(--ink); color: var(--ink); }
.grp-toggle .gt-caret { width: 0; height: 0; border-left: 4px solid currentColor; border-top: 3px solid transparent; border-bottom: 3px solid transparent; transition: transform .12s; }
.grp-toggle.open .gt-caret { transform: rotate(90deg); }
.grp-children { margin-top: 9px; padding-left: 12px; border-left: 2px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
/* `display:flex` above out-specifies the UA [hidden] rule, so the collapsed state
   must be re-asserted or the members show (and the toggle does nothing visually). */
.grp-children[hidden] { display: none; }
/* Overflow sources (11+) — same column layout, revealed by the "Load all" button. */
.grp-more { display: flex; flex-direction: column; gap: 8px; }
.grp-more[hidden] { display: none; }
.grp-more-btn {
  align-self: flex-start; margin-top: 2px; cursor: pointer;
  font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--ink-soft);
  background: var(--paper); border: 1px solid var(--line); padding: 3px 9px;
}
.grp-more-btn:hover { border-color: var(--ink); color: var(--ink); }
.grp-child { text-decoration: none; display: block; }
.grp-child .gc-title { display: block; font-size: 12.5px; color: var(--ink); line-height: 1.35; }
.grp-child:hover .gc-title { text-decoration: underline; }
.grp-child .gc-meta { display: block; font-family: var(--mono); font-size: 10px; color: var(--ink-soft); margin-top: 2px; }
/* The headline title is a block (so summary/location stack under it). An inline
   star before a block would drop the headline to the next line — so HANG the star
   in a left gutter (absolute, out of flow). Headlines then align across rows
   whether or not they're starred, and the star reads as a margin marker. */
.news-table tbody td.c-title { position: relative; padding-left: 26px; }
/* national-pickup star — orange, matching the dashboard lists (shared .src-star). */
.c-title .src-star { position: absolute; left: 6px; top: 14px; font-size: 11px; margin: 0; }
.grp-child { position: relative; padding-left: 15px; }
.grp-child .src-star { position: absolute; left: 0; top: 1px; font-size: 10px; margin: 0; }
.grp-child .src-bullet { position: absolute; left: 1px; top: 0; font-size: 13px; margin: 0; }

/* Multi-source title is a <button> that expands the coverage — make it look and
   sit exactly like the <a> headline (inherits .news-link size/weight/color). */
button.news-link { background: none; border: 0; padding: 0; margin: 0; width: 100%; text-align: left; cursor: pointer; font-family: var(--grotesque); }

/* ============================================================
   "Trending on Wikipedia" — full panel (/news) + compact left-rail mini
   ============================================================ */
.wiki-trends { border: 1px solid var(--ink); padding: 14px 16px; margin-bottom: 20px; background: var(--paper); }
.wt-head { font-size: 12px; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; color: var(--ink); margin-bottom: 12px; }
.wt-head .wt-sub { font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 11px; color: var(--ink-soft); }
.wt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(225px, 1fr)); gap: 12px; }
.wt-card { border: 1px solid var(--line); padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.wt-row1 { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.wt-name { font-size: 13.5px; font-weight: 600; color: var(--ink); text-decoration: none; line-height: 1.2; }
.wt-name:hover { text-decoration: underline; }
.wt-mag { font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.wt-mag .wt-per { font-size: 9px; font-weight: 400; color: var(--ink-soft); }
.wt-ratio { font-family: var(--mono); font-size: 11px; font-weight: 700; color: var(--orange); white-space: nowrap; }
.wt-base { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); white-space: nowrap; }
.wt-row2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wt-spark { color: var(--ink); flex: 0 0 auto; display: block; }
.wt-story { font-family: var(--mono); font-size: 10px; color: var(--ink-soft); text-decoration: none; line-height: 1.35; }
.wt-story:hover { color: var(--ink); text-decoration: underline; }

.wiki-mini { margin-top: 18px; }
.wm-head { font-size: 9px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 9px; }
.wm-item { display: flex; align-items: center; gap: 7px; text-decoration: none; padding: 4px 0; }
.wm-name { flex: 1; min-width: 0; font-size: 11.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wm-item:hover .wm-name { text-decoration: underline; }
.wm-item .wt-spark { color: var(--ink-soft); }
.wm-mag { font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.wm-mag.surge { color: var(--orange); }
.wm-more { display: inline-block; margin-top: 9px; font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--ink-soft); text-decoration: none; }
.wm-more:hover { color: var(--ink); }


/* The weather ear in the metro flyover header — same line the Edition masthead wears. */
.cs-wx { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; color: var(--ink); margin-top: 8px; }

/* "Read the edition" — a labeled affordance in the metro flyover header. */
.cs-edition-btn {
  display: inline-block; margin-top: 10px; padding: 5px 11px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); border: 1px solid var(--ink); border-radius: 3px; text-decoration: none;
}
.cs-edition-btn:hover { background: var(--ink); color: var(--paper); }

/* ---------- About page (2026-07-03) ---------- */
/* Plain-prose register: a readable column, mono section labels, and a credits
   grid. Same paper/ink discipline as everything else. */
.about { max-width: 780px; margin: 0 auto; padding: 34px 26px 70px; }
.ab-lede h1 { font-family: Georgia, "Times New Roman", serif; font-size: 30px; font-weight: 700; margin: 0 0 14px; }
.about p { font-size: 14.5px; line-height: 1.65; margin: 0 0 12px; color: var(--ink); }
.ab-sect { margin-top: 30px; border-top: 1px solid var(--ink); padding-top: 12px; }
.ab-label { font-family: var(--mono); font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink); margin: 0 0 10px; }
.ab-note { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }
.ab-srcs { margin-top: 14px; }
.ab-src {
  display: grid; grid-template-columns: 220px 1fr auto; gap: 6px 16px; align-items: baseline;
  padding: 9px 0; border-top: 1px solid var(--line);
}
.ab-src strong { font-size: 12.5px; }
.ab-src span { font-size: 12px; line-height: 1.5; color: var(--ink-soft); }
.ab-src a {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none; white-space: nowrap;
}
.ab-src a:hover { color: var(--ink); }
@media (max-width: 700px) { .ab-src { grid-template-columns: 1fr; gap: 2px; } }
.ab-foot { margin-top: 44px; }
.ab-foot span { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); padding-top: 8px; text-align: center; }

/* ---------- The Metro Edition (2026-07-03) ---------- */
/* Newspaper conventions inside the Rand system. Serif display type is
   sanctioned HERE ONLY — an edition earns a masthead; everywhere else the
   sans/mono grammar holds. Days ruled off with the classic thick-thin pair. */
.edition { max-width: 1060px; margin: 0 auto; padding: 26px 28px 60px; background: var(--paper); }
.edition a { color: var(--ink); }
.ed-mast-rule { border-top: 1px solid var(--ink); }
.ed-mast-rule.thick { border-top: 3px solid var(--ink); margin-top: 6px; }
.ed-mast-row { display: flex; justify-content: space-between; gap: 14px; padding: 6px 0 2px; flex-wrap: wrap; }
.ed-vol, .ed-date, .ed-note { font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); }
.ed-note.ed-wx { color: var(--ink); }   /* the weather ear is data — full ink */
.ed-title { font-family: Georgia, "Times New Roman", serif; font-size: 46px; font-weight: 700; letter-spacing: .01em; text-align: center; margin: 10px 0 12px; }
.ed-columns { display: grid; grid-template-columns: 1fr 230px; gap: 34px; margin-top: 24px; }
@media (max-width: 860px) { .ed-columns { grid-template-columns: 1fr; } }

.ed-kicker { font-family: var(--mono); font-size: 9px; letter-spacing: .22em; color: var(--orange); margin-bottom: 6px; }
.ed-headline { font-family: Georgia, serif; font-size: 32px; line-height: 1.15; font-weight: 700; margin: 0 0 10px; }
.ed-h3 { font-family: Georgia, serif; font-size: 19px; line-height: 1.2; font-weight: 700; margin: 0 0 6px; }
.ed-h4 { font-family: Georgia, serif; font-size: 15.5px; line-height: 1.25; font-weight: 700; margin: 0 0 4px; }
.ed-summary { font-size: 14px; line-height: 1.55; color: var(--ink); margin: 0 0 8px; }
.ed-summary.sm { font-size: 12.5px; line-height: 1.5; }
.ed-meta { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; color: var(--ink-faint); }
.ed-meta a { text-decoration: none; border-bottom: 1px solid var(--line); }
.ed-meta.faint { color: var(--ink-faint); opacity: .7; }

/* Headlines ARE the story links — newspaper convention, no underline at rest,
   an ink rule on hover says "this goes somewhere". Color stays inherited. */
.ed-headline a, .ed-h3 a, .ed-h4 a { color: inherit; text-decoration: none; }
.ed-headline a:hover, .ed-h3 a:hover, .ed-h4 a:hover { border-bottom: 2px solid var(--ink); }

/* Source credit — the prominent byline chip (outlet NAME, not domain).
   .edition-scoped so it outranks the generic .ed-meta a border-bottom. */
.edition .ed-src {
  display: inline-block; font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink); text-decoration: none;
  border: 1px solid var(--ink); border-radius: 2px; padding: 3px 8px; margin: 3px 6px 0 0;
}
.edition .ed-src:hover { background: var(--ink); color: var(--paper); }
/* "all N sources" — the Explorer deep-link that spreads the credit */
.edition .ed-allsrc {
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none; border-bottom: none; margin-right: 6px;
}
.edition .ed-allsrc:hover { color: var(--ink); }

.ed-lead { padding: 18px 0 20px; border-bottom: 1px solid var(--line); }
.ed-front { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; padding: 18px 0; border-bottom: 1px solid var(--line); }
@media (max-width: 720px) { .ed-front { grid-template-columns: 1fr; } }

.ed-editorial { margin: 22px 0; padding: 14px 18px; border: 1px solid var(--ink); }
.ed-editorial p { font-size: 13.5px; line-height: 1.6; margin: 6px 0 8px; }

.ed-section { margin-top: 26px; }
.ed-sec-rule { border-top: 3px solid var(--ink); border-bottom: 1px solid var(--ink); height: 3px; }
.ed-sec-label { font-family: var(--mono); font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink); margin: 8px 0 4px; }
.ed-day { margin-top: 10px; }
.ed-day-rule { display: flex; align-items: center; gap: 10px; color: var(--ink-soft); }
.ed-day-rule::before, .ed-day-rule::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.ed-day-rule span { font-family: var(--mono); font-size: 9px; letter-spacing: .22em; text-transform: uppercase; }
.ed-day-grid { column-count: 2; column-gap: 30px; margin-top: 12px; }
@media (max-width: 720px) { .ed-day-grid { column-count: 1; } }
.ed-item { break-inside: avoid; margin-bottom: 16px; }
.ed-empty { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); padding: 40px 0; text-align: center; }

.ed-margin .ed-box { border-top: 1px solid var(--ink); padding: 10px 0 16px; }
.ed-fig { font-family: Georgia, serif; font-size: 26px; font-weight: 700; margin: 4px 0 2px; }
.ed-noticed { font-size: 11.5px; margin: 5px 0; color: var(--ink); }
.ed-noticed .nr-mark { color: var(--orange); }
.ed-elsewhere { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; margin: 7px 0; text-decoration: none; border-bottom: none; color: var(--ink-soft); }
.ed-elsewhere:hover { color: var(--ink); }
.ed-foot { margin-top: 44px; }
.ed-foot span { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); padding-top: 8px; text-align: center; }

/* Floating section-jump nav — lives in the cream to the RIGHT of the paper.
   Right-aligned text with an ink tick on the outer edge for the section in view.
   Hidden when the viewport can't hold it beside the 1060px sheet, and in print. */
.ed-jump {
  position: fixed; right: 20px; top: 50%; transform: translateY(-50%);
  z-index: 60; text-align: right; max-width: 170px;
}
.ed-jump-label { font-family: var(--mono); font-size: 8.5px; letter-spacing: .24em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px; padding-right: 10px; }
.ed-jump-link {
  display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none; padding: 4px 8px 4px 0;
  border-right: 2px solid var(--line);
}
.ed-jump-link:hover { color: var(--ink); }
.ed-jump-link.active { color: var(--ink); border-right-color: var(--ink); }
.ed-jump-top {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint); text-decoration: none; margin-top: 10px; padding-right: 10px;
}
.ed-jump-top:hover { color: var(--ink); }
/* "Sources featured" — the roster at the nav's foot. Native <details>,
   collapsed by default; expanded list scrolls internally past ~40vh. */
.ed-jump-srcs { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 8px; }
.ed-jump-srcs summary {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-soft); cursor: pointer; list-style: none; padding-right: 10px;
}
.ed-jump-srcs summary::-webkit-details-marker { display: none; }
.ed-jump-srcs summary::after { content: " ▸"; }
.ed-jump-srcs[open] summary::after { content: " ▾"; }
.ed-jump-srcs summary:hover { color: var(--ink); }
.ejs-list { max-height: 40vh; overflow-y: auto; margin-top: 6px; }
.ejs-list a {
  display: flex; justify-content: flex-end; gap: 8px; align-items: baseline;
  font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none; padding: 3px 10px 3px 0;
}
.ejs-list a:hover .ejs-name { color: var(--ink); border-bottom: 1px solid var(--ink); }
.ejs-n { color: var(--ink-faint); min-width: 16px; text-align: right; }

/* Wide screens: the rail is always open, no toggle chrome. */
.ed-jump-toggle { display: none; }

/* ≤1440px the fixed rail would collide with the 1060px sheet — collapse to a
   labeled floating button (bottom-right, per the labeled-affordances rule)
   that opens the same nav as a bordered panel. */
@media (max-width: 1440px) {
  .ed-jump {
    top: auto; bottom: 18px; right: 16px; transform: none;
    max-width: none;
  }
  .ed-jump-toggle {
    display: inline-block; font-family: var(--mono); font-size: 9.5px;
    letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
    color: var(--ink); background: var(--paper); border: 1px solid var(--ink);
    border-radius: 3px; padding: 7px 12px;
    box-shadow: -2px 2px 0 rgba(8, 8, 8, .12);
  }
  .ed-jump-toggle:hover { background: var(--ink); color: var(--paper); }
  .ed-jump-panel { display: none; }
  .ed-jump.open .ed-jump-panel {
    display: block; position: absolute; bottom: calc(100% + 8px); right: 0;
    background: var(--paper); border: 1px solid var(--ink); border-radius: 3px;
    padding: 12px 14px; min-width: 210px; max-height: 62vh; overflow-y: auto;
    box-shadow: -3px 3px 0 rgba(8, 8, 8, .1);
  }
}

/* Anchor jumps land with breathing room; smooth unless the reader asked otherwise. */
.ed-editorial, .ed-lead, .ed-section { scroll-margin-top: 20px; }
@media (prefers-reduced-motion: no-preference) { html:has(.ed-jump) { scroll-behavior: smooth; } }

@media print {
  .ed-margin .ed-box:last-child, .news-totop, .ed-jump { display: none; }
  .edition { max-width: none; padding: 0; }
  .ed-meta a { border-bottom: none; }
}


/* ---------- sitewide footer (2026-07-03) ---------- */
.site-foot {
  border-top: 1px solid var(--ink); background: var(--paper);
  padding: 18px 22px 24px; margin-top: 40px;
}
.sf-row { display: flex; justify-content: space-between; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.sf-word { font-size: 13px; font-weight: 700; letter-spacing: .26em; }
.sf-tag { display: block; font-family: var(--mono); font-size: 7.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-top: 4px; }
.sf-nav { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.sf-nav a { font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); text-decoration: none; }
.sf-nav a:hover { color: var(--ink); }
.sf-line { font-family: var(--mono); font-size: 8.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); margin-top: 14px; }
/* On the dashboard the footer exists for the PHONE flow only — desktop is the
   locked full-screen stage (the marquee is its bottom edge). */
.site-foot-dash { display: none; }
@media print { .site-foot { display: none; } }

/* Edition back-to-top: the wide-screen rail already has "↑ top" — the floating
   button serves the collapsed-rail widths. */
.ed-totop { display: none; }
@media (max-width: 1440px) { .ed-totop { display: block; bottom: 64px; } }

/* ============================================================
   Phone layout (≤760px, 2026-07-03) — the dashboard becomes a single
   scrolling column in PRIORITY order: map first, then the right rail's
   briefs/noticed/wiki, then the layer sections, then the story strip.
   Same partials, re-declared grid areas — no markup change (the same
   trick as the 1079px two-column reflow above).
   ============================================================ */
@media (max-width: 760px) {
  /* the stage stops being a locked full-screen canvas and becomes a page */
  body { overflow: auto; display: block; height: auto; min-height: 100%; }
  /* position: static is the load-bearing part — the desktop #viewport is
     position: FIXED (pinned to the screen), so the document never grew and
     the page couldn't scroll at all (user-caught on a real phone). */
  #viewport { position: static; overflow: visible; }
  html { height: auto; }
  #stage {
    min-width: 0; min-height: 0; width: 100%; height: auto;
    /* minmax(0,1fr), NOT 1fr: a bare 1fr can't shrink below min-content, and the
       footer marquee's duplicated track (~19,000px) blew the whole column out —
       the map SVG then sized itself to a 19,412px-wide #main. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(320px, 52vh) auto auto auto;
    grid-template-areas: "top" "main" "right" "left" "bottom";
  }
  #bottom { min-width: 0; overflow: hidden; }

  /* compact band: brand row + nav row (wraps); wall-display chrome hidden */
  #top { height: auto; padding: 8px 14px; flex-wrap: wrap; row-gap: 2px; }
  #clock, #top .status, #progress { display: none; }
  .brand img { height: 24px; }
  .brand .word { font-size: 14px; letter-spacing: .2em; }
  .brand-tag { font-size: 6.5px; letter-spacing: .12em; margin-top: 3px; }
  .topnav { margin-left: auto; gap: 13px; }
  .topnav-link, .topnav-drop-btn { font-size: 10px; letter-spacing: .1em; }

  /* rails flow as full-width stacked sections */
  #left, #right {
    border-left: none; border-right: none; border-top: 1px solid var(--ink);
    height: auto; min-height: 0; overflow: visible; padding: 12px 14px;
  }
  .rail-more { display: none !important; }   /* the rail no longer scrolls internally */

  /* footer stories: auto height, stacked lanes still marquee full-width */
  #bottom { height: auto; min-height: 60px; padding: 8px 14px; }

  .site-foot-dash { display: block; margin-top: 0; }

  /* flyovers cover the viewport (fixed — the stage is tall and scrolls now) */
  #fly-sheet { position: fixed; }
  #fly-sheet .cs-surface { width: 100%; border-left: none; padding: 18px 16px 30px; }
}

/* Shared site band (Explorer/Editions/About) — same compact wrap on phones. */
@media (max-width: 760px) {
  .site-top { height: auto; padding: 8px 14px; flex-wrap: wrap; row-gap: 2px; }
  .site-top .brand img { height: 24px; }
  .site-top .word { font-size: 14px; letter-spacing: .2em; }
  .site-top .brand-tag { font-size: 6.5px; letter-spacing: .12em; margin-top: 3px; }
  .site-top .topnav { margin-left: auto; gap: 13px; }
  .site-top .topnav-link, .site-top .topnav-drop-btn { font-size: 10px; letter-spacing: .1em; }

  /* Explorer: rows read as cards — headline leads, sig+date fold inline below */
  .news-page-wrap { padding: 14px 14px 60px; }
  .news-table thead { display: none; }
  .news-table, .news-table tbody, .news-table tr, .news-table td { display: block; }
  .news-table tr { border-top: 1px solid var(--line); padding: 11px 0; }
  .news-table td { border: none; padding: 0; }
  .news-table td.c-sig, .news-table td.c-date {
    display: inline-block; padding: 5px 12px 0 0;
    font-size: 10.5px; color: var(--ink-soft);
  }

  /* Editions: masthead scales down; the jump nav is already a floating button */
  .ed-title { font-size: 31px; }
  .ed-headline { font-size: 24px; }
  .edition { padding: 18px 16px 50px; }
  .about { padding: 22px 16px 60px; }
}
