/* ═══════════════════════════════════════════════════════════════════════════
   BLUESHIFT — Tomorrow.io terminal design system · kernel v1.0
   Internal name: BLUESHIFT. Public name: none — it is simply the Tomorrow.io
   terminal. Ratified 2026-07-01. The skin is a shared node: version data and
   functions, never the grammar.

   GOVERNANCE (ship-blockers, verbatim):
   (1) #0100FF never sets `color` on dark — fill/border/background/shadow only;
       text blues are the voice triplet (#6E8EF5 / #9DB4FF / #CFDCFF).
   (2) Honest encoding: ramp fills = sourced magnitudes with declared
       breakpoints; red/amber = NWS taxonomy only; specimen data wears the
       SPECIMEN chip.
   (3) Sourced-or-cut: rebranded pages keep original numbers + attributions
       verbatim.
   (4) Render static: plain HTML/CSS + minimal vanilla JS, file:// safe,
       Google Fonts only.
   (5) One brand: tomorrow.io wordmark upper-left; Roboto / Roboto Condensed /
       Roboto Mono only.
   (6) Density is respect — 20+ earned fields per screen.
   (7) Local artifacts; nothing outbound without Cole.
   (8) The skin is a shared node: a new vertical is a config, not a redesign.
   (9) NO BLUE UNDERLINE, ever. Impact Blue is never a text underline, nav
       seam, or link/emphasis rule. This experience is retired system-wide.
   (10) GLOW IS NOT A SIGNAL. Blur/box-shadow may mark exactly one singular
       emphasis point per panel (a record cell, a pivotal KPI) — never a
       per-value, every-"on"-segment decoration. Ordinary state is read from
       solid fill contrast alone. If removing every glow on the page loses
       information, the component was never actually legible.
   Anti-patterns banned: scanlines/CRT theater, decorative density, fake
   liveness, cryptic-only nav, finance green/red transplants, saying
   "Bloomberg for weather" out loud, access gates, blue underlines, glow
   used as the primary read signal.

   TEXT-ON-DARK LAW: `color` on any dark surface may be --hi/--ink/--prose/
   --dim/--faint, the voice triplet, --live, a hazard hue inside its own
   tier chip, or a domain-scale hue inside its own scale chip — nothing
   else. --d0…--d6 and --impact never set text on dark.

   DOMAIN-SCALE LAW (ratified 2026-07-06, Cole — the Hurricanes record was
   the forcing case): when a field has a CANONICAL, PUBLISHED, reader-native
   scale — Saffir-Simpson for tropical-cyclone intensity (--ss-*), radar dBZ,
   Enhanced Fujita — a chart may DECLARE that scale and use its canonical
   hues, because the reader already decodes it: forcing the house ramp onto
   such a field is LESS honest and LESS legible, not more. Three locks:
   (1) the scale must be a real published standard, never an invented ramp;
   (2) the legend prints the scale (names + bin thresholds), on the chart;
   (3) the scale's hues carry ONLY that scale's meaning and ONLY inside the
   declaring chart — outside it, red still belongs to NWS Warning, orange to
   heat, and the reserved semantics of chips/boards/chrome are untouched.
   Corollary — LINE ≠ FILL: the --d0…--d6 luminance ramp is a FILL encoding
   (cells, bars, hexes, washes); its weak end sits by design at the ground
   and disappears on a stroke. A LINE that must stay legible across its whole
   range takes a single high-contrast stroke or a declared domain scale —
   never the fill ramp.

   DECORATION LAW: Impact Blue is a PLACE, not a line under a word. It may
   fill, wash, border a chip/panel, or mark a left seam — but it is NEVER a
   `border-bottom` / `text-decoration:underline` beneath text or a nav tab.
   Emphasis = the flare swipe (hero, once per surface) or brighter ink
   (--hi, body). Active nav = impact-wash FILL. No blue underline anywhere.

   GLOW LAW: box-shadow/blur is reserved for ONE singular marker per panel
   (see .mx-cell.rec — "the panel's only glow"). Every repeating component
   (spark, board rows, chips, matrix cells) reads from solid background
   fill contrast, hard edges, zero blur. Cute beats legible exactly never.

   TWO-GROUNDS LAW: the terminal ships on two grounds — space-black (default)
   and the broadsheet (light, [data-theme="light"]). The ground is a token
   remap only; the grammar never forks. Because luminance encodes magnitude,
   the ramp INVERTS by ground: on dark, magnitude = brightness (--d0 charcoal
   → --d6 near-white); on light, magnitude = DEPTH (--d0 pale → --d6 deep).
   Same monotonic claim, opposite physics — a bright cell must never read as
   "more" on paper. Every surface must stay honest and legible in BOTH grounds;
   ship neither without checking the other. Impact Blue may be text on light.

   MAP LAW: a map is a PANEL that shows *where*, not decoration. The basemap
   recedes (land/water/hairline admin in --map-* tokens) so the DATA floats.
   The field layer obeys every other law: it encodes only what the data earned,
   its ramp is the SAME --d0..--d6 that inverts by ground, its legend prints the
   scale, forecast reads as forecast (hatch/hollow, never solid), hazard hues
   only for real hazards. Impact is the LOCATOR (crosshair/selection/"pointing
   here"), never a data value. Every map stamps its valid-time and prints its
   provenance (basemap © + data source); baked vs live is labeled, never faked.
   The hex/H3 heat layer is ONE signature field-style among several (raster ·
   choropleth · points/stations · swath) — reach for the honest one, not the
   flashy one. The component (frame + docks) is static CSS and CR1-safe; the
   payload inside is a baked image by default, a live Mapbox canvas only for
   genuinely interactive experiences.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 01 · TOKENS ────────────────────────────────────────────────────────── */
