/* ============================================================
   Section detail — page-scoped CSS
   Loaded by pages/section.html. Design source:
   design/Round-3-Screens.html §02 (desktop + mobile, light).
   Reuses tokens, .pill, .btn, .grade-chip from components.css.
   ============================================================ */

.sd-wrap {
  max-width: 1200px;
  margin: 0 auto;
  padding: 18px 24px 60px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.sd-crumbs {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.sd-crumbs a { color: var(--link); text-decoration: none; }
.sd-crumbs a:hover { color: var(--link-hover); text-decoration: underline; }

.sd-hero {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-5);
  flex-wrap: wrap;
}
.sd-hero-text .river {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: lowercase;
  margin-bottom: 4px;
}
.sd-hero-text h1 {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
  text-wrap: balance;
}
.sd-hero-text .meta-row {
  display: flex;
  gap: 8px;
  align-items: center;
  color: var(--text-secondary);
  font-size: 13.5px;
}
.sd-hero-text .meta-row .sep { color: var(--text-disabled); }

.grade-chip {
  background: var(--surface-sunken);
  color: var(--text-primary);
  padding: 3px 10px;
  border-radius: var(--radius-xs);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 12px;
}
.length-chip {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
  padding: 2px 8px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  letter-spacing: 0.02em;
  background: transparent;
}

.sd-hero-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* --- Readout + chart block --- */

.sd-readout-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.sd-warning {
  display: flex;
  gap: var(--space-3);
  padding: 10px 14px;
  background: var(--warning-bg);
  border: 1px solid var(--warning-border);
  color: var(--warning-fg);
  border-radius: var(--radius-md);
  font-size: 13px;
  align-items: flex-start;
}
.sd-warning svg { flex: 0 0 16px; margin-top: 2px; }

.sd-readout {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-6);
  align-items: end;
  padding: var(--space-6);
  background: var(--surface-raised);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
}
.sd-readout .caption {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: lowercase;
  margin-bottom: 4px;
}
.sd-readout .big {
  font-size: 48px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--text-primary);
}
.sd-readout .big .u {
  font-size: 14px;
  font-weight: 500;
  margin-left: 4px;
  color: var(--text-secondary);
}
.sd-readout .big .muted { color: var(--text-muted); }
.sd-readout .pill-col {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
.sd-readout .fresh-col {
  text-align: right;
  font-size: 12.5px;
  color: var(--text-secondary);
}
.sd-readout .fresh-col .muted { color: var(--text-muted); }

/* Freshness dot — same vocabulary as .sec-card .fresh on the home
   page (components.css L148). Green = fresh, amber = stale
   (≥ 2h since last reading). See DESIGN_NOTES §"Data states". */
.sd-fresh {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sd-fresh::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--status-good-dot);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--status-good-dot) 25%, transparent);
  flex-shrink: 0;
}
.sd-fresh.is-stale { color: var(--warning-fg); }
.sd-fresh.is-stale::before {
  background: var(--warning-border);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--warning-border) 25%, transparent);
}

/* --- Chart panel --- */

