/* MERIDIAN — WEATHER BROADCAST.
   A broadcast wants a different posture from a console: the chart is the whole frame, the
   furniture floats over it, and the words sit where a viewer's eye already is — along the bottom.
   Every colour is a palette token; nothing here introduces a second set of hues. */

.wxb-stage { position: relative; overflow: hidden; }
#wxbMap { position: absolute; inset: 0; }
/* Windy.com's visualisation. z-index 1: over the chart, under the fields canvas, vignette and
   every piece of furniture. It fades out for the approach flight so the chart's four-second
   zoom is what the eye follows, and fades back in aimed at the new act. */
.wxb-windy { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; z-index: 1; background: transparent; opacity: 1; transition: opacity .55s ease; }
.wxb-windy.fade { opacity: 0; pointer-events: none; }
.wxb-windy[hidden] { display: none; }
/* With Windy drawing its own particles, MERIDIAN's field canvas would double the wind. */
.wxb-stage.windy .wxb-fields { display: none; }

/* The animated wind and swell fields. pointer-events:none so the map underneath still pans —
   the canvas is a picture over the chart, never a lid on it. */
.wxb-fields { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; }

/* Cinema vignette. Purely optical: it darkens the corners so the caption and the act card read
   against imagery of any brightness, from a black night-time IR frame to a white cloud shield. */
.wxb-vignette {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background:
    radial-gradient(120% 90% at 50% 45%, transparent 42%, rgba(3, 7, 15, .55) 100%),
    linear-gradient(to bottom, rgba(3, 7, 15, .55) 0, transparent 16%, transparent 60%, rgba(3, 7, 15, .82) 100%);
}

.wxb-act {
  position: absolute; left: 16px; top: 14px; z-index: 6;
  padding: 8px 13px; border-radius: 8px;
  background: rgba(4, 9, 18, .74); border: 1px solid var(--edge); backdrop-filter: blur(7px);
}
.wxb-act b { display: block; font: 800 14px/1.15 var(--disp); letter-spacing: .12em; color: var(--ink); }
.wxb-act i { display: block; margin-top: 3px; font: 600 11px var(--mono); font-style: normal; letter-spacing: .1em; color: var(--brand); }

.wxb-clock {
  position: absolute; right: 16px; top: 14px; z-index: 6; text-align: right;
  padding: 8px 13px; border-radius: 8px;
  background: rgba(4, 9, 18, .74); border: 1px solid var(--edge); backdrop-filter: blur(7px);
}
.wxb-clock b { display: block; font: 700 13px var(--mono); letter-spacing: .06em; color: var(--ink); }
.wxb-clock i { display: block; margin-top: 2px; font: 700 10.5px var(--mono); font-style: normal; letter-spacing: .16em; color: var(--teal); }

/* The coverage strip. Its job is to make a gap VISIBLE: a layer with no frame at the chosen
   instant reads .gap and says so, rather than quietly showing a newer frame under the wrong
   timestamp. Hue is doubled by the wording in each chip, so the state survives greyscale. */