:root{
  /* ground — cool-cast instrument blacks */
  --bg:#000000;         /* page field; the only true black */
  --panel:#0B0C10;      /* primary module fill */
  --panel2:#07080B;     /* recessed fill: charts, matrix ground, code wells */
  --chrome:#060709;     /* masthead / ticker / status-bar / footer chrome */
  --raise:#10131A;      /* hover / raised surface; landmass fill */
  --active:#161A24;     /* active/selected chrome fill; inset request blocks */

  /* hairlines */
  --rule:#23262E;       /* primary: panel borders, masthead rule, etched grid */
  --rule2:#15171C;      /* secondary: row separators, inner dividers */
  --rule3:#2B303C;      /* tertiary: chip borders, focus dividers (loudest) */

  /* text ramp — luminance IS hierarchy; white is earned by data */
  --hi:#FFFFFF;         /* the live datum, the NOW seam, matrix selection ONLY */
  --ink:#EDEEF2;        /* primary table text; bolds inside prose */
  --prose:#C9CDD6;      /* body/annotation prose — the sans voice */
  --dim:#8B909C;        /* secondary labels, cities, axis text, kickers */
  --faint:#565B68;      /* ranks, units, hints, placeholders, source lines */

  /* THE VOICE TRIPLET — the ONLY blues permitted as TEXT on dark */
  --voice:#6E8EF5;      /* labels, addresses, links, interactive register */
  --bright:#9DB4FF;     /* emphasized values, key numbers, status-bar values */
  --peak:#CFDCFF;       /* the single loudest datum per panel */

  /* THE BLUESHIFT DATA RAMP — FILL ONLY · never text · never danger */
  --d0:#24262B;         /* zero / verified-quiet — the drawn charcoal cell */
  --d1:#2C3550;         /* trace */
  --d2:#3A4A7E;         /* low */
  --d3:#4A63B8;         /* moderate — default bar fill */
  --d4:#5B7FE8;         /* elevated — hard cap for any forecast fill */
  --d5:#8FAFF5;         /* high */
  --d6:#CFDCFF;         /* peak/record — earns the panel's only data glow */

  /* brand — Impact Blue is a PLACE, not a voice (fill/accent only on dark) */
  --impact:#0100FF;
  --impact-wash:rgba(1,0,255,.14);
  --impact-glow:rgba(64,90,255,.50);
  --flare-band:var(--impact);   /* hero highlighter swipe: solid on dark (white text over it) */


  /* semantic hazard set — earned only; hue = class, border = NWS tier */
  --hz-warning:#FF4D52;   --hz-warning-d:#4F1C1F;
  --hz-watch:#F5A623;     --hz-watch-d:#52401A;
  --hz-heat:#FF8A3D;
  --hz-trop:#C08BFF;
  --hz-flood:#2BD9C5;
  --hz-winter:#56D4EC;
  --hz-quiet:#5B6068;

  /* DOMAIN SCALE · Saffir–Simpson (see DOMAIN-SCALE LAW) — canonical TC
     intensity, gray → warm → red, usable ONLY inside a chart that declares
     it and prints the scale. TS is below category and stays quiet. */
  --ss-ts:#8B909C; --ss-c1:#C2A854; --ss-c2:#CF8F42;
  --ss-c3:#DC7433; --ss-c4:#E35426; --ss-c5:#EA3323;

  /* system state */
  --live:#36C786;       /* feed-alive dot, [M] badge — status, never magnitude */
  --fcst:#5C6C9E;       /* forecast stroke register — dashed, right of NOW */
  --now:#FFFFFF;        /* the NOW seam — the certainty boundary is a datum */

  /* map base — the instrument's viewport onto Earth (basemap recedes; data floats) */
  --map-land:#0E1016;   /* land fill — one notch above the void */
  --map-water:#070810;  /* water — recedes toward bg */
  --map-line:#242833;   /* admin boundaries + graticule — hairline */
  --map-label:#8B909C;  /* place labels — mono, quiet (= --dim) */
  --map-locator:var(--impact); /* the crosshair / "pointing here" — Impact, always */

  /* fonts */
  --mono:"Roboto Mono",ui-monospace,Menlo,monospace;
  --sans:"Roboto",-apple-system,"Helvetica Neue",Arial,sans-serif;
  --cond:"Roboto Condensed",var(--sans);
}

:root{color-scheme:dark}

/* ── 01b · LIGHT GROUND — "the broadsheet": the terminal printed on paper ──
   Same grammar, inverted physics. On dark, brightness = magnitude (near-white
   is the peak). On paper that collapses — brighter reads as LESS — so magnitude
   is carried by DEPTH: the ramp runs pale→deep, more ink = more. Impact Blue,
   forbidden as text on dark, becomes a legal ink here. The starfield goes dark;
   the flare swipe pales so dark text stays legible over it. Applied by theme.js
   (stored choice → OS preference), toggleable on every page.
   ───────────────────────────────────────────────────────────────────────── */
:root[data-theme="light"]{
  color-scheme:light;
  /* ground — cool newsprint, white panels */
  --bg:#E7EAF1; --panel:#FFFFFF; --panel2:#F3F5F9;
  --chrome:#FBFCFE; --raise:#EEF1F7; --active:#E1E8FA;
  /* hairlines — ink on paper */
  --rule:#CDD2DC; --rule2:#E4E7ED; --rule3:#B7BECC;
  /* text ramp — DARKNESS is hierarchy; deepest ink earned by data */
  --hi:#0A0C12; --ink:#1B1F27; --prose:#3C424C; --dim:#6B707B; --faint:#9AA0AC;
  /* voice triplet — blue is a legal ink on paper; louder = deeper */
  --voice:#2A3AD0; --bright:#1220C4; --peak:#0100FF;
  /* the ramp — pale→deep · FILL ONLY · depth = magnitude */
  --d0:#E3E8F3; --d1:#C6D2EC; --d2:#9DB2E2; --d3:#7191D6;
  --d4:#4E72C6; --d5:#2F51AE; --d6:#172E9C;
  /* brand — Impact holds; wash/flare re-tint for a white ground */
  --impact:#0100FF; --impact-wash:rgba(1,0,255,.10); --impact-glow:rgba(1,0,255,.28);
  --flare-band:rgba(1,0,255,.20);
  /* hazards — readable on white, black-text-safe when filled; -d chips → light tints */
  --hz-warning:#EE2A32; --hz-warning-d:#FBE2E3;
  --hz-watch:#C67F00;   --hz-watch-d:#F7ECD2;
  --hz-heat:#E06A1E; --hz-trop:#8A4FD8; --hz-flood:#0FA192;
  --hz-winter:#1B8FB0; --hz-quiet:#8A8F98;
  /* Saffir–Simpson on paper — same scale, ink-weight versions (deep enough
     to read as a stroke on white; the progression stays gray→warm→red) */
  --ss-ts:#6E7787; --ss-c1:#9A7D1E; --ss-c2:#B26714;
  --ss-c3:#C04E10; --ss-c4:#C93414; --ss-c5:#B80D1D;
  /* system state */
  --live:#12925F; --fcst:#7484B4; --now:#0100FF;   /* NOW seam = Impact ink on paper */
  /* map base — the broadsheet's viewport: paper land, pale water, ink hairlines */
  --map-land:#EEF1F7; --map-water:#DBE2EF; --map-line:#C7CEDA; --map-label:#6B707B;
}
:root[data-theme="light"] .stars::before{display:none}   /* paper has no stars */

/* theme toggle — a chrome chip theme.js appends to the masthead, every page */
.theme-tog{
  font:500 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim);background:none;border:1px solid var(--rule3);
  padding:5px 9px;border-radius:2px;align-self:center;white-space:nowrap;
  transition:color .12s ease,border-color .12s ease;
}
.theme-tog:hover{color:var(--voice);border-color:var(--voice)}