.chart-panel {
  background: var(--surface-raised);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.chart-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.chart-title-block {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.chart-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}
.chart-title .sub {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 500;
  margin-left: 8px;
}
/* R10.D.1 — basin-rainfall footnote below the chart title. Muted
   second line that explains either the unavailable state or (when
   the feed lands) the basin-overlay legend. Sits inside
   .chart-title-block so the title + footnote pair travels as one
   left-anchored unit at narrow widths even when the range pills
   wrap below; CSS gates which copy reads via the empty/ready
   variants. Empty-state copy is locked verbatim per scoping §0 /
   B2. */
.chart-header-footnote {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  line-height: 1.3;
}
.range-pills {
  display: flex;
  gap: 2px;
  background: var(--surface-sunken);
  padding: 3px;
  border-radius: var(--radius-pill);
  align-items: center;
}
.range-pills a {
  color: var(--text-secondary);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-size: 12.5px;
  text-decoration: none;
  font-weight: 500;
  line-height: 1;
  transition: background 0.12s, color 0.12s;
}
.range-pills a.prim {
  background: var(--surface-raised);
  color: var(--text-primary);
  box-shadow: var(--elev-1);
}
.range-pills a:hover:not(.prim) { color: var(--text-primary); }
.range-pills .sep {
  width: 1px;
  height: 16px;
  background: var(--border-default);
  margin: 0 4px;
}

/* R10.A chart-body layout: chart on the left, readout panel on the
   right (desktop). Falls back to a single-column stack on the mobile
   media query below. The flex container is set on .chart-body so
   the no-data state (a single .chart-empty child) keeps centering
   inside the panel without further rules. */
.chart-body {
  display: flex;
  align-items: stretch;
  gap: var(--space-5);
}
.chart-canvas-wrap {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
}
.chart-host {
  width: 100%;
  height: 280px;
}

/* R10.D.1 — basin-rainfall overlay z-order contract.
   Layers paint bottom-up: status bands (z=0, painted by the
   bandsPlugin in section_chart.js) → basin precipitation bars
   (z=1, this rule) → flow line / observed series (z=2, drawn by
   uPlot's series rendering after all drawClear hooks).
   The class is the wire format for the inline-overlay path: feed
   integration paints these as positioned <div>s inside
   .chart-canvas-wrap (matching the .chart-bands-overlay pattern)
   or as canvas rects via the precipPlugin (TBD at feed time).
   Slice 1 PR B publishes the rule shell so the colour + blend
   contract is settled before any data flows; no element on the
   page carries this class yet. Multiply blend pairs the
   translucent brand-500 wash with the warm band tints below
   without going garish on the green optimal-band area. */
.chart-precip-bar {
  background: color-mix(in oklch, var(--brand-500) 25%, transparent);
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* R10.D.1 — mobile sparkline strip. At <600px the inline overlay
   degrades to a 40px-tall strip stacked above the chart — kayakers
   on phones get a glanceable rainfall scan without the chart
   contending with a second data layer in the same vertical extent.
   At ≥600px the strip is hidden and the inline overlay (above)
   carries the basin signal. Both forms are visually empty in slice
   1 since the basin feed isn't wired yet; the empty-state copy is
   the only painted content. Copy locked verbatim per scoping §0 /
   B2. */
.chart-precip-strip {
  display: none;
  height: 40px;
  margin-bottom: var(--space-3);
  padding: 0 var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* R10.A — five flow-status band labels overlaid on the canvas.
   The bands themselves paint inside the canvas via section_chart.js
   (bandsPlugin); these <span>s are positioned absolutely over the
   canvas at each band's vertical centre. JS re-positions them after
   uPlot init + on resize. Labels are aria-hidden — the pill in the
   readout already announces the status — so they're a visual
   affordance only. */
.chart-bands-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.chart-band-label {
  position: absolute;
  right: 8px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  /* Translate up by -50% so the label's baseline-centre lands on
     the band's vertical centre. JS sets `top` to the y-pixel of
     the band centre. */
  transform: translateY(-50%);
  white-space: nowrap;
  /* Hidden until JS positions it; avoids a flash of un-positioned
     labels stacked at the top of the chart frame on first paint. */
  visibility: hidden;
}
.chart-band-label.is-positioned { visibility: visible; }
.chart-band-label.band-too-low   { color: var(--status-too-low-fg); }
.chart-band-label.band-low       { color: var(--status-low-fg); }
.chart-band-label.band-good      { color: var(--status-good-fg); }
.chart-band-label.band-high      { color: var(--status-high-fg); }
.chart-band-label.band-very-high { color: var(--status-very-high-fg); }

/* R10.A readout panel — 280px right-anchored alongside the chart on
   desktop. <600px collapses to a one-line bar above the chart via
   the media query at the bottom of this file. Hover-driven cursor
   updates are handled in section_chart.js (uPlot internal cursor;
   per slice-1 §0 / B5 no cursor-store extension in this PR). */
.chart-readout {
  flex: 0 0 280px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
  font-size: 13px;
  color: var(--text-secondary);
  align-self: flex-start;
}
.chart-readout .cr-value-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.chart-readout .cr-value {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary);
  font-feature-settings: "tnum";
}
.chart-readout .cr-unit {
  font-size: 12px;
  color: var(--text-muted);
}
.chart-readout .cr-pill {
  display: flex;
}
.chart-readout .cr-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
}
.chart-readout .cr-meta-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-4);
}
.chart-readout .cr-meta dt {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: lowercase;
  margin: 0;
}
.chart-readout .cr-meta dd {
  margin: 0;
  font-size: 12.5px;
  color: var(--text-primary);
  font-feature-settings: "tnum";
  text-align: right;
}
.chart-readout .cr-hint {
  margin: 0;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.35;
}
.chart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 80px var(--space-5);
  color: var(--text-muted);
  text-align: center;
  min-height: 240px;
}
.chart-empty .sub {
  font-size: 12.5px;
  color: var(--text-muted);
  max-width: 50ch;
}

