/* water.css — the /water section (site-keyed spectral-change monitoring).
   Tokens come from base.css — nothing here re-declares a colour, radius, or
   shadow of its own.

   Two instrument hues, used consistently across every panel and every chart:
   mHR = --accent (teal), mFL = --imu (violet). They are never mixed on one axis;
   the detector panel's shared axis is percentile, which is unit-free by
   construction.

   Section numbers below follow the page's own panel order, which Phase 9
   inverted: hero, published parameters, days worth a look, change detector,
   day notes, method. */

/* `width: 100%` is load-bearing, not belt-and-braces. base.css sets
   `body { display: flex; flex-direction: column }` for the main viewer's app
   shell, which makes this a flex item — and an auto cross-axis margin disables
   `align-items: stretch`, so `margin: 0 auto` alone left the wrapper
   **shrink-to-fit**: measured 791px on /water/day and 997px on /water in the
   same 1280px viewport, i.e. the page width tracked its own content instead of
   the window. `.wa-chart-grid`'s `minmax(380px, 1fr)` then never had room for
   two columns on any desktop, and every chart on both pages drew in one. */
.wa-wrap { max-width: 1140px; width: 100%; margin: 0 auto; padding: 28px 24px 64px; }

.wa-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 18px;
}
.wa-title {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 700;
  letter-spacing: -0.01em; color: var(--ink-strong); margin: 0;
}

/* ── Site switcher ─────────────────────────────────────────────────── */

.wa-sites { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 20px; }
/* The switcher is a wrapping flex row, so the deep-link fallback note has to
   claim a full basis or it lands beside the last button as a stray column. */
.wa-site-miss {
  flex: 0 0 100%; font-size: 0.74rem; color: var(--dim); font-style: italic;
  max-width: 68ch; line-height: 1.55;
}
.wa-site-btn {
  font: inherit; font-size: 0.82rem; font-weight: 500;
  /* 12px, not 11: at 11 the rendered height lands on 43px, one under the
     44px touch-target floor. Height is padding-driven here, so the padding
     is the knob. */
  padding: 12px 16px; border: 1px solid var(--line);
  background: var(--panel-alt); color: var(--mid);
  border-radius: var(--r-lg); cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.wa-site-btn:hover { background: var(--panel); color: var(--ink); }
.wa-site-btn.is-active {
  background: var(--accent); border-color: var(--accent);
  color: #fff; box-shadow: var(--shadow-xs);
}
.wa-site-btn .wa-site-n { opacity: 0.7; font-size: 0.74rem; margin-left: 6px; }

/* ── Panels ────────────────────────────────────────────────────────── */

.wa-panel {
  background: var(--panel); border: 1px solid var(--line-soft);
  border-radius: var(--r-card); box-shadow: var(--shadow-xs);
  padding: 18px 20px; margin-bottom: 16px;
}
.wa-panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}
.wa-panel-title {
  font-size: 0.75rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--dim); margin: 0;
}
/* The lead panel says so in type, not only in position. Six identical eyebrow
   titles meant the Phase 9 inversion was expressed by ordering alone — a reader
   arriving mid-scroll had nothing telling them which panel answers the
   question. `--font-display` at reading size is the treatment `analytics.css`
   uses to mark a block heading, so this costs no new vocabulary. */
#waIndexPanel > .wa-panel-head .wa-panel-title {
  font-family: var(--font-display); font-size: 0.98rem; font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--ink-strong);
}
.wa-panel-note { font-size: 0.74rem; color: var(--faint); }
/* The one sentence standing between the title and the first published number.
   Upright and `--mid`, not italic `--faint` — it is read, not skimmed past. */
.wa-lede {
  font-style: normal; color: var(--mid); margin-bottom: 4px;
}

/* The hero's published-value strip. Filled by the index panel, because the
   values arrive on that payload — see `heroValuesHtml`. Empty until then, and
   it collapses to nothing rather than reserving a gap, so a site with no
   published index does not get a blank band under its header. */
