/* Forecast Season — the bridge between the site's stylesheet and the shared explorer.
 *
 * `explorer.css` and `legacy.css` are Forecast Eagle's, vendored byte-for-byte, and
 * they are written entirely against CSS custom properties. That is what makes this file
 * short: skinning the explorer for this site is a matter of *naming the colours*, not of
 * restating a layout. Keep it that way — a rule that changes a size or a position
 * belongs upstream, where six other viewers can have it too.
 *
 * Three jobs, in order:
 *
 *   1. Supply the four variables Eagle's site stylesheet declares and this one does not.
 *   2. Re-point the explorer's "active" colour from the network's guide green to
 *      Forecast Season's own twilight violet, which is route 90's colour and the thing
 *      that makes this page belong to this site rather than to that one.
 *   3. Restate the handful of chrome rules that live in `forecasteagle.css` — the
 *      compact button, the segmented control, the timeline strip — **scoped inside
 *      `.explorer` and `.lab-page`**. season.css already owns `.btn` at the top level,
 *      with a much larger pill for the prose pages; a control strip of thirty of those
 *      is a screen and a half before the map appears, and unscoping them here would
 *      wreck every other page on the site.
 */

/* The one rule that is not a colour, and the one this file exists to catch.
 *
 * Eagle's site stylesheet carries `[hidden] { display: none !important }` globally, and
 * a dozen controls in the vendored viewer depend on it: the regions drawer, the city
 * time-series panel, the wind and contour option boxes, the export status line, the
 * "no WebGL" plate. Every one of them is styled `display: flex` or `display: block` by
 * `legacy.css` / `explorer.css`, which beats the browser's own `[hidden]` rule on
 * specificity — so without this, the locked viewer loads with its full-height "All
 * regions" drawer already open across half the screen, and the explorer shows an empty
 * options box under every heading.
 *
 * season.css does not carry it, and should not have to: it is a rule about this
 * viewer's markup, so it belongs with the viewer's skin. Caught by looking at the page,
 * which is the only way this class of bug is ever caught. */
[hidden] { display: none !important; }

/* The wind canvas, and the second rule of the same kind.
 *
 * `initWind` appends a bare <canvas id="wind-overlay"> to the stage wrapper and expects
 * the site stylesheet to place it — Eagle's does, in one line, and without it the canvas
 * is a static block laid out *below* the map inside a wrapper that clips its overflow.
 * The streamlines are drawn perfectly and nobody ever sees them, which is the worst way
 * for a feature to fail: every control works, the option rows appear, the sidecar is
 * fetched, and the map is simply blank. Found by photographing the page. */
#wind-overlay { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

:root {
  --font: 'Overpass', Helvetica, Arial, sans-serif;
  --mono-font: 'Overpass Mono', ui-monospace, monospace;
  /* The dark inset behind a map figure, and the shield red the error state uses. */
  --figure: #0a0e14;
  --figure-line: #223142;
  --shield-red: #af1e2d;
}

/* The explorer's accent. Eagle's `--sign` is the Interstate guide green that runs its
   whole site; here the guide green belongs to the network chrome and the *route* is
   violet, so inside the map every "on" state, focus ring and buffer bar reads violet
   and the green stays where it means "you are on the Forecast Network". */
.explorer, .lab-page {
  --sign: var(--accent);
  --sign-dk: var(--accent-dk);
  --sign-sub: var(--accent-sub);
}

/* ── controls (from forecasteagle.css, scoped) ─────────────────────────────── */
.explorer .btn, .lab-page .btn {
  display: inline-flex; align-items: center; gap: .4rem;
  cursor: pointer; border: 1px solid var(--line); background: #fff; color: var(--ink2);
  border-radius: 3px; font-family: var(--font); font-weight: 700; font-size: 11.5px;
  letter-spacing: .02em; padding: 7px 12px; line-height: 1.3; text-transform: none;
  transition: .12s;
}
.explorer .btn:hover, .lab-page .btn:hover {
  border-color: var(--sign); color: var(--ink); transform: none;
}
.explorer .btn.on, .explorer .btn[aria-pressed="true"],
.lab-page .btn.on, .lab-page .btn[aria-pressed="true"] {
  background: var(--accent); color: #fff; border-color: var(--accent-dk);
}
.explorer .btn:disabled, .lab-page .btn:disabled { opacity: .5; cursor: default; }