/* settings — a masthead chip + popover theme.js injects on pages that opt in
   with <html data-settings>. On the terminal SHELL, settings lives in the left
   nav instead; the doc pages have no rail, so it sits upper-right here. */
.mast-settings{
  font:500 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim);background:none;border:1px solid var(--rule3);
  padding:5px 9px;border-radius:2px;align-self:center;white-space:nowrap;display:flex;gap:6px;align-items:center;
  transition:color .12s ease,border-color .12s ease;
}
.mast-settings:hover,.mast-settings[aria-expanded="true"]{color:var(--voice);border-color:var(--voice)}
.mast-settings .gr{font-size:11px;line-height:1}
.set-pop{ /* viewport-anchored (the masthead clips its overflow) */
  position:fixed;top:44px;right:12px;z-index:80;width:268px;
  background:var(--chrome);border:1px solid var(--rule);
  box-shadow:0 8px 28px -8px rgba(0,0,0,.6);
}
.set-pop[hidden]{display:none}
.set-pop .set-hd{display:flex;align-items:center;gap:8px;padding:11px 14px 9px;border-bottom:1px solid var(--rule2)}
.set-pop .set-hd .seam{width:12px;height:3px;background:var(--impact);flex:0 0 auto}
.set-pop .set-hd .t{font:500 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
.set-row{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--rule2)}
.set-row .k{font:500 10px/1.3 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--dim);flex:1}
.set-row .k .soon{color:var(--faint);font-size:8.5px;letter-spacing:.08em;margin-left:6px}
/* segmented control — the live setting shape */
.seg{display:inline-flex;border:1px solid var(--rule3);border-radius:2px;overflow:hidden;flex:0 0 auto}
.seg button{font:500 9.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--dim);padding:5px 9px;border-right:1px solid var(--rule3);white-space:nowrap}
.seg button:last-child{border-right:0}
.seg button:hover{color:var(--bright)}
.seg button.on{background:var(--impact-wash);color:var(--bright)}
.seg[data-soon] button{color:var(--faint);cursor:default}
.seg[data-soon] button:hover{color:var(--faint)}
.set-ft{padding:9px 14px;font:400 9.5px/1.5 var(--mono);letter-spacing:.03em;color:var(--faint)}

/* ── 02 · BASE / RESET ──────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg);color:var(--prose);
  font:400 13px/1.55 var(--sans);
  font-variant-numeric:tabular-nums;   /* live values never reflow */
  -webkit-font-smoothing:antialiased;
}
img,svg,canvas{display:block;max-width:100%}
a{color:var(--voice);text-decoration:none}
a:hover{color:var(--bright)}
::selection{background:var(--impact-wash);color:var(--hi)}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
table{border-collapse:collapse;width:100%}
/* radius discipline: 0 on data surfaces · 2px chips · ≤6px outer shell only */

/* ── 03 · TYPE SCALE ────────────────────────────────────────────────────── */
.t-micro   {font:400 8.5px/1.2 var(--mono)}                                /* matrix numerals, month letters */
.t-unit    {font:400 10.5px/1.4 var(--mono);letter-spacing:.06em}          /* units, footnotes, source lines */
.t-label   {font:500 11px/1.3 var(--mono);letter-spacing:.14em;text-transform:uppercase} /* panel labels, chips */
.t-body-m  {font:400 12.5px/1.5 var(--mono)}                               /* mono body, wire items */
.t-body    {font:400 13px/1.55 var(--sans)}                                /* sans base body */
.t-addr    {font:600 13.5px/1.3 var(--mono);color:var(--voice)}            /* addresses */
.t-val     {font:600 14.5px/1.2 var(--mono);font-variant-numeric:tabular-nums;color:var(--hi)} /* row values */
.t-dek     {font:400 16.5px/1.58 var(--sans);color:var(--prose);max-width:60ch}
.t-code    {font:500 26px/1.1 var(--mono);color:var(--ink)}                /* field-panel code display */
.t-kpi     {font:700 38px/0.92 var(--cond);letter-spacing:-.03em;color:var(--hi)} /* KPI figure — WHITE, never blue */
.t-h1      {font:700 37px/1.1 var(--cond);letter-spacing:-.02em;color:var(--hi);max-width:22ch} /* sentence case */
.t-mega    {font:900 clamp(56px,8vw,128px)/0.84 var(--cond);letter-spacing:-.04em;color:var(--hi)}
.mono{font-family:var(--mono)}
.sans{font-family:var(--sans)}
.cond{font-family:var(--cond)}
/* text-color utilities — the full legal set for dark surfaces */
.c-hi{color:var(--hi)} .c-ink{color:var(--ink)} .c-prose{color:var(--prose)}
.c-dim{color:var(--dim)} .c-faint{color:var(--faint)}
.c-voice{color:var(--voice)} .c-bright{color:var(--bright)} .c-peak{color:var(--peak)}
.c-live{color:var(--live)}

/* emphasis — exactly two treatments, never both on one word */
h1 em,.t-h1 em,.flare{
  font-style:normal;color:var(--hi);padding:0 2px;
  background-image:linear-gradient(transparent 62%,var(--flare-band) 62%,var(--flare-band) 88%,transparent 88%);
} /* the flare fires ONCE per surface — band re-tints per ground so text stays legible over it */
p em,.em-law{font-style:normal;color:var(--hi);font-weight:500;padding:0} /* body emphasis = brighter ink, NEVER a blue underline (see DECORATION LAW) */
strong,b{font-weight:700;color:var(--ink)}

/* ── 04 · SHELLS — document page + app console ──────────────────────────── */
/* DOCUMENT shell: single centered column, PAGE-00N family */
.doc{max-width:1060px;margin:0 auto;padding:0 24px 90px}
/* APP shell: topbar / ticker / rail|main|aside / status bar */
.app{
  height:100vh;display:grid;
  grid-template-rows:48px 30px 1fr 28px;
}
.app-body{display:grid;grid-template-columns:232px 1fr 288px;min-height:0}
.app-body>*{overflow-y:auto;min-height:0}
/* the console's center pane fills whatever the fixed-width rail+aside leave —
   no reading-width cap here (that belongs to .doc); a workstation uses the
   whole screen, and rail+aside already bound the layout on both sides */
@media(max-width:1080px){.app-body{grid-template-columns:232px 1fr}.app .aside{display:none}}
@media(max-width:760px){
  .app-body{grid-template-columns:1fr}.app .rail{display:none}
  .grid-2,.grid-3{grid-template-columns:1fr!important}
}