.wa-hero-values:empty { display: none; }
.wa-hero-values { margin: 12px 0 2px; }
.wa-hv-label {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--dim); margin-bottom: 5px;
}
.wa-hv-row { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.wa-hv { display: flex; flex-direction: column; gap: 1px; }
.wa-hv-name { font-size: 0.72rem; color: var(--mid); }
.wa-hv-val {
  font-family: var(--font-mono); font-size: 1.05rem; font-weight: 600;
  color: var(--ink-strong); font-variant-numeric: tabular-nums;
}
/* The unit that produced it, always. A site-level value with no device on it
   would be the pooled number the stats table one panel down exists to refuse. */
.wa-hv-sub { font-size: 0.68rem; color: var(--dim); }
/* The Forel-Ule step's own colour beside its number, off the same ramp the
   scale strip draws — the number alone names nothing to a first-time reader. */
.wa-hv-swatch {
  display: inline-block; width: 0.85em; height: 0.85em; border-radius: 2px;
  margin-right: 6px; vertical-align: -1px; border: 1px solid rgba(20, 23, 29, 0.14);
}

/* ── Section nav ───────────────────────────────────────────────────── */

/* Sticky, because the page is six panels and ~8000px: the hero's verdict names
   a day the ranked list holds four screens down, and a reader who scrolls has
   no map. No ancestor sets `overflow` (base.css gives body 100vh and the
   content overflows it), so the viewport is the scrollport and `top: 0` pins
   to it — an `overflow` on `.wa-wrap` or `.wa-body` would stop it. Painted in
   `--bg`, the page ground, so panels slide under it cleanly. */
.wa-jump {
  position: sticky; top: 0; z-index: 5;
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none;
  margin: -4px 0 12px; padding: 6px 0;
  background: var(--bg); border-bottom: 1px solid var(--line-soft);
}
.wa-jump::-webkit-scrollbar { display: none; }
.wa-jump a {
  font-size: 0.74rem; font-weight: 600; color: var(--mid); text-decoration: none;
  padding: 9px 11px; border-radius: var(--r-md); white-space: nowrap;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.wa-jump a:hover { color: var(--accent); background: var(--accent-fade); }
.wa-jump a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Anchored panels land under the sticky bar without this. */
.wa-panel { scroll-margin-top: 52px; }

/* ── 1. Site header ────────────────────────────────────────────────── */

.wa-hero { padding: 22px 24px; }
.wa-hero-line {
  font-size: 1.32rem; font-weight: 600; color: var(--ink-strong);
  letter-spacing: -0.01em; margin-bottom: 4px;
}
.wa-hero-state { font-weight: 700; }
.wa-hero-state.is-quiet   { color: var(--good); }
.wa-hero-state.is-notable { color: var(--warn); }
.wa-hero-state.is-unknown { color: var(--dim); }
.wa-hero-sub { font-size: 0.86rem; color: var(--mid); line-height: 1.55; }
.wa-hero-sub .wa-sep { color: var(--faint); margin: 0 7px; }
/* Each instrument's latest day is a link to that day. Underlined in the rule
   colour, not the accent: it is a date first and a control second. */
.wa-hero-date {
  color: inherit; text-decoration: underline;
  text-decoration-color: var(--line-strong); text-underline-offset: 2px;
}
.wa-hero-date:hover { color: var(--accent); text-decoration-color: currentColor; }
/* The one action the verdict implies. Inline after the "why" sentence so it
   reads as its consequence, in the same voice as the ranked rows' "open →". */
.wa-hero-open {
  font-weight: 600; color: var(--accent); text-decoration: none; white-space: nowrap;
  /* A larger hit area than the 17px text line, without moving the line. */
  display: inline-block; padding: 8px 0; margin: -8px 0;
}
.wa-hero-open:hover { text-decoration: underline; }
/* Why the headline word says what it says — the bar, the instrument and the day
   it came from, so the site header is traceable to the ranked list below it. */
.wa-hero-why {
  margin-top: 5px; font-size: 0.78rem; color: var(--dim);
  /* `pretty`, not `balance`: this runs to four lines and balance would even out
     every one of them. All that is wanted is no one-word last line, which is
     what it kept producing ("…answered / quietly"). */
  line-height: 1.5; max-width: 78ch; text-wrap: pretty;
}

.wa-instr-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.wa-instr {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 12px; border-radius: var(--r-md);
  background: var(--panel-alt); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--line-strong);
  min-width: 150px;
}
.wa-instr.is-mHR { border-left-color: var(--accent); }
.wa-instr.is-mFL { border-left-color: var(--imu); }
.wa-instr-name {
  font-size: 0.72rem; font-weight: 600; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.wa-instr-val { font-family: var(--font-mono); font-size: 0.9rem; color: var(--ink-strong); }
.wa-instr-val.is-grey  { color: var(--dim); }
.wa-instr-val.is-refus { color: var(--dim); font-size: 0.78rem; font-family: var(--font-ui); font-style: italic; }
.wa-instr-sub { font-size: 0.7rem; color: var(--dim); }

/* ── 1b. The range control ─────────────────────────────────────────── */

/* Ruled off from the site identity above it. The control governs the panels
   *below* this card, not the chips above it, and an unseparated row at the foot
   of the hero reads as one more fact about the site. */
.wa-range {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-soft);
}
.wa-range.is-busy { opacity: 0.55; }
.wa-range-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.wa-range-label {
  font-size: 0.72rem; font-weight: 600; color: var(--dim);
  text-transform: uppercase; letter-spacing: 0.05em;
}
/* The presets are one control, so they sit in one segmented group rather than
   as four loose buttons that happen to be adjacent. */
.wa-range-presets {
  display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden;
}
.wa-range-btn {
  font: inherit; font-size: 0.78rem; font-weight: 500;
  /* Padding-driven height, matching .wa-site-btn: these are primary controls on
     a touch surface and must clear the 44px floor. */
  padding: 12px 14px; min-height: 44px;
  border: none; border-right: 1px solid var(--line);
  background: var(--panel-alt); color: var(--mid); cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.wa-range-btn:last-child { border-right: none; }
.wa-range-btn:hover:not(:disabled) { background: var(--panel); color: var(--ink); }
.wa-range-btn.is-active { background: var(--accent); color: #fff; }
.wa-range-btn:disabled { cursor: default; }
.wa-range-custom {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.74rem; color: var(--dim);
}
.wa-range-custom input[type="date"] {
  font: inherit; font-size: 0.8rem; padding: 5px 8px; min-height: 44px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--panel-alt); color: var(--ink);
}
.wa-range-apply { font-size: 0.78rem; padding: 11px 14px; }
.wa-range-msg { font-size: 0.74rem; color: var(--warn); }
/* The sentence that names which panels this moves. Prose measure, because the
   one panel it does *not* govern — the ranked list, which counts back from
   today — is on the same page and nothing else distinguishes them. */
.wa-range-sub {
  margin-top: 8px; font-size: 0.74rem; color: var(--dim);
  line-height: 1.55; max-width: 78ch;
}

.wa-range-btn:focus-visible,
.wa-range-custom input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* ── 3. Days worth a look ──────────────────────────────────────────── */

.wa-attn-list { display: flex; flex-direction: column; gap: 1px; }
/* An `<a href>`, not a button: `color`/`text-decoration` are reset here because
   the row inherits neither the way the old <button> did. */
.wa-attn {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 10px; border-radius: var(--r-md);
  background: transparent; border: 1px solid transparent;
  cursor: pointer; text-align: left; font: inherit; width: 100%;
  color: inherit; text-decoration: none;
  transition: background var(--t-fast) var(--ease);
}
.wa-attn:hover { background: var(--accent-fade); border-color: var(--line-soft); }
.wa-attn-date {
  font-family: var(--font-mono); font-size: 0.82rem; font-weight: 600;
  color: var(--ink-strong); min-width: 72px;
}
.wa-attn-instr {
  font-size: 0.74rem; font-weight: 600; padding: 2px 7px;
  border-radius: var(--r-sm); white-space: nowrap;
}
.wa-attn-instr.is-mHR { background: var(--accent-soft); color: var(--accent-strong); }
.wa-attn-instr.is-mFL { background: var(--imu-bg); color: var(--imu); }
.wa-attn-rank { font-size: 0.84rem; color: var(--ink); }
.wa-attn-rank b { font-weight: 700; }
/* The same rule `.wa-reason` below states and this one was breaking: a filled
   tint behind a secondary line out-weighs the two axes above it that carry the
   numbers the row is ranked on. `--panel-sunken` (#cdd2da) made the other
   regime's reading the darkest thing in every row. Raised chrome + a rule
   instead — still a chip, no longer the loudest one. */
.wa-attn-tag {
  font-size: 0.72rem; font-style: italic; color: var(--mid);
  padding: 2px 7px; border-radius: var(--r-sm);
  background: var(--panel-alt); border: 1px solid var(--line-soft);
}
.wa-attn-floor { font-size: 0.72rem; color: var(--dim); }
.wa-attn-open { margin-left: auto; font-size: 0.76rem; color: var(--accent); font-weight: 600; }

/* The two ranking axes. Stacked below 900px, where two columns would turn both
   sentences into fragments; side by side above it, where each column is
   ~600px and a row of the list is one screen-line of question, one bar, one
   sentence per axis. Measured: stacked at 1440px the six rows ran 1750px.
   `flex-basis: 100%` breaks the row so the axes never share a line with the
   date/instrument chips above them. */
.wa-axes { flex-basis: 100%; display: flex; flex-direction: column; gap: 5px; }
@media (min-width: 900px) {
  .wa-axes { flex-direction: row; gap: 28px; }
  .wa-axis { flex: 1 1 0; min-width: 0; }
}
.wa-axis { font-size: 0.84rem; color: var(--ink); line-height: 1.45; }
.wa-axis b { font-weight: 700; }
/* The percentile as a length. The sentence beside it still carries the angle
   and the count (every rank carries the quantity it ranks); the bar is what
   lets a reader compare six rows without reading six sentences. Capped at
   320px so it is a gauge, not a full-width progress bar. */
.wa-axis-bar {
  display: block; height: 4px; width: 100%; max-width: 320px;
  background: var(--line-soft); border-radius: 2px; margin: 2px 0 5px; overflow: hidden;
}
.wa-axis-bar i { display: block; height: 100%; background: var(--dim); border-radius: 2px; }
.wa-axis.is-lead .wa-axis-bar i { background: var(--accent); }
/* The axis that put this day on the list. A left rule rather than a background:
   two stacked tinted blocks read as a table, and only one of the two is ever
   the lead. */
.wa-axis.is-lead {
  border-left: 2px solid var(--accent); padding-left: 8px; margin-left: -10px;
}
.wa-axis-q {
  display: block; font-size: 0.7rem; letter-spacing: 0.02em;
  text-transform: lowercase; color: var(--dim); margin-bottom: 1px;
}

/* What moved — the reason, one line, below the axes.
   A rule and a marker rather than a filled bar: a full-width tint behind a
   nine-word sentence out-weighs the two axes above it, which carry the numbers
   the row is ranked on. */
.wa-reason {
  flex-basis: 100%; font-size: 0.78rem; color: var(--ink);
  padding-left: 14px; position: relative;
}
.wa-reason::before {
  content: ""; position: absolute; left: 2px; top: 0.45em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--mid);
}
.wa-reason.is-quiet { color: var(--dim); font-style: italic; }
.wa-reason.is-quiet::before { background: var(--line); }
.wa-reason.is-named::before { background: var(--accent); }
.wa-reason b { font-weight: 700; }
.wa-reason-caveat { display: block; font-size: 0.7rem; color: var(--dim); font-style: italic; }

/* ── 2 + 4. Charts ─────────────────────────────────────────────────── */

.wa-chart { width: 100%; height: 320px; }
.wa-chart.is-spectra { height: 300px; }
.wa-chart-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }

