/* Atlas — dark cartographic UI.
   Chrome recedes, data carries the colour. Every accent hue is reserved for a
   measurement, so nothing decorative competes with a shallow M6. */

:root {
  --bg:        #080b10;
  --surface:   rgba(16, 21, 28, 0.86);
  --surface-2: rgba(26, 33, 43, 0.92);
  --line:      rgba(255, 255, 255, 0.10);
  --line-2:    rgba(255, 255, 255, 0.18);
  --ink:       #e8edf3;
  --ink-2:     #9aa8b8;
  --ink-3:     #64748b;
  --accent:    #4cc9f0;
  --ok:        #34d399;
  --warn:      #fbbf24;
  --bad:       #f87171;

  /* Depth ramp — shallow quakes are felt hardest, so shallow reads hottest. */
  --d0: #ff3b30; --d1: #ff8c42; --d2: #ffd166; --d3: #4cc9f0; --d4: #4361ee;

  --rail-w: 310px;
  --radius: 10px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
          "Noto Sans", sans-serif;  /* full macron coverage: ā ē ī ō ū */
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%; overflow: hidden;
  background: var(--bg); color: var(--ink);
  font-family: var(--font);
  font-size: 14px; line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: var(--accent); }

#map { position: absolute; inset: 0; }
.maplibregl-ctrl-attrib { display: none !important; }   /* replaced by our own footer */
/* Zoom and scale live top-right: the bottom of the map belongs to the
   scrubber, which was sitting on top of them. */
.maplibregl-ctrl-top-right { top: 56px; }
.maplibregl-ctrl-top-right .maplibregl-ctrl {
  background: var(--surface); border: 1px solid var(--line);
  backdrop-filter: blur(14px); box-shadow: none;
}
.maplibregl-ctrl-top-right .maplibregl-ctrl button + button { border-top: 1px solid var(--line); }
.maplibregl-ctrl-top-right .maplibregl-ctrl-scale {
  color: var(--ink-3); font: 400 10px/1.6 var(--mono); border-color: var(--line-2);
}

/* ------------------------------------------------------------ masthead */

.masthead {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 16px;
  background: linear-gradient(180deg, rgba(8,11,16,.92) 0%, rgba(8,11,16,0) 100%);
  pointer-events: none;
}
.masthead > * { pointer-events: auto; }

.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 26px; height: 26px; border-radius: 7px; flex: none;
  background: conic-gradient(from 210deg, var(--d0), var(--d1), var(--d2), var(--d3), var(--d4), var(--d0));
  box-shadow: inset 0 0 0 4px var(--bg);
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-text strong { font-size: 15px; letter-spacing: .22em; }
.brand-text small { font-size: 10.5px; color: var(--ink-3); letter-spacing: .03em; }

.feed-status {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 11.5px; color: var(--ink-2); backdrop-filter: blur(10px);
}
.feed-status .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3);
  box-shadow: 0 0 0 0 currentColor;
}
.feed-status.is-live .dot { background: var(--ok); animation: pulse 2.4s ease-out infinite; color: var(--ok); }
.feed-status.is-stale .dot { background: var(--warn); }
.feed-status.is-down  .dot { background: var(--bad); }
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(52,211,153,.55); }
  70%  { box-shadow: 0 0 0 7px rgba(52,211,153,0); }
  100% { box-shadow: 0 0 0 0 rgba(52,211,153,0); }
}

/* ---------------------------------------------------------------- rail */

.rail {
  /* Clears the legend, which shares the bottom-left corner. Every pixel taken
     here comes straight off the event list, so it tracks the legend's real
     height (set by JS) rather than a constant: the constant was measured
     against the geohazard legend and the two taller lenses ran underneath it.
     The fallback is that original measurement, for the frame before JS runs. */
  position: absolute; top: 58px; left: 12px; z-index: 6;
  bottom: calc(var(--legend-h, 106px) + 20px);
  width: var(--rail-w); display: flex;
  transition: transform .28s cubic-bezier(.4,0,.2,1);
}
.rail.is-closed { transform: translateX(calc(-1 * var(--rail-w) - 12px)); }