.explorer select, .lab-page select,
.explorer input[type="text"], .lab-page input[type="text"] {
  background: #fff; border: 1px solid var(--line); color: var(--ink);
  border-radius: 3px; padding: 6px 9px; font-family: var(--font);
  font-weight: 700; font-size: 12px;
}
.explorer select:focus, .lab-page select:focus,
.explorer .btn:focus-visible, .lab-page .btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.explorer label, .lab-page label {
  font-size: 9.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--mut);
}

/* ── timeline ──────────────────────────────────────────────────────────────── */
.timeline {
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  margin-top: 12px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 14px 9px; box-shadow: 0 6px 22px rgba(0, 0, 0, .08);
}
.tl-side { display: flex; flex-direction: column; gap: 5px; }
.tl-lab { font-size: 9px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mut); }
.tl-transport { display: flex; align-items: center; gap: 5px; }
.tl-track { flex: 1 1 340px; min-width: 240px; display: flex; flex-direction: column; }
.tl-track input[type="range"] { width: 100%; margin: 0; accent-color: var(--accent); }
/* Inset by half a thumb so the first and last ticks sit under the thumb's travel,
   not under the ends of the groove the thumb never reaches. */
.tl-ticks { position: relative; height: 23px; margin: 3px 9px 0; pointer-events: none; }
.tl-ticks .tk { position: absolute; top: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; }
.tl-ticks .tk.at-start { transform: translateX(-2px); align-items: flex-start; }
.tl-ticks .tk.at-end { transform: translateX(calc(-100% + 2px)); align-items: flex-end; }
.tl-ticks .tk i { width: 1px; height: 5px; background: var(--line); display: block; }
.tl-ticks .tk span { font: 700 8.5px var(--mono-font); color: var(--ink2);
  white-space: nowrap; line-height: 1; margin-top: 3px; letter-spacing: .04em; }
/* On a monthly axis every tick is a month and the *first* one is the one that carries
   the year, so `.day` marks the start of the run rather than a date boundary — see the
   `fmtTick` branch in maptimeline.js. */
.tl-ticks .tk.day i { height: 9px; width: 2px; background: var(--accent); }
.tl-ticks .tk.day span { color: var(--ink); font-weight: 800; }
.tl-buffer { height: 2px; margin: 2px 9px 0; border-radius: 2px; background: var(--line2);
  overflow: hidden; transition: opacity .4s ease .3s; }
.tl-buffer::before { content: ""; display: block; height: 100%; width: var(--pct, 0%);
  background: var(--accent); transition: width .15s linear; }
.tl-buffer.is-full { opacity: 0; }
.tl-ends { display: flex; justify-content: space-between; gap: 10px;
  font: 700 9.5px var(--mono-font); color: var(--mut); letter-spacing: .02em; }
.tl-count { font: 900 13px var(--mono-font); color: var(--ink); }
.tl-hint { margin-top: 7px; font-size: 11px; font-weight: 700; color: var(--mut); }
.tl-load { margin-left: 8px; }

/* ── segmented control ─────────────────────────────────────────────────────── */
.seg { display: flex; }
.seg button { font: 700 11px var(--mono-font); background: var(--card); color: var(--ink2);
  border: 1px solid var(--line); border-left-width: 0; padding: 5px 8px; cursor: pointer; }
.seg button:first-child { border-left-width: 1px; border-radius: 4px 0 0 4px; }
.seg button:last-child { border-radius: 0 4px 4px 0; }
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--accent); color: #fff; border-color: var(--accent-dk); }
.seg button:disabled { cursor: not-allowed; }
/* A control the current run cannot drive. Greyed as a block rather than hidden: a
   control that quietly vanishes reads as a bug, one that is greyed out reads as an
   answer, and a strip that changes length as you switch is disorienting. */
