/* Brain: Runbooks/watts-bar (prototype, local-only)
   Repo: watts.bar/prototypes/water-system/weather.css
   Purpose: the WEATHER section in the iOS Weather idiom, rendered in the watts.bar
   skin (spec: docs/superpowers/specs/2026-07-07-weather-ios-idiom-rebuild.md).
   Structure: now hero -> alert -> summary + hourly strip -> 10-day range list ->
   2-col tile grid. Paper-inset surfaces + hairlines, NEVER frosted glass; Oswald
   caps for labels, Montserrat for numbers; reuses the shared :root tokens. */

:root {
  --wx-accent: #c0832a;        /* warm sun accent (icons, offline glyph) vs the lake's teal */
  --wx-rain: #1b71bc;          /* the ONE rain blue (kept from cc525eec4): hourly %, 10-day %, precip text. 5.08:1 on white (AA at 11.5px text); OKLCH hue 250 matches the rain-magnitude ramps so all rain reads as one blue. */
  --wx-sun-text: #9a6a1e;      /* gold label/icon tone (sunrise/sunset, tile-head icons) */
  --wx-ico-day: #b07d2c;       /* condition icons, daytime (warm gold, 3.2:1 graphical) */
  --wx-ico-night: #67708c;     /* condition icons, night (slate blue, 4.6:1 graphical) */
  --moon-lit: #e0b85c;         /* warm lit limb of the moon glyph */
  --moon-dark: #a9afb8;        /* shadowed limb, cool gray so the crescent reads on white */
  --wx-dot-ring: #ffffff;      /* ring around the today-dot / scale markers */
  --wx-uv-meas: #9a5b16;       /* measured-UV line on the UV card: deep so it reads over the forecast arc + its gradient (graphical, ~4.9:1 on white) */
}
@media (prefers-color-scheme: dark) {
  :root {
    --wx-accent: #e0a851;
    --wx-rain: #549de5;        /* same rain blue on dark slate: 5.07:1 on #232a31 (AA), hue 250 */
    --wx-sun-text: #d6a24d;
    --wx-ico-day: #dca452;
    --wx-ico-night: #93a0c4;
    --moon-lit: #efe6c8;
    --moon-dark: #424a54;
    --wx-dot-ring: #232a31;
    --wx-uv-meas: #f7cd86;     /* measured-UV line on dark slate: bright warm so it reads over the arc */
  }
}

/* ── AT A GLANCE: the page's one-glance NARRATIVE card — single column. The serif
   verdict + the NWS forecast + the provenance meta line, the elegant prose summary.
   (The live vitals it briefly held as a left column moved to the weather section's
   Current Conditions module.) A teal gradient top line ties it to the lake spine,
   matching the water-system + wildlife cards. */
.aag-card { position: relative; background: var(--paper-inset); border-radius: 4px 4px 14px 14px; box-shadow: var(--shadow-light); overflow: hidden; margin-bottom: 18px; padding: 16px 18px 15px; }
.aag-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, transparent, var(--water), transparent); }
.aag-card[hidden] { display: none; }
.aag-title { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0 0 12px; font-family: var(--body); font-weight: 700; font-size: clamp(20px, 4.4vw, 26px); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); line-height: 1.1; }
.aag-title-icon { width: 23px; height: 23px; color: var(--ut-orange); flex: 0 0 auto; }

.aag-summary { min-width: 0; }
.aag-verdict { font-family: var(--display); font-weight: 500; font-size: clamp(20px, 4.9vw, 27px); line-height: 1.32; color: var(--ink); margin: 0 0 12px; text-wrap: pretty; letter-spacing: 0.005em; }
.aag-verdict:empty { display: none; }
/* a very slight hairline separates OUR generated verdict (above) from the NWS forecast we
   pass through (below) -- Eli: make clear what's theirs vs ours. */
.aag-forecast { font-family: var(--body); font-size: 14px; font-weight: 500; line-height: 1.55; color: var(--ink-soft); margin: 0 0 12px; padding-top: 13px; border-top: 1px solid var(--rule-ghost); text-wrap: pretty; }
.aag-forecast:empty { display: none; padding-top: 0; border-top: 0; }
.aag-fc-when { color: var(--ink); font-weight: 700; }
.aag-src { display: inline-block; font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); border: 1px solid var(--rule-ghost); border-radius: 4px; padding: 1px 5px; margin-right: 8px; vertical-align: 1.5px; }
.aag-meta { font-family: var(--body); font-size: 11.5px; line-height: 1.4; color: var(--ink-faint); margin: 0; }
.aag-meta a { color: var(--water-text); text-underline-offset: 2px; }