.rail-body {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); backdrop-filter: blur(16px);
  border: 1px solid var(--line); border-radius: var(--radius);
  /* The taller lenses (severe weather carries a metric switch, four layer
     toggles and a three-row legend) ran the list out of room; hidden meant it
     was silently clipped to its heading. Scroll the rail instead. */
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
}

.rail-toggle {
  position: absolute; top: 10px; left: calc(100% + 6px);
  width: 22px; height: 34px; border-radius: 6px;
  background: var(--surface); border: 1px solid var(--line);
  color: var(--ink-2); backdrop-filter: blur(10px);
}
.rail.is-closed .rail-toggle { transform: rotate(180deg); }

.block { padding: 10px 14px; border-bottom: 1px solid var(--line); }
.block:last-child { border-bottom: 0; }
/* The controls stay put and only the list scrolls — on a 720p screen the whole
   rail used to scroll, so reading down the events took the filters off-screen. */
.block.grow { flex: 1; min-height: 168px; display: flex; flex-direction: column; }
.block h2 {
  margin: 0 0 8px; font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
}
.hint { margin: -4px 0 9px; font-size: 11.5px; color: var(--ink-3); }

.row {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 0; font-size: 13px; cursor: pointer;
}
.row span:nth-of-type(1) { flex: 1; }
.row input[type=checkbox] { accent-color: var(--accent); width: 15px; height: 15px; }
.count { font: 500 11px/1 var(--mono); color: var(--ink-3); }

.slider-row { gap: 10px; margin-top: 3px; }
/* .row's first span is the flexible label everywhere else; here the range
   needs the space instead. */
.slider-row .slider-label { flex: 0 0 auto; font-size: 12px; color: var(--ink-3); }
input[type=range] { flex: 1; accent-color: var(--accent); height: 3px; }
output { font: 500 12px/1 var(--mono); min-width: 30px; text-align: right; color: var(--ink-2); }

.lenses { display: grid; gap: 6px; }
.lens {
  display: flex; flex-direction: column; gap: 1px; text-align: left;
  padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--line); background: rgba(255,255,255,.02);
}
.lens-name { font-size: 12.5px; font-weight: 550; }
.lens-sub  { font-size: 10.5px; color: var(--ink-3); }
.lens:hover { border-color: var(--line-2); }
.lens.is-on { border-color: rgba(76,201,240,.5); background: rgba(76,201,240,.10); }
.lens.is-on .lens-name { color: var(--accent); }

/* Roadmap lenses, one line. They were full-height buttons; four of them ate
   300px of rail and pushed the event list below the fold at 720p. */
.planned {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin: 6px 0 0; font-size: 10.5px; color: var(--ink-3);
}
.h2-note { letter-spacing: 0; text-transform: none; font-weight: 400; opacity: .7; }
.chip {
  padding: 2px 7px; border-radius: 999px; font-size: 10.5px;
  border: 1px solid var(--line); color: var(--ink-3);
  background: rgba(255,255,255,.02); cursor: not-allowed;
}

.segmented { display: flex; gap: 4px; margin: 8px 0 2px; }
.segmented button {
  flex: 1; padding: 6px 0; border-radius: 7px; font-size: 12px;
  border: 1px solid var(--line); color: var(--ink-2); background: rgba(255,255,255,.02);
}
.segmented button.is-on { border-color: rgba(76,201,240,.5); background: rgba(76,201,240,.12); color: var(--accent); }