.wa-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; font-size: 0.75rem; color: var(--mid); }
.wa-legend-item { display: flex; align-items: center; gap: 6px; }
.wa-swatch { width: 12px; height: 3px; border-radius: 2px; background: var(--dim); }
.wa-swatch.is-mHR { background: var(--accent); }
.wa-swatch.is-mFL { background: var(--imu); }
.wa-swatch.is-refusal { background: var(--bad); width: 8px; height: 8px; border-radius: 50%; }

/* ── 5. Band strip ─────────────────────────────────────────────────── */

/* Grid, not flex: mHR contributes two bands and mFL five, and `flex: 1 1`
   stretched the two into half-width slabs next to the five compact ones. A
   fixed track keeps a band the same size whichever instrument it came from. */
.wa-bands {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
}
.wa-band {
  padding: 10px 12px; border-radius: var(--r-md);
  background: var(--panel-alt); border: 1px solid var(--line-soft);
}
.wa-band.is-diagnostic { opacity: 0.72; }
.wa-band-label { font-size: 0.78rem; font-weight: 600; color: var(--ink); }
.wa-band-nm { font-size: 0.68rem; color: var(--faint); font-family: var(--font-mono); }
.wa-band-delta {
  font-family: var(--font-mono); font-size: 1.02rem; font-weight: 600;
  margin-top: 5px; color: var(--mid);
}
/* Direction is colour-neutral, and deliberately so: the arrow carries the sign.
   Painting "up" alarm-red and "down" reassuring-teal applies one verdict to
   bands whose physical meaning is opposite — a *quenched* (down) water Raman is
   the oil signal (§2.6), so the discriminator would have been rendered
   inverted. Colour here would be a threshold-free warning smuggled in through
   CSS; the reader gets the number and the pattern sentence instead. */
.wa-band-delta.is-up,
.wa-band-delta.is-down { color: var(--ink); }
.wa-band-delta.is-flat { color: var(--dim); }
.wa-band-refusal {
  margin-top: 5px; font-size: 0.74rem; font-style: italic; color: var(--dim);
}
.wa-band-sub { font-size: 0.68rem; color: var(--dim); margin-top: 3px; }

/* Panel tint, not warn tint. Every named pattern landed in a warning-coloured
   box, including "consistent with a bloom" — the paragraph already says
   "consistent with", and it should not also shout. */
.wa-pattern {
  margin-top: 12px; padding: 10px 12px; border-radius: var(--r-md);
  background: var(--panel-alt); border: 1px solid var(--line-soft);
  font-size: 0.82rem; color: var(--ink); line-height: 1.5;
}
.wa-pattern b { font-weight: 700; }
/* The un-named reading — a level move, or a largest-move with no pattern
   attached — has to read as *quieter* than the named claim, not louder.
   `--panel-sunken` is base.css's inset-chip token (#cdd2da); on a 140px-tall
   paragraph it made the page's least assertive verdict its darkest block, so
   the three verdict weights ran backwards: no pattern → no box, "consistent
   with a bloom" → light box, "no named pattern" → slab. Every other use of the
   token in this file is a chip under 26px.

   Unfilled, keeping the base rule — never dashed: dashed-grey is this
   section's "we looked and there was nothing" box (`.wa-empty`), and this is a
   stated reading, not an absence. */
.wa-pattern.is-plain { background: transparent; color: var(--mid); }
.wa-pattern-none {
  margin-top: 12px; font-size: 0.78rem; color: var(--dim); font-style: italic;
}