.chart-legend {
  display: flex;
  gap: var(--space-5);
  font-size: 12.5px;
  color: var(--text-secondary);
  flex-wrap: wrap;
}
.chart-legend .li { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend .sw {
  display: inline-block;
  width: 18px;
  height: 3px;
  border-radius: 2px;
}
.chart-legend .sw-observed { background: #2285c6; }
.chart-legend .sw-forecast {
  background: transparent;
  border-top: 2px dashed #4ea0d6;
  height: 0;
  margin-top: 1px;
}
.chart-legend .sw-band {
  background: rgba(31, 154, 102, 0.35);
  height: 10px;
}
.chart-legend .sw-climatology {
  background: transparent;
  border-top: 2px dashed #5a6f87;
  height: 0;
  margin-top: 1px;
}

/* --- Detail panels --- */

.sd-panel {
  background: var(--surface-raised);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-1);
  padding: var(--space-6);
}
.sd-panel h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 var(--space-4);
  color: var(--text-primary);
}
.sd-panel h3 {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 var(--space-3);
  color: var(--text-primary);
}

.sd-grid-below {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
.info-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.info-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px var(--space-4);
  margin: 0;
  font-size: 13.5px;
}
.info-grid dt {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: lowercase;
  padding-top: 2px;
}
.info-grid dd {
  margin: 0;
  color: var(--text-primary);
}
.info-grid dd.mono { font-family: var(--font-mono); font-size: 12.5px; }
.info-grid dd a { color: var(--link); text-decoration: none; }
.info-grid dd a:hover { color: var(--link-hover); text-decoration: underline; }
.mono { font-family: var(--font-mono); }

.sd-description {
  margin-top: var(--space-4);
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.55;
  white-space: pre-line;
}

.sd-note {
  color: var(--text-muted);
  font-size: 13px;
  margin: 0;
}

/* --- Features --- */

/* Round 6: mobile-first stacked; ≥ 900 px flips to the 58 / 42
   two-column grid with a shared height so the map stays visible
   while the list scrolls internally. See DESIGN.md §"Components —
   Features grid" and DESIGN_NOTES.md §"Why map + list got a shared
   viewport". */
