/* StormCast map page — layout for the canvas stage, timeline and HUD.
   Colors come from the site palette in style.css. */

.sc-main { max-width: 1100px; margin: 0 auto; padding: 18px 12px 40px; }
.sc-stage { padding: 0; overflow: hidden; }

/* the domain is square and the view is fixed: a centered square canvas,
   height-capped so the timeline stays on screen */
.sc-mapbox { position: relative; background: #0b0e12;
  aspect-ratio: 1/1; margin: 0 auto;
  /* vh is the LARGE viewport on phones — it ignores the browser chrome, so
     74vh overshoots and pushes the timeline below the fold on first paint,
     before the toolbar collapses. dvh tracks the visible viewport; the vh
     line stays as the fallback for engines that do not know dvh. */
  width: min(100%, 74vh);
  width: min(100%, 74dvh); }
#sc-map { position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; }

.sc-veil { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; text-align: center;
  background: rgba(10, 14, 18, .55); color: var(--ink-2); z-index: 3;
  padding: 20px; }
.sc-veil b { font-size: 17px; letter-spacing: .4px; color: var(--ink); }
.sc-veil span { color: var(--muted); font-size: 13px; max-width: 420px; }
.sc-veil[hidden] { display: none; }

/* THE HUD MUST WRAP. Three tabs plus a fixed 110 px legend needs ~380 px,
   and a 375 px phone offers 355 — so the switch was squeezed until
   `overflow: hidden` clipped the last tab clean off ("7 day" became "7 da").
   Wrapping costs a row of height at narrow widths and never truncates a
   control the user is supposed to be able to press. */
.sc-hud { position: absolute; left: 10px; bottom: 10px; right: 10px;
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 10px; pointer-events: none; z-index: 2; }
.sc-headswitch { display: flex; gap: 0; pointer-events: auto;
  border: 1px solid var(--ring); border-radius: 8px; overflow: hidden;
  background: rgba(13, 13, 13, .78); backdrop-filter: blur(4px); }
/* nowrap so a label never breaks mid-phrase ("at" / "minute" on two lines),
   and fluid padding so the control narrows before it ever has to */
.sc-headswitch button { appearance: none; border: 0; background: transparent;
  color: var(--muted); font: inherit; font-size: 12px;
  padding: 6px clamp(9px, 2.6vw, 13px); white-space: nowrap;
  min-height: 32px;                     /* a comfortable touch target */
  cursor: pointer; }
.sc-headswitch button.on { background: var(--surface-2); color: var(--ink); }

.sc-legend { display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: var(--muted); background: rgba(13, 13, 13, .78); padding: 4px 8px;
  border-radius: 8px; border: 1px solid var(--ring);
  backdrop-filter: blur(4px); }
/* the ramp is the first thing that should give up width, not the controls */
.sc-legend i { width: clamp(56px, 17vw, 110px);
  height: 8px; border-radius: 4px; display: block;
  background: linear-gradient(90deg,
    rgba(57, 135, 229, 0) 0%,   rgba(57, 135, 229, .55) 22%,
    rgba(25, 158, 112, .75) 45%, rgba(201, 133, 0, .85) 68%,
    rgba(230, 103, 103, .95) 100%); }

.sc-stale { position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  background: rgba(35, 26, 8, .92); color: var(--warning); z-index: 4;
  border: 1px solid rgba(250, 178, 25, .4); border-radius: 8px;
  padding: 5px 12px; font-size: 12px; white-space: nowrap; }
.sc-stale.soft { color: var(--ink-2); background: rgba(20, 22, 26, .92);
  border-color: var(--ring); }

/* THE SLIDER ROW HOLDS ONLY CONSTANT-WIDTH THINGS. It used to be a flex row
   [now][track][label] and the label stacked the clock AND the variable text
   ("+38 h · Monday · gbm · unverified lead"), so its width followed the
   longest line and the track — the flex:1 item — gave up whatever the text
   took. Measured on the 7-day tier, 2026-08-22: the track went 323 → 216 →
   193 px as the lead changed, i.e. the thing under the pointer shrank while
   it was being dragged. Now the row is a grid of the button, the track and
   the clock (always HH:MM), and every DYNAMIC string lives on its own row
   below, clipped to one line — nothing it says can move the track. */
.sc-timeline { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; column-gap: 12px; row-gap: 2px;
  padding: 12px 14px 12px; background: var(--surface); }