/* The ratio channels and the bar each was measured against — the evidence the
   verdict below them is built on. One row per channel, value right-aligned, so
   the marks line up and a reader can scan which one is over. */
.wa-channels { margin-top: 12px; display: flex; flex-direction: column; gap: 2px; }
.wa-ch {
  display: flex; align-items: baseline; gap: 10px; justify-content: space-between;
  padding: 3px 8px 3px 10px; border-radius: var(--r-sm); font-size: 0.78rem;
  border-left: 2px solid transparent;
}
/* Over the bar is marked on the rule and the figure, not by a wash: measured,
   `--accent-fade` (#f0f5f5) against this panel is a ~2% luminance step and was
   indistinguishable from the un-tinted row beside it. */
.wa-ch.is-over { background: var(--accent-soft); border-left-color: var(--accent); }
.wa-ch.is-over .wa-ch-v { color: var(--accent); font-weight: 600; }
.wa-ch-k { color: var(--mid); }
/* Tabular figures so the percentages form a column rather than a ragged edge —
   these are read against each other, which is the whole point of the strip. */
.wa-ch-v { color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; }
.wa-ch-bar { color: var(--dim); font-size: 0.72rem; }

/* The withdrawn oil/runoff readings. Collapsed, but present: this page carried
   the claim, so this page carries the correction. */
/* A small aside behind a disclosure: the oil retraction, the daylight
   fluorescence mechanism. Named for its role, not its first use. */
.wa-aside { margin-top: 10px; font-size: 0.76rem; color: var(--dim); }
/* Shares the Layer-2 summary shape rather than re-rolling one. On its own it
   drew the native ▶ marker in `--mid` at 18px tall, so the panel offered two
   different expander affordances and this one missed the 44px touch target
   every other expander on the page meets. */
.wa-aside > summary {
  cursor: pointer; font-size: 0.76rem; font-weight: 600; color: var(--accent);
  padding: 10px 2px; list-style: none; min-height: 44px;
  display: flex; align-items: center; gap: 6px;
}
.wa-aside > summary::-webkit-details-marker { display: none; }
.wa-aside > summary::before {
  content: '▸'; font-size: 0.7rem; color: var(--dim);
  transition: transform var(--t-fast) var(--ease);
}
.wa-aside[open] > summary::before { transform: rotate(90deg); }
.wa-aside > summary:hover { color: var(--accent-strong); }
.wa-aside > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wa-aside > div { margin-top: 6px; line-height: 1.5; max-width: 78ch; }
.wa-aside b { font-weight: 700; color: var(--ink); }