.sd-features,
.features-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
.sd-feature-map {
  width: 100%;
  height: 280px;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  /* Anchor for the absolutely-positioned .rail-toggle chip (R8).
     ``z-index: 0`` (with position: relative) creates a stacking
     context that contains Leaflet's internal z-indices
     (tile-pane 200, controls 800–1000) below the bottom
     tabbar's z-index: 100 — without this clamp the map's
     attribution and zoom controls leaked through the tabbar
     when the page scrolled to a position where the map
     overlapped it. */
  position: relative;
  z-index: 0;
}
.sd-map-pin { background: none; border: none; filter: drop-shadow(0 1px 2px rgba(14,26,38,0.3)); }
.sd-feature-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Gauge row — sits at the top of the feature list and acts as the
   crossref target for the triangle pin on the section map. Visual
   vocabulary mirrors .river-gauge-subrow (triangle + gauge label +
   provider key) but the row is non-linking — the existing Section →
   Gauge details pane already carries the provenance link. List shape
   so a future N-gauge schema slots in without a structural rewrite
   (D9 / D10 in docs/polish-pass-scoping.md). */
.sd-gauge-row {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: var(--space-3);
  align-items: center;
  padding: 8px 12px;
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
  border-left: 3px solid transparent;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
  font-size: 13px;
}
.sd-gauge-row:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--brand-500) 50%, transparent);
  outline-offset: 2px;
}
.sd-gauge-row.is-hover {
  background: var(--surface-raised);
  border-left-color: var(--brand-500);
}
.sd-gauge-row.is-locked {
  background: var(--brand-050, #e7f2fa);
  border-left-color: var(--brand-500);
}
.sd-gauge-row.is-proxy { opacity: 0.92; }
.sd-gauge-row .triangle { width: 12px; height: 12px; display: block; }
.sd-gauge-row .triangle polygon { stroke: #fff; stroke-width: 1; }
.sd-gauge-row .triangle[data-status="good"]     polygon { fill: var(--status-good-fg); }
.sd-gauge-row .triangle[data-status="low"]      polygon { fill: var(--status-low-fg); }
.sd-gauge-row .triangle[data-status="high"]     polygon { fill: var(--status-high-fg); }
.sd-gauge-row .triangle[data-status="veryhigh"] polygon { fill: var(--status-very-high-fg); }
.sd-gauge-row .triangle[data-status="unknown"]  polygon { fill: var(--text-disabled); }
.sd-gauge-row .gid { color: var(--text-primary); font-weight: 500; }
.sd-gauge-row .gid .proxy-mark { color: var(--text-muted); }
.sd-gauge-row .meta { color: var(--text-muted); font-size: 11.5px; }
.sd-feature-row {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: var(--space-3);
  align-items: center;
  padding: 10px 12px;
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
  border-left: 3px solid transparent;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.sd-feature-row:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--brand-500) 50%, transparent);
  outline-offset: 2px;
}
.sd-feature-row.is-hover {
  background: var(--surface-raised);
  border-left-color: var(--brand-500);
}
.sd-feature-row.is-locked {
  background: var(--brand-050, #e7f2fa);
  border-left-color: var(--brand-500);
}
.sd-feature-row.no-coords {
  cursor: default;
}
.sd-feature-row.no-coords.is-hover,
.sd-feature-row.no-coords.is-locked {
  border-left-color: var(--status-low-fg);
}
.sd-feature-nocoord { color: var(--status-low-fg); }

/* Map pin states — halo ring + scale per DESIGN.md §"Components —
   Feature pin". The icon div is 22×28 with iconAnchor (11, 28), so
   the ring's center at left:50%/top:100% lines up with the coord
   anchor (the pin's tip, not the SVG bbox middle). */
.sd-map-pin {
  transition: transform 150ms ease;
  overflow: visible;
}
.sd-map-pin::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  border: 3px solid var(--pin-color, var(--brand-500));
  background: color-mix(in srgb, var(--pin-color, var(--brand-500)) 15%, transparent);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.9);
  pointer-events: none;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 140ms ease, transform 140ms ease;
  z-index: -1;
}
.sd-map-pin.is-hover,
.sd-map-pin.is-locked {
  transform: scale(1.12);
  z-index: 500;
}
.sd-map-pin.is-hover::before,
.sd-map-pin.is-locked::before {
  opacity: 1;
  transform: scale(1);
}
.sd-map-pin.is-locked::before {
  animation: sd-pin-pulse 1.6s ease-in-out infinite;
}
@keyframes sd-pin-pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.9),
                0 0 0 0 color-mix(in srgb, var(--pin-color, var(--brand-500)) 50%, transparent);
  }
  50% {
    transform: scale(1.14);
    box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.9),
                0 0 0 6px color-mix(in srgb, var(--pin-color, var(--brand-500)) 20%, transparent);
  }
}
.sd-feature-body { min-width: 0; }
.sd-feature-directions { flex-shrink: 0; gap: 4px; }
.sd-feature-row .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 5px;
  background: var(--brand-500);
}
.sd-feature-row.feature-putin .dot { background: var(--status-good-dot); }
.sd-feature-row.feature-takeout .dot { background: var(--brand-500); }
.sd-feature-row.feature-alt .dot { background: var(--status-low-dot); }
.sd-feature-row.feature-portage .dot { background: var(--status-very-high-dot); }
.sd-feature-row.feature-play .dot { background: var(--brand-400); }
.sd-feature-row.feature-parking .dot { background: var(--text-muted); }
.sd-feature-row.feature-info .dot { background: var(--border-strong); }