/* ── SECTION WRAPPER: ONE white section card matching .ws-card (styles.css) — a
   paper-inset surface, the same 4/14px radius + ambient shadow, and a gradient top
   accent (its own warm gold, as ws-card owns teal + wl-card owns moss). The inner
   modules are grey-OUTLINED rows on this surface (below), not floating cards. ──── */
.wx-card { position: relative; display: flex; flex-direction: column; gap: 13px; margin-bottom: 18px; background: var(--paper-inset); border-radius: 4px 4px 14px 14px; box-shadow: var(--shadow-light); overflow: hidden; padding: 0 16px 16px; }
.wx-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, transparent, var(--wx-accent), transparent); }
.wx-card[hidden] { display: none; }
/* hidden modules stay hidden even where display is set (flex/grid surfaces) */
.wx-card [hidden] { display: none !important; }

/* graceful offline notice (shown only when the weather feed is unreachable) */
.wx-card-offline { background: var(--paper-inset); border-radius: 14px; box-shadow: var(--shadow-light); margin-bottom: 18px; padding: 2rem 1.4rem; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; }
.wx-card-offline[hidden] { display: none; }
.wx-card-offline svg { width: 34px; height: 34px; color: var(--wx-accent); opacity: 0.85; margin-bottom: 6px; }
.wx-card-offline-title { font-family: var(--display); font-size: clamp(18px, 3.4vw, 22px); font-weight: 600; color: var(--ink); margin: 0; }
.wx-card-offline-sub { font-family: var(--body); font-size: 0.88rem; line-height: 1.5; color: var(--ink-soft); margin: 0; max-width: 44ch; }

.wx-cardhead { padding: 14px 0 0; }
.wx-cardtitle { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0; font-family: var(--body); font-weight: 700; font-size: clamp(20px, 4.4vw, 26px); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); line-height: 1.1; }
.wx-cardtitle-icon { width: 23px; height: 23px; color: var(--wx-accent); flex: 0 0 auto; }

/* ── THE MODULE SURFACE (.wx-mod): a grey-OUTLINED inset row on the white card,
   matching the water-system card's inner blocks (.nl-col / the "ws-nowline" look) —
   same paper-inset surface separated by a hairline, NO float shadow. (NO glass,
   NO backdrop blur.) The hairline alone carries the edge, so the modules read as
   native members of the card, not the floating iOS cards they were. ──────────── */
.wx-mod {
  position: relative;
  background: var(--paper-inset);
  border: 1px solid var(--rule-ghost);
  border-radius: 8px;
  padding: 14px 16px 15px;
  min-width: 0;
}
@media (prefers-color-scheme: dark) {
  /* on the dark card the 0.07 ghost hairline all but vanishes with no shadow to
     lift it — step up to the stronger faint rule so the outline still reads */
  .wx-mod { border-color: var(--rule-faint); }
}

/* module caps header: Oswald condensed uppercase, the instrument's LABEL voice */
.wx-mod-head { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.12em; font-size: 12px; font-weight: 600; line-height: 1; color: var(--ink-faint); display: flex; align-items: center; gap: 7px; margin: 1px 0 4px; }
.wx-mod-head svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--wx-sun-text); }
/* current reading pinned to the top-right of a chart-card header (UV): a BIG number to match
   the tile values (wind mph etc.) with the band word ("High") anchored to the TOP, same idiom
   as the tile units (Eli). */