/* etched grid — the graticule: gutters read as engraved hairlines */
.etch{display:grid;gap:1px;background:var(--rule)}
.etch>*{background:var(--panel)}
.grid-2{display:grid;gap:1px;background:var(--rule);grid-template-columns:1fr 1fr}
.grid-3{display:grid;gap:1px;background:var(--rule);grid-template-columns:1fr 1fr 1fr}
.grid-2>*,.grid-3>*{background:var(--panel)}
/* sibling panels share one seam */
.panel+.panel,.panel+.kpi,.kpi+.panel{margin-top:1px}

/* ── 05 · MASTHEAD / TERMINAL CHROME ────────────────────────────────────── */
.masthead{
  background:var(--chrome);border-bottom:1px solid var(--rule);
  display:flex;align-items:center;gap:16px;padding:0 16px;height:48px;
  position:relative;overflow:hidden;
}
/* the real Tomorrow.io logo — signs every cropped screenshot. one DOM shape,
   two <img> (ink + white); the ground picks which one paints, CSS-only. */
.wordmark{display:inline-flex;align-items:center;flex:0 0 auto;align-self:center;vertical-align:-3px}
.wordmark img{height:22px;width:auto;display:block}
.wordmark .lg-i{display:none}
:root[data-theme="light"] .wordmark .lg-w{display:none}
:root[data-theme="light"] .wordmark .lg-i{display:block}
.wordmark.mini img{height:13px}
.mast-title{
  font:500 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);
}
.mast-spacer{flex:1}
.mast-chip{ /* the PAGE 00N pattern */
  font:500 10.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--voice);border:1px solid var(--rule3);padding:5px 8px;border-radius:2px;
}
/* function-key row — hazard-sector chips doubling as top-level nav */
.fnrow{
  background:var(--chrome);border-bottom:1px solid var(--rule);
  display:flex;gap:8px;padding:8px 16px;overflow-x:auto;
}
.fnkey{
  font:500 10.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--voice);border:1px solid var(--rule3);padding:6px 10px;border-radius:2px;
  white-space:nowrap;
}
.fnkey:hover{color:var(--bright);background:var(--raise)}
.fnkey.active{background:var(--impact-wash);color:var(--bright)} /* active tab = blue-wash FILL, never an underline seam (see DECORATION LAW) */

/* ── 06 · STARFIELD — chrome zones ONLY, never behind data ──────────────── */
.stars{position:relative}
.stars::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.35;
  background-image:
    radial-gradient(circle .7px at 4% 22%,rgba(255,255,255,.40),transparent 100%),
    radial-gradient(circle 1px at 12% 68%,rgba(255,255,255,.55),transparent 100%),
    radial-gradient(circle .7px at 21% 35%,rgba(255,255,255,.32),transparent 100%),
    radial-gradient(circle 1.3px at 33% 76%,rgba(255,255,255,.70),transparent 100%),
    radial-gradient(circle .7px at 41% 18%,rgba(255,255,255,.38),transparent 100%),
    radial-gradient(circle 1px at 52% 58%,rgba(255,255,255,.50),transparent 100%),
    radial-gradient(circle .7px at 61% 30%,rgba(255,255,255,.30),transparent 100%),
    radial-gradient(circle 1.8px at 69% 72%,rgba(255,255,255,.92),transparent 100%),
    radial-gradient(circle .7px at 78% 24%,rgba(255,255,255,.42),transparent 100%),
    radial-gradient(circle 1px at 86% 64%,rgba(255,255,255,.58),transparent 100%),
    radial-gradient(circle .7px at 93% 40%,rgba(255,255,255,.34),transparent 100%),
    radial-gradient(circle 1.3px at 97% 80%,rgba(255,255,255,.66),transparent 100%);
  background-repeat:no-repeat;
}
.stars>*{position:relative;z-index:1}

/* ── 07 · Z-BAR — the Zulu heartbeat status strip ───────────────────────── */
.zbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;height:28px;
  background:var(--chrome);border-top:1px solid var(--rule);
  display:flex;align-items:stretch;
  font:400 10.5px/1 var(--mono);letter-spacing:.1em;color:var(--dim);
  text-transform:uppercase;
}
.app .zbar{position:static;grid-row:4}
.zbar .zcell{display:flex;align-items:center;gap:6px;padding:0 14px;border-right:1px solid var(--rule2);white-space:nowrap}
.zbar .zv{color:var(--bright);letter-spacing:.04em}
.zbar .bake{margin-left:auto;border-right:0;border-left:1px solid var(--rule2);color:var(--faint)}
.zbar .zseam{width:12px;height:3px;background:var(--impact);box-shadow:0 0 8px var(--impact-glow);flex:0 0 auto}
.zbar .zseam.pulse{animation:zpulse 6s ease-in-out infinite}
@keyframes zpulse{0%,92%,100%{opacity:1}96%{opacity:.35}} /* the only animation besides the ticker */
/* feed-alive dot — status only, never magnitude, only when genuinely live */
.dot-live{width:6px;height:6px;border-radius:50%;background:var(--live);box-shadow:0 0 7px var(--live);flex:0 0 auto}
body:has(.zbar:not(.app .zbar)){padding-bottom:28px} /* clear the fixed bar */

/* ── 08 · COMMAND BAR — dual-path by law ────────────────────────────────── */
.cmdbar{
  display:flex;align-items:center;gap:0;background:var(--panel);
  border:1px solid var(--rule);height:38px;
}
.cmdbar .glyph{font:700 14px/1 var(--mono);color:var(--voice);padding:0 4px 0 12px}
.cmdbar input{
  flex:1;background:transparent;border:0;outline:0;height:100%;
  font:400 13.5px/1 var(--mono);color:var(--ink);padding:0 10px;min-width:0;
}
.cmdbar input::placeholder{color:var(--faint)}
.cmdbar:focus-within{box-shadow:0 0 0 3px var(--impact-wash);border-color:var(--rule3)}
.cmdbar .go{ /* app-shell only: white ON blue fill — legal and signature */
  background:var(--impact);color:#FFFFFF;height:100%;padding:0 18px;
  font:700 11px/1 var(--cond);letter-spacing:.18em;text-transform:uppercase;
  box-shadow:0 0 14px var(--impact-glow);flex:0 0 auto;
}
/* the command echo chip — every click back-fills its command */
.echo{
  display:inline-block;font:500 10.5px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--voice);background:var(--impact-wash);
  border:1px solid var(--rule3);padding:5px 8px;border-radius:2px;
}