.sd-feature-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.sd-feature-type {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
}
.sd-feature-desc {
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 2px;
}

/* Round 6: Essentials rows get a slightly heavier treatment so
   put-in / parking / take-out scan as a unit without dominating.
   +1 px label, +100 weight, +1 px left accent. See DESIGN.md
   §"Components — Feature hierarchy". */
.sd-feature-row.essential {
  border-left-width: 4px;
}
.sd-feature-row.essential .sd-feature-name {
  font-size: 15px;
  font-weight: 600;
}

/* Round 6: group subheadings sticky-pin to the top of the list
   viewport when the list scrolls internally (desktop two-column).
   Rendered only when both groups are present; single-group case
   renders no subheading at all.

   Deviation from DESIGN.md §"Components — Feature hierarchy":
   the spec colours Essentials brand-700 and Along-the-run text-muted
   to differentiate weight. Production review preferred visual parity
   between the two — both headings carry equal structural weight
   and the typographic mono cap already separates them from row
   content. Applied brand-700 to the base so both match. */
.feat-group-head {
  padding: 14px 4px 8px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-700);
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border-subtle);
}
.feat-group-head .count {
  font-weight: 500;
  color: var(--text-muted);
  margin-left: 4px;
}

/* Round 6: hazard lozenge replaces the plain type tag on Awareness
   rows. Reuses the Round 1 status-very-high tokens — no new color
   primitives. See DESIGN.md §"Components — Feature list row →
   Hazard lozenge". */
.hazard-lozenge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 7px;
  border-radius: var(--radius-xs);
  background: var(--status-very-high-bg);
  color: var(--status-very-high-fg);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-right: 4px;
}
.hazard-lozenge svg { flex-shrink: 0; }

/* Round 6: per-row affordance buttons. Transit rows get a primary
   Directions + secondary satellite icon; observational + hazard rows
   get a single View-on-map primary. See DESIGN.md §"Components —
   Feature affordances". */
.feat-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.feat-action {
  white-space: nowrap;
  padding: 5px 11px;
  height: 28px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: transparent;
  text-decoration: none;
}
.feat-action.directions {
  color: var(--brand-700);
  border: 1px solid var(--brand-500);
}
.feat-action.view {
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
}
.feat-action.directions:hover { background: var(--brand-050); }
.feat-action.view:hover       { background: var(--surface-sunken); }
.feat-action:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
}

.feat-sat {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  background: transparent;
}
.feat-sat:hover { background: var(--surface-sunken); color: var(--text-primary); }
.feat-sat:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
}