/* mHR's OWT histogram — a class tally, never a mean (nominal classes). */
.wa-owt { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.wa-owt-chip {
  font-family: var(--font-mono); font-size: 0.72rem;
  padding: 2px 7px; border-radius: var(--r-sm);
  background: var(--panel-sunken); color: var(--ink);
}
.wa-owt-chip.is-new { background: var(--warn-bg); color: var(--warn); font-weight: 600; }

/* ── Layer 2 — the evidence expansions ─────────────────────────────── */

/* One expander shape for all five, so "there is more under this panel" is a
   single learned affordance rather than five. Bodies are built on first open —
   see water.js — which is also why nothing here may assume a measured height. */
.wa-l2 { margin-top: 14px; border-top: 1px solid var(--line-soft); }
.wa-l2 > summary {
  cursor: pointer; font-size: 0.76rem; font-weight: 600; color: var(--accent);
  padding: 10px 2px; list-style: none; min-height: 44px;
  display: flex; align-items: center; gap: 6px;
}
.wa-l2 > summary::-webkit-details-marker { display: none; }
.wa-l2 > summary::before {
  content: '▸'; font-size: 0.7rem; color: var(--dim);
  transition: transform var(--t-fast) var(--ease);
}
.wa-l2[open] > summary::before { transform: rotate(90deg); }
.wa-l2 > summary:hover { color: var(--accent-strong); }
.wa-l2 > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wa-l2-body { padding: 4px 0 6px; }
.wa-l2-block { margin-bottom: 20px; }
.wa-l2-block:last-child { margin-bottom: 0; }
.wa-l2-sub { margin-top: 12px; }

.wa-chart.is-degrees { height: 240px; }
.wa-chart.is-index   { height: 200px; }

/* ── 2. Published parameters (the lead panel since Phase 9) ────────── */

/* The instrument band. §2.4: the parameter set is disjoint by instrument —
   mFL publishes three scalars and no class, mHR two classes and no scalar, and
   they never overlap. Rendering the five as peers made that something a reader
   had to infer from which charts came out empty; a labelled rule makes it the
   panel's structure. */
.wa-idx-instr {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px;
  margin: 22px 0 4px; padding-top: 12px; border-top: 1px solid var(--line);
}
.wa-idx-instr:first-of-type { margin-top: 10px; padding-top: 0; border-top: 0; }
.wa-idx-instr-name { margin: 0; font-size: 0.9rem; font-weight: 600; color: var(--ink); }
/* --mid, not --dim: this states the instrument's coverage for the window, which
   is what separates "measured nothing unusual" from "was not here". A
   load-bearing sentence does not get decorative contrast (issues.md
   #faint-token-fails-wcag). */
.wa-idx-instr-sub { font-size: 0.78rem; color: var(--mid); }

.wa-idx { margin-top: 14px; }
.wa-idx:first-of-type { margin-top: 8px; }
.wa-idx-name {
  font-size: 0.84rem; font-weight: 600; color: var(--ink); margin-bottom: 4px;
}
/* An index the instrument reported on and never published. Held in the flow
   with its own coverage table rather than collapsed into a footnote — it is a
   statement about the processing, and the footnote read as "no data".
   Deliberately carries **no** `opacity` — dimming it by 15% was the footnote
   gesture this comment exists to reject, and the box below already reads as a
   different state.

   Solid with a `--warn` edge, against `.wa-empty`'s dashed grey. The panel's
   whole thesis is that "the instrument was never here" and "the instrument was
   here every day and published nothing" are different claims, and until this
   rule existed the two rendered in the same box ~200px apart. Dashed grey keeps
   its meaning — absence of the instrument — and the processing gap gets the
   note idiom, because it is a statement someone should act on. */
.wa-empty.is-published-none {
  border-style: solid; border-color: var(--line);
  border-left: 3px solid var(--warn);
  color: var(--ink);
}
.wa-idx-sub { margin-top: 10px; }
/* The per-device chart caption is the only thing telling two otherwise
   identical stacked charts apart, so it takes `--mid` like every other
   load-bearing sentence in this panel. Scoped rather than changing
   `.wa-panel-note` itself, which is the section-wide `--faint` question logged
   in issues.md#faint-token-fails-wcag and settled separately. */
.wa-idx-sub .wa-panel-note { color: var(--mid); }
.wa-idx-none { color: var(--mid); font-style: italic; }

/* The window statistics. One row per device, never one per index: two units of
   one type are two calibrations whose levels differ by more than the trend
   does, so a pooled site figure would describe neither. */
.wa-idx-stats {
  width: 100%; border-collapse: collapse; margin: 6px 0 8px;
  font-size: 0.78rem;
  /* Its own minimum, so the scroll wrapper has something to scroll rather than
     crushing four prose columns into unreadable slivers. */
  min-width: 460px;
  /* Fixed, with the widths declared here rather than left to the content. Five
     of these tables stack in one panel and auto layout sized each to its own
     longest cell — the four column heads drifted up to 133px between adjacent
     tables, on the axis the reader scans straight down. */
  table-layout: fixed;
}
.wa-idx-stats col.c-dev  { width: 15%; }
.wa-idx-stats col.c-cov  { width: 20%; }
.wa-idx-stats col.c-now  { width: 30%; }
.wa-idx-stats col.c-vs   { width: 35%; }
/* `tabular-nums` for the same reason the Layer-2 tables use it: these rows are
   read by comparing one device against another down a column, and proportional
   digits make the medians fail to line up on the decimal point. */
.wa-idx-stats td.wa-mono, .wa-idx-delta { font-variant-numeric: tabular-nums; }
.wa-idx-stats th {
  text-align: left; font-weight: 500; color: var(--mid);
  /* `--line`, not `--line-soft`: the header shared the body rows' rule and was
     separated from them by colour alone, so it read as a fifth row. Matches
     `.wa-table th` one expander away. */
  border-bottom: 1px solid var(--line); padding: 3px 10px 4px 0;
  /* Top, not the inherited middle — the fourth head carries a second line (the
     compared span), and centring left the other three sitting ~6px below its
     first line. Four labels on two baselines. */
  vertical-align: top;
}
.wa-idx-stats td {
  padding: 5px 10px 5px 0; vertical-align: baseline; color: var(--ink);
  border-bottom: 1px solid var(--line-soft);
}
.wa-idx-stats tr:last-child td { border-bottom: 0; }
/* The compared span, under its own column head. `--mid`, not `--dim`: which
   months are being compared is what tells a seasonal step from a real one. */
.wa-idx-th-sub {
  display: block; font-weight: 400; font-size: 0.72rem; color: var(--mid);
}
/* Weight, not colour. `--warn` measures 3.88:1 on `--panel` and this cell is
   body text, not a badge — and the emphasis is redundant anyway, since the cell
   already reads "0 of 61 reported days". */
.wa-idx-stats td.is-partial { font-weight: 600; }
.wa-idx-delta { font-family: var(--font-mono); font-weight: 600; }
.wa-mono { font-family: var(--font-mono); }
/* The trailing value, stated rather than left to be read off the end of the
   line. Baseline-aligned so the number and its provenance sit on one line and
   the eye does not have to travel to find out which day it belongs to. */
.wa-idx-latest {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  margin: 2px 0 4px;
}
.wa-idx-val {
  font-family: var(--font-mono); font-size: 1.05rem; font-weight: 600;
  color: var(--ink-strong);
}
.wa-idx-share { font-family: var(--font-ui); font-size: 0.78rem; font-weight: 400; color: var(--dim); }
.wa-idx-when { font-size: 0.72rem; color: var(--dim); }

/* Linear/log. Sits above its own chart rather than in a page-level toolbar:
   the setting is per series, and one shared control would silently rescale
   charts the reader is not looking at. */
/* Left, not right: Plotly's modebar owns the chart's top-right corner, and two
   control clusters in one corner read as one confused cluster. */
.wa-scale-toggle {
  display: flex; gap: 0; margin: 0 auto 4px 0; width: max-content;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden; background: var(--panel-alt);
}
.wa-scale-btn {
  font: inherit; font-size: 0.7rem; font-weight: 500; letter-spacing: 0.02em;
  /* Shorter than .wa-range-btn — this is a per-chart control, and six of them at
     the full 44px would add more chrome than chart. It still takes the 44px
     touch floor at the mobile breakpoint below, where the floor is for. */
  padding: 6px 11px; min-height: 30px;
  border: 0; background: transparent; color: var(--dim);
  cursor: pointer; transition: background var(--t-fast) var(--ease),
                               color var(--t-fast) var(--ease);
}
.wa-scale-btn + .wa-scale-btn { border-left: 1px solid var(--line); }
.wa-scale-btn:hover { background: var(--panel); color: var(--ink); }
/* Same selected-segment treatment as .wa-range-btn.is-active. The page already
   says what a chosen segment looks like; a second answer to that on the same
   screen is drift, not variety. */
.wa-scale-btn.is-on { background: var(--accent); color: #fff; }
.wa-scale-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* The Forel-Ule comparator, printed under the chart it explains. This is the
   scale a field observer holds against the water, so it is the one legend on
   the page that needs no key of its own. */
.wa-fu-scale { margin: 6px 0 2px; }
.wa-fu-strip {
  display: grid; grid-template-columns: repeat(21, 1fr); gap: 1px;
  border-radius: var(--r-sm); overflow: hidden;
}
.wa-fu-step { height: 13px; }
/* Which classes this window actually held. An inset ring rather than a border,
   so marking a step does not change the width of the step next to it. */
.wa-fu-step.is-present {
  box-shadow: inset 0 0 0 1.5px var(--panel), inset 0 0 0 3px var(--ink-strong);
}
/* OWT's key. Same slot and same weight as the Forel-Ule strip so the two
   histogram panels read as siblings, even though their colours mean opposite
   things — which is exactly what the note underneath is there to say. */
.wa-owt-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
  margin: 6px 0 2px;
}
.wa-owt-key {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 0.7rem; color: var(--mid); white-space: nowrap;
}
.wa-owt-key i {
  width: 11px; height: 11px; border-radius: 2px; flex: none;
  box-shadow: inset 0 0 0 1px rgba(30, 40, 60, 0.12);
}
.wa-owt-key i.is-rest { background: var(--dim); opacity: 0.45; }
.wa-owt-key b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.wa-owt-note {
  flex-basis: 100%; font-size: 0.66rem; color: var(--dim);
  max-width: 62ch; text-wrap: balance;
}

.wa-fu-ends {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: 0.66rem; color: var(--dim); margin-top: 3px;
}
.wa-fu-ends span:nth-child(2) { color: var(--faint); }
@media (max-width: 560px) {
  /* Three labels do not fit a phone; the ends are the ones that carry the
     scale's direction, so the middle one goes rather than wrapping. */
  .wa-fu-ends span:nth-child(2) { display: none; }
  /* The touch floor .wa-range-btn documents, applied where touch happens. */
  .wa-scale-btn { min-height: 44px; padding: 12px 16px; }
  /* 21 steps across a phone is ~15px each; the gaps cost more than they give. */
  .wa-fu-strip { gap: 0; }
}

/* Four prose columns never fit a phone. The scroll box was technically lossless
   — the content was reachable — but macOS overlay scrollbars give it no
   affordance, so 42% of the column carrying the verdict was hidden by default
   and what showed was truncated mid-word: `75 nov` for "75 now", `vs the
   previous 9` for 91. A cut word is worse than a wrapped one, because it still
   reads as a word. Stacked per-device blocks instead, the same call
   `.wa-facts` already makes at this width. */
@media (max-width: 560px) {
  .wa-idx-stats { min-width: 0; table-layout: auto; }
  .wa-idx-stats colgroup, .wa-idx-stats thead { display: none; }
  .wa-idx-stats tr {
    display: block; padding: 8px 0;
    border-bottom: 1px solid var(--line-soft);
  }
  .wa-idx-stats tr:last-child { border-bottom: 0; }
  .wa-idx-stats td {
    display: block; padding: 1px 0; border-bottom: 0;
  }
  /* The column head, carried on the cell. Without it a stacked row is four
     unlabelled fragments — and two of these columns count different things
     (experiments and days), which is exactly what the head disambiguates. */
  .wa-idx-stats td[data-label]::before {
    content: attr(data-label); display: block;
    /* Explicit, not inherited: the median cell is `.wa-mono`, and a column head
       set in the data font reads as another value. */
    font-family: var(--font-ui); font-weight: 500;
    font-size: 0.68rem; color: var(--mid); text-transform: uppercase;
    letter-spacing: 0.04em; margin-top: 4px;
  }
  .wa-idx-stats td:first-child {
    font-weight: 600; font-family: var(--font-mono); font-size: 0.8rem;
  }
  .wa-idx-stats td:first-child::before { content: none; }
}
/* Same word the chart draws hollow, in the same colour family — a reader who
   matched the two should not have to check whether they mean the same thing. */
.wa-idx-old { font-size: 0.7rem; color: var(--warn); }
/* The per-point tables run the length of the window, so they scroll in their own
   box rather than pushing the panel below the fold on a wide range. */
.wa-table-scroll.is-tall { max-height: 340px; overflow-y: auto; }

/* Data tables. `tabular-nums` on the numeric columns so a column of magnitudes
   lines up on the decimal point — these are read by comparing rows, and
   proportional digits make that a slower read than it needs to be. */
.wa-table {
  width: 100%; border-collapse: collapse; margin-top: 8px;
  font-size: 0.78rem; color: var(--ink);
}
/* Scoped to the table so the charts beside it stay at the viewport width
   instead of being dragged out to the table's. */
.wa-table-scroll { overflow-x: auto; max-width: 100%; }
.wa-table th {
  text-align: left; font-size: 0.68rem; font-weight: 600; color: var(--dim);
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 6px 10px 6px 0; border-bottom: 1px solid var(--line);
  vertical-align: bottom;
}
.wa-table td {
  padding: 8px 10px 8px 0; border-bottom: 1px solid var(--line-soft);
  vertical-align: top; line-height: 1.45;
}
.wa-table tr:last-child td { border-bottom: none; }
.wa-table .is-num, .wa-table th.is-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
}
.wa-table th.is-num { font-family: var(--font-ui); }
.wa-table a { color: var(--accent); font-family: var(--font-mono); }
/* Stored but never drawn (§2.4). Dimmed rather than hidden: a scientist who
   cannot see the row has no way to tell "not measured" from "not shown". */