/* ── 09 · PANEL CHROME CONTRACT — every module, no exceptions ───────────── */
.panel{background:var(--panel);border:1px solid var(--rule);padding:20px 22px 14px}
.app .panel{padding:14px}
.panel-hd{display:flex;align-items:center;gap:9px;margin-bottom:14px;min-height:14px}
/* the Impact seam — the terminal's pointing language, always a fill */
.seam{width:12px;height:3px;background:var(--impact);box-shadow:0 0 8px var(--impact-glow);flex:0 0 auto}
.panel-label{
  font:500 11px/1.3 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);white-space:nowrap;
}
.panel-label b,.panel-label .dyn{font-weight:700;color:var(--voice)} /* the dynamic word */
.panel-hd .hrule{flex:1;height:1px;background:linear-gradient(90deg,var(--rule),transparent)} /* fading header rule */
.panel-hd .hval{font:500 12px/1 var(--mono);color:var(--bright);white-space:nowrap} /* right-pushed value */
.panel-ft{
  border-top:1px solid var(--rule2);margin-top:14px;padding-top:8px;
  font:400 10.5px/1.5 var(--mono);letter-spacing:.05em;color:var(--faint);
  text-transform:uppercase;
} /* "SOURCE: NWS SPC · DATA AS OF 2026-07-01 12Z" — no panel ships without it */
.panel-why{font:400 13px/1.55 var(--sans);color:var(--prose);max-width:82ch;margin:10px 0 2px} /* ONE per panel */
/* specimen chip — non-live/sample data must wear it (governance 2) */
.chip-specimen{
  font:500 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);border:1px dashed var(--rule3);padding:4px 7px;border-radius:2px;
  white-space:nowrap;
}

/* ── 10 · BOARD — the dense data table, the native document ─────────────── */
.board{width:100%}
.board .brow{
  display:grid;grid-template-columns:30px 1fr 116px 122px;gap:12px;
  align-items:center;padding:9px 16px;border-bottom:1px solid var(--rule2);
  cursor:pointer;
}
.board .brow.no-spark{grid-template-columns:30px 1fr 122px}
.board .brow:hover{background:var(--raise)}
.board .brow.sel{background:var(--impact-wash);box-shadow:inset 3px 0 0 var(--impact)} /* seam IS selection on chrome */
.board .brank{font:400 11.5px/1 var(--mono);color:var(--faint);text-align:right}
.board .baddr{font:600 13.5px/1.3 var(--mono);color:var(--voice);min-width:0}
.board .brow:hover .baddr{color:var(--bright)}
.board .baddr .city{font:400 12px/1.3 var(--sans);color:var(--dim);margin-left:7px}
.board .bval{text-align:right}
.board .bval .v{font:600 14.5px/1.2 var(--mono);font-variant-numeric:tabular-nums;color:var(--hi);display:block}
.board .brow.top .bval .v{color:var(--bright)} /* the #1 row may lift */
.board .bval .ctx{font:400 10.5px/1.4 var(--mono);color:var(--faint);display:block} /* no number uncontextualized */

/* ── 11 · HEAT MATRIX — the identity component ──────────────────────────── */
.matrix{background:var(--panel2);padding:12px;overflow-x:auto}
.mx{display:grid;gap:2px;width:max-content}
.mx-cell{
  width:13px;height:13px;border-radius:1px;background:var(--d0); /* the drawn zero */
  position:relative;
}
.mx-cell.sq{width:auto;height:auto;aspect-ratio:1}
/* ramp fills — FILL ONLY, never text */
.f-d0{background:var(--d0);--gl:var(--d0)} .f-d1{background:var(--d1);--gl:var(--d1)} .f-d2{background:var(--d2);--gl:var(--d2)}
.f-d3{background:var(--d3);--gl:var(--d3)} .f-d4{background:var(--d4);--gl:var(--d4)} .f-d5{background:var(--d5);--gl:var(--d5)}
.f-d6{background:var(--d6);--gl:var(--d6)}
.mx-cell.rec{ /* record: near-white + white ring + the panel's ONLY glow */
  background:var(--d6);box-shadow:0 0 0 1px var(--hi),0 0 9px -2px var(--d5);
}
.mx-cell.sel{outline:2px solid var(--hi);outline-offset:1px;z-index:2} /* selection ≠ magnitude */
.mx-cell.today{outline:1px solid var(--now);outline-offset:0}
.mx-cell.fx{ /* forecast: hollow — right of NOW, ramp capped at --d4 */
  background:transparent;border:1px dashed var(--d3);
}
.mx-lab{font:400 8.5px/1 var(--mono);color:var(--faint);align-self:center}
.mx-lab.col{text-align:center}
/* legend row — the ramp is a claim, so it shows its scale */
.mx-legend{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px;align-items:center}
.mx-legend .lg{display:flex;align-items:center;gap:5px;font:400 9.5px/1 var(--mono);color:var(--faint);letter-spacing:.04em}
.mx-legend .sw{width:11px;height:11px;border-radius:1px;flex:0 0 auto}

/* ── 12 · SPARKLINES / MICRO-CHARTS ─────────────────────────────────────── */
/* 10-segment ordinal sparkbar: <div class="spark"><i class="f-d2 on">…×10 */
.spark{display:inline-flex;gap:3px;align-items:flex-end;height:16px;width:120px}
.spark i{flex:1;height:100%;background:var(--d0);border-radius:0}
/* solid fill IS the signal — same law as the matrix (fill-only; glow reserved for one record marker, never per-value). (0,2,1) beats .spark i's (0,1,1) so this reliably wins the cascade. */
.spark i.on{background:var(--gl,var(--d3))}
/* 12-month micro-bars — PAGE 001 grammar */
.microbars{position:relative;height:78px}
.microbars.hero{height:110px}
.microbars .mrow{display:flex;gap:8px;align-items:flex-end;height:calc(100% - 16px)}
.microbars.mini .mrow{gap:5px}
.microbars .bar{flex:1;background:var(--d3);min-height:2px}
.microbars .bar.pk{background:var(--d6);box-shadow:0 0 9px -2px var(--d5)}
.microbars .bar.fx{background:transparent;border:1px dashed var(--d3);border-bottom:0}
.microbars .mlabs{display:flex;gap:8px;margin-top:6px}
.microbars .mlabs span{flex:1;text-align:center;font:400 8.5px/1 var(--mono);color:var(--faint)}
.microbars .meanline{ /* dashed national-mean — always drawn AND captioned */
  position:absolute;left:0;right:0;border-top:1px dashed var(--dim);pointer-events:none;
}
/* time-series (SVG): stroke/fill hooks — no area fills, no chart-junk */
.ts-obs{stroke:var(--d5);stroke-width:1.5;fill:none}
.ts-fcst{stroke:var(--fcst);stroke-width:1.25;fill:none;stroke-dasharray:4 3;opacity:.55}
.ts-env{fill:rgba(255,255,255,.05)}          /* climatological envelope band */
.ts-member{stroke:var(--d2);stroke-width:1;fill:none;stroke-dasharray:4 3;opacity:.4}
.ts-median{stroke:var(--d4);stroke-width:1.5;fill:none;stroke-dasharray:4 3}
.ts-spread{fill:var(--d1);opacity:.45}       /* width = the honest uncertainty */
.ts-now{stroke:var(--now);stroke-width:1}
.ts-axis{font:400 9px/1 var(--mono);fill:var(--faint)}
.ts-flag{font:500 9px/1 var(--mono);fill:var(--dim);letter-spacing:.06em} /* AL09 · HEAT-0630 */
.ts-last{font:600 11px/1 var(--mono);fill:var(--peak)} /* last value, right edge */
.ts-runlab{font:400 9px/1 var(--mono);fill:var(--dim)}