/* Round 6: two-column layout at ≥ 900 px. Container owns the
   shared height via the h-{full|short|tiny} modifier; map and list
   fill 100 % of the cell. List gains internal scroll + a bottom
   fade mask when overflow is flagged server-side. The 900 px
   breakpoint is independent of the prompt-pattern 560 px — the
   grid needs horizontal room for the 58 / 42 split to give the
   map a legible aspect ratio. */
@media (min-width: 900px) {
  .features-grid {
    grid-template-columns: 58% 42%;
    gap: 0;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
  }
  .features-grid.h-full  { height: var(--feat-h-full); }
  .features-grid.h-short { height: var(--feat-h-short); }
  .features-grid.h-tiny  { height: var(--feat-h-tiny); }
  .features-grid .sd-feature-map {
    height: 100%;
    border-radius: 0;
    border: none;
    border-right: 1px solid var(--border-subtle);
  }
  .features-grid .feat-list {
    height: 100%;
    overflow-y: auto;
    padding: 0 var(--space-4);
    scrollbar-width: thin;
    scrollbar-color: rgba(14, 26, 38, 0.18) transparent;
  }
  .features-grid .feat-list::-webkit-scrollbar        { width: 8px; }
  .features-grid .feat-list::-webkit-scrollbar-thumb  { background: rgba(14, 26, 38, 0.18); border-radius: 4px; }
  .features-grid .feat-list::-webkit-scrollbar-track  { background: transparent; }
  .features-grid .feat-list.overflow {
    -webkit-mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 24px), transparent 100%);
            mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 24px), transparent 100%);
  }
  .features-grid .feat-group-head {
    position: sticky;
    top: 0;
    z-index: 2;
    margin: 0 calc(-1 * var(--space-4));
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }

  /* Hide-rail — DESIGN.md §"Components — Hide-rail". Collapses the
     42 % list so the map takes full width. Shared pattern with
     .river-grid; list-child selector differs (.feat-list here,
     .river-list on /river/<id>). */
  .features-grid[data-rail="hidden"] {
    grid-template-columns: 100% 0;
  }
  .features-grid[data-rail="hidden"] .feat-list,
  .features-grid[data-rail="hidden"] .sd-feature-list {
    display: none;
  }
  .features-grid[data-rail="hidden"] .sd-feature-map {
    border-right: none;
  }
}

/* --- R9 slice 5: section-scale elevation strip mount glue ---
   The strip partial (``partials/_elevation_strip.html``) is
   self-contained — it renders a ``.elevation-strip.section-scale``
   block with its own internal padding (head + svg + axis row).
   This block sits inside ``#features`` between the features grid
   and the photos block per artboard C. Section page wraps it in
   the section panel's flex flow; the only page-level concern is
   the gap to its neighbours and a subtle border so it reads as
   its own row when neither neighbour is rendered. */
#features > .elevation-strip.section-scale {
  margin-top: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  /* The component-level rule sets a top border for the river-page
     stack ordering (strip below the river map, shares its top
     edge). Inside #features the strip is a standalone card and
     should carry the full border above. */
  border-top: 1px solid var(--border-subtle);
}
#features > .sd-images {
  /* Photos block inherits the panel's row gap from .sd-panel
     children, but margin-top is the consistent spacing primitive
     on this page; explicit so the strip + photos pair don't
     collapse together when both render. */
  margin-top: var(--space-4);
}

.sd-images {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.sd-images figure {
  margin: 0;
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--elev-1);
}
.sd-images img {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
}
.sd-images figcaption {
  font-size: 12px;
  color: var(--text-muted);
  padding: 6px 10px;
}

/* --- Notices --- */

.notice {
  display: flex;
  gap: var(--space-3);
  padding: 12px 14px;
  background: var(--warning-bg);
  border: 1px solid var(--warning-border);
  color: var(--warning-fg);
  border-radius: var(--radius-md);
  font-size: 13.5px;
  align-items: flex-start;
  margin-bottom: var(--space-3);
}
.notice svg { flex: 0 0 16px; margin-top: 2px; }
.notice .date {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 4px;
}
.notice.notice-danger {
  background: var(--danger-bg);
  border-color: var(--danger-border);
  color: var(--danger-fg);
}
.notice.notice-danger .date a { color: var(--danger-fg); text-decoration: underline; }