#sc-now { grid-column: 1; grid-row: 1; appearance: none;
  border: 1px solid var(--ring); cursor: pointer;
  border-radius: 8px; background: var(--surface-2); color: var(--muted);
  font: inherit; font-size: 12px; padding: 7px 12px; white-space: nowrap; }
#sc-now.live { color: var(--good); border-color: rgba(12, 163, 12, .45); }

.sc-sliderwrap { grid-column: 2; grid-row: 1; position: relative; min-width: 0; }
#sc-slider { width: 100%; margin: 0; accent-color: var(--s-blue);
  cursor: pointer; }
#sc-slider.loading { accent-color: var(--warning); }
.sc-ticks { position: relative; height: 14px; font-size: 10px;
  color: var(--muted); }
.sc-ticks span { position: absolute; transform: translateX(-50%);
  white-space: nowrap; }

.sc-timelabel { grid-column: 3; grid-row: 1; text-align: right;
  min-width: 86px; line-height: 1.25; white-space: nowrap; }
.sc-timelabel b { font-size: 15px; letter-spacing: .5px; display: block;
  font-variant-numeric: tabular-nums; }
/* the dynamic line: full width, under the track, one line, never wider */
.sc-timerel { grid-column: 1 / -1; grid-row: 2; font-size: 11px;
  color: var(--muted); text-align: right; line-height: 14px; min-height: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* ---------- city panel ---------- */

@media (min-width: 1020px) {
  /* THE CARD HUGS THE MAP. The map is square and HEIGHT-capped (74dvh), so on
     a short, wide viewport it comes out narrower than the 1fr column holding
     it: at 1280x720 the map was 533px in a 734px column, leaving 101px of
     dead card on each side and stretching the timeline to the full 734px —
     200px wider than the map it scrubs, so the slider no longer lined up with
     the thing it moves. Cap the PAGE by the same height budget instead, and
     the column collapses onto the map, with the timeline inheriting its width
     for free. 366px is everything that rides beside the map: 340 panel +
     24 main padding + 2 card border. vh first as the fallback, per .sc-mapbox. */
  .sc-main { max-width: min(1100px, calc(74vh + 366px));
             max-width: min(1100px, calc(74dvh + 366px)); }
  .sc-stage { display: grid; grid-template-columns: minmax(0, 1fr) 340px;
    grid-template-rows: auto auto; }
  /* fill the column, which is now the map's own width; the base rule's
     min(100%, 74dvh) would re-derive the same number one cap later */
  .sc-mapbox { grid-column: 1; grid-row: 1; width: 100%; }
  .sc-timeline { grid-column: 1; grid-row: 2; }
  /* THE SLIDER STAYS WELDED TO THE MAP. The panel spans both rows, so its
     height fed their intrinsic sizing: select a city and the feed list made
     the panel 139px taller than map + timeline, and grid split that surplus
     across BOTH auto rows — half opening a gap under the map, half stretching
     the timeline band so the slider floated inside it. Measured at 1152x974,
     the slider sat ~200px adrift from the map it scrubs, and it got worse as
     the viewport got shorter, because the map shrinks while the panel does
     not. `height: 0` takes the panel out of row sizing altogether;
     `min-height: 100%` then grows it back into the area the map and timeline
     have defined. The long feed list scrolls inside .sc-city-body, which was
     already carrying overflow-y: auto and only ever needed a panel with a
     definite height. Below 1020px the panel stacks and must NOT do this —
     it flows at full height with the page, so this stays inside the query.

     NOTE THE SELECTOR: the base `.sc-panel` rule below this block sets
     `min-height: 0`, and being later in the file it beat a plain `.sc-panel`
     here on source order — min-height computed to 0px, the panel collapsed to
     zero and `overflow: hidden` clipped the city away entirely. Matching on
     `.sc-stage >` wins on specificity instead, which does not care where the
     rules sit. */
  .sc-stage > .sc-panel { grid-column: 2; grid-row: 1 / -1;
    border-left: 1px solid var(--grid);
    height: 0; min-height: 100%; overflow: hidden; }
}

.sc-panel { background: var(--surface); display: flex; flex-direction: column;
  min-height: 0; }
.sc-search { position: relative; padding: 12px 12px 10px;
  border-bottom: 1px solid var(--grid); }
#sc-city-input { width: 100%; box-sizing: border-box; font: inherit;
  font-size: 14px; color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--ring); border-radius: 8px; padding: 9px 12px;
  outline: none; }