/* ── 13 · KPI MONITOR ───────────────────────────────────────────────────── */
.kpi{background:var(--panel);border:1px solid var(--rule);padding:18px 20px 12px;position:relative}
.kpi .fig{font:700 38px/0.92 var(--cond);letter-spacing:-.03em;color:var(--hi);
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:8px}
.kpi .sub{font:500 10px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--dim);margin-top:6px}
.kpi .src{border-top:1px solid var(--rule2);margin-top:12px;padding-top:7px;
  font:400 10.5px/1.5 var(--mono);letter-spacing:.05em;color:var(--faint);text-transform:uppercase}
.kpi.pivotal{background:var(--impact-wash);border:1px solid var(--impact)} /* ONE per page: pointing here */
.kpi.hz-edge{box-shadow:inset 3px 0 0 var(--edge,var(--hz-watch))} /* only when officially a hazard state */
/* delta chip — earned semantics only, never finance green/red */
.kpi .delta{font:500 10.5px/1 var(--mono);letter-spacing:.06em;border:1px solid var(--rule3);
  padding:4px 6px;border-radius:2px;color:var(--dim)}
/* percentile bar — today located inside the station's own climatology */
.pctbar{position:relative;height:4px;margin-top:12px;
  background:linear-gradient(90deg,var(--d1),var(--d3),var(--d5))}
.pctbar .tick{position:absolute;top:-3px;bottom:-3px;width:1px;background:var(--hi);
  box-shadow:0 0 5px rgba(255,255,255,.6)}

/* M / D / X source badges — honest encoding on every figure */
.badge{
  display:inline-block;font:500 8.5px/1 var(--mono);letter-spacing:.08em;
  border:1px solid var(--rule3);border-radius:2px;padding:3px 4px;vertical-align:middle;
}
.badge.m{color:var(--live)}   /* Measured */
.badge.d{color:var(--voice)}  /* Derived */
.badge.x{color:var(--faint)}  /* Excluded / withheld until sourced */

/* ── 14 · MODEL-CONSENSUS BAND — chrome around the SVG hooks in §12 ─────── */
.consensus{background:var(--panel2);padding:12px}
.cs-agree{ /* "SPREAD ±3°F · 5 MODELS" */
  display:inline-block;font:400 10px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim);border:1px solid var(--rule2);
  padding:4px 7px;border-radius:2px;margin-top:8px;
}
/* older runs dim stepwise: luminance = recency */
.cs-run-0{opacity:1}.cs-run-1{opacity:.66}.cs-run-2{opacity:.42}.cs-run-3{opacity:.25}

/* ── 15 · ALERT / HAZARD STACK — the wire ───────────────────────────────── */
.wire .witem{
  display:grid;grid-template-columns:64px auto 1fr;gap:10px;align-items:baseline;
  padding:9px 16px 9px 13px;border-bottom:1px solid var(--rule2);
  box-shadow:inset 3px 0 0 var(--edge,var(--d3)); /* informational default */
}
.wire .witem.watch{--edge:var(--hz-watch)}
.wire .witem.warn{--edge:var(--hz-warning)} /* ONLY Warning-class, ever */
.wire .wts{font:400 10.5px/1.4 var(--mono);color:var(--faint)}
.wire .whed{font:600 13px/1.45 var(--sans);color:var(--ink)}
.wire .witem.warn .whed{font-weight:700} /* headline stays --ink; hazard hue lives in the edge + tier chip only */
.wire .wsrc{grid-column:2/-1;font:400 10.5px/1.4 var(--mono);letter-spacing:.05em;
  color:var(--dim);text-transform:uppercase} /* mandatory attribution */