/* R10.D.1 — basin sparkline strip visibility breakpoint.
   Scoping §0 / B2 locks 600px (independent of the page-level 767px
   tablet/mobile boundary used elsewhere in this file): the strip
   represents a discrete UI mode for the chart pane only, not the
   page chrome. Below 600px the chart loses enough horizontal extent
   that an inline rainfall overlay would compete with the flow line
   for vertical pixels; the strip slot above the chart restores a
   glanceable rainfall scan without that contention. */
@media (max-width: 599.98px) {
  .chart-precip-strip { display: flex; }
}

/* --- Mobile adjustments --- */

@media (max-width: 767px) {
  .sd-wrap { padding: 14px 14px calc(var(--tabbar-height) + 24px); }
  .sd-hero { flex-direction: column; align-items: stretch; }
  .sd-hero-text h1 { font-size: 26px; }
  .sd-hero-actions { justify-content: stretch; }
  .sd-hero-actions .btn { flex: 1; }
  .sd-readout {
    grid-template-columns: 1fr;
    gap: var(--space-4);
    padding: var(--space-5);
  }
  .sd-readout .big { font-size: 40px; }
  .sd-readout .pill-col { align-items: flex-start; }
  .sd-readout .fresh-col { text-align: left; }
  /* Move chart-panel's horizontal padding off the panel itself
     and onto chart-head + chart-legend, so chart-body / chart-host
     get the panel's full inner width. The .sd-feature-map's map
     widget reads as visibly wider than the chart's plot area
     because of this exact difference (panel-padding vs
     widget-fills-panel); matching the pattern here lets the
     uPlot canvas use the same horizontal extent. */
  .chart-panel { padding-inline: 0; }
  .chart-head { align-items: flex-start; padding-inline: var(--space-5); }
  .chart-legend { padding-inline: var(--space-5); }
  .chart-host { height: 220px; }
  /* R10.A — readout collapses to a one-line bar above the chart on
     mobile. flex-direction column + order:-1 puts the readout first
     in the flex flow even though it's last in DOM order. The panel
     loses its decorative padding and re-flows its dl into a
     horizontal scan: value · pill · 1h · 24h. The hint copy hides
     entirely — too much vertical noise for one-line. */
  .chart-body { flex-direction: column; gap: var(--space-3); }
  .chart-readout {
    order: -1;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    flex: 0 0 auto;
    width: auto;
    margin-inline: var(--space-5);
    padding: var(--space-3) var(--space-4);
    gap: var(--space-4);
    align-self: stretch;
  }
  .chart-readout .cr-value-row { gap: 2px; }
  .chart-readout .cr-meta { flex-direction: row; flex-wrap: wrap; gap: var(--space-3) var(--space-4); }
  .chart-readout .cr-meta-row { gap: 6px; }
  .chart-readout .cr-meta dd { text-align: left; }
  .chart-readout .cr-hint { display: none; }
  .sd-grid-below { grid-template-columns: 1fr; }
  .range-pills { overflow-x: auto; }
}

/* --- Dark mode overrides --- */

.theme-dark .sd-readout,
.theme-dark .chart-panel,
.theme-dark .sd-panel {
  background: var(--surface-raised);
}
.theme-dark .range-pills { background: var(--surface-sunken); }
.theme-dark .sd-feature-row { background: var(--surface-sunken); }

@media (prefers-color-scheme: dark) {
  .sd-readout, .chart-panel, .sd-panel { background: var(--surface-raised); }
  .range-pills { background: var(--surface-sunken); }
  .sd-feature-row { background: var(--surface-sunken); }
}