/* recent-events list */
.events { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; }
.events li {
  display: grid; grid-template-columns: 42px 1fr auto; align-items: center;
  gap: 9px; padding: 7px 8px; border-radius: 7px; cursor: pointer;
}
.events li:hover, .events li.is-sel { background: rgba(255,255,255,.06); }
.events .mag {
  font: 600 13px/1 var(--mono); text-align: center;
  padding: 4px 0; border-radius: 5px; color: #0a0e14;
}
.events .where { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.events .when  { font: 400 10.5px/1 var(--mono); color: var(--ink-3); }
.events .expired { opacity: .45; }
.events .empty { padding: 14px 4px; color: var(--ink-3); font-size: 12px; cursor: default; display: block; line-height: 1.5; }
/* Evidence line for a bloom row — which of the two independent signals it is. */
.events .ev {
  font: 400 9.5px/1 var(--mono); font-style: normal; color: var(--ink-3);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; margin-left: 5px;
}

/* -------------------------------------------------------------- legend */

.legend {
  position: absolute; left: 12px; bottom: 12px; z-index: 5; width: var(--rail-w);
  padding: 8px 12px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); backdrop-filter: blur(14px);
}
.legend-row { display: grid; grid-template-columns: 62px 1fr; gap: 6px; align-items: center; margin-bottom: 3px; }
.legend-title { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.ramp {
  height: 7px; border-radius: 4px;
  background: linear-gradient(90deg, var(--d0), var(--d1) 28%, var(--d2) 50%, var(--d3) 78%, var(--d4));
}
/* `display: grid` on .legend-row beats the UA's [hidden] { display: none },
   which is how all three metric rows ended up on screen at once. */
.legend-row[hidden] { display: none; }
.ramp-labels { grid-column: 2; display: flex; justify-content: space-between; }
.ramp-labels i { font: 400 9.5px/1 var(--mono); font-style: normal; color: var(--ink-3); }
.sizes { display: flex; align-items: center; justify-content: space-between; height: 20px; }
.sizes i { border-radius: 50%; background: rgba(255,255,255,.22); border: 1px solid rgba(255,255,255,.4); }
.sizes .s1 { width: 5px;  height: 5px; }
.sizes .s3 { width: 9px;  height: 9px; }
.sizes .s5 { width: 14px; height: 14px; }
.sizes .s7 { width: 20px; height: 20px; }
.legend-note { margin: 4px 0 0; font-size: 10.5px; color: var(--ink-3); }
.legend-note strong { color: var(--ink-2); font-weight: 600; }

/* Chlorophyll-a: log-scaled, so the stops sit where log10 puts them across the
   0.1–20 mg/m3 range the ramp covers, not at even intervals. */
.ramp-chla {
  background: linear-gradient(90deg,
    #0a2454 0%, #10547e 26%, #16807a 45%, #2ea058 66%, #9ec03a 86%, #f6cd42 100%);
}
.tiers { display: flex; align-items: center; justify-content: space-between; height: 18px; }
.tiers i { width: 13px; height: 13px; border-radius: 50%; }
.tiers .t-watch { background: rgba(251,191,36,.85); border: 1.5px solid #fbbf24; }
.tiers .t-alert { background: rgba(251,146,60,.85); border: 1.5px solid #fb923c; }
.tiers .t-high  { background: rgba(248,113,113,.85); border: 1.5px solid #f87171; }

/* Flow bands. Same five colours as BAND_COLOR in config.js — a legend that
   drifts from the map is worse than no legend. */
.tiers .b-drought { background: rgba(245,158,11,.85);  border: 1.5px solid #f59e0b; }
.tiers .b-low     { background: rgba(253,224,71,.85);  border: 1.5px solid #fde047; }
.tiers .b-normal  { background: rgba(96,165,250,.85);  border: 1.5px solid #60a5fa; }
.tiers .b-high    { background: rgba(251,113,133,.85); border: 1.5px solid #fb7185; }
.tiers .b-flood   { background: rgba(244,63,94,.9);    border: 1.5px solid #f43f5e; }

/* Avalanche danger, EAWS scale. Squares, not circles: the map draws these as
   filled regions, and the legend should say which mark it is describing. */
.tiers.sq i { border-radius: 2px; }
.tiers .a1 { background: #ccff66; border: 1.5px solid #a8d84a; }
.tiers .a2 { background: #ffff00; border: 1.5px solid #d8d800; }
.tiers .a3 { background: #ff9900; border: 1.5px solid #e08600; }
.tiers .a4 { background: #ff0000; border: 1.5px solid #cc0000; }
/* Level 5 is black in the standard; on a dark map that needs the red edge the
   map layer also gives it, or it reads as an empty hole. */
.tiers .a5 { background: #000; border: 1.5px solid #ff0000; }

/* Wind, by Beaufort band. Same six colours as WIND_COLOR in config.js. */
.tiers .w-calm    { background: rgba(96,165,250,.85);  border: 1.5px solid #60a5fa; }
.tiers .w-breezy  { background: rgba(125,211,252,.85); border: 1.5px solid #7dd3fc; }
.tiers .w-windy   { background: rgba(253,224,71,.85);  border: 1.5px solid #fde047; }
.tiers .w-gale    { background: rgba(251,146,60,.85);  border: 1.5px solid #fb923c; }
.tiers .w-storm   { background: rgba(244,63,94,.9);    border: 1.5px solid #f43f5e; }
.tiers .w-violent { background: rgba(190,24,93,.9);    border: 1.5px solid #be185d; }

/* Rainfall accumulation. `dry` is deliberately the dimmest thing on the strip:
   it is a reading, but it is never the reason anyone opened this lens. */
.tiers .r-dry     { background: rgba(71,85,105,.85);   border: 1.5px solid #475569; }
.tiers .r-light   { background: rgba(147,197,253,.85); border: 1.5px solid #93c5fd; }
.tiers .r-mod     { background: rgba(56,189,248,.85);  border: 1.5px solid #38bdf8; }
.tiers .r-heavy   { background: rgba(45,212,191,.85);  border: 1.5px solid #2dd4bf; }
.tiers .r-vheavy  { background: rgba(250,204,21,.85);  border: 1.5px solid #facc15; }
.tiers .r-extreme { background: rgba(244,63,94,.9);    border: 1.5px solid #f43f5e; }

/* Pressure tendency, diverging around steady. Falling is the warm half because
   falling is the half that brings the weather. */
.tiers .p-fvf    { background: rgba(244,63,94,.9);    border: 1.5px solid #f43f5e; }
.tiers .p-ff     { background: rgba(251,113,133,.85); border: 1.5px solid #fb7185; }
.tiers .p-f      { background: rgba(251,191,36,.85);  border: 1.5px solid #fbbf24; }
.tiers .p-steady { background: rgba(148,163,184,.85); border: 1.5px solid #94a3b8; }
.tiers .p-r      { background: rgba(125,211,252,.85); border: 1.5px solid #7dd3fc; }
.tiers .p-rf     { background: rgba(96,165,250,.85);  border: 1.5px solid #60a5fa; }

/* Atmospheric river category, Atlas's own ordering of the AR Scale. Squares to
   match the ringed digit the map draws, the same rule the avalanche row uses. */
.tiers .ar1 { background: rgba(147,197,253,.85); border: 1.5px solid #93c5fd; }
.tiers .ar2 { background: rgba(56,189,248,.85);  border: 1.5px solid #38bdf8; }
.tiers .ar3 { background: rgba(45,212,191,.85);  border: 1.5px solid #2dd4bf; }
.tiers .ar4 { background: rgba(250,204,21,.85);  border: 1.5px solid #facc15; }
.tiers .ar5 { background: rgba(244,63,94,.9);    border: 1.5px solid #f43f5e; }

/* ------------------------------------------------------------ scrubber */

.scrubber {
  position: absolute; left: calc(var(--rail-w) + 28px); right: 12px; bottom: 12px; z-index: 6;
  padding: 9px 14px 4px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); backdrop-filter: blur(14px);
}
.scrub-top { display: flex; align-items: center; gap: 14px; }
.windows { display: flex; gap: 3px; }
.windows button {
  padding: 5px 10px; border-radius: 6px; font-size: 11.5px;
  color: var(--ink-3); border: 1px solid transparent;
}
.windows button:hover { color: var(--ink); }
.windows button.is-on { color: var(--accent); border-color: rgba(76,201,240,.4); background: rgba(76,201,240,.10); }

.scrub-time { flex: 1; display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.scrub-time strong { font: 600 13px/1 var(--mono); }
.scrub-time span { font-size: 11.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.scrub-actions { display: flex; gap: 5px; }
.scrub-actions button {
  padding: 5px 10px; border-radius: 6px; font-size: 11px; letter-spacing: .06em;
  border: 1px solid var(--line); color: var(--ink-2);
}
#live.is-on { color: var(--ok); border-color: rgba(52,211,153,.45); background: rgba(52,211,153,.10); }

.scrub-track { position: relative; height: 30px; margin-top: 2px; }
#scrub-spark { position: absolute; inset: 0 0 auto; width: 100%; pointer-events: none; opacity: .85; }
#scrub {
  position: absolute; inset: auto 0 0; width: 100%; margin: 0; height: 20px;
  background: none; -webkit-appearance: none; appearance: none;
}
#scrub::-webkit-slider-runnable-track { height: 2px; background: var(--line-2); border-radius: 2px; }
#scrub::-moz-range-track { height: 2px; background: var(--line-2); border-radius: 2px; }
#scrub::-webkit-slider-thumb {
  -webkit-appearance: none; width: 3px; height: 22px; margin-top: -10px;
  border-radius: 2px; background: var(--accent); box-shadow: 0 0 8px rgba(76,201,240,.8);
}
#scrub::-moz-range-thumb {
  width: 3px; height: 22px; border: 0; border-radius: 2px;
  background: var(--accent); box-shadow: 0 0 8px rgba(76,201,240,.8);
}

/* --------------------------------------------------------------- panel */

.panel {
  position: absolute; top: 58px; right: 12px; bottom: 118px; z-index: 7;
  width: 372px; max-width: calc(100vw - 24px);
  background: var(--surface); backdrop-filter: blur(16px);
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow-y: auto; overscroll-behavior: contain;
  animation: slide-in .22s cubic-bezier(.4,0,.2,1);
}
@keyframes slide-in { from { opacity: 0; transform: translateX(16px); } }
.panel-close {
  position: absolute; top: 8px; right: 10px; z-index: 2;
  width: 26px; height: 26px; border-radius: 6px; font-size: 17px; line-height: 1;
  color: var(--ink-2); background: rgba(8,11,16,.7);
}

.p-head { padding: 14px 16px 12px; border-bottom: 1px solid var(--line); }
/* padding-right keeps the kind line — and any tier badge sitting at its end —
   clear of the close button, which floats over the header at top:8 right:10. */
.p-kind {
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
  padding-right: 32px;
}
.p-title { display: flex; align-items: baseline; gap: 10px; margin: 5px 0 2px; }
.p-mag { font: 700 30px/1 var(--mono); }
/* A magnitude is a bare number; a wind speed is not. Where the headline figure
   needs its unit to mean anything, it rides small and quiet alongside. */
.p-unit { font: 400 10px/1 var(--mono); font-style: normal; color: var(--ink-3); margin-left: 3px; }
.p-where { font-size: 14px; color: var(--ink); }
.p-when { font-size: 11.5px; color: var(--ink-3); }

.p-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border-bottom: 1px solid var(--line); }
.p-cell { background: rgba(16,21,28,.6); padding: 9px 14px; }
.p-cell dt { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.p-cell dd { margin: 2px 0 0; font: 500 14px/1.2 var(--mono); }
/* Dates and species lists do not belong in a 14px mono slab — they wrap badly
   and read as measurements when they are not. */
.p-cell dd.dd-text { font: 400 12px/1.3 var(--font); }
.p-cell dd .dd-unit { font-size: 9.5px; color: var(--ink-3); margin-left: 4px; }
.p-grid-flush { border-bottom: 0; border-top: 1px solid var(--line); }

.p-sec { padding: 13px 16px; border-bottom: 1px solid var(--line); }
.p-sec h3 {
  margin: 0 0 8px; font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
}
.p-sec p { margin: 0 0 6px; font-size: 12.5px; color: var(--ink-2); }
.p-sec p:last-child { margin-bottom: 0; }
.p-sec p.p-note { font-size: 11.5px; color: var(--ink-3); }

.ttl-bar { height: 5px; border-radius: 3px; background: rgba(255,255,255,.09); overflow: hidden; }
.ttl-fill { height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--accent), var(--ok)); }
.ttl-meta { display: flex; justify-content: space-between; margin-top: 6px; font: 400 11px/1 var(--mono); color: var(--ink-3); }

#inset { height: 208px; border-radius: 8px; overflow: hidden; background: #0d1117; position: relative; }
#inset .maplibregl-ctrl-bottom-left, #inset .maplibregl-ctrl-bottom-right { display: none; }
.inset-wrap { position: relative; }
.inset-x {
  position: absolute; left: 50%; top: 50%; width: 36px; height: 36px;
  transform: translate(-50%,-50%); pointer-events: none; z-index: 2;
}
.inset-x::before, .inset-x::after {
  content: ''; position: absolute; background: rgba(255,255,255,.9);
  box-shadow: 0 0 4px rgba(0,0,0,.9);
}
.inset-x::before { left: 50%; top: 0; bottom: 0; width: 1px; margin-left: -.5px; }
.inset-x::after  { top: 50%; left: 0; right: 0; height: 1px; margin-top: -.5px; }
.inset-ring {
  position: absolute; left: 50%; top: 50%; width: 15px; height: 15px;
  transform: translate(-50%,-50%); border: 1.5px solid rgba(255,255,255,.95);
  border-radius: 50%; pointer-events: none; z-index: 2;
}
.inset-tabs { display: flex; gap: 4px; margin-bottom: 8px; }
.inset-tabs button {
  padding: 4px 9px; border-radius: 6px; font-size: 11px;
  border: 1px solid var(--line); color: var(--ink-3);
}
.inset-tabs button.is-on { color: var(--accent); border-color: rgba(76,201,240,.4); background: rgba(76,201,240,.10); }

/* ------------------------------------------------- bloom evidence rows */

/* Each row is a reading, a bar showing its sub-score, and the site's own
   yardstick underneath. The yardstick is the point: it is what turns "18 400
   cells per litre" from a number nobody can weigh into a claim anyone can
   check. The row's `color` is set inline from the tier, and the bar inherits
   it via currentColor. */
.drv { list-style: none; margin: 0; padding: 0; }
.drv li { padding: 8px 0; border-bottom: 1px dashed var(--line); }
.drv li:first-child { padding-top: 0; }
.drv li:last-child { border-bottom: 0; padding-bottom: 0; }
.d-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.d-name { font-size: 12.5px; color: var(--ink); }
.d-val { font: 500 12.5px/1.2 var(--mono); white-space: nowrap; }
.d-val i { font-style: normal; font-size: 10px; color: var(--ink-3); margin-left: 3px; }
.d-bar {
  display: block; height: 4px; border-radius: 3px; margin: 7px 0 5px;
  background: rgba(255,255,255,.09); overflow: hidden;
}
.d-bar b { display: block; height: 100%; border-radius: 3px; background: currentColor; }
.d-note { display: block; font: 400 10.5px/1.4 var(--mono); color: var(--ink-3); }
.d-none { font-size: 12px; color: var(--ink-3); }
/* Sampling-site readings are measurements, not scores — no bar to show. */
.drv-plain li { padding: 7px 0; }

/* Elevation range beside an avalanche band name. Deliberately the same chip as
   the event list's evidence tag: it is the same idea — a qualifier on the row's
   subject — and the panel should not invent a second vocabulary for it. */
.d-name .ev {
  font: 400 9.5px/1 var(--mono); font-style: normal; color: var(--ink-3);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; margin-left: 5px;
  white-space: nowrap;
}

/* Likelihood / size / trend / bands for one avalanche problem. They wrap
   because four of them do not fit across a 372px panel at any font size worth
   reading. */
.prob-meta { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 5px; }
.prob-meta span {
  font: 400 10px/1.4 var(--mono); color: var(--ink-3);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px;
}

/* The 8-point aspect rose, flattened into a strip. A rose would be truer to the
   forecast but at this width each sector would be ~20px, too small to label —
   and an unlabelled compass is a puzzle, not information. */
.asp { display: flex; gap: 3px; margin: 0 0 6px; }
.asp i {
  flex: 1; text-align: center; font: 500 9.5px/1.7 var(--mono); font-style: normal;
  color: var(--ink-3); border: 1px solid var(--line); border-radius: 3px;
  background: rgba(255,255,255,.02);
}
/* Warn amber rather than the band's danger colour: a problem's aspects are one
   fact about that problem, and re-using level 4's red here would read as a
   second danger rating. */
.asp i.is-on {
  color: var(--warn); font-weight: 700;
  border-color: rgba(251,191,36,.55); background: rgba(251,191,36,.14);
}

/* The one section that must not read as another grey block of body copy. */
.p-warn { background: rgba(248,113,113,.06); border-left: 2px solid rgba(248,113,113,.5); }
.p-warn h3 { color: var(--bad); }
.p-warn p { color: var(--ink-2); }

.revs { list-style: none; margin: 0; padding: 0; font: 400 11.5px/1.5 var(--mono); }
.revs li { display: flex; gap: 9px; padding: 3px 0; border-bottom: 1px dashed var(--line); }
.revs li:last-child { border-bottom: 0; }
.revs .r { color: var(--ink-3); min-width: 22px; }
.revs .v { flex: 1; }

.badge {
  display: inline-block; padding: 2px 7px; border-radius: 5px;
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  border: 1px solid var(--line-2); color: var(--ink-2);
}
.badge.warn { color: var(--warn); border-color: rgba(251,191,36,.4); background: rgba(251,191,36,.10); }
.badge.ok   { color: var(--ok);   border-color: rgba(52,211,153,.4); background: rgba(52,211,153,.10); }
.badge.bad  { color: var(--bad);  border-color: rgba(248,113,113,.4); background: rgba(248,113,113,.10); }

.link-out { display: inline-block; margin-top: 4px; font-size: 12px; }

/* -------------------------------------------------------- attribution */

/* CC-BY attribution for GeoNet and LINZ — a licence condition, so it must stay
   legible, not tuck under the detail panel. It lives in the 96–118px band
   between the scrubber and the panel's lower edge, which only works while it
   stays on one line: at max-width 340px it wrapped to two and collided. */
.attrib {
  position: absolute; right: 12px; bottom: 96px; z-index: 4;
  font-size: 10px; line-height: 1.4; color: var(--ink-2); text-align: right;
  /* A text-shadow was enough over the dark basemap and vanished over LINZ
     aerial, which is pale. The scrim holds contrast on any of the three.
     max-content keeps the box hugging the text instead of the whole strip. */
  width: max-content; max-width: calc(100vw - var(--rail-w) - 56px);
  padding: 3px 8px; border-radius: 6px;
  background: rgba(6,10,16,.6); backdrop-filter: blur(6px);
}
.attrib a { color: var(--ink-2); text-decoration: none; }
.attrib a:hover { color: var(--accent); }

/* The marine lens hides the scrubber — blooms are standing states, not a
   stream of instants, so there is nothing to scrub through. Both bands above
   it were sized around the scrubber's 106px, so without this the panel stops
   short and the attribution floats in empty space. */
body.lens-marine .panel { bottom: 46px; }
body.lens-marine .attrib { bottom: 12px; }

/* Freshwater hides it for the same reason: a river's percentile and a morning
   avalanche advisory are both "where things stand now", not a timeline. */
body.lens-freshwater .panel { bottom: 46px; }
body.lens-freshwater .attrib { bottom: 12px; }

/* Severe weather hides it too. A gauge reading and a model run are both "as of
   now"; the scrubber replays an event stream, and there isn't one here. */
body.lens-weather .panel { bottom: 46px; }
body.lens-weather .attrib { bottom: 12px; }

/* ------------------------------------------------------------ tooltip */

/* left/top pinned to 0 because JS positions it with transform; without the
   origin set, an absolutely-positioned element with no offsets falls back to
   its static position at the end of <body> and the tooltip lands offscreen. */
.tip {
  position: fixed; left: 0; top: 0; z-index: 9; pointer-events: none;
  padding: 6px 9px; border-radius: 7px; font-size: 12px; white-space: nowrap;
  background: rgba(8,11,16,.94); border: 1px solid var(--line-2);
}
.tip b { font: 600 13px/1 var(--mono); }
.tip small { display: block; color: var(--ink-3); font-size: 10.5px; }

/* -------------------------------------------------------------- small */

@media (max-width: 860px) {
  .rail { bottom: auto; max-height: 46vh; width: min(310px, calc(100vw - 24px)); }
  .legend { display: none; }
  .scrubber { left: 12px; }
  /* Narrow screens let the attribution wrap to two lines, so the panel has to
     start higher or it clips it. */
  .panel { top: auto; bottom: 132px; height: 52vh; width: calc(100vw - 24px); }
  .attrib { left: auto; right: 12px; max-width: calc(100vw - 24px); }
  /* The marine credit line names four data holders and wraps to three lines on
     a phone. The desktop lens-marine offset assumes one, so it has to be
     re-stated here or the panel sits on top of the attribution. */
  body.lens-marine .panel { bottom: 68px; }
  /* Freshwater's credit line is longer still — four councils and the advisory. */
  body.lens-freshwater .panel { bottom: 68px; }
  /* Weather's names the same four councils plus Open-Meteo. */
  body.lens-weather .panel { bottom: 68px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