#sc-city-input:focus { border-color: var(--s-blue); }
#sc-city-list { position: absolute; left: 12px; right: 12px; top: 100%;
  margin: -6px 0 0; padding: 4px; list-style: none; z-index: 30;
  background: #14161a; border: 1px solid var(--ring); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .5); max-height: 320px;
  overflow-y: auto; }
#sc-city-list li { display: flex; align-items: baseline; gap: 8px;
  padding: 7px 10px; border-radius: 7px; cursor: pointer; font-size: 13px; }
#sc-city-list li.on, #sc-city-list li:hover { background: var(--surface-2); }
#sc-city-list .nm { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
#sc-city-list .cc { color: var(--muted); font-size: 11px; }
#sc-city-list .pp { color: var(--muted); font-size: 11px; min-width: 34px;
  text-align: right; }

.sc-city-body { padding: 12px; overflow-y: auto; flex: 1; min-height: 120px; }
.sc-empty { color: var(--muted); font-size: 12.5px; display: flex;
  flex-direction: column; gap: 6px; padding: 18px 6px; }
.sc-empty b { color: var(--ink-2); font-size: 14px; }

.sc-cityhead { margin-bottom: 10px; }
.sc-cityhead > b { font-size: 17px; letter-spacing: .3px; }
.sc-cityhead .fl { font-size: 14px; margin-left: 4px; }
.sc-soft { color: var(--muted); font-size: 11.5px; margin-top: 2px; }
.sc-dim { color: var(--muted); font-style: normal; }

.sc-block { background: var(--surface-2); border: 1px solid var(--ring);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.sc-mini { font-size: 10.5px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px; }
.sc-headline { font-size: 15.5px; font-weight: 700; line-height: 1.25; }
.sc-headline.good { color: var(--good); }
.sc-headline.warn { color: var(--warning); }
.sc-headline.serious { color: var(--serious); }
.sc-headline.crit { color: var(--critical); }
.sc-sub { font-size: 12px; color: var(--ink-2); margin-top: 3px; }
.sc-badge { display: inline-block; margin-top: 6px; font-size: 10.5px;
  color: var(--warning); border: 1px solid rgba(250, 178, 25, .4);
  border-radius: 5px; padding: 1px 7px; }

.sc-spark { width: 100%; height: auto; margin-top: 8px; display: block; }
.sc-spark .gl { stroke: var(--grid); stroke-width: 1; }
.sc-spark .tk { fill: var(--muted); font-size: 8.5px; }
.sc-spark .ln-inst { fill: none; stroke: var(--s-blue); stroke-width: 1.6; }
.sc-spark .ln-cum { fill: none; stroke: var(--s-aqua); stroke-width: 1.6; }
.sc-spark .nowl { stroke: var(--ink-2); stroke-dasharray: 2 3; }
.sc-spark-leg { font-size: 10.5px; color: var(--muted); margin-top: 4px; }
.sc-spark-leg i { display: inline-block; width: 14px; height: 3px;
  border-radius: 2px; vertical-align: middle; margin: 0 3px 0 8px; }
.sc-spark-leg i.li { background: var(--s-blue); margin-left: 0; }
.sc-spark-leg i.lc { background: var(--s-aqua); }

.sc-row { font-size: 12px; color: var(--ink-2); padding: 7px 10px;
  border: 1px solid var(--ring); border-radius: 8px; margin-bottom: 10px; }
.sc-row.hot { color: var(--warning);
  border-color: rgba(250, 178, 25, .35); }

.sc-kv { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.sc-kv td { padding: 3px 0; }
.sc-kv td:first-child { color: var(--muted); width: 45%; }

.sc-src { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.sc-src td { padding: 3.5px 0; vertical-align: baseline; }
.sc-src td:nth-child(2) { text-align: right; white-space: nowrap; }
.sc-src td.ag { text-align: right; color: var(--muted); font-size: 10px;
  width: 62px; }
.sc-src i { color: var(--muted); font-style: normal; font-size: 10px; }
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px; background: var(--muted); }
.dot.healthy, .dot.fresh { background: var(--good); }
.dot.stale, .dot.aging { background: var(--warning); }
.dot.down, .dot.missing, .dot.error { background: var(--critical); }

@media (max-width: 640px) {
  .sc-timelabel { min-width: 0; }
}