.wxb-legend { position: absolute; left: 16px; bottom: 96px; z-index: 6; display: flex; flex-wrap: wrap; gap: 6px; max-width: min(620px, 62%); }
.wxb-lg {
  display: inline-flex; flex-direction: column; gap: 1px; padding: 4px 8px; border-radius: 5px;
  background: rgba(4, 9, 18, .78); border: 1px solid var(--edge);
  font: 700 9.5px var(--mono); letter-spacing: .1em; color: var(--dim);
}
.wxb-lg i { font: 600 9.5px var(--mono); font-style: normal; letter-spacing: .04em; color: var(--faint); }
.wxb-lg.ok { border-color: #3fd0c955; color: var(--teal); }
.wxb-lg.warn { border-color: var(--caution); color: var(--caution); }
.wxb-lg.gap { border-color: var(--nogo); color: var(--nogo); opacity: .9; }
.wxb-lg.stamp { border-color: transparent; background: none; color: var(--faint); }

/* The transcript line. Always rendered — the voice is optional, the attribution is not. */
.wxb-caption {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 56px; z-index: 7;
  width: min(860px, calc(100% - 40px)); text-align: center;
}
.wxb-caption span {
  display: inline-block; padding: 9px 16px; border-radius: 9px;
  background: rgba(3, 7, 15, .86); border: 1px solid var(--edge);
  font: 500 15px/1.45 var(--sans, system-ui); color: var(--ink); text-wrap: balance;
}
.wxb-caption i {
  display: block; margin-top: 5px; font: 700 9.5px var(--mono); font-style: normal;
  letter-spacing: .16em; color: var(--faint);
}
.wxb-caption:empty { display: none; }

.wxb-transport {
  position: absolute; left: 16px; right: 16px; bottom: 12px; z-index: 8;
  display: flex; align-items: center; gap: 8px;
}
.wxb-btn {
  font: 800 11px var(--mono); letter-spacing: .12em; color: var(--dim); cursor: pointer;
  background: rgba(4, 9, 18, .82); border: 1px solid var(--edge); border-radius: 999px; padding: 8px 14px;
}
.wxb-btn:hover { color: var(--ink); border-color: var(--dim); }
.wxb-btn.on { color: var(--brand); border-color: #f2a93b88; background: #f2a93b1a; }
.wxb-btn.live.on { color: var(--go); border-color: color-mix(in srgb, var(--go) 55%, transparent); background: color-mix(in srgb, var(--go) 10%, transparent); }
.wxb-scrub { flex: 1; min-width: 120px; accent-color: var(--teal); cursor: pointer; }

/* ── synoptic markers ───────────────────────────────────────────────────────────────────────
   A forecast position must never read like an observation, so .fcst is hollow, dimmed and
   dashed — the same distinction the dashed track line makes. */
.wxb-syn { display: flex; align-items: center; gap: 5px; pointer-events: auto; cursor: help; white-space: nowrap; }
.wxb-syn .wxb-syn-g {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  font: 900 14px var(--disp); color: #eaf4ff; background: rgba(6, 16, 28, .9); border: 2px solid var(--dim);
}
.wxb-syn .wxb-syn-t { font: 700 11px var(--mono); letter-spacing: .05em; color: #eaf4ff; text-shadow: 0 1px 3px #000, 0 0 6px #000; }
.wxb-syn .wxb-syn-t i { display: block; font: 600 10px var(--mono); font-style: normal; color: #cfe0f2; }
.wxb-syn.low .wxb-syn-g { border-color: var(--nogo); color: #ffc9c0; }
.wxb-syn.high .wxb-syn-g { border-color: var(--teal); color: #bff3ef; }
.wxb-syn.trop .wxb-syn-g { border-color: var(--nogo); background: color-mix(in srgb, var(--nogo) 26%, rgba(6, 16, 28, .9)); color: #fff; animation: wxb-spin 6s linear infinite; }
/* A forecast fix is a waypoint on the dashed track, not a second storm: small, hollow, unlabelled
   (see paintSynoptic), and quiet enough that the current position stays the loud one. */
.wxb-syn.fcst { opacity: .55; }
.wxb-syn.fcst .wxb-syn-g { width: 13px; height: 13px; font-size: 8px; border-width: 1.5px; border-style: dashed; background: transparent; }
.wxb-syn.fcst.trop .wxb-syn-g { animation: none; }
@keyframes wxb-spin { to { transform: rotate(360deg); } }

.wxb-buoy { display: flex; flex-direction: column; align-items: center; gap: 1px; cursor: help; }
.wxb-buoy b { font: 800 11px var(--mono); color: #8fe3ff; text-shadow: 0 1px 3px #000; }
.wxb-buoy i { font: 600 11px var(--mono); font-style: normal; color: #cfe8ff; background: rgba(5, 9, 17, .78); border: 1px solid #4a6a8a66; border-radius: 3px; padding: 1px 5px; white-space: nowrap; }

/* ── the rail ───────────────────────────────────────────────────────────────────────────── */
.wxb-script { max-height: 300px; overflow: auto; }
.wxb-ln { padding: 6px 8px; border-left: 2px solid var(--edge); margin: 4px 0; font: 500 12px/1.45 var(--sans, system-ui); color: var(--faint); }
.wxb-ln i { display: block; margin-top: 2px; font: 700 9px var(--mono); font-style: normal; letter-spacing: .14em; color: var(--edge); }
.wxb-ln.on { border-left-color: var(--brand); color: var(--ink); background: #f2a93b0f; }
.wxb-ln.on i { color: var(--faint); }

.wxb-site { padding: 7px 9px; border: 1px solid var(--edge); border-radius: 7px; margin: 0 0 7px; cursor: pointer; }
.wxb-site:hover { border-color: var(--dim); }
.wxb-site.on { border-color: #3fd0c977; background: #3fd0c90f; }
.wxb-site-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; font: 700 12px var(--disp); color: var(--ink); }
.wxb-call { font: 800 10px var(--mono); letter-spacing: .1em; padding: 2px 7px; border-radius: 999px; }
.wxb-site-r { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 4px; font: 600 11px var(--mono); color: var(--dim); }

.wxb-raw {
  max-height: 320px; overflow: auto; margin: 8px 0 0; padding: 8px;
  background: var(--bg2); border: 1px solid var(--edge); border-radius: 6px;
  font: 500 10.5px/1.4 var(--mono); color: var(--dim); white-space: pre-wrap;
}

@media (max-width: 900px) {
  .wxb-legend { display: none; }
  .wxb-caption { bottom: 62px; width: calc(100% - 24px); }
  .wxb-caption span { font-size: 13px; padding: 7px 12px; }
  .wxb-transport { flex-wrap: wrap; gap: 6px; }
  .wxb-act, .wxb-clock { padding: 6px 9px; }
  .wxb-act b { font-size: 12px; }
}

/* prefers-reduced-motion is honoured in JS as well — the flight becomes a cut and the fields
   draw one still frame — but the cyclone glyph is pure CSS, so it is stopped here. */
@media (prefers-reduced-motion: reduce) {
  .wxb-syn.trop .wxb-syn-g { animation: none; }
}