.wa-table tr.is-unsurfaced td { opacity: 0.66; }

.wa-faint { font-size: 0.68rem; color: var(--faint); line-height: 1.45; font-weight: 400; }
.wa-table td b { font-weight: 600; }

/* Definition list for the per-day facts — two columns on desktop, stacked on
   mobile, so a term is never orphaned from its value. */
.wa-facts {
  display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px;
  margin: 10px 0 0; font-size: 0.78rem;
}
.wa-facts dt { font-weight: 600; color: var(--dim); }
.wa-facts dd { margin: 0; color: var(--ink); max-width: 72ch; }

/* ── 5. Day notes ──────────────────────────────────────────────────── */

.wa-note-form { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.wa-note-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.wa-note-form textarea {
  font: inherit; font-size: 0.84rem; padding: 8px 10px; resize: vertical;
  min-height: 62px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--panel-alt); color: var(--ink);
}
.wa-note-form textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.wa-note-form select, .wa-note-form input[type="date"] {
  font: inherit; font-size: 0.8rem; padding: 5px 8px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--panel-alt); color: var(--ink);
}
.wa-btn {
  font: inherit; font-size: 0.8rem; font-weight: 600; padding: 11px 16px;
  min-height: 44px;
  border-radius: var(--r-md); border: 1px solid var(--accent);
  background: var(--accent); color: #fff; cursor: pointer;
}
.wa-btn:hover { background: var(--accent-strong); }
.wa-btn:disabled { opacity: 0.5; cursor: default; }
.wa-btn.is-ghost { background: transparent; color: var(--mid); border-color: var(--line); }
.wa-btn.is-ghost:hover { background: var(--panel-alt); color: var(--ink); }
/* An anchor styled as a button is still an inline box, and `min-height` does
   not apply to one (CSS 2.1 §10.7) — so every `<a class="wa-btn">` silently
   missed the 44px target the rule above exists to guarantee. The page's own
   error state was the worst case: its only way out was such an anchor. */
a.wa-btn { display: inline-flex; align-items: center; text-decoration: none; }