#wx-uv-mod .wx-mod-head { align-items: flex-start; }
.wx-chart-now { margin-left: auto; display: inline-flex; align-items: flex-start; gap: 5px; letter-spacing: normal; line-height: 1; }
.wx-chart-now:empty { display: none; }
.wx-chart-now b { font-family: var(--body); font-size: 42px; font-weight: 700; color: var(--ink); line-height: 0.72; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.wx-chart-now-lbl { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.05em; font-size: 11px; font-weight: 700; color: var(--ink-faint); margin-top: 0.3em; }
.wx-mod-foot { font-family: var(--body); font-size: 11px; line-height: 1.45; color: var(--ink-faint); margin: 9px 0 0; }

/* ── LIVE PROVENANCE (.wx-prov): card-level freshness line under the title, the honesty
   stamp for the whole live dashboard. LIVE pill + "our dock, updated X". The current
   now-read itself is the NOW tile (.wx-tile--now). weather.js -> renderProv. */
/* margin: 0 bottom -- the default <p> 1em bottom margin was stacking on top of the card's
   flex gap, adding ~13px extra above the alert / first module (Eli: weird spacing). */
.wx-prov { display: flex; align-items: center; gap: 9px; margin: 6px 0 0;
  font-family: var(--body); font-size: 12.5px; font-weight: 500; color: var(--ink-faint); line-height: 1.3; }
.wx-prov:empty { display: none; }
/* keep the AA-safe LIVE green on the light card surface (the shared token is only
   ~4.4:1 here); dark mode already clears AA so re-assert the shared token. */
/* bare pulsing live dot (matches the .wl-live / .nl-live convention used elsewhere on the
   page, not a pill badge) -- Eli wanted one consistent live indicator. Reuses live-beat. */
.wx-prov-dot { position: relative; display: inline-block; width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.wx-prov-dot[data-live="live"] { background: var(--live-green); }
.wx-prov-dot[data-live="delayed"] { background: var(--live-amber); }
.wx-prov-dot[data-live="offline"] { background: var(--live-grey); }
.wx-prov-dot[data-live="live"]::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--live-green); animation: live-beat 2.6s cubic-bezier(0,0,0.2,1) infinite; }
@media (prefers-reduced-motion: reduce) { .wx-prov-dot[data-live="live"]::after { animation: none; display: none; } }

/* ── NOW tile (.wx-tile--nowfeels): two tight columns (Eli: no whitespace band). LEFT = NOW
   label over the condition (icon + word); RIGHT = big temp over H/L, right-aligned. Both
   top-aligned, so the condition sits right under NOW and H/L right under the temp. */
.wx-now-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.wx-now-lead { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.wx-now-read { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: 0 0 auto; }
.wx-now-read .wx-tile-val { font-size: 44px; line-height: 0.82; display: inline-flex; align-items: flex-start; }
.wx-now-read .wx-u { font-size: 15px; margin-top: 0.35em; }
@media (min-width: 900px) { .wx-now-read .wx-tile-val { font-size: 47px; } }
.wx-now-cond { display: inline-flex; align-items: center; gap: 7px; min-width: 0; font-family: var(--body); font-size: 16px; font-weight: 600; color: var(--ink); line-height: 1.2; }
.wx-now-cico { display: inline-flex; flex: 0 0 auto; align-self: center; }
.wx-now-cico svg { width: 22px; height: 22px; }
.wx-now-cword { min-width: 0; }
.wx-now-hl { flex: 0 0 auto; white-space: nowrap; font-family: var(--body); font-size: 15px; font-weight: 600; color: var(--ink); }
/* the H / L micro-label voice, matching the Oswald-caps tag language used across tiles */
.wx-now-tag { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.08em; font-size: 10.5px; font-weight: 700; color: var(--ink-faint); margin-right: 3px; }
/* always 2 columns (shade | sun, humidity | dew) -- keeps humidity + dew on the same line so
   the Now tile isn't tall on the narrow 2-up mobile grid (Eli). */
.wx-now-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 14px; margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--rule-ghost); }
/* stat = icon column + a (label / value) column. Label and value share the SAME left edge
   -- the value hangs under the label TEXT, not under the icon (Eli). */