/* hazard chips — hue = CLASS · border treatment = NWS TIER */
.hz{
  display:inline-block;font:500 10px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;padding:4px 7px;border-radius:2px;white-space:nowrap;
  color:var(--h);border:1px solid var(--h); /* hue as text ONLY inside its own chip */
}
.hz.heat{--h:var(--hz-heat)}   .hz.severe{--h:var(--hz-watch)}
.hz.trop{--h:var(--hz-trop)}   .hz.flood{--h:var(--hz-flood)}
.hz.winter{--h:var(--hz-winter)} .hz.quiet{--h:var(--hz-quiet)}
.hz.warnc{--h:var(--hz-warning)}
.hz.adv{border-style:dashed}                       /* ADVISORY = dashed */
.hz.watch{border-style:solid}                      /* WATCH = solid outline */
.hz.warn{background:var(--h);color:#000;border-color:var(--h)} /* WARNING = filled, #000 text */

/* ── 16 · TICKER TAPE ───────────────────────────────────────────────────── */
.ticker{
  height:30px;background:var(--chrome);border-top:1px solid var(--rule2);
  border-bottom:1px solid var(--rule2);display:flex;align-items:stretch;overflow:hidden;
}
.app .ticker{grid-row:2;border-top:0}
.ticker .tag{ /* solid --impact + white text ONLY when genuinely live */
  background:var(--impact);color:#FFFFFF;display:flex;align-items:center;
  font:700 10px/1 var(--mono);letter-spacing:.14em;padding:0 12px;white-space:nowrap;
  box-shadow:0 0 16px var(--impact-glow);flex:0 0 auto;text-transform:uppercase;
}
.ticker .tag.baked{background:var(--panel);color:var(--dim);box-shadow:none;
  border-right:1px solid var(--rule2)} /* no counterfeit liveness */
.ticker .tk-win{flex:1;overflow:hidden;display:flex;align-items:center}
.ticker .track{display:flex;gap:34px;align-items:center;white-space:nowrap;
  animation:tkscroll 46s linear infinite;padding-left:20px}
.ticker .track:hover{animation-play-state:paused}
@keyframes tkscroll{to{transform:translateX(-50%)}}
.ticker .ti{font:400 11.5px/1 var(--mono);color:var(--dim)}
.ticker .ti::before{content:"▸ ";color:var(--voice)}
.ticker .ti b{color:var(--ink);font-weight:700}
.ticker .ti .tv{color:var(--hi);font-variant-numeric:tabular-nums}

/* ── 17 · MAPX — the instrument's viewport onto Earth ───────────────────────
   A map is a PANEL that shows *where*. Same chrome, same color law, same
   honesty: the field layer encodes only what the data earned (the ramp
   inverts by ground like every other magnitude), Impact is the locator not
   the data, hazard hues only for real hazards, valid-time always stamped.
   The basemap RECEDES so the data floats. One root, four sizes, a stage that
   hosts a live Mapbox canvas OR a baked static payload, and a kit of docks
   that wire the map to the numbers around it. Map internals use the .mp-
   prefix (matrix owns .mx-). See the MAP LAW in the kernel header. */
.mapx{position:relative;background:var(--map-water);border:1px solid var(--rule);
  overflow:hidden;isolation:isolate}
/* the stage — Mapbox mounts here; a static SVG/img fallback lives beneath and
   shows through until (or unless) a live canvas paints over it */
.mapx .mp-stage{position:absolute;inset:0;z-index:0}
.mapx .mapboxgl-map{position:absolute;inset:0;font:inherit}
.mapx .mapboxgl-ctrl-logo,.mapx .mapboxgl-ctrl-attrib{display:none} /* we print our own provenance */
/* static fallback vectors (baked payload · CR1) */
.mapx .mp-land{fill:var(--map-land);stroke:none}
.mapx .mp-water{fill:var(--map-water)}
.mapx .mp-coast,.mapx .mp-admin{fill:none;stroke:var(--map-line);stroke-width:1;vector-effect:non-scaling-stroke}
.mapx .mp-grat{fill:none;stroke:var(--map-line);stroke-width:1;opacity:.45}
.mapx .mp-hz{fill:none;stroke:var(--h,var(--hz-watch));stroke-width:1.25}
.mapx .mp-hz.adv{stroke-dasharray:4 3}
.mapx .mp-fx{fill:url(#fxhatch);opacity:.7}          /* forecast: 45° hatch, never solid */
.mapx .mp-hex{stroke:var(--map-water);stroke-width:.6}/* hex layer: fill = ramp, seam = ground */
.mapx .mp-pt{stroke:var(--map-water);stroke-width:1} /* station/point marker */

/* SIZES — from an inline glance to the whole page ------------------------- */
.mapx.sz-chip{height:84px;border-radius:0}           /* inline: in a row/KPI, a locator */
.mapx.sz-panel{height:340px}                          /* default: a module in a panel */
.mapx.sz-hero{height:480px}                           /* a page's lead, chrome floats */
.mapx.sz-full{position:absolute;inset:0;height:auto;border:0} /* full-bleed: the map IS the page */

/* DOCKS — floating chrome that wires the map to its numbers --------------- */
.mapx .mp-dock{position:absolute;z-index:4;background:color-mix(in srgb,var(--chrome) 88%,transparent);
  border:1px solid var(--rule);backdrop-filter:blur(3px);pointer-events:auto}
.mapx .mp-dock.tl{top:10px;left:10px}  .mapx .mp-dock.tr{top:10px;right:10px}
.mapx .mp-dock.bl{bottom:10px;left:10px} .mapx .mp-dock.br{bottom:10px;right:10px}
.mapx .mp-dock.bc{bottom:10px;left:50%;transform:translateX(-50%)}
.mapx.sz-chip .mp-dock{display:none}                  /* chip is too small for chrome */

/* title — place · field · valid-time (top-left, mirrors panel-label) */
.mapx .mp-title{padding:7px 11px;max-width:60%}
.mapx .mp-title .pl{font:500 10.5px/1.3 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink)}
.mapx .mp-title .fl{font:400 9.5px/1.4 var(--mono);letter-spacing:.06em;color:var(--dim);margin-top:2px}

/* layer switcher — the field-style vocabulary as fnkey chips (top-right) */
.mapx .mp-layers{display:flex;gap:0;padding:0}
.mapx .mp-layers button{font:500 9.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim);padding:7px 10px;border-right:1px solid var(--rule);white-space:nowrap}
.mapx .mp-layers button:last-child{border-right:0}
.mapx .mp-layers button:hover{color:var(--bright);background:var(--raise)}
.mapx .mp-layers button.on{color:var(--bright);background:var(--impact-wash)} /* active layer = blue-wash fill */

/* legend — the ramp is a claim, so it prints its scale (bottom-left) */
.mapx .mp-legend{padding:8px 11px}
.mapx .mp-legend .lk{font:500 9px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--faint);margin-bottom:6px}
.mapx .mp-legend .ramp{display:flex;align-items:center;gap:0}
.mapx .mp-legend .ramp i{width:22px;height:9px;display:block}
.mapx .mp-legend .scale{display:flex;justify-content:space-between;margin-top:3px;font:400 8.5px/1 var(--mono);color:var(--faint)}

/* readout — cursor lat/lon · scale · zoom (bottom-right, terminal precision) */
.mapx .mp-readout{padding:6px 10px;font:400 9.5px/1.5 var(--mono);color:var(--faint);text-align:right}
.mapx .mp-readout b{color:var(--dim);font-weight:400}
.mapx .mp-readout .v{color:var(--bright)}

/* inspector — click a feature → its sourced values (floating card, top-right) */
.mapx .mp-inspect{width:212px;padding:0}
.mapx .mp-inspect .ih{display:flex;align-items:baseline;gap:8px;padding:8px 11px;border-bottom:1px solid var(--rule2)}
.mapx .mp-inspect .ih .ia{font:600 11.5px/1.2 var(--mono);color:var(--voice)}   /* the address */
.mapx .mp-inspect .ih .ic{font:400 9px/1.2 var(--mono);color:var(--faint);margin-left:auto} /* coords */
.mapx .mp-inspect .irow{display:flex;justify-content:space-between;gap:10px;padding:5px 11px;font:400 10.5px/1.4 var(--mono)}
.mapx .mp-inspect .irow .k{color:var(--dim)} .mapx .mp-inspect .irow .val{color:var(--hi);font-variant-numeric:tabular-nums}
.mapx .mp-inspect .isrc{padding:6px 11px;border-top:1px solid var(--rule2);font:400 8.5px/1.35 var(--mono);letter-spacing:.04em;color:var(--faint);text-transform:uppercase}