.wa-note {
  padding: 10px 12px; border-radius: var(--r-md); margin-bottom: 6px;
  background: var(--panel-alt); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--accent);
}
.wa-note-meta {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  font-size: 0.72rem; color: var(--dim); margin-bottom: 3px;
}
.wa-note-meta .wa-note-day { font-family: var(--font-mono); font-weight: 600; color: var(--ink); }
.wa-note-body { font-size: 0.86rem; color: var(--ink); line-height: 1.5; white-space: pre-wrap; }
.wa-note-del {
  margin-left: auto; font: inherit; font-size: 0.72rem; color: var(--dim);
  background: none; border: none; cursor: pointer;
  padding: 8px 10px; margin-top: -8px; margin-bottom: -8px;   /* 44px tap area, same visual box */
}
.wa-note-del:hover { color: var(--bad); }

/* ── Shared states ─────────────────────────────────────────────────── */

/* Refusals are a display state, not an empty div — every one of these carries
   its own reason in the text, never a blank panel (ROADMAP §6). */
.wa-empty {
  padding: 16px 14px; border-radius: var(--r-md);
  background: var(--panel-alt); border: 1px dashed var(--line);
  font-size: 0.84rem; color: var(--mid); line-height: 1.55;
}
.wa-empty b { color: var(--ink); font-weight: 600; }
/* A refusal standing in for a chart fills the chart's box. Measured: "Not
   published on this day." drew 55px inside a 344px grid cell, leaving a quarter
   of the 2×2 grid blank and the live charts beside it reading as a broken row.
   `.wa-chart` already carries the height; the box just has to take it. */
.wa-chart > .wa-empty {
  height: 100%; display: flex; align-items: center; box-sizing: border-box;
}

/* Column, not a run of inline content: the action was `margin-left: 10px` on an
   inline button, so the sentence broke around it and left its last word
   stranded beside the control ("…rebuilt / since. [Back to Water]"). */
.wa-error {
  display: flex; flex-direction: column; align-items: flex-start; gap: 12px;
  padding: 14px 16px; border-radius: var(--r-md);
  background: var(--bad-bg); border: 1px solid var(--bad);
  font-size: 0.84rem; color: var(--ink); line-height: 1.55; max-width: 78ch;
}

/* These carry the page's honesty caveats, so they have to be readable prose,
   not a 150-character single line spanning the full card. */
.wa-grey-note {
  font-size: 0.74rem; color: var(--dim); margin-top: 8px; font-style: italic;
  max-width: 68ch; line-height: 1.55;
}
.wa-empty, .wa-pattern, .wa-pattern-none, .wa-method-body { max-width: 78ch; }

/* The custom buttons drop the UA outline the moment a background is set, so
   the keyboard ring is declared explicitly rather than inherited by luck. */
.wa-site-btn:focus-visible,
.wa-attn:focus-visible,
.wa-btn:focus-visible,
.wa-note-del:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.wa-method { margin-top: 4px; }
/* Two columns above 900px. The body was a 599px measure — about 93 characters,
   well past a comfortable line — sitting in a 1050px card, so the card read
   half-empty *and* the lines ran long. Columns fix both at once: ~60ch each,
   and the card is filled. */
.wa-method-body { max-width: 62ch; }
@media (min-width: 900px) {
  .wa-method-body { max-width: none; columns: 2; column-gap: 44px; }
  .wa-method-body > * { break-inside: avoid; }
}
.wa-method summary {
  cursor: pointer; font-size: 0.78rem; color: var(--mid); font-weight: 600;
  /* Full-bleed row, so width was never the problem — 4px padding left it
     26px tall. Padded rather than flex-centred: unlike .wa-l2 this summary
     uses the native disclosure marker, and display:flex suppresses it. */
  padding: 13px 0;
}
.wa-method summary:hover { color: var(--accent); }
.wa-method-body {
  font-size: 0.8rem; color: var(--mid); line-height: 1.6; padding: 10px 2px 2px;
}
.wa-method-body code {
  font-family: var(--font-mono); font-size: 0.76rem;
  background: var(--panel-sunken); padding: 1px 5px; border-radius: var(--r-sm);
}
.wa-method-body dt { font-weight: 600; color: var(--ink); margin-top: 8px; }
.wa-method-body dd { margin: 2px 0 0 0; }

/* ── Panel 3 — through the day ───────────────────────────────────────────
   The diurnal cut on the same published parameters. It reuses panel 2's
   sub-heading and empty-state idioms rather than inventing a second visual
   language for "here is a parameter and a chart of it" — the two panels sit
   adjacent and a reader scrolling from one to the other should not have to
   re-learn where the name of the thing is. */
.wa-diu { margin: 2px 0 18px; }
.wa-diu + .wa-diu { border-top: 1px solid var(--line-soft); padding-top: 14px; }
.wa-diu-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 2px;
}
.wa-diu-name { font-weight: 600; font-size: 0.88rem; color: var(--ink-strong); }
/* The reference signal is labelled, not coloured differently: it is the same
   instrument and the same kind of measurement, and Phase 7's rule is that
   chart colour belongs to the measurand. What sets it apart is what it is FOR,
   which is a word, not a hue. */
.wa-diu-tag {
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--warn);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 1px 6px;
}
.wa-diu-units { display: flex; gap: 0; margin-left: auto; }
/* Same selected-segment treatment as .wa-scale-btn — one answer on the page to
   "this segment is chosen", not a third. */
.wa-chip {
  font: inherit; font-size: 0.7rem; font-weight: 500;
  padding: 6px 10px; min-height: 30px;
  border: 1px solid var(--line); background: var(--panel-alt); color: var(--dim);
  cursor: pointer; transition: background var(--t-fast) var(--ease),
                               color var(--t-fast) var(--ease);
}
.wa-chip:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.wa-chip:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.wa-chip + .wa-chip  { border-left: 0; }
.wa-chip:hover { background: var(--panel); color: var(--ink); }
.wa-chip.is-on { background: var(--accent); color: #fff; border-color: var(--accent); }
.wa-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The day count is the reason to pick one unit over the other, so it travels
   with the id rather than living in a tooltip. */
.wa-diu-days { font-family: var(--font-mono); opacity: 0.75; }

.wa-diu .wa-chart { height: 210px; }
/* The panel's conclusion, and the only line in it a reader can act on — so it
   gets --ink and a rule, not the grey every other note takes. */
.wa-diu-verdict {
  color: var(--ink); border-left: 2px solid var(--line);
  padding-left: 9px; margin-top: 6px;
}
/* The one note that changes how the three charts ABOVE it are read, printed
   under the signal they are ratios to. --warn edge for the same reason
   .wa-empty.is-published-none has one: it is a statement someone should act on
   before believing the charts, not a footnote. */
.wa-diu-ref {
  color: var(--ink); border-left: 3px solid var(--warn);
  padding-left: 9px; margin-top: 6px;
}
/* A result, not an empty state — the class genuinely did not move. It reads as
   a statement rather than as the dashed "nothing here" box, which would say the
   opposite of what was measured. */
.wa-diu-flat {
  font-size: 0.82rem; color: var(--ink); line-height: 1.55;
  background: var(--panel-alt); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); padding: 10px 12px; margin: 4px 0 2px;
}