.wx-now-stat { display: flex; flex-direction: row; align-items: flex-start; gap: 6px; min-width: 0; }
.wx-now-sico { flex: 0 0 auto; margin-top: 1px; display: inline-flex; }
.wx-now-sico svg { width: 13px; height: 13px; color: var(--wx-sun-text); }
.wx-now-scol { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.wx-now-slbl { font-family: var(--mono); text-transform: uppercase;
  letter-spacing: 0.04em; font-size: 9.5px; line-height: 1.28; font-weight: 600; color: var(--ink-faint); }
.wx-now-sval { font-family: var(--body); font-size: 20px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; line-height: 1; }
/* the two stats in a grid row share a line-count (shade+sun wrap to two, heat+dew stay one),
   so their values align without reserving height -- keeps the card compact. */

/* ── ALERT PILL (NWS watch/warning or nearby lightning), its own iOS-style row ── */
/* tuck the alert tighter into the card flow so it doesn't add a full extra card-gap that
   reads as a blank line above/below it (Eli). */
.wx-alert { display: flex; align-items: center; gap: 9px; margin: -4px 0; padding: 9px 14px; border-radius: 8px; font-family: var(--body); font-size: 13px; line-height: 1.4; }
.wx-alert[hidden] { display: none; }
.wx-alert svg { width: 18px; height: 18px; flex: 0 0 auto; }
.wx-alert b { font-weight: 700; }
.wx-alert-src { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.1em; font-size: 9.5px; font-weight: 600; margin-left: auto; padding-left: 10px; opacity: 0.8; white-space: nowrap; align-self: center; }
/* tint layered over the card surface (not the bare page) so the pill reads as its
   own card; text tones verified 4.5:1+ against the composited result, both themes */
.wx-alert--warn { background: linear-gradient(rgba(217,68,60,0.10), rgba(217,68,60,0.10)), var(--paper-inset); border: 1px solid rgba(217,68,60,0.35); color: #a8322a; }
.wx-alert--bolt { background: linear-gradient(rgba(224,168,40,0.14), rgba(224,168,40,0.14)), var(--paper-inset); border: 1px solid rgba(224,168,40,0.4); color: #7d5514; }
@media (prefers-color-scheme: dark) { .wx-alert--warn { color: #f0928a; } .wx-alert--bolt { color: #e7c878; } }
/* the NWS alert is a link out to the point forecast (zip 37854); the whole pill is clickable */
.wx-alert-link { display: flex; align-items: center; gap: 9px; width: 100%; min-width: 0; color: inherit; text-decoration: none; }
.wx-alert-link:hover span:not(.wx-alert-src), .wx-alert-link:focus-visible span:not(.wx-alert-src) { text-decoration: underline; text-underline-offset: 2px; }
.wx-alert-src svg { width: 12px; height: 12px; margin-left: 4px; }

/* ── HOURLY STRIP: a labelled header, a hairline, then the horizontal hour scroll. ── */
.wx-hourly { display: flex; overflow-x: auto; scroll-snap-type: x proximity; margin: 11px -16px 0; padding: 11px 10px 4px; border-top: 1px solid var(--rule-ghost); scrollbar-width: thin; scrollbar-color: var(--rule-faint) transparent; }
/* scroll affordance handled by the shared .wb-hscroll system (styles.css) + wbScrollHint. */
.wx-hr { scroll-snap-align: start; flex: 0 0 auto; min-width: 52px; display: flex; flex-direction: column; align-items: center; gap: 0; }
.wx-hr-t { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.05em; font-size: 11px; font-weight: 600; color: var(--ink-soft); line-height: 1; }
.wx-hr--now .wx-hr-t { color: var(--ut-orange-text); letter-spacing: 0.1em; }
.wx-hr-i { height: 26px; display: flex; align-items: center; margin-top: 7px; }
.wx-hr-i svg { width: 22px; height: 22px; }
.wx-hr-p { height: 14px; margin-top: 2px; font-family: var(--body); font-size: 12px; font-weight: 700; color: var(--wx-rain); line-height: 14px; }
.wx-hr-v { margin-top: 2px; font-family: var(--body); font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.15; }
/* per-hour wind: a small from-direction arrow + speed (mph) under the temp */
.wx-hr-w { margin-top: 4px; min-height: 13px; display: inline-flex; align-items: baseline; gap: 3px; font-family: var(--body); font-size: 11.5px; font-weight: 600; color: var(--ink-soft); line-height: 1; }
/* cardinal direction (Eli: dumped the too-small per-hour arrow for a legible compass code) */
.wx-hr-wd { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.02em; font-size: 9.5px; font-weight: 600; color: var(--ink-faint); }
.wx-hr--sun .wx-hr-w { display: none; }
/* sunrise/sunset columns: gold event glyph, the word as the value row (iOS idiom) */
.wx-hr--sun .wx-hr-i { color: var(--wx-sun-text); }
.wx-hr--sun .wx-hr-v { font-size: 11.5px; font-weight: 600; color: var(--wx-sun-text); text-transform: uppercase; letter-spacing: 0.06em; font-family: var(--mono); line-height: 22.5px; }

/* ── 10-DAY LIST: day | icon+% | low | shared-scale range bar | high ──────────── */
.wx-tenday { display: grid; margin-top: 3px; }
.wx-td { display: grid; grid-template-columns: 3.4rem 2.5rem 2.2rem 1fr 2.2rem; align-items: center; gap: 10px; padding: 8px 2px; border-top: 1px solid var(--rule-ghost); min-height: 40px; }
.wx-td:first-child { border-top: 0; }
.wx-td-day { display: flex; flex-direction: column; gap: 1px; font-family: var(--body); font-weight: 600; font-size: 13.5px; color: var(--ink); }
/* per-day wind under the day name (Eli) -- reuses the day column, no new grid track */
.wx-td-wind { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.01em; font-size: 9.5px; font-weight: 600; color: var(--ink-faint); white-space: nowrap; }
.wx-td-ico { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.wx-td-ico svg { width: 22px; height: 22px; }
.wx-td-pop { font-family: var(--body); font-size: 12px; font-weight: 700; color: var(--wx-rain); margin-top: 1px; }
.wx-td-lo { font-family: var(--body); font-weight: 600; font-size: 14px; color: var(--ink-faint); text-align: right; }
.wx-td-hi { font-family: var(--body); font-weight: 600; font-size: 14px; color: var(--ink); text-align: right; }
.wx-td-bar { position: relative; height: 5px; background: var(--rule-ghost); border-radius: 3px; }
.wx-td-bar-fill { position: absolute; top: 0; bottom: 0; border-radius: 3px; }
/* today's current-temp dot riding the bar (iOS signature) */
.wx-td-dot { position: absolute; top: 50%; width: 9px; height: 9px; border-radius: 50%; background: var(--ink); border: 2px solid var(--wx-dot-ring); transform: translate(-50%, -50%); box-shadow: 0 0 0 1px rgba(75,75,75,0.25); }
@media (max-width: 420px) { .wx-td { grid-template-columns: 3rem 2.2rem 2rem 1fr 2rem; gap: 7px; } }

/* ── TILE GRID: rounded tiles, 2-col (4-col on desktop), always-on values ─────── */
/* dashboard grid: 2-up on phones, 3-up on desktop. Six tiles (Now+Feels combined, wind,
   water, pressure, air, sun & moon) -> two even rows of three; every tile normal-sized. */
/* Tiles stretch to equal heights (equal visual weight, Eli). To keep that from leaving the
   shorter tiles full of white, each tile's main viz grows to fill (sparkline / scale bar /
   feels list flex up), and Sun & Moon is compacted so the shared row height stays modest. */
/* desktop (3-up): content is trimmed so the tallest tile is modest, then equal rows finish the
   job -- even AND short, no over-padding (Eli). Mobile (2-up, tiles stack tall): natural heights,
   because forcing equal there just pads the short tiles out. */
/* equal-height rows at every width (Eli): each row's tiles share a vertical border so the
   grid reads as a grid, not randomly sized boxes. */
/* Phones: ONE column, each card its natural height -- the original card layouts get full
   width (so the two-column Now head has room and never collides), with no equal-height row
   forcing a void into the lighter card. 2-up returns at >=600, 3-up on desktop (unchanged). */
.wx-tiles { display: grid; grid-template-columns: 1fr; gap: 13px; }
@media (min-width: 600px) { .wx-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; align-items: stretch; } }
@media (min-width: 900px) { .wx-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.wx-tile {
  position: relative;
  background: var(--paper-inset);
  border: 1px solid var(--rule-ghost);
  border-radius: 8px;
  padding: 12px 13px 12px;
  display: flex; flex-direction: column; gap: 6px;
  min-width: 0; min-height: 118px;
}
@media (prefers-color-scheme: dark) {
  .wx-tile { border-color: var(--rule-faint); }
}
/* topline: on the narrow 2-up tiles the label stacks above the big value (no room beside it);
   on the wide 3-up desktop tiles the value moves top-RIGHT, clear of the label, and runs large. */
.wx-tile-topline { display: flex; flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 10px; }
/* headwrap: label + its secondary read (direction / trend / band) stacked, tucked beside the
   tall number so the secondary doesn't cost its own line under the number (Eli). */
.wx-tile-headwrap { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.wx-tile-head { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.12em; font-size: 11px; font-weight: 600; line-height: 1; color: var(--ink-faint); display: inline-flex; align-items: center; gap: 6px; padding-top: 3px; }
.wx-tile-head svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--wx-sun-text); }
.wx-tile-sub2 { display: inline-flex; align-items: center; gap: 4px; font-family: var(--body); font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.1; }
.wx-tile-sub2 svg { width: 13px; height: 13px; flex: 0 0 auto; }
/* topval: just the big number now; the unit rides at the TOP of it (superscript, Eli), and the
   whole thing sits top-left on mobile, top-right on desktop. */
.wx-tile-topval { min-width: 0; flex: 0 1 auto; display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.wx-tile-topval .wx-tile-val { font-size: 44px; line-height: 0.85; display: inline-flex; align-items: flex-start; }
.wx-tile-topval .wx-u { font-size: 15px; margin-top: 0.35em; }
.wx-tile--baro .wx-tile-topval .wx-tile-val { font-size: 40px; }   /* 5-digit pressure reading */
/* wind + pressure: unit sits UNDER the number (Eli), not superscripted like the temp degF */
.wx-tile--wind .wx-tile-topval .wx-tile-val, .wx-tile--baro .wx-tile-topval .wx-tile-val { flex-direction: column; align-items: flex-end; line-height: 0.86; }
.wx-tile--wind .wx-tile-topval .wx-u, .wx-tile--baro .wx-tile-topval .wx-u { margin-top: 1px; font-size: 14px; }
/* wind direction (compass + arrow) a touch bigger (Eli) */
.wx-tile--wind .wx-tile-sub2 { font-size: 15px; }
.wx-tile--wind .wx-tile-sub2 .wx-wind-arrow { width: 17px; height: 17px; }
@media (min-width: 900px) {
  /* topline already places the value top-right at every width now; desktop just runs it larger */
  .wx-tile-topval .wx-tile-val { font-size: 47px; line-height: 0.82; }
  .wx-tile--baro .wx-tile-topval .wx-tile-val { font-size: 42px; }
}
.wx-tile-val { font-family: var(--body); font-weight: 600; font-size: 34px; line-height: 1.02; color: var(--ink); letter-spacing: -0.015em; }
.wx-tile-val .wx-u { font-size: 14px; font-weight: 600; color: var(--ink-faint); margin-left: 3px; letter-spacing: 0; }
.wx-tile-band { font-family: var(--body); font-size: 13px; font-weight: 700; color: var(--ink); margin-top: -2px; }
.wx-tile-sub { font-family: var(--body); font-size: 12px; font-weight: 500; line-height: 1.45; color: var(--ink-soft); }
.wx-tile-sub b { font-weight: 700; color: var(--ink); }
/* forward-looking hedge (water "Likely ..." line) reads a touch softer than the measured line */
.wx-tile-sub--fc { color: var(--ink-faint); margin-top: 2px; }
.wx-tile-foot { font-family: var(--body); font-size: 10.5px; line-height: 1.4; color: var(--ink-faint); margin-top: auto; padding-top: 6px; }
.wx-tile-spacer { flex: 0 1 auto; }   /* no longer grows: the tile's viz fills the middle instead */

/* wind tile: the speed is the headline now (enlarged - Eli: the old dial number read too
   small), a small from-direction arrow beside it, a forecast sparkline, then the prose read */
.wx-wind-big { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.wx-wind-dir { display: inline-flex; align-items: center; gap: 3px; font-family: var(--mono); font-weight: 600; font-size: 14px; letter-spacing: 0.04em; color: var(--ink-soft); }
.wx-wind-arrow { width: 15px; height: 15px; flex: 0 0 auto; }
.wx-wind-chop { font-weight: 700; color: var(--water-text); }

/* tile sparkline: a small forward-forecast trajectory; the tile's big value is the current
   reading, the sparkline is the shape ahead. The Now -> end-time axis names its span; hover
   or touch-scrub reveals exact values via the shared #wx-tip schema. Real series only. */
/* sparkline grows to fill the equal-height tile (capped modest so it stays a sparkline, not a chart) */
.wx-spark-wrap { margin: 8px 0 3px; flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; min-height: 34px; }
.wx-spark { display: block; width: 100%; flex: 1 1 auto; height: auto; min-height: 34px; max-height: 54px; }
.wx-spark--tip { cursor: crosshair; touch-action: pan-y; }
/* Now -> +12h scale under the sparkline (replaces the old per-tile forecast explainer) */
.wx-spark-axis { display: flex; justify-content: space-between; margin-top: 1px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-faint); }

/* air-quality body: scale + read, centered to fill the equal-height tile (Eli: no empty box) */
.wx-air-fill { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; gap: 13px; }
.wx-air-fill .wx-tile-sub { margin: 0; }
/* scale bars (UV + AQI): always-on marker, no tooltips */
.wx-scale { position: relative; height: 8px; border-radius: 4px; margin: 0 5px; }
.wx-scale-dot { position: absolute; top: 50%; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); border: 2px solid var(--wx-dot-ring); transform: translate(-50%, -50%); box-shadow: 0 0 0 1px rgba(75,75,75,0.3); }

/* pressure tile: big readable value + a trend arrow/word, then a forecast sparkline (the
   old gauge set the number in small SVG text - hard to read, same complaint as the wind dial) */
/* (wind/pressure headline blocks now use .wx-tile-val + .wx-topval-sub in the shared topval) */

/* sun & moon tile: horizon arc + times, hairline, moon phase row -- kept compact (Eli) */
.wx-sunarc { width: 100%; height: auto; display: block; }
.wx-sun-times { display: flex; justify-content: space-between; align-items: baseline; font-family: var(--body); font-size: 11px; font-weight: 500; color: var(--ink-soft); margin-top: 1px; }
.wx-sun-times b { font-family: var(--mono); font-weight: 600; font-size: 12.5px; color: var(--ink); letter-spacing: 0.01em; display: block; }
.wx-sun-len { text-align: center; }
.wx-moon-row { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--rule-ghost); margin-top: 5px; padding-top: 6px; font-family: var(--body); font-size: 12px; font-weight: 500; color: var(--ink-soft); }
.wx-moon-row b { color: var(--ink); font-weight: 700; }
.wx-moon-glyph { width: 20px; height: 20px; flex: 0 0 auto; }
.wx-sun-body { min-width: 0; }
/* smaller arc + centered so the Sun & Moon tile stays as compact as its rowmates */
.wx-tile--sun .wx-sunarc { max-width: none; }   /* fill the tile width (Eli); arc is flattened to stay short */
.wx-tile--sun .wx-sun-body { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; gap: 2px; }

/* ── UV + PRECIP CHART CARDS: full-width .wx-mod surfaces whose value is the TIME curve
   (when the UV bites, when rain arrives, how much it hit or missed). The graphs are back
   (Eli), reskinned into the card language: honest measured-vs-forecast, one NOW marker. ── */
.wx-chart { display: block; width: 100%; cursor: crosshair; touch-action: pan-y; }
.wx-chart--uv { height: 132px; }
.wx-chart--when { height: 104px; }
.wx-chart--hitmiss { height: 112px; }
@media (prefers-reduced-motion: reduce) { .wx-chart { cursor: default; } }
/* the precip card stacks two honest panels (when / hit-or-miss) with a little air between */
.wx-chart-panel + .wx-chart-panel { margin-top: 13px; }
/* precip: the two reads (When / Hit-or-miss) sit side by side on desktop instead of
   stacking -- they were eating a lot of vertical space (Eli). Charts re-measure their
   container width on resize, so the narrower panels draw correctly. Stack under 760px. */
@media (min-width: 760px) {
  .wx-precip-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 0 30px; align-items: start; }
  .wx-precip-panels .wx-chart-panel + .wx-chart-panel { margin-top: 0; }
}
.wx-chart-sub { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.1em; font-size: 10.5px; font-weight: 600; color: var(--ink-soft); margin: 2px 0 4px; }
.wx-chart-sub span { text-transform: none; letter-spacing: 0; font-family: var(--body); font-weight: 500; color: var(--ink-faint); }
/* legend: measured vs forecast, so colour is never the only cue */
.wx-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin: 8px 0 0; font-family: var(--body); font-size: 11.5px; font-weight: 500; color: var(--ink-soft); }
.wx-leg { display: inline-flex; align-items: center; gap: 6px; }
.wx-leg-line { width: 16px; height: 0; flex: 0 0 auto; }
.wx-leg-line--meas { border-top: 2.4px solid var(--wx-uv-meas); }
.wx-leg-line--fc { border-top: 2px dashed var(--wx-sun-text); }
.wx-leg-sw { width: 12px; height: 10px; border-radius: 2px; flex: 0 0 auto; }
.wx-leg-sw--meas { background: var(--wx-rain); }
.wx-leg-sw--fc { background: transparent; border: 1.4px dashed var(--wx-rain); }
/* the plain-language read under each chart: peak/timing/hit-or-miss in full sentences */
.wx-chart-read { font-family: var(--body); font-size: 13px; font-weight: 500; line-height: 1.5; color: var(--ink-soft); margin: 9px 0 0; text-wrap: pretty; }
.wx-chart-read:empty { display: none; }
.wx-chart-read b { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── LEGACY SHARED HEADERS: the WILDLIFE section (wildlife.css/index.html) reuses
   .wx-tl-head/.wx-tl-sub for "What's Singing" / "What's Biting". The weather
   rebuild no longer uses them, but they must survive verbatim for wildlife. ───── */
.wx-tl-head { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.08em; font-size: clamp(15px, 2.5vw, 18px); font-weight: 600; line-height: 1.15; color: var(--ink); display: inline-flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.wx-tl-head svg { width: 18px; height: 18px; flex: 0 0 auto; color: var(--wx-sun-text); }
.wx-tl-sub { font-family: var(--body); font-weight: 600; text-transform: none; letter-spacing: 0; font-size: 12px; color: var(--ink-faint); margin-left: 4px; }

/* state-only motion, product register: nothing here animates on load; the LIVE
   pill heartbeat (styles.css) already respects prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .wx-hourly { scroll-behavior: auto; }
}

/* ── PAGE-HERO cam (the real sky, above the fold) — NOT part of the weather card.
   Full-bleed live video + a few glanceable readings; you scroll past it. ──────── */
.wx-camhero { position: relative; width: 100%; aspect-ratio: 16 / 9; max-height: 80vh; background: #0c1320; overflow: hidden; border-radius: 0 0 16px 16px; margin-bottom: 18px; }
.wx-camhero-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: 0; }
.wx-camhero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: 1; opacity: 0; transition: opacity 0.6s ease; }
/* Reveal the video over the poster ONLY while it's genuinely live; on connecting /
   reconnecting / off the refreshing cam.jpg poster shows through -- so the hero is never a
   black or blank frame, even mid-recovery. */
.wx-camhero[data-state="live"] .wx-camhero-video { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .wx-camhero-video { transition: none; } }

/* ── OVERDRIVE: go-live reveal ─────────────────────────────────────────────────
   (The connecting state shows a clean still + a loading spinner in the pill -- no
   over-the-photo sweep, which read like a glitch rather than "video incoming".) */
/* GO-LIVE (one-shot): the video resolves out of blur + a hair of scale into focus over the
   still -- the lens locking on. `both` holds the end frame until cam.js drops the class. */
.wx-cam--golive .wx-camhero-video { animation: cam-focuspull 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes cam-focuspull {
  0%   { opacity: 0; filter: blur(9px); transform: scale(1.025); }
  100% { opacity: 1; filter: blur(0);   transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .wx-cam--golive .wx-camhero-video { animation: none; }
}
.wx-camhero-grad { position: absolute; inset: 0; z-index: 2; pointer-events: none; background: linear-gradient(to top, rgba(8,14,26,0.72) 0%, rgba(8,14,26,0.12) 32%, transparent 56%); }
.wx-camhero-read { position: absolute; left: clamp(14px, 4vw, 34px); bottom: clamp(13px, 3.5vw, 28px); color: #fff; text-shadow: 0 1px 10px rgba(0,0,0,0.55); display: flex; flex-direction: column; gap: 2px; }
.wx-cr-live { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.12em; font-size: 11px; font-weight: 600; opacity: 0.92; display: inline-flex; align-items: center; gap: 6px; }
.wx-cr-main { display: inline-flex; align-items: center; gap: 9px; }
.wx-cr-ico svg { width: 40px; height: 40px; }
.wx-cr-temp { font-family: var(--mono); font-weight: 600; font-size: clamp(42px, 11vw, 66px); line-height: 0.92; }
.wx-cr-sub { font-family: var(--body); font-weight: 600; font-size: 14px; opacity: 0.96; }
.wx-camhero-read .nl-live { background: var(--live-green); }


/* --- html[data-night="1"] mirror of the prefers-color-scheme:dark rules above, so the
   site's time-based night theme also darkens this homepage (added at homepage cutover) --- */
html[data-night="1"] {
    --wx-accent: #e0a851;
    --wx-rain: #549de5;        /* same rain blue on dark slate: 5.07:1 on #232a31 (AA), hue 250 */
    --wx-sun-text: #d6a24d;
    --wx-ico-day: #dca452;
    --wx-ico-night: #93a0c4;
    --moon-lit: #efe6c8;
    --moon-dark: #424a54;
    --wx-dot-ring: #232a31;
    --wx-uv-meas: #f7cd86;     /* measured-UV line on dark slate: bright warm so it reads over the arc */
  }
html[data-night="1"] /* on the dark card the 0.07 ghost hairline all but vanishes with no shadow to
     lift it — step up to the stronger faint rule so the outline still reads */
  .wx-mod { border-color: var(--rule-faint); }
html[data-night="1"] .wx-alert--warn { color: #f0928a; }
html[data-night="1"] .wx-alert--bolt { color: #e7c878; }
html[data-night="1"] .wx-tile { border-color: var(--rule-faint); }