/* valid-time chip / scrubber — baked stamp or live dot; obs↔forecast (bottom-center) */
.mapx .mp-time{display:flex;align-items:center;gap:8px;padding:6px 11px;font:500 9.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--dim)}
.mapx .mp-time .vt{color:var(--bright)}
.mapx .mp-time .bake{color:var(--faint)}
.mapx .mp-time .dot-live{width:6px;height:6px;border-radius:50%;background:var(--live);box-shadow:0 0 6px -1px var(--live)}

/* crosshair — the Impact locator: "the system is pointing here" (a place = a fill) */
.mapx .mp-cross{position:absolute;z-index:5;width:16px;height:16px;margin:-8px 0 0 -8px;pointer-events:none}
.mapx .mp-cross::before,.mapx .mp-cross::after{content:"";position:absolute;background:var(--map-locator)}
.mapx .mp-cross::before{left:7px;top:0;width:2px;height:16px}
.mapx .mp-cross::after{top:7px;left:0;height:2px;width:16px}

/* provenance — Mapbox © + data source (mandatory, bottom strip) */
.mapx .mp-attrib{position:absolute;left:0;right:0;bottom:0;z-index:3;padding:3px 10px;
  font:400 8.5px/1.3 var(--mono);letter-spacing:.03em;color:var(--faint);
  background:linear-gradient(transparent,color-mix(in srgb,var(--bg) 70%,transparent));text-align:right}

/* corner brackets — the terminal's registration marks */
.mapx::before,.mapx::after{content:"";position:absolute;width:14px;height:14px;z-index:4;pointer-events:none}
.mapx::before{top:5px;left:5px;border-top:1px solid var(--rule3);border-left:1px solid var(--rule3)}
.mapx::after{bottom:5px;right:5px;border-bottom:1px solid var(--rule3);border-right:1px solid var(--rule3)}
.mapx.sz-full::before,.mapx.sz-full::after,.mapx.sz-chip::before,.mapx.sz-chip::after{display:none}

/* CONNECTION LAYOUTS — how the map wires to the information around it ------ */
/* split: map beside an info rail (board rows / inspector / KPIs cross-linked) */
.map-split{display:grid;grid-template-columns:1fr 300px;gap:1px;background:var(--rule)}
.map-split>.mapx{border:0}
.map-split .mp-rail{background:var(--panel);display:flex;flex-direction:column;min-width:0}
.map-split .mp-rail .brow.linked.hot{background:var(--impact-wash)} /* row the cursor is over on the map */
@media(max-width:760px){.map-split{grid-template-columns:1fr}}
/* full-bleed page: map fills the viewport, chrome floats over it (masthead, docks, z-bar) */
.map-page{position:fixed;inset:0;overflow:hidden}
.map-page>.masthead,.map-page>.fnrow,.map-page>.zbar{position:relative;z-index:10;
  background:color-mix(in srgb,var(--chrome) 82%,transparent);backdrop-filter:blur(4px)}
.map-page>.mapx.sz-full{z-index:1}

/* ── 18 · OBS-VS-FORECAST SEAM — mandatory on every time axis ───────────── */
.timefield{position:relative}
.now-seam{
  position:absolute;top:0;bottom:0;width:1px;background:var(--now);
  box-shadow:0 0 6px rgba(255,255,255,.5);z-index:3;
}
.now-seam .nlab{
  position:absolute;top:-2px;left:5px;font:700 8.5px/1 var(--mono);
  letter-spacing:.14em;color:var(--hi);
}
.fx-zone{ /* everything right of NOW */
  background-image:repeating-linear-gradient(45deg,transparent 0 5px,rgba(58,74,126,.28) 5px 6px);
}
.bar.fx,.mx-cell.fx{background-image:none} /* hollow beats hatch on cells/bars */

/* ── 19 · RAIL NAV (app shell) + WATCHLIST ──────────────────────────────── */
.rail{background:var(--panel);border-right:1px solid var(--rule);padding:12px 0}
.rail .rlabel{display:flex;align-items:center;gap:8px;padding:12px 14px 7px;
  font:500 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
.rail .rlabel::before{content:"";width:12px;height:3px;background:var(--impact);
  box-shadow:0 0 8px var(--impact-glow)}
.rail a{display:block;padding:8px 14px;font:400 12.5px/1.4 var(--mono);color:var(--dim)}
.rail a:hover{background:var(--raise);color:var(--ink)}
.rail a.active{background:var(--impact-wash);box-shadow:inset 3px 0 0 var(--impact);color:var(--ink)}
.aside{background:var(--panel);border-left:1px solid var(--rule)}
.wl .wli{display:grid;grid-template-columns:1fr auto;gap:2px 10px;
  padding:9px 14px;border-bottom:1px solid var(--rule2)}
.wl .wln{font:500 12.5px/1.3 var(--mono);color:var(--ink)}
.wl .wls{font:400 10px/1.3 var(--mono);color:var(--faint)}
.wl .wlv{font:600 13px/1.3 var(--mono);color:var(--hi);text-align:right;font-variant-numeric:tabular-nums}
.wl .wbar{grid-column:1/-1;height:3px;background:var(--d0)}
.wl .wbar i{display:block;height:100%;background:var(--d3)} /* width = sourced %, ramp step = class */

/* ── 20 · PAGE FOOTER / PROVENANCE BAR ──────────────────────────────────── */
.pagefoot{
  border-top:1px solid var(--rule);margin-top:56px;padding:20px 0 16px;
  font:400 10.5px/1.7 var(--mono);letter-spacing:.05em;color:var(--faint);
  display:flex;flex-wrap:wrap;gap:12px 26px;align-items:flex-start;
}
.pagefoot .manifest{flex:1;min-width:260px;text-transform:uppercase}
.pagefoot .permalink{color:var(--voice)}
.crumb{font:500 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--faint);margin:38px 0 0;display:flex;align-items:center;gap:10px}
.crumb::after{content:"";flex:1;height:1px;background:var(--rule2)}

/* ── 21 · GENERIC CHIP + MISC ───────────────────────────────────────────── */
.chip{
  display:inline-block;font:500 10.5px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim);border:1px solid var(--rule3);
  padding:4px 7px;border-radius:2px;white-space:nowrap;
}
.chip.voice{color:var(--voice)}
hr{border:0;border-top:1px solid var(--rule2);margin:26px 0}
.right{text-align:right}
.tnum{font-variant-numeric:tabular-nums}

/* ── 22 · DOCUMENT BREAKPOINT ───────────────────────────────────────────── */
@media(max-width:760px){
  .doc{padding:0 14px 90px}
  .board .brow{grid-template-columns:26px 1fr 96px;gap:8px}
  .board .brow .bspark{display:none}
  .t-h1{font-size:30px}
  .kpi .fig{font-size:32px}
  .zbar .zcell{padding:0 9px}
}
/* ═══ end kernel — new verticals arrive as configs wearing this uniform ═══ */