.seg.unavailable { opacity: .35; }
.seg.unavailable button { cursor: not-allowed; text-decoration: line-through;
  text-decoration-thickness: 1px; }

/* ── misc ──────────────────────────────────────────────────────────────────── */
.explorer .panel, .lab-page .panel {
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 16px; box-shadow: 0 6px 22px rgba(0, 0, 0, .08);
}
.badge { display: inline-block; padding: 3px 9px; border-radius: 3px;
  font-size: 10px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase; }
.badge-live { background: var(--accent); color: #fff; }
.badge-new { background: var(--shield-red); color: #fff; }
.badge-soon { background: var(--paper2); color: var(--mut); border: 1px solid var(--line); }
.faint { color: var(--mut); }
.wrap-wide { max-width: 1560px; margin: 0 auto; padding: 0 18px; }
.skip { position: absolute; left: -9999px; top: 0; background: var(--accent); color: #fff;
  padding: 9px 14px; z-index: 200; font-weight: 800; }
.skip:focus { left: 0; }

/* ── the one thing this page says that a short-range viewer never has to ────
   Whether the month on screen has already happened.

   Lead 1 is the initialisation's own month, so the newest run's first frame is always
   part-elapsed, and an older run's first frames are wholly in the past. Presenting
   either as "the outlook" without saying so would be the single most misleading thing
   this page could do, so the frame itself is marked: a hatched rail down the left edge
   of the stage, and the readout above it says which. */
.stage-wrap[data-month-state="elapsed"]::after,
.stage-wrap[data-month-state="current"]::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 6px; z-index: 3;
  pointer-events: none;
  background: repeating-linear-gradient(135deg,
    var(--warn) 0 5px, transparent 5px 10px);
}
.stage-wrap[data-month-state="elapsed"]::after { --warn: #8a6508; }
.stage-wrap[data-month-state="current"]::after { --warn: var(--accent); }

/* ── the field picker, shelved ─────────────────────────────────────────────────
   Eagle's field list is a flat row of chips, which is right for six or nine fields on
   one grid. Sixteen fields across four quite different questions — how warm, how wet,
   the ocean, the circulation — is a wall, and a reader looking for sea ice should not
   have to read past four temperature fields to find out whether it is published.

   So the fields shelve the way the regions already do, with the same label column and
   the same geometry, and the two columns of the guide sign end up mirroring each other
   rather than one being a row and the other a stack. */
.explorer #fields {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
}
.field-group { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.field-group-label {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); min-width: 72px;
}
/* The two shelved pickers are the guide sign; the run picker and the tools ride beside
   them rather than being squeezed between. */
.explorer .primary > .pgroup:first-child { flex: 2 1 420px; }

/* ── the point view's box and whisker ──────────────────────────────────────────
   Drawn behind the median line, in the site's accent, with the hindcast reference in
   ink. The box is filled rather than outlined because at six steps it is a wide shape
   and an outline would compete with the grid; at sixty it is a hairline and a fill is
   all that survives. */
.pp-box .pp-wh { stroke: var(--accent); stroke-width: 1.2; opacity: .75; }
.pp-box .pp-iqr { fill: var(--accent); fill-opacity: .22;
                  stroke: var(--accent); stroke-width: 1; stroke-opacity: .55; }
.pp-box .pp-med { stroke: var(--accent-dk); stroke-width: 2.2; }
/* The model's own hindcast median for the same month and lead. Dashed, in ink, wider
   than the box: it is the thing the box is read *against*, so it must not look like
   another percentile of the same distribution. */
.pp-box .pp-clim { stroke: var(--ink2); stroke-width: 1.4; stroke-dasharray: 3 2;
                   opacity: .8; }
.pp-foot b { color: var(--ink); font-weight: 800; }