/* Placed AFTER `.wa-chip`, not with the other 560px rules further up the file:
   these overrides and the base rule have the same specificity, so source order
   is the whole tie-break. Sitting above the base rule they parsed fine, matched
   at 390px, and were silently overwritten — measured 30px tall on a phone. */
@media (max-width: 560px) {
  /* Same touch floor as .wa-scale-btn, and for the same reason. */
  .wa-chip { min-height: 44px; padding: 12px 14px; }
  /* `margin-left: auto` pushes the unit picker to the right of the parameter
     name, which on a phone leaves it stranded on its own line half off the
     head. Below the name, full width, is where a two-item choice belongs. */
  .wa-diu-units { margin-left: 0; width: 100%; }
  .wa-diu-units .wa-chip { flex: 1 1 0; justify-content: center; }
}

@media (max-width: 720px) {
  .wa-wrap { padding: 20px 14px 48px; }
  .wa-chart-grid { grid-template-columns: 1fr; }
  .wa-hero-line { font-size: 1.12rem; }
  /* The instrument table is seven columns wide and will not usefully reflow, so
     it scrolls inside itself rather than pushing the page sideways. Scoped to
     the table, not to the whole L2 body, so the charts beside it stay at the
     viewport width instead of being dragged out to the table's. */
  /* The scroll lives on the wrapper, never on the table. Setting the table to
     `display: block` and its thead/tbody to `display: table` makes head and body
     two independent table boxes, so their columns size separately — measured up
     to 56px of drift on the 7-column panel-1 table, i.e. headers pointing at the
     wrong column on the one table whose whole job is reading down a column. */
  .wa-table { min-width: 560px; }
  .wa-facts { grid-template-columns: 1fr; gap: 2px 0; }
  .wa-facts dt { margin-top: 8px; }
}

/* Phase 11 surfaces at phone width. Declared at the END of the file on purpose:
   these override base rules that appear earlier, and an equal-specificity
   media block placed ABOVE its base rule is dead CSS — the exact failure that
   left the touch-target rule inert in Phase 10. */
@media (max-width: 560px) {
  /* The label/value split needs ~34 characters of label and a 12-character
     value on one line; at 390px that is 2+2 wrapped lines and a ragged right
     edge on the one strip whose job is reading down a column. Stacked, the
     figure sits under its own label and the marks still align left. */
  .wa-ch { flex-direction: column; align-items: stretch; gap: 1px; padding-top: 5px; padding-bottom: 5px; }
  .wa-ch-v { text-align: left; }
  /* The lead rule hangs into the row's own padding at desktop width; at phone
     width there is none to hang into. */
  .wa-axis.is-lead { margin-left: 0; }
  /* Same 44px touch floor as every other control on the page. */
  .wa-jump a { padding: 13px 11px; }
  .wa-panel { scroll-margin-top: 60px; }
  /* Two values per row, not four stacked blocks 130px each. */
  .wa-hv-row { gap: 10px 16px; }
  .wa-hv { flex: 1 1 40%; min-width: 0; }
}

/* Informational text must remain readable outdoors on both Water pages.
   Scope token corrections here rather than changing the viewer's app shell. */
.wa-wrap { --faint: var(--mid); --dim: var(--mid); }
.wa-wrap .back-link { min-height: 44px; display: inline-flex; align-items: center; }
.wa-wrap .wa-panel-title { text-transform: none; letter-spacing: 0; color: var(--ink); font-size: 1rem; }
.wa-wrap .wa-grey-note { font-style: normal; }
.wa-wrap .wa-instr-sub { color: var(--mid); }

/* Alert evidence is selected and explained in place, without relying on colour. */
.wa-alert-focus { border-left: 3px solid var(--accent); background: var(--panel-alt); padding: 16px; margin: 12px 0; min-width: 0; }
.wa-alert-focus h3 { font-size: 16px; margin: 8px 0; }
.wa-alert-focus p { font-size: 14px; line-height: 1.6; margin: 8px 0 14px; }
.wa-alert-label { font-size: 13px; font-weight: 600; color: var(--accent); }
.wa-alert-context { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 16px; }
#wdAlertEvidence[hidden] { display: none; }

/* Visual keys sit outside Plotly so they wrap instead of covering the data. */
.wa-chart-key { display:flex; flex-wrap:wrap; gap:10px 24px; margin:12px 0; font-size:.82rem; color:var(--mid); }
.wa-chart-key > span { display:inline-flex; align-items:center; gap:9px; }
.wa-chart-key i { display:inline-block; flex:none; width:30px; color:var(--key-colour); }
.wa-key-line { border-top:2px solid currentColor; }
.wa-key-thick { border-top:4px solid currentColor; }
.wa-key-dash { border-top:2px dotted currentColor; }
.wa-chart-key .wa-key-dot { width:9px; height:9px; margin:0 10px; border-radius:50%; background:currentColor; }
.wa-key-band { height:14px; background:var(--key-colour); opacity:.2; }
.wa-calculation { display:flex; flex-wrap:wrap; gap:14px; padding:0; margin:14px 0 22px; list-style:none; color:var(--mid); font-size:.84rem; }
.wa-calculation li { flex:1 1 180px; border-left:2px solid var(--line); padding:6px 12px; }
.wa-calculation b, .wa-calculation span { display:block; }
.wa-calculation span { margin-top:5px; line-height:1.5; }
.wa-sensor-chart + .wa-sensor-chart { border-top:1px solid var(--line); padding-top:20px; margin-top:24px; }
.wa-status-reasons { display:grid; gap:10px; margin:18px 0; padding:0; list-style:none; color:var(--mid); font-size:.88rem; }
.wa-status-reasons strong { display:block; margin-bottom:4px; color:var(--ink); }
