/* The map.
 *
 * The two kinds of ink, the palette and the type registers are in tokens.css,
 * which every page on this site loads. This file is the instrument: the canvases
 * and the evidence workspace that remains physically separate from them.
 *
 * Layout runs on four shapes, not on a grid framework:
 *   portrait  map above, independently scrolling evidence below
 *   landscape evidence beside an unobstructed map
 *   wide      a calm reading column beside a larger map
 */

/* The active layer keys the accent. */
body[data-layer="normal"]   { --accent: var(--div-3); }
body[data-layer="temp"]     { --accent: var(--temp-3); }
body[data-layer="quality"]  { --accent: var(--quality-4); }
body[data-layer="res"]      { --accent: var(--res-full); }
body[data-layer="ice"]      { --accent: var(--ice); }
body[data-layer="residual"] { --accent: var(--law); }
body[data-layer="use"]      { --accent: var(--use-out); }
body[data-layer="source"]   { --accent: var(--res-full); }

/* The map is one screen and never scrolls; the pages do. */
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; }

/* ---- the two canvases ----
   The base map redraws only when the view or the data changes. The current runs
   on its own canvas every frame over the top, so 3 200 particles never force a
   redraw of 8 711 reaches. touch-action is none so the canvas takes its own
   gestures; the rest of the page still pinches normally. */
#map, #flow { position: fixed; inset: 0; width: 100%; height: 100%; display: block; }
#map { cursor: grab; touch-action: none; }
#map.dragging { cursor: grabbing; }
#map:focus-visible { outline: 3px solid var(--accent); outline-offset: -4px; }
#flow { pointer-events: none; }

.srOnly {
  position: absolute !important; width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important; overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important;
}

/* ---- floating furniture, shared ---- */
.card {
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--hairline);
  border-radius: var(--r);
}

/* ---- title ---- */
#titlebar {
  position: fixed; top: var(--pad); left: calc(var(--pad) + var(--safe-l));
  max-width: min(340px, 34vw);
  pointer-events: none; z-index: 6;
  background: linear-gradient(to right, color-mix(in srgb, var(--plane) 90%, transparent), color-mix(in srgb, var(--plane) 62%, transparent) 70%, color-mix(in srgb, var(--plane) 0%, transparent));
  padding: 10px 40px 12px 12px; margin: -10px 0 0 -12px; border-radius: 8px;
}
#titlebar h1 {
  margin: 0; font-size: clamp(17px, 1.35vw, 24px); font-weight: 600; letter-spacing: -0.015em;
  line-height: 1.15;
}
#titlebar .sub { display: none; margin: 5px 0 0; color: var(--ink-2); font-size: 12.5px; line-height: 1.4; }
@media (min-width: 1500px) { #titlebar .sub { display: block; } }

/* ---- the evidence bar ----
   The one claim this page makes about itself: most of what you see is inference.
   The bar is the drawing's own composition by class of evidence, counted on every
   live read rather than written here in prose. It costs vertical room in the title
   block, so it appears only where there is room for it without pushing the legend
   off the screen; the same figures are in the sources panel at every size. */
#evidence { display: none; margin: 12px 0 0; padding-top: 11px; border-top: 1px solid var(--rule); }
@media (min-width: 1100px) and (min-height: 780px) { #evidence { display: block; } }
@media (min-width: 701px) and (min-height: 1000px) { #evidence { display: block; } }
#evidence .evLabel {
  margin: 0 0 7px; font-size: 10px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-muted);
}
.evBar { display: flex; gap: 2px; height: 8px; }     /* 2px of plane between the fills */
.evBar span { display: block; border-radius: 1px; min-width: 2px; }
.evBar span:first-child { border-radius: 4px 1px 1px 4px; }
.evBar span:last-child  { border-radius: 1px 4px 4px 1px; }
.evKeys { list-style: none; margin: 9px 0 0; padding: 0; }
.evKeys li {
  display: flex; align-items: baseline; gap: 7px;
  font-size: 11.5px; color: var(--ink-2); margin-bottom: 3px;
}
.evKeys i { width: 8px; height: 8px; border-radius: 2px; flex: none; align-self: center; }
.evKeys b {
  margin-left: auto; font-weight: 500; color: var(--ink);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}

/* ---- where the site goes ----
   Map, project record and evidence pages use one route system. The current place
   is stated rather than inferred from which control happens to be missing. */
#siteNav {
  display: flex; flex-wrap: wrap; gap: 2px;
  margin-top: 11px; padding-top: 9px; border-top: 1px solid var(--rule);
  pointer-events: auto;
}
#siteNav a {
  position: relative;
  color: var(--ink-2); text-decoration: none; font-size: 11.5px;
  padding: 5px 7px; border-radius: 5px; white-space: nowrap;
  transition: color 120ms, background 120ms;
}
#siteNav a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
#siteNav a[aria-current="page"] { color: var(--ink); font-weight: 650; }
#siteNav a[aria-current="page"]::after {
  content: ''; position: absolute; right: 7px; bottom: 2px; left: 7px;
  height: 2px; border-radius: 2px; background: var(--accent);
}
#siteNav a.contributeLink { color: var(--accent); font-weight: 650; }

/* Shown once, then never again. The map answers when it is pointed at, and
   nothing on a still screen says so. */
.hint {
  margin: 10px 0 0; font-size: 11.5px; line-height: 1.45;
  color: var(--ink-2); pointer-events: auto;
  transition: opacity 500ms;
}
.hint.gone { opacity: 0; }
.hint a { color: var(--accent); text-decoration: none; border-bottom: 1px solid currentColor; }

#titlebar .stamp {
  margin: 9px 0 0; color: var(--ink-muted); font-size: 11.5px;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}

/* ---- layer switch ----
   Seven layers is too many for one undifferentiated row, so they are grouped by
   the question they answer: what is there now, what is stored, what the law says.
   The group label is the structure doing work, not decoration. */
#modes {
  position: fixed; top: var(--pad); left: 50%; transform: translateX(-50%);
  display: flex; gap: 3px; padding: 3px; z-index: 8;
  background: color-mix(in srgb, var(--surface-1) 90%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--hairline); border-radius: 9px;
  max-width: calc(100vw - 2 * var(--pad));
}
.modeGroup { display: flex; align-items: center; gap: 2px; }
.modeGroup + .modeGroup { border-left: 1px solid var(--rule); padding-left: 5px; margin-left: 2px; }
.modeGroupLabel {
  font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-muted); padding: 0 5px 0 3px; user-select: none;
}
#modes button {
  background: none; border: 0; border-radius: 6px;
  color: var(--ink-muted); font-size: 12px;
  padding: 7px 11px; cursor: pointer; white-space: nowrap;
  transition: background 120ms, color 120ms;
}
#modes button:hover:not(:disabled) { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }
#modes button.on { background: color-mix(in srgb, var(--ink) 11%, transparent); color: var(--ink); }
#modes button:disabled { opacity: 0.32; cursor: default; }

/* ---- map camera ----
   The controls stay where a thumb, mouse or trackpad user can always recover the
   country. The camera itself is bounded in app.js; this is a visible affordance,
   not the only way back. */
#mapControls {
  position: fixed; top: var(--pad); right: calc(var(--pad) + var(--safe-r)); z-index: 8;
  display: grid; gap: 7px; width: 48px;
}
.zoomGroup, #zoomFit, #dataViewOpen {
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
  backdrop-filter: blur(10px); border: 1px solid var(--control-border); border-radius: 9px;
  box-shadow: var(--shadow);
}
.zoomGroup { display: grid; overflow: hidden; }
.zoomGroup button, #zoomFit, #dataViewOpen {
  min-width: 46px; min-height: 46px; padding: 0; border: 0; background: transparent;
  color: var(--ink-2); cursor: pointer; font-family: var(--sans); font-size: 22px;
}
.zoomGroup button:hover, #zoomFit:hover, #dataViewOpen:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 8%, transparent); }
.zoomGroup button:disabled { color: var(--ink-muted); opacity: 0.4; cursor: default; }
#zoomLevel {
  display: grid; place-items: center; min-height: 27px; border-block: 1px solid var(--rule);
  color: var(--ink-muted); font: 10.5px/1 var(--mono); font-variant-numeric: tabular-nums;
}
#zoomFit, #dataViewOpen { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; }

/* ---- non-canvas data view ---- */
#dataView {
  width: min(1040px, calc(100vw - 32px)); max-height: calc(100vh - 32px);
  box-sizing: border-box;
  padding: clamp(22px, 4vw, 44px); color: var(--ink);
  background: var(--surface-1); border: 1px solid var(--control-border);
  border-radius: 14px; box-shadow: 0 28px 90px rgba(0,0,0,0.46);
}
#dataView::backdrop { background: color-mix(in srgb, var(--plane) 72%, transparent); backdrop-filter: blur(4px); }
#dataViewClose {
  position: absolute; top: 10px; right: 10px; width: 44px; height: 44px;
  border: 0; border-radius: 50%; color: var(--ink-muted); background: transparent;
  font: 24px/1 var(--sans); cursor: pointer;
}
#dataViewClose:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 8%, transparent); }
.dataEyebrow {
  margin: 0 48px 8px 0; color: var(--accent); font-size: 10px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
}
#dataViewTitle { margin: 0 48px 8px 0; font: 600 clamp(25px, 4vw, 42px)/1.05 var(--serif); letter-spacing: -0.025em; }
#dataViewLead { max-width: 720px; margin: 0 0 22px; color: var(--ink-2); line-height: 1.5; }
#dataView label { display: block; margin: 0 0 7px; color: var(--ink-2); font-size: 12px; font-weight: 600; }
#dataSearch {
  width: 100%; min-height: 44px; margin: 0 0 14px; padding: 10px 12px;
  color: var(--ink); background: var(--surface-2); border: 1px solid var(--control-border);
  border-radius: 7px; font: 15px/1.3 var(--sans);
}
#dataSearch:focus-visible, #dataView button:focus-visible, #dataView a:focus-visible {
  outline: 3px solid var(--accent); outline-offset: 2px;
}
.dataTableWrap { max-height: min(50vh, 520px); overflow: auto; border-block: 1px solid var(--control-border); }
#dataView table { width: 100%; border-collapse: collapse; font-size: 13px; line-height: 1.4; }
#dataView caption { padding: 10px 0; text-align: left; color: var(--ink-2); font-weight: 600; }
#dataView th { position: sticky; top: 0; z-index: 1; background: var(--surface-1); color: var(--ink-muted); text-align: left; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
#dataView th, #dataView td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
#dataView td:first-child { color: var(--ink); font-weight: 500; }
#dataView td:not(:first-child) { color: var(--ink-2); }
.dataFooter { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
#dataStatus { margin: 0 auto 0 0; color: var(--ink-muted); font: 11px/1.4 var(--mono); }
.dataPager { display: flex; gap: 6px; }
.dataPager button, .dataFooter a {
  min-height: 40px; padding: 0 12px; border: 1px solid var(--control-border);
  border-radius: 6px; color: var(--ink-2); background: transparent; font: 12px/1 var(--sans);
}
.dataPager button { cursor: pointer; }
.dataPager button:disabled { opacity: 0.42; cursor: default; }
.dataFooter a { display: inline-flex; align-items: center; text-decoration: none; white-space: nowrap; }

/* ---- first-visit brief ---- */
#intro {
  width: min(900px, calc(100vw - 32px)); max-height: calc(100vh - 32px);
  padding: clamp(26px, 5vw, 58px); overflow: auto;
  overscroll-behavior: contain; scrollbar-gutter: stable;
  color: var(--ink); background: color-mix(in srgb, var(--surface-1) 97%, var(--plane));
  border: 1px solid var(--hairline); border-radius: 14px; box-shadow: 0 28px 90px rgba(0,0,0,0.42);
}
#intro::backdrop { background: color-mix(in srgb, var(--plane) 68%, transparent); backdrop-filter: blur(5px); }
#introClose {
  position: absolute; top: 12px; right: 12px; width: 42px; height: 42px;
  border: 0; border-radius: 50%; background: transparent; color: var(--ink-muted);
  font: 24px/1 var(--sans); cursor: pointer;
}
#introClose:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.introTop { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin: 0 46px 16px 0; }
.introEyebrow {
  margin: 0; color: var(--accent); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase;
}
.introLangs { margin-left: auto; padding-left: 10px; pointer-events: auto; }
#introTitle {
  max-width: 650px; margin: 0; font: 600 clamp(35px, 6vw, 68px)/0.98 var(--serif);
  letter-spacing: -0.045em; text-wrap: balance;
}
.introLead {
  max-width: 650px; margin: 24px 0 0; color: var(--ink-2);
  font: 400 clamp(16px, 2.1vw, 20px)/1.5 var(--serif);
}
.cycleViz { margin: 30px 0 0; }
.cycleViz svg {
  display: block; width: 100%; height: auto; max-height: 230px;
  border-radius: 9px; background: color-mix(in srgb, var(--surface-2) 78%, transparent);
}
.cycleAtmosphere, .cycleGround, .cycleAquifer, .cycleRiver, .cycleWetland,
.cycleRain, .cycleReturn {
  fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.cycleAtmosphere { stroke: var(--ink-muted); stroke-width: 2; stroke-dasharray: 2 9; }
.cycleMountain { fill: color-mix(in srgb, var(--law) 15%, var(--surface-2)); stroke: var(--law-line); stroke-width: 1.5; }
.cycleMountainBack { opacity: .56; }
.cycleSnow { fill: var(--ice); opacity: .9; }
.cycleGlacier { fill: color-mix(in srgb, var(--ice) 68%, var(--seq-400)); opacity: .9; }
.cycleGround { stroke: var(--law-dim); stroke-width: 2; }
.cycleAquifer { stroke: var(--res-mid); stroke-width: 8; stroke-dasharray: 2 12; opacity: .75; }
.cycleRiver { stroke: var(--seq-300); stroke-width: 7; stroke-dasharray: 18 8; }
.cycleLake { fill: var(--lake); stroke: var(--lake-line); stroke-width: 2; }
.cycleWetland { stroke: rgb(var(--wet-water-rgb)); stroke-width: 3; }
.cycleRain { stroke: var(--seq-200); stroke-width: 3; stroke-dasharray: 3 8; }
.cycleReturn { stroke: var(--ink-muted); stroke-width: 2; stroke-dasharray: 5 8; }
.cycleSource { fill: var(--res-full); stroke: var(--res-head); stroke-width: 2; }
.cycleUse { fill: var(--surface-2); stroke: var(--use-out); stroke-width: 4; }
.cycleViz figcaption {
  max-width: 720px; margin: 13px 0 0; color: var(--ink-2);
  font: 400 14px/1.5 var(--serif);
}
.cycleStages {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  list-style: none; margin: 16px 0 0; padding: 1px; overflow: hidden;
  background: var(--rule); border-radius: 8px;
}
.cycleStages li { min-width: 0; background: var(--surface-1); }
.cycleStages button {
  display: grid; gap: 4px; width: 100%; min-height: 62px; padding: 11px 13px;
  text-align: left; color: var(--ink); background: transparent; border: 0;
  font-family: var(--sans); cursor: pointer;
}
.cycleStages button:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.cycleStages button:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.cycleStages b { overflow-wrap: anywhere; font-size: 12px; line-height: 1.25; font-weight: 600; }
.cycleStages span { color: var(--ink-muted); font-size: 10.5px; line-height: 1.25; }
.cycleGap { margin: 12px 0 0; color: var(--ink-muted); font-size: 11px; line-height: 1.45; }
.cycleGap a { color: var(--ink-2); text-decoration-color: var(--hairline); text-underline-offset: 3px; }
.cycleGap a:hover { color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .cycleRiver, .cycleRain, .cycleReturn { animation: cycleMove 7s linear infinite; }
  @keyframes cycleMove { to { stroke-dashoffset: -52; } }
}
.introFacts {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  list-style: none; margin: 32px 0 0; padding: 1px; background: var(--rule);
  border-radius: 8px; overflow: hidden;
}
.introFacts li { display: grid; gap: 7px; padding: 17px 18px; background: var(--surface-1); }
.introFacts strong { color: var(--ink); font: 500 18px/1 var(--mono); }
.introFacts span { color: var(--ink-muted); font-size: 11.5px; line-height: 1.3; }
.introActions { display: flex; align-items: center; gap: 16px; margin-top: 28px; }
#introEnter, .introActions a {
  display: inline-flex; align-items: center; justify-content: center; min-height: 48px;
  border-radius: 7px; padding: 0 18px; font-size: 13px; font-weight: 600; text-decoration: none;
}
#introEnter { border: 1px solid var(--accent); background: var(--accent); color: var(--plane); cursor: pointer; }
#introEnter:hover { filter: brightness(1.08); }
.introActions a { color: var(--ink-2); border: 1px solid var(--hairline); }
.introActions a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.introNote { margin: 20px 0 0; color: var(--ink-muted); font-size: 11px; }

/* ---- legend ---- */
#legend {
  position: fixed; left: calc(var(--pad) + var(--safe-l)); bottom: calc(var(--pad) + var(--safe-b));
  width: var(--legend-w); z-index: 7;
  background: color-mix(in srgb, var(--surface-1) 90%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--hairline); border-radius: var(--r);
  padding: 14px 14px 12px;
  /* never up into the title block: it carries the evidence bar, which is the one
     claim the page makes about itself and must not be covered by a legend */
  max-height: calc(100vh - var(--title-h) - var(--pad) - var(--safe-b) - 14px);
  overflow-y: auto; overscroll-behavior: contain;
}
#legend h2 {
  margin: 0 0 8px; font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted);
}
#sheetHandle { display: none; }

.ramp { height: 8px; border-radius: 4px; }
.ramp-seq {
  background: linear-gradient(90deg,
    var(--seq-600) 0%, var(--seq-500) 20%, var(--seq-450) 40%,
    var(--seq-400) 58%, var(--seq-300) 74%, var(--seq-200) 88%, var(--seq-100) 100%);
}
/* Diverging: brown below the mean, blue above, grey at it. Grey in the middle on
   purpose — a river at its long-term mean is not news. */
.ramp-div {
  background: linear-gradient(90deg,
    var(--div-1) 0%, var(--div-2) 15%, var(--div-3) 28%, var(--div-4) 40%,
    var(--div-5) 50%, var(--div-6) 60%, var(--div-7) 72%, var(--div-8) 86%, var(--div-9) 100%);
}
.ramp-res {
  background: linear-gradient(90deg,
    var(--res-1) 0%, var(--res-2) 20%, var(--res-3) 40%, var(--res-4) 60%, var(--res-5) 80%, var(--res-6) 100%);
}
.ramp-temp {
  background: linear-gradient(90deg,
    var(--temp-1) 0%, var(--temp-2) 26%, var(--temp-3) 52%, var(--temp-4) 78%, var(--temp-5) 100%);
}
.ramp-quality {
  background: linear-gradient(90deg,
    var(--quality-1) 0%, var(--quality-2) 20%, var(--quality-3) 40%,
    var(--quality-4) 60%, var(--quality-5) 80%, var(--quality-6) 100%);
}
.rampLabels {
  display: flex; justify-content: space-between; margin-top: 5px;
  font-size: 10px; color: var(--ink-muted);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.notes { list-style: none; margin: 12px 0 0; padding: 0; font-size: 12px; color: var(--ink-2); }
.notes li { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.swatch { width: 22px; height: 3px; border-radius: 2px; flex: none; }
.swatch.measured  { background: var(--seq-200); }
.swatch.estimated { background: var(--seq-200); opacity: 0.6; }
.swatch.nobasis   { background: var(--ev-none-dim); }
.swatch.ice1850 { background: rgba(var(--ice-past-rgb),0.42); height: 8px; border: 1px solid rgba(var(--ice-past-rgb),0.7); }
.swatch.ice2023 { background: var(--ice); height: 8px; }
.swatch.resFull  { width: 10px; height: 10px; border-radius: 50%; background: var(--res-full); }
.swatch.resFlood { width: 10px; height: 10px; border-radius: 50%; background: var(--res-flood); }
/* statutory swatches wear the bone, because they mark a computed legal minimum */
.swatch.resiMeas { width: 10px; height: 10px; border-radius: 50%; background: var(--law); }
.swatch.resiMod  { width: 10px; height: 10px; border-radius: 50%; background: transparent; box-shadow: inset 0 0 0 1.5px var(--law-dim); }

/* The wetland inventories. Two registers, and the swatch has to carry which: an
   area in the water's hue is protected by an ordinance whose aim is stated as water,
   an area in bone is protected by Art. 78(5) BV outright. Mire landscapes are the
   outline with no fill, exactly as they are drawn on the plane. */
.wetKeys li { align-items: baseline; }
.wetKeys .swatch { width: 12px; height: 12px; border-radius: 2px; }
.swatch.wet_auen  { background: rgba(var(--wet-key-rgb),0.30); box-shadow: inset 0 0 0 1px rgba(var(--wet-key-rgb),0.75); }
.swatch.wet_amphi { background: rgba(var(--wet-key-rgb),0.14); box-shadow: inset 0 0 0 1px rgba(var(--wet-key-rgb),0.55); }
.swatch.wet_hoch  { background: rgba(var(--law-rgb),0.34); box-shadow: inset 0 0 0 1px rgba(var(--law-rgb),0.8); }
.swatch.wet_flach { background: rgba(var(--law-rgb),0.18); box-shadow: inset 0 0 0 1px rgba(var(--law-rgb),0.58); }
.swatch.wet_moorl { background: transparent; box-shadow: inset 0 0 0 1px rgba(var(--law-rgb),0.5); }
/* Count and area sit right, in the mono, because they are measured figures. */
.wetKeys li i { margin-left: auto; font-style: normal; font-family: var(--mono);
                font-size: 10px; color: var(--ink-muted); white-space: nowrap; }
.wetKeys li i .wetKm { margin-left: 8px; color: var(--ink-2); }

.lgNote { margin: 9px 0 0; font-size: 11px; line-height: 1.5; color: var(--ink-muted); }
.lgNote b { color: var(--ink-2); font-weight: 600; }

/* Quality is dense in evidence but sparse in controls: a handful of useful
   starting points, then the complete federal parameter register in one native
   select. The select remains a platform control on phones, where 724 custom menu
   items would be both slower and less accessible. */
.qualityPicker { display: grid; gap: 6px; margin-bottom: 10px; }
.qualityPicker label, .qualityYear label {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  color: var(--ink-muted); font-size: 10px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
}
#qualityParameter {
  width: 100%; min-height: 38px; padding: 7px 28px 7px 9px;
  border: 1px solid var(--hairline); border-radius: 6px;
  background: var(--surface-2); color: var(--ink-2); font-size: 12px;
}
.qualityPresets { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0 12px; }
.qualityPresets button {
  min-height: 30px; padding: 4px 7px; border: 1px solid var(--hairline); border-radius: 999px;
  background: transparent; color: var(--ink-muted); cursor: pointer; font-size: 10.5px;
}
.qualityPresets button:hover, .qualityPresets button.on {
  border-color: var(--accent); color: var(--ink); background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.qualityYear { margin: 12px 0 10px; padding: 10px 0; border-block: 1px solid var(--rule); }
.qualityYear output { color: var(--ink); font: 500 12px/1 var(--mono); letter-spacing: 0; }
#qualityYear { width: 100%; height: 32px; margin: 3px 0 0; accent-color: var(--accent); }
.qualityKeys .swatch { width: 11px; height: 11px; border-radius: 2px; transform: rotate(45deg); }
.swatch.qualityValue { background: var(--quality-5); box-shadow: inset 0 0 0 1px var(--quality-hi); }
.swatch.qualityBelow { background: transparent; box-shadow: inset 0 0 0 1.5px var(--quality-hi); }
.swatch.qualityNone { background: transparent; box-shadow: inset 0 0 0 1px var(--ink-muted); opacity: .42; }

.useKeys .swatch { width: 10px; height: 10px; border-radius: 50%; }
/* Two hues and four registers, so the register is in the form: a filled disc has a
   quantity behind it, an open ring has a place and nothing more, and the four
   nuclear sites get a second ring because four points among three thousand cannot
   be found by hue alone. */
.swatch.useHydro { background: var(--use-out); }
.swatch.useAbs   { background: transparent; box-shadow: inset 0 0 0 2px var(--use-out); }
.swatch.useNpp   { background: transparent;
                   box-shadow: inset 0 0 0 2px var(--use-out), inset 0 0 0 4px var(--surface-1),
                               inset 0 0 0 5px var(--use-out); }
.swatch.useAra   { background: var(--use-in); }
/* Where the water comes from. The one layer this map draws itself, the
   headwaters, wears the map's own teal; the three that arrive as somebody else's
   picture wear the wash they are actually drawn in, at the alpha they are drawn
   at, so the legend is a sample of the screen rather than a promise about it. */
.srcKeys .swatch { width: 14px; height: 10px; border-radius: 2px; }
/* These three key a picture this map does not draw: they are federal and cantonal
   WMS tiles, rendered on a server that has never heard of this page and returns the
   same pixels on either surface. A swatch that moved with the theme would stop
   matching the thing it is a key to, so these three alone are written literally. */
.swatch.srcGw    { background: rgba(90,140,190,0.62); border: 1px solid rgba(140,180,220,0.5); }
.swatch.srcZone  { background: rgba(158,86,196,0.8); border: 1px solid rgba(190,130,220,0.7); }
.swatch.srcCatch { background: rgba(150,150,150,0.30); border: 1px solid rgba(190,190,190,0.35); }
.swatch.srcHead  { width: 22px; height: 3px; border-radius: 2px; background: var(--res-mid); }
.srcKeys li { display: block; }
.srcKeys label { display: flex; align-items: center; gap: 0.45rem; cursor: pointer; padding: 3px 0; }
.srcKeys input { margin: 0; accent-color: var(--accent); }

.useKeys li { display: block; }
.useKeys label { display: flex; align-items: center; gap: 0.45rem; cursor: pointer; padding: 3px 0; }
.useKeys input { margin: 0; accent-color: var(--accent); }
.useDir {
  margin: 11px 0 2px; font-size: 10px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-muted);
}
.useDir:first-child { margin-top: 0; }

/* The 25 C ceiling is a status, not a value on the ramp, so it ships with a label
   and is never left to colour alone. */
.threshold {
  display: flex; align-items: center; gap: 6px;
  margin: 10px 0 0; padding: 5px 8px; border-radius: 3px;
  background: color-mix(in srgb, var(--critical) 13%, transparent); border: 1px solid color-mix(in srgb, var(--critical) 34%, transparent);
  font-size: 11px; line-height: 1.35; color: var(--ink-2);
}
.threshold i {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--temp-5); box-shadow: 0 0 0 2px var(--critical);
}

.controls { margin-top: 12px; border-top: 1px solid var(--rule); padding-top: 10px; }
.controls label {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--ink-2); margin-bottom: 6px; cursor: pointer;
  min-height: 22px;
}
.controls input { accent-color: var(--accent); margin: 0; }
/* The ground is a choice of one, so it is radios laid on a line rather than a
   column of checkboxes: three grounds stacked read as three things you can have. */
.groundRow { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px;
             margin-top: 8px; border-top: 0; padding-top: 0; }
.groundRow label { margin-bottom: 0; }
.ctlLabel { font-size: 10px; font-weight: 600; letter-spacing: 0.09em;
            text-transform: uppercase; color: var(--ink-muted); }

/* Live only. It removes 98 % of the map, so it does not sit in the same list as
   the switch for the gauge dots: it gets a rule of its own and states what it
   took away in the same breath. */
.liveRow { margin-top: 10px; border-top: 1px solid var(--rule); padding-top: 10px; }
.liveSwitch {
  display: flex; align-items: center; gap: 7px; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--ink-2); min-height: 22px;
}
.liveSwitch input { accent-color: var(--ev-measured); margin: 0; }
body.liveOnly .liveSwitch { color: var(--ev-measured); }
body.liveOnly #liveNote { margin-top: 6px; }
#liveNote:empty { display: none; }
#liveNote.flash { color: var(--ev-measured); transition: color 120ms; }
@media (prefers-reduced-motion: reduce) { #liveNote.flash { transition: none; } }
/* A layer built on an old register is not disabled under Live only, it is struck
   through: disabling it would hide the fact that the map has four of them. */
#modes button.archival {
  opacity: 0.42;
  text-decoration: line-through;
  text-decoration-color: var(--ev-none);
  text-decoration-thickness: 1px;
}

.btnRow { display: grid; gap: 6px; margin-top: 10px; }
.btnRow button, .btnRow a {
  display: block; width: 100%; padding: 8px 10px; min-height: 34px;
  background: transparent; color: var(--ink-2);
  border: 1px solid var(--hairline); border-radius: 6px;
  font-size: 12px; cursor: pointer; text-align: center; text-decoration: none;
  transition: background 120ms, color 120ms;
}
.btnRow button:hover, .btnRow a:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); color: var(--ink); }
.btnRow button:disabled { opacity: 0.5; cursor: default; }
/* The two that leave for a page about the law wear the statutory ink, so that the
   destination is legible before the click. */
.btnLaw { color: var(--law-dim) !important; border-color: var(--law-line) !important; }
.btnLaw:hover { background: var(--law-bg) !important; color: var(--law) !important; }

/* ---- the time ribbon ----
   The signature of the page. On the layers that describe only now it is not
   there at all. On the layers that describe a change it carries the record: the
   reservoir series against twenty-six years of itself, the ice across five dated
   surveys held in their real intervals. It is a chart and a control at once. */
#ribbon {
  position: fixed; z-index: 7;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--pad) + var(--safe-b));
  width: min(760px, calc(100vw - 2 * var(--pad) - var(--legend-w) - var(--panel-w) - 40px));
  min-width: 320px;
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--hairline); border-radius: var(--r);
  padding: 10px 12px 8px;
}
#ribbon[hidden] { display: none; }
/* The read-out is the sentence the layer exists to say, and on the reservoir
   layer it runs to seventy characters. It must never be the thing that gives
   way: the head wraps and the read-out takes the second line whole rather than
   squeezing the label into an ellipsis. */
.ribbonHead { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
#ribbon h2 {
  margin: 0; font-size: 11px; font-weight: 600; flex: 0 1 auto; min-width: 0;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#ribbonRead {
  flex: 1 1 auto;
  font-size: 12px; color: var(--ink);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: right;
}
#play {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  background: color-mix(in srgb, var(--ink) 7%, transparent); color: var(--ink-2);
  border: 1px solid var(--hairline); border-radius: 6px;
  padding: 5px 10px; min-height: 28px; cursor: pointer; font-size: 11.5px;
}
#play:hover { background: color-mix(in srgb, var(--ink) 12%, transparent); color: var(--ink); }
#play svg { fill: currentColor; }
#play:disabled { opacity: 0.45; cursor: default; }
#ribbonCv { display: block; width: 100%; height: 74px; margin-top: 8px; }
#scrub {
  -webkit-appearance: none; appearance: none; width: 100%; height: 18px;
  background: transparent; margin: 2px 0 0; cursor: pointer;
}
#scrub::-webkit-slider-runnable-track { height: 2px; background: var(--rule); border-radius: 1px; }
#scrub::-moz-range-track { height: 2px; background: var(--rule); border-radius: 1px; }
#scrub::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%; margin-top: -6px;
  background: var(--ink); border: 0; box-shadow: 0 0 0 3px rgba(var(--halo-rgb),0.8);
}
#scrub::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink); border: 0; box-shadow: 0 0 0 3px rgba(var(--halo-rgb),0.8);
}
.ribbonNote { margin: 4px 0 0; font-size: 10.5px; line-height: 1.45; color: var(--ink-muted); }
.ribbonNote b { color: var(--ink-2); }

/* ---- detail panel ---- */
#panel {
  position: fixed; right: calc(var(--pad) + var(--safe-r)); top: calc(var(--pad) + 48px);
  width: var(--panel-w); z-index: 9;
  background: color-mix(in srgb, var(--surface-1) 93%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--hairline); border-radius: var(--r);
  padding: 16px 16px 14px;
  max-height: calc(100vh - 2 * var(--pad) - 48px);
  overflow-y: auto; overscroll-behavior: contain;
}
#panel h2 { margin: 0 26px 12px 0; font-size: 15px; font-weight: 600; line-height: 1.25; }
#panelClose {
  position: absolute; top: 10px; right: 10px;
  background: none; border: 0; color: var(--ink-muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 4px 9px;
  min-width: 34px; min-height: 34px;
}
#panelClose:hover { color: var(--ink); }
#panel dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; }
#panel dt { color: var(--ink-muted); font-size: 12px; }
#panel dd {
  margin: 0; text-align: right; font-size: 13px;
  font-family: var(--mono); font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
#panel dd .unit { color: var(--ink-muted); font-size: 11px; margin-left: 3px; font-family: var(--sans); }
/* a row whose value is a word rather than a quantity */
#panel dd.plain { font-family: var(--sans); font-variant-numeric: normal; font-size: 12.5px; color: var(--ink-2); }
#panel a { color: var(--seq-200); }
/* a row that states a legal quantity wears the statutory ink */
#panel dd.statutory { color: var(--law); font-family: var(--serif); }
#panel dt.statutory { color: var(--law-dim); }

.panelNote {
  margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--rule);
  font-size: 11px; line-height: 1.55; color: var(--ink-muted);
}
.panelNote b { color: var(--ink-2); }
.pill {
  display: inline-block; padding: 1px 7px; border-radius: 10px;
  font-size: 11px; font-weight: 600;
}
.pill.d1 { background: color-mix(in srgb, var(--good) 18%, transparent);  color: var(--good); }
.pill.d2 { background: color-mix(in srgb, var(--warning) 18%, transparent); color: var(--warning); }
.pill.d3 { background: color-mix(in srgb, var(--serious) 20%, transparent); color: var(--serious); }
.pill.d4, .pill.d5 { background: color-mix(in srgb, var(--critical) 22%, transparent); color: var(--critical); }

.aside, .flag, .statute {
  /* declared block so they read the same whether the panel emits a <p> or drops
     one inline into a note as a <span> */
  display: block;
  margin: 12px 0 0; padding: 8px 10px; border-radius: 6px;
  font-size: 11px; line-height: 1.5;
}
.aside { background: color-mix(in srgb, var(--ink) 4%, transparent); border: 1px solid var(--hairline); color: var(--ink-muted); }
.flag  { background: color-mix(in srgb, var(--critical) 14%, transparent); border: 1px solid color-mix(in srgb, var(--critical) 35%, transparent); color: var(--ink-2); }
/* a block that carries a statutory consequence, in the statutory ink */
.statute {
  background: var(--law-bg); border: 1px solid var(--law-line);
  color: var(--law); font-family: var(--serif); font-size: 11.5px;
}
.statute b { color: var(--law-hi); }

/* ---- the tongue sparkline ---- */
.spark { margin: 12px 0 0; }
.spark svg { width: 100%; height: auto; display: block; }
.sparkZero { stroke: var(--rule); stroke-width: 1; }
.sparkLine { fill: none; stroke: var(--seq-200); stroke-width: 1.4; stroke-linejoin: round; }
.spark figcaption { margin-top: 5px; font-size: 10.5px; color: var(--ink-muted); }

/* Exact NAWA samples, loaded only after a quality station is opened. Each row is
   a compact lab record, not a chart point stripped of its sampling window. */
.qualityExact { margin: 12px 0 0; }
.qualityExact h3 { margin: 0 0 7px; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-muted); }
.qualitySamples { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.qualitySamples li { display: grid; grid-template-columns: minmax(82px, auto) 1fr; gap: 3px 10px; padding: 8px 0; border-bottom: 1px solid var(--rule); }
.qualitySamples time { color: var(--ink-muted); font-size: 10.5px; }
.qualitySamples strong { justify-self: end; color: var(--ink); font: 500 11.5px/1.3 var(--mono); }
.qualitySamples small { grid-column: 1 / -1; color: var(--ink-muted); font-size: 10px; line-height: 1.4; overflow-wrap: anywhere; }
.qualitySamples .below { color: var(--quality-hi); }
.qualityApi { margin: 8px 0 0; color: var(--ink-muted); font-size: 10px; }

/* ---- tooltip ---- */
#tooltip {
  position: fixed; pointer-events: none; z-index: 20;
  background: color-mix(in srgb, var(--surface-1) 95%, transparent);
  border: 1px solid var(--hairline); border-radius: 7px;
  padding: 7px 10px; font-size: 12px; max-width: 240px;
  box-shadow: var(--shadow);
}
#tooltip .tName { font-weight: 600; }
#tooltip .tName.num { color: var(--ink); }
#tooltip .tVal { color: var(--ink-2); font-family: var(--mono); font-variant-numeric: tabular-nums; }
#tooltip .tVal i { color: var(--ink-muted); font-style: normal; margin: 0 5px; }
#tooltip .tEst { color: var(--ink-muted); font-size: 11px; }
/* Rhein, Le Rhin, Rein and Reno are one river. The other names it has are shown
   rather than chosen between, in the face the map uses for a name on the water. */
#tooltip .tAlt { color: var(--ink-muted); font-size: 11px; font-style: italic; margin-top: 2px; }
#tooltip .tLaw { color: var(--law); font-family: var(--serif); font-size: 11.5px; }

/* ---- credits ---- */
#credits {
  position: fixed; right: calc(var(--pad) + var(--safe-r)); bottom: calc(var(--pad) + var(--safe-b));
  max-width: 430px; z-index: 5;
  font-size: 10.5px; line-height: 1.55; color: var(--ink-muted);
  text-align: right; pointer-events: none;
  background: linear-gradient(to left, color-mix(in srgb, var(--plane) 88%, transparent), color-mix(in srgb, var(--plane) 74%, transparent) 70%, color-mix(in srgb, var(--plane) 0%, transparent));
  padding: 10px 12px 10px 40px; border-radius: 8px;
}
body.hasRibbon #credits { display: none; }
#credits p { margin: 0; }
#credits strong { color: var(--ink-2); font-weight: 600; }
#credits em { color: var(--law-dim); font-style: normal; }
.creditsNav { display: flex; flex-wrap: wrap; gap: 5px 14px; margin-top: 9px; }
.creditsNav a { color: var(--ink-2); text-decoration: none; }
.creditsNav a:last-child { color: var(--accent); }
.creditsNav a:hover { color: var(--ink); text-decoration: underline; }

/* ============================================================
   Responsive furniture: keep every fixed element in its own measured region.
   ============================================================ */
/* Five translated groups need as much as 1 284 px; the wide title needs 460 px.
   They share the top line only once both fit beside the camera controls. Until
   then the switch stays at the foot and the furniture there lifts over it. */
@media (max-width: 1899px) {
  #modes { top: auto; bottom: calc(var(--pad) + var(--safe-b)); }
  #credits { bottom: calc(var(--pad) + var(--safe-b) + 52px); }
  #panel { top: var(--pad); max-height: calc(100vh - 2 * var(--pad) - 56px); }
  #legend { bottom: calc(var(--pad) + var(--safe-b) + 52px);
            max-height: calc(100vh - var(--title-h) - var(--pad) - var(--safe-b) - 66px); }
  #ribbon { bottom: calc(var(--pad) + var(--safe-b) + 52px); }
}

@media (max-width: 1499px) {
  #credits { display: none; }
}

/* A tablet has room for the layer names, but not for five additional group
   captions. The group landmarks remain in the accessibility tree and the rules
   between them remain visible. If the translated names still need more room,
   the rail is deliberately scrollable by touch, trackpad, wheel and keyboard. */
@media (min-width: 701px) and (max-width: 1340px) {
  #modes {
    overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
    touch-action: pan-x; scroll-snap-type: x proximity; scroll-padding-inline: 8px;
    scrollbar-width: thin; scrollbar-color: var(--rule) transparent;
    justify-content: safe center; padding-inline: 8px;
  }
  #modes::-webkit-scrollbar { height: 3px; }
  #modes::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 3px; }
  #modes button {
    min-height: 44px; padding-inline: 8px; font-size: 11.5px;
    scroll-snap-align: center;
  }
  .modeGroup { flex: none; }
  .modeGroup + .modeGroup { margin-left: 1px; padding-left: 4px; }
  .modeGroupLabel { display: none; }
}

/* On a genuinely wide screen the rail occupies the measured gap between the
   460 px reading column and the camera controls instead of being centred over
   the title. */
@media (min-width: 1900px) {
  #modes {
    left: calc(var(--pad) + 484px); right: calc(var(--pad) + 64px);
    transform: none; max-width: none; justify-content: center;
  }
}

@media (max-width: 1180px) {
  :root { --panel-w: 268px; --legend-w: 250px; }
  #ribbon { width: min(560px, calc(100vw - 2 * var(--pad) - var(--legend-w) - 24px)); }
}

/* Between phone and desktop the legend keeps the left rail, so the ribbon stops
   being centred and takes the room that is left beside it. */
@media (min-width: 701px) and (max-width: 1180px) {
  #ribbon {
    left: auto; right: calc(var(--pad) + var(--safe-r)); transform: none;
    width: min(560px, calc(100vw - 3 * var(--pad) - var(--legend-w)));
  }
}

@media (max-width: 900px) {
  :root { --panel-w: 260px; --legend-w: 230px; }
  #titlebar { max-width: 54vw; }
}

/* ============================================================
   Phone. One sheet, three snap states, and the map keeps the screen.
   The legend stops being a floating card and becomes a bottom sheet with a
   handle: peek shows the layer name, half shows the legend, full scrolls.
   ============================================================ */
@media (max-width: 700px) {
  :root { --fs-base: 15px; --panel-w: auto; }

  #titlebar {
    top: 0; left: 0; right: 0; max-width: none;
    padding: calc(8px + var(--safe-t)) calc(10px + var(--safe-r)) 8px calc(10px + var(--safe-l));
    margin: 0; border-radius: 0;
    background: linear-gradient(to bottom, color-mix(in srgb, var(--plane) 94%, transparent), color-mix(in srgb, var(--plane) 70%, transparent) 60%, color-mix(in srgb, var(--plane) 0%, transparent));
  }
  #titlebar h1 { font-size: 16px; }
  #titlebar .stamp {
    margin-top: 3px; overflow: hidden; font-size: 11px;
    white-space: nowrap; text-overflow: ellipsis;
  }
  #titlebar .hint { display: none; }
  #siteNav { flex-wrap: nowrap; align-items: center; margin-top: 7px; padding-top: 6px; }
  #titlebar .langs { margin-left: auto; padding-left: 4px; }
  #titlebar .langs [lang] {
    display: grid; place-items: center; min-width: 28px; min-height: 44px; padding: 0 2px;
  }
  #titlebar .themeBtn { width: 44px; height: 44px; }

  /* the layer switcher scrolls horizontally rather than wrapping or shrinking
     below a usable tap target */
  #modes {
    /* --title-h is the measured foot of the masthead, so the switch follows it
       whether or not the title wrapped and whether or not the prompt is shown. */
    top: var(--title-h); bottom: auto; left: 0; right: 0; transform: none;
    max-width: none; border-radius: 0; border-left: 0; border-right: 0;
    overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
    scroll-snap-type: x proximity;
    padding: 4px calc(8px + var(--safe-l)) 4px calc(8px + var(--safe-r));
    justify-content: flex-start;
  }
  #modes::-webkit-scrollbar { display: none; }
  #modes button {
    min-height: 44px; padding: 10px 13px; font-size: 12.5px;
    scroll-snap-align: start;
  }
  .modeGroupLabel { display: none; }
  .modeGroup + .modeGroup { margin-left: 4px; padding-left: 6px; }

  #mapControls {
    top: calc(var(--title-h) + 55px); right: calc(8px + var(--safe-r));
    display: flex; width: auto; gap: 6px;
  }
  .zoomGroup { display: flex; }
  .zoomGroup button { min-width: 44px; min-height: 44px; }
  #zoomLevel { min-width: 37px; min-height: 44px; border-block: 0; border-inline: 1px solid var(--rule); }
  #zoomFit, #dataViewOpen { min-width: 48px; min-height: 46px; }

  #dataView { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; padding: 22px 16px 16px; border: 0; border-radius: 0; }
  #dataViewLead { font-size: 13px; }
  .dataTableWrap { max-height: calc(100dvh - 340px); overflow-x: hidden; overflow-y: auto; border: 0; }
  #dataView table, #dataView tbody { display: block; width: 100%; }
  #dataView thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  #dataView tbody { display: grid; gap: 9px; }
  #dataView tr {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 14px;
    padding: 12px; background: var(--surface-2); border: 1px solid var(--rule); border-radius: 8px;
  }
  #dataView td {
    display: block; min-width: 0; padding: 0; border: 0;
    overflow-wrap: anywhere; word-break: normal;
  }
  #dataView td:first-child, #dataView td:nth-child(4), #dataView td:only-child { grid-column: 1 / -1; }
  #dataView td[data-label]::before {
    display: block; margin-bottom: 3px; color: var(--ink-muted); content: attr(data-label);
    font: 600 10px/1.2 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  }
  .dataFooter { flex-wrap: wrap; }
  #dataStatus { flex-basis: 100%; }

  /* ---- the sheet ---- */
  #legend {
    left: 0; right: 0; bottom: 0; width: auto; max-height: 76vh; max-height: 76dvh;
    border-radius: 14px 14px 0 0; border-left: 0; border-right: 0; border-bottom: 0;
    padding: 0 0 calc(10px + var(--safe-b));
    background: color-mix(in srgb, var(--surface-1) 96%, transparent);
    transition: transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1);
    overflow: hidden;
    display: flex; flex-direction: column;
  }
  #sheetHandle {
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    width: 100%; padding: 8px 14px 10px; min-height: 46px;
    background: none; border: 0; color: var(--ink-2); cursor: pointer;
    touch-action: none;
  }
  .grip { width: 38px; height: 4px; border-radius: 2px; background: var(--rule); }
  .sheetTitle {
    font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-muted);
  }
  #legendBody {
    padding: 0 14px 14px; overflow-y: auto; overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  #legend.collapsed #legendBody { overflow: hidden; }
  #legend h2 { display: none; }             /* the handle carries the title */
  #legendBody .notes, #legendBody .lgNote { font-size: 13px; line-height: 1.5; }
  #legendBody .rampLabels { font-size: 11px; }
  #legendBody .useDir, #legendBody .ctlLabel { font-size: 11px; }
  .btnRow { grid-template-columns: 1fr 1fr; }
  .btnRow button:first-child { grid-column: 1 / -1; }
  .btnRow button, .btnRow a { min-height: 44px; line-height: 26px; }
  .controls label { min-height: 44px; }
  #qualityParameter { min-height: 44px; font-size: 13px; }
  .qualityPresets button { min-height: 44px; padding-inline: 10px; }
  #qualityYear { height: 44px; }

  /* the panel becomes a second sheet, over the first */
  #panel {
    left: 0; right: 0; top: auto; bottom: 0; width: auto;
    max-height: 72vh; max-height: 72dvh; border-radius: 14px 14px 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: 16px 14px calc(16px + var(--safe-b));
    background: color-mix(in srgb, var(--surface-1) 97%, transparent);
    z-index: 12;
    animation: sheetUp 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  @keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
  #panelClose { top: 8px; right: 8px; min-width: 44px; min-height: 44px; }
  #panel h2 { font-size: 17px; }
  #panel dt, #panel dd.plain { font-size: 13px; }
  #panel dd { font-size: 13.5px; }
  .panelNote, #panel .aside, #panel .flag, #panel .statute { font-size: 12.5px; }
  .qualitySamples time, .qualitySamples small, .qualityApi { font-size: 11.5px; }
  .qualitySamples strong { font-size: 12.5px; }

  /* the ribbon sits above the sheet */
  #ribbon {
    left: 8px; right: 8px; width: auto; min-width: 0; transform: none;
    bottom: calc(var(--sheet-h) + 8px + var(--safe-b));
    transition: bottom 260ms cubic-bezier(0.22, 0.61, 0.36, 1);
    padding: 8px 10px 6px;
  }
  #ribbonCv { height: 60px; }
  /* the reading gets its own line rather than a truncation: on this layer the
     clause that says where the week sits against the record is the whole point */
  .ribbonHead { flex-wrap: wrap; }
  #ribbon h2 { display: none; }
  #ribbonRead {
    flex: 1 0 100%; order: 2; text-align: left;
    white-space: normal; font-size: 12px; line-height: 1.35; margin-top: 6px;
  }
  #play { min-height: 44px; }
  #scrub { height: 44px; margin-top: -8px; }
  #scrub::-webkit-slider-thumb { width: 20px; height: 20px; margin-top: -9px; }
  #scrub::-moz-range-thumb { width: 20px; height: 20px; }
  .ribbonNote { display: none; }

  #tooltip { display: none; }               /* a finger has no hover */

  #intro {
    width: calc(100vw - 12px); max-height: calc(100vh - 12px); max-height: calc(100dvh - 12px);
    padding: calc(22px + var(--safe-t)) 18px calc(20px + var(--safe-b)); border-radius: 12px;
  }
  #introTitle { font-size: clamp(30px, 10vw, 44px); line-height: 1; }
  .introTop { align-items: flex-start; flex-direction: column; gap: 8px; margin-right: 42px; }
  .introLangs { margin-left: 0; padding-left: 0; border-left: 0; }
  #intro .introLangs [lang] {
    display: grid; place-items: center; min-width: 40px; min-height: 44px; padding: 0;
  }
  .introLead { margin-top: 15px; font-size: 15px; line-height: 1.42; }
  .introActions { align-items: stretch; flex-direction: column; gap: 8px; margin-top: 18px; }
  #introEnter, .introActions a { width: 100%; min-height: 48px; }
  .cycleViz { margin-top: 22px; }
  .cycleViz svg { height: 118px; max-height: none; }
  .cycleViz figcaption { margin-top: 10px; font-size: 13px; line-height: 1.4; }
  .cycleStages { grid-template-columns: repeat(2, 1fr); }
  .cycleStages li:last-child { grid-column: 1 / -1; }
  .cycleStages button { min-height: 68px; padding: 10px; }
  .introFacts { grid-template-columns: 1fr; margin-top: 23px; }
  .introFacts li { grid-template-columns: 105px 1fr; align-items: baseline; padding: 12px 14px; }
}

/* very small phones: give the numbers room by dropping the sub-labels */
@media (max-width: 380px) {
  #modes button { padding: 10px 11px; font-size: 12px; }
  #titlebar h1 { font-size: 15px; }
  #titlebar .langs [lang] { min-width: 26px; }
  .cycleStages b { font-size: 11.5px; }
}

@media (max-width: 480px) {
  .introFacts, .introNote { display: none; }
}

/* short landscape phones: the sheet would eat the map */
@media (max-height: 480px) and (orientation: landscape) and (max-width: 940px) {
  #titlebar .sub, #titlebar .stamp, #titlebar .hint { display: none; }
  #titlebar h1 { font-size: 14px; }
  #siteNav { margin-top: 4px; padding-top: 3px; }
  #legend { max-height: 60vh; }
  #ribbon { display: none; }
}

@media (min-width: 701px) and (max-width: 940px) and (max-height: 480px) and (orientation: landscape) {
  #legend { overflow: auto; overscroll-behavior: contain; }
}

/* ============================================================
   Wide and very wide. Switzerland is about 2.2:1, so on a wide screen the
   country fits with room to spare. That room becomes a reading column on the
   right rather than more black around a small map.
   ============================================================ */
@media (min-width: 1800px) {
  :root { --fs-base: 15px; --panel-w: 360px; --legend-w: 320px; --r: 12px; }
  #titlebar { max-width: 460px; }
  #titlebar .sub { font-size: 13.5px; }
  #ribbon { width: min(760px, 40vw); }
  #credits { max-width: 520px; font-size: 11.5px; }
  #legend { padding: 18px 18px 16px; }
  .notes, .controls label { font-size: 13px; }
  .lgNote { font-size: 12px; }
  #panel { padding: 20px 20px 18px; }
  #panel dt { font-size: 13px; }
  #panel dd { font-size: 14px; }
}
@media (min-width: 2400px) {
  :root { --fs-base: 16px; --panel-w: 400px; --legend-w: 360px; }
  #titlebar h1 { font-size: 26px; }
  #ribbon { width: 820px; }
  #ribbonCv { height: 96px; }
}

/* ---- reduced motion ----
   The particles stop and the replays stop advancing on their own. The scrubber
   still works, because a control the reader drives is not motion imposed on them. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important; }
}

/* ============================================================
   TWO-SURFACE WORKSPACE

   The map is evidence, not a backdrop. Permanent controls and explanatory text
   live on a separate surface: beside the map when width permits, below it on a
   portrait phone or tablet. Nothing in this workspace obscures geography.
   ============================================================ */
:root {
  --workspace-w: clamp(380px, 31vw, 480px);
  --workspace-h: 52dvh;
}

#workspace {
  position: fixed; inset: 0 auto 0 0; z-index: 10;
  display: flex; flex-direction: column;
  width: var(--workspace-w); min-width: 0; min-height: 0;
  color: var(--ink); background: var(--surface-1);
  border-right: 1px solid var(--control-border);
  box-shadow: 10px 0 28px rgba(0,0,0,.12);
  overflow: hidden;
}

#workspaceHead {
  position: relative; z-index: 11; flex: none; min-width: 0;
  background: var(--surface-1); border-bottom: 1px solid var(--control-border);
}
.workspaceUtility {
  display: flex; align-items: center; min-width: 0; min-height: 44px;
  padding: calc(6px + var(--safe-t)) 12px 4px calc(14px + var(--safe-l));
}
.workspaceBrand {
  display: inline-flex; align-items: center; gap: 9px; min-width: 0;
  min-height: 38px; color: var(--ink); text-decoration: none;
  font-size: 13px; letter-spacing: -.01em;
}
.workspaceBrand:hover { color: var(--ink); }
.workspaceBrand .mark { display: block; flex: none; }
.workspaceBrand .mA { fill: var(--ev-measured); }
.workspaceBrand .mB { fill: var(--ev-estimated); }
.workspaceBrand .mC { fill: var(--ev-none); }
#workspaceHead .langs { margin-left: auto; }
#workspaceHead .langs [lang] {
  display: grid; place-items: center; min-width: 28px; min-height: 38px; padding: 0 2px;
}
#workspaceHead .themeBtn { width: 38px; height: 38px; margin-left: 5px; }
#workspaceBack {
  display: inline-flex; align-items: center; min-height: 38px; margin-right: auto;
  padding: 5px 8px; color: var(--ink); background: transparent;
  border: 0; border-radius: 5px; font: 650 13px/1.2 var(--sans); cursor: pointer;
}
#workspaceBack:hover { background: color-mix(in srgb, var(--ink) 7%, transparent); }
#workspaceBack[hidden] { display: none; }
#workspaceHead #siteNav {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 0;
  margin: 0; padding: 2px calc(8px + var(--safe-r)) 7px calc(8px + var(--safe-l));
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent; border-top: 1px solid var(--rule);
}
#workspaceHead #siteNav::-webkit-scrollbar { height: 3px; }
#workspaceHead #siteNav > a {
  display: inline-flex; align-items: center; flex: none; min-height: 40px;
  margin: 0; padding: 6px 5px; color: var(--ink-2); font-size: 12px;
  scroll-snap-align: start;
}
#workspaceHead #siteNav > a[aria-current="page"] { color: var(--ink); }
#workspaceHead #siteNav > a.contributeLink { color: var(--accent); }
#workspaceScroll {
  flex: 1 1 auto; min-width: 0; min-height: 0;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-gutter: stable; scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--ink-muted) 82%, transparent) transparent;
}
#workspaceScroll::-webkit-scrollbar { width: 11px; }
#workspaceScroll::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--ink-muted) 72%, transparent);
  border: 3px solid transparent; border-radius: 10px; background-clip: padding-box;
}
#workspaceScroll:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}

#map, #flow {
  inset: auto; top: 0; left: var(--workspace-w);
  width: calc(100vw - var(--workspace-w)); height: 100dvh;
}

#workspace #titlebar {
  position: static; z-index: auto; flex: none;
  width: auto; max-width: none;
  margin: 0; padding: calc(16px + var(--safe-t)) 18px 13px calc(18px + var(--safe-l));
  pointer-events: auto; border-radius: 0;
  background: transparent; border-bottom: 1px solid var(--rule);
}
#workspace #titlebar h1 { font-size: clamp(18px, 1.55vw, 23px); }
#workspace #titlebar .sub { display: block; max-width: 35em; }
#workspace #titlebar .stamp { margin-top: 6px; }
#workspace #evidence { display: none; }
#workspace #modeRail {
  position: static; z-index: 7;
  display: block; min-width: 0;
  background: var(--surface-1); border-bottom: 1px solid var(--rule);
}
#workspace .modeRailCue {
  position: absolute; z-index: 2; top: 0; bottom: 1px;
  display: none; place-items: center; width: 34px;
  color: var(--ink); font-size: 23px; line-height: 1;
  opacity: 0; pointer-events: none;
  transition: opacity 140ms ease;
}
#workspace .modeRailCue-start {
  left: 0; justify-items: start; padding-left: 6px;
  background: linear-gradient(90deg, var(--surface-1) 36%, transparent);
}
#workspace .modeRailCue-end {
  right: 0; justify-items: end; padding-right: 6px;
  background: linear-gradient(270deg, var(--surface-1) 36%, transparent);
}
#workspace #modeRail.canScrollBack .modeRailCue-start,
#workspace #modeRail.canScrollForward .modeRailCue-end { opacity: 1; }
#mobileModePicker { display: none; }
@media (min-width: 1100px) and (min-height: 860px) {
  #workspace #evidence { display: block; }
}
@media (max-height: 799px) {
  #workspace #titlebar .sub { display: none; }
}

#workspace #modes {
  position: static; z-index: auto; flex: none; transform: none;
  display: flex; flex-direction: column;
  gap: 0; width: auto; max-width: none;
  padding: 8px 12px; overflow: visible;
  background: transparent; backdrop-filter: none;
  border: 0; border-radius: 0;
}
#workspace .modeGroup {
  display: grid; grid-template-columns: 82px minmax(0, 1fr);
  align-items: stretch; gap: 3px; min-width: 0;
  padding: 3px 4px;
}
#workspace .modeGroup:first-child,
#workspace .modeGroup:nth-child(4) { grid-template-columns: 82px repeat(3, minmax(0, 1fr)); }
#workspace .modeGroup:nth-child(3) { grid-template-columns: 82px repeat(2, minmax(0, 1fr)); }
#workspace .modeGroup + .modeGroup {
  margin: 0; border-left: 0; border-top: 1px solid var(--rule); padding-left: 4px;
}
#workspace .modeGroupLabel {
  display: flex; align-items: center; grid-column: auto; padding: 0 5px;
  font-size: 10px; line-height: 1.2;
}
#workspace #modes button {
  min-width: 0; min-height: 38px; padding: 7px 6px;
  white-space: normal; line-height: 1.18; text-align: left;
}
/* At the 340 px minimum workspace, long German layer names need the full row.
   The category becomes a quiet heading rather than consuming a narrow column. */
@media (max-width: 1350px) and (min-height: 561px) {
  #workspace .modeGroup { grid-template-columns: minmax(0, 1fr); }
  #workspace .modeGroup:first-child,
  #workspace .modeGroup:nth-child(4) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #workspace .modeGroup:nth-child(3) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #workspace .modeGroupLabel {
    grid-column: 1 / -1; min-height: 16px; padding: 2px 5px 0;
  }
}

#workspace #mapControls {
  position: static; z-index: auto; flex: none;
  display: flex; align-items: center; gap: 6px;
  width: auto; padding: 8px 16px;
  background: var(--surface-2); border-bottom: 1px solid var(--rule);
}
#workspace .zoomGroup,
#workspace #zoomFit,
#workspace #workspaceRead,
#workspace #dataViewOpen {
  background: transparent; backdrop-filter: none;
  border: 1px solid var(--control-border); border-radius: 6px; box-shadow: none;
}
#workspace .zoomGroup { display: flex; }
#workspace .zoomGroup button,
#workspace #zoomFit,
#workspace #workspaceRead,
#workspace #dataViewOpen { min-width: 44px; min-height: 44px; }
#workspace #zoomLevel {
  min-width: 44px; min-height: 44px;
  border-block: 0; border-inline: 1px solid var(--rule);
}
#workspace #dataViewOpen { margin-left: auto; padding-inline: 10px; }
#workspace #workspaceRead { margin-left: auto; padding-inline: 10px; }
#workspace #workspaceRead + #dataViewOpen { margin-left: 0; }

/* A flat status row on the evidence surface—not another card over the map. The
   compact line is always visible; the legal basis and station list open in the
   same column without changing the geography. */
#workspace #liveAlerts {
  flex: none; min-width: 0;
  background: var(--surface-2); border-bottom: 1px solid var(--rule);
}
#workspace #liveAlertsToggle {
  display: grid; grid-template-columns: auto minmax(0, 1fr) 12px;
  align-items: center; gap: 9px;
  width: 100%; min-height: 48px; padding: 7px 16px;
  color: var(--ink); background: transparent; border: 0; border-radius: 0;
  text-align: left; cursor: pointer;
}
#workspace #liveAlertsToggle:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
#workspace #liveAlertsToggle:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
#workspace .liveAlertHeading {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 10px; line-height: 1.2; font-weight: 650;
  letter-spacing: .065em; text-transform: uppercase; white-space: nowrap;
}
#workspace .liveAlertHeading i {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: var(--ink-muted); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink-muted) 14%, transparent);
}
#workspace #liveAlertsSummary {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-2); font-size: 11.5px; line-height: 1.35;
}
#workspace .liveAlertChevron {
  width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  color: var(--ink-muted); transform: rotate(45deg) translate(-2px, 2px); transition: transform 140ms ease;
}
#workspace #liveAlertsToggle[aria-expanded="true"] .liveAlertChevron {
  transform: rotate(225deg) translate(-1px, -1px);
}
#workspace #liveAlerts[data-state="clear"] .liveAlertHeading i {
  background: var(--good); box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 14%, transparent);
}
#workspace #liveAlerts[data-state="alert"] .liveAlertHeading i {
  background: var(--critical); box-shadow: 0 0 0 3px color-mix(in srgb, var(--critical) 17%, transparent);
}
#workspace #liveAlerts[data-state="alert"] #liveAlertsSummary { color: var(--critical); font-weight: 650; }
#workspace #liveAlertsBody {
  max-height: none; padding: 14px 18px 17px; overflow-y: visible;
  color: var(--ink-2); border-top: 1px solid var(--rule);
}
#workspace #liveAlertsBody[hidden] { display: none; }
#workspace .liveAlertScope,
#workspace .liveAlertLimit { margin: 0; font-size: 13px; line-height: 1.55; }
#workspace .liveAlertLimit { margin-top: 11px; color: var(--ink-muted); }
#workspace #liveAlertsList { margin: 10px 0 0; padding: 0; list-style: none; }
#workspace #liveAlertsList:empty { display: none; }
#workspace #liveAlertsList li + li { border-top: 1px solid var(--rule); }
#workspace #liveAlertsList button {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px;
  width: 100%; min-height: 52px; padding: 8px 4px;
  color: var(--ink); background: transparent; border: 0; border-radius: 0;
  text-align: left; cursor: pointer;
}
#workspace #liveAlertsList button:hover strong { text-decoration: underline; text-underline-offset: 3px; }
#workspace #liveAlertsList button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
#workspace #liveAlertsList strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
#workspace .liveAlertValue { color: var(--critical); font: 11px/1.35 var(--mono); white-space: nowrap; }
#workspace .liveAlertReason { grid-column: 1 / -1; color: var(--ink-muted); font-size: 12px; line-height: 1.4; }
#workspace .liveAlertLinks { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 14px 0 0; font-size: 13px; }
#workspace .liveAlertLinks a { color: var(--law); text-underline-offset: 3px; }

#workspace #tooltip {
  position: static; flex: none;
  width: auto; max-width: none; margin: 0; padding: 9px 16px;
  background: var(--surface-2); border: 0; border-bottom: 1px solid var(--rule);
  border-radius: 0; box-shadow: none;
}

#workspace #legend {
  position: static; z-index: auto; flex: none;
  width: auto; min-width: 0; min-height: 0; max-height: none;
  margin: 0; padding: 16px 18px calc(18px + var(--safe-b));
  overflow: visible;
  background: transparent; backdrop-filter: none;
  border: 0; border-radius: 0;
}
#workspace #sheetHandle { display: none; }
#workspace #legend h2 { display: block; font-size: 12px; }
#workspace #legendBody { padding: 0; overflow: visible; }
#workspace #legendBody .notes,
#workspace #legendBody .lgNote { font-size: 13px; line-height: 1.55; }

#workspace #credits {
  position: static; display: block; max-width: none;
  margin: 20px 0 0; padding: 14px 0 0;
  text-align: left; pointer-events: auto;
  color: var(--ink-muted); background: transparent;
  border-top: 1px solid var(--rule); border-radius: 0;
}
#workspace #credits { font-size: 12.5px; line-height: 1.55; }
body.hasRibbon #workspace #credits { display: block; }

#workspace #ribbon {
  position: static; z-index: auto; flex: none; transform: none;
  width: auto; min-width: 0; max-height: min(250px, 38vh);
  padding: 11px 16px 10px; overflow-y: auto;
  background: var(--surface-2); backdrop-filter: none;
  border: 0; border-top: 1px solid var(--control-border); border-radius: 0;
}
#workspace #ribbonCv { height: 64px; }

#workspace #panel {
  position: absolute; inset: var(--workspace-head-h, 99px) 0 0; z-index: 12;
  width: auto; max-height: none;
  padding: 22px 22px calc(24px + var(--safe-b));
  overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable;
  background: var(--surface-1); backdrop-filter: none;
  border: 0; border-top: 1px solid var(--control-border); border-radius: 0;
  box-shadow: none;
}
#workspace #panelClose {
  position: sticky; top: 0; z-index: 2; display: grid; place-items: center;
  margin: -10px -10px -34px auto;
  color: var(--ink-2); background: color-mix(in srgb, var(--surface-1) 94%, transparent);
  border: 1px solid var(--control-border); border-radius: 50%;
}
#workspace #panel h2 { font-size: 18px; line-height: 1.3; }
#workspace #panel dt { font-size: 13px; line-height: 1.4; }
#workspace #panel dd { font-size: 13.5px; line-height: 1.4; }
#workspace .panelNote,
#workspace .aside,
#workspace .flag,
#workspace .statute { font-size: 13px; line-height: 1.55; }
#workspace .qualitySamples time,
#workspace .qualitySamples small,
#workspace .qualityApi { font-size: 12px; line-height: 1.45; }

#workspace #intro {
  position: absolute; inset: 0; z-index: 15;
  box-sizing: border-box; width: 100%; height: 100%; max-height: none;
  margin: 0; padding: 28px 24px calc(26px + var(--safe-b));
  overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable;
  color: var(--ink); background: var(--surface-1);
  border: 0; border-radius: 0; box-shadow: none;
}
#workspace #intro::backdrop { display: none; background: transparent; backdrop-filter: none; }
#workspace #introTitle { font-size: clamp(37px, 4vw, 52px); line-height: .98; }
#workspace .introTop { align-items: flex-start; flex-direction: column; gap: 9px; margin-right: 38px; }
#workspace .introLangs { margin-left: 0; padding-left: 0; }
#workspace .introLead { margin-top: 18px; font-size: 16px; line-height: 1.46; }
#workspace .introActions { align-items: stretch; flex-direction: column; gap: 8px; margin-top: 20px; }
#workspace #introEnter,
#workspace .introActions a { width: 100%; min-height: 46px; }
#workspace .cycleViz { margin-top: 24px; }
#workspace .cycleViz svg { max-height: 150px; }
#workspace .cycleStages { grid-template-columns: repeat(2, minmax(0, 1fr)); }
#workspace .cycleStages li:last-child { grid-column: 1 / -1; }
#workspace .introFacts { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 24px; }

/* A portrait phone or tablet uses the same two surfaces, stacked. The map keeps
   the upper viewport and the workspace scrolls independently below it. */
@media (max-width: 900px) and (orientation: portrait) {
  body:is(.readingLegal, .readingDetail, .readingBrief) { --workspace-h: 72dvh; }
  #workspace {
    inset: auto 0 0; width: auto; height: var(--workspace-h);
    border-right: 0; border-top: 1px solid var(--control-border);
    box-shadow: 0 -10px 28px rgba(0,0,0,.16);
  }
  #map, #flow {
    inset: auto; top: 0; left: 0;
    width: 100vw; height: calc(100dvh - var(--workspace-h));
  }
  #workspace #titlebar {
    padding: 9px calc(11px + var(--safe-r)) 7px calc(11px + var(--safe-l));
  }
  #workspace #titlebar h1 { font-size: 16px; }
  #workspace #titlebar .sub,
  #workspace #titlebar .hint,
  #workspace #evidence { display: none; }
  #workspace #titlebar .stamp {
    margin-top: 3px; font-size: 10.5px; line-height: 1.35;
    white-space: normal;
  }
  #workspace #modeRail {
    position: sticky; top: 0; display: block; min-width: 0;
  }
  #workspace .modeRailCue { display: grid; }
  #workspace #modes {
    display: flex; flex-direction: row; gap: 2px; padding: 4px 8px;
    overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
    touch-action: pan-x; scroll-snap-type: x proximity;
    scrollbar-width: thin; scrollbar-color: var(--rule) transparent;
  }
  #workspace #modes::-webkit-scrollbar { display: block; height: 3px; }
  #workspace .modeGroup,
  #workspace .modeGroup:first-child,
  #workspace .modeGroup:nth-child(4) {
    display: flex; flex: none; gap: 2px; padding: 0 3px;
    border: 0; border-left: 1px solid var(--rule); grid-template-columns: none;
  }
  #workspace .modeGroup:first-child { border-left: 0; }
  #workspace .modeGroupLabel { display: none; }
  #workspace #modes button {
    min-height: 44px; padding: 7px 10px; white-space: nowrap; scroll-snap-align: center;
  }
  #workspace #mapControls { padding: 5px 10px; }
  #workspace #liveAlertsToggle { min-height: 44px; padding: 6px 11px; }
  #workspace .liveAlertHeading { font-size: 9px; }
  #workspace #liveAlertsSummary { font-size: 10.5px; }
  #workspace #liveAlertsBody { padding: 12px 14px 15px; }
  #workspace .zoomGroup button,
  #workspace #zoomLevel,
  #workspace #zoomFit,
  #workspace #workspaceRead,
  #workspace #dataViewOpen { min-height: 44px; }
  #workspace #legend { padding: 11px 13px calc(13px + var(--safe-b)); }
  #workspace #legendBody .notes,
  #workspace #legendBody .lgNote { font-size: 13px; }
  #workspace #ribbon { max-height: min(190px, 32dvh); }
  #workspace #ribbonCv { height: 54px; }
  #workspace #panel { padding: 18px 16px calc(20px + var(--safe-b)); }
  #workspace #intro { padding: 20px 18px calc(20px + var(--safe-b)); }
  #workspace #introTitle { font-size: clamp(31px, 9vw, 43px); }
  #workspace .introLangs [lang] { min-width: 40px; min-height: 44px; }
}
@media (max-width: 480px) {
  #workspace #modeRail { display: none; }
  #workspace #mobileModePicker {
    position: sticky; z-index: 7; top: 0;
    display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px;
    padding: 7px calc(10px + var(--safe-r)) 7px calc(10px + var(--safe-l));
    color: var(--ink-muted); background: var(--surface-1); border-bottom: 1px solid var(--rule);
    font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  }
  #workspace #modeSelect {
    width: 100%; min-width: 0; min-height: 44px; padding: 7px 34px 7px 11px;
    color: var(--ink); background: var(--surface-2); border: 1px solid var(--control-border);
    border-radius: 6px; font: 600 14px/1.2 var(--sans); letter-spacing: 0; text-transform: none;
  }
  #workspace #modeSelect:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
}
@media (max-width: 480px) and (max-height: 650px) and (orientation: portrait) {
  :root { --workspace-h: 62dvh; }
  #workspace #titlebar { padding-top: 6px; padding-bottom: 4px; }
  #workspace #titlebar .stamp {
    font-size: 9.5px; line-height: 1.25; letter-spacing: -.01em;
  }
}
@media (max-width: 360px) {
  #workspaceHead #siteNav { gap: 0; padding-inline: 4px; }
  #workspaceHead #siteNav > a { min-height: 44px; padding-inline: 4px; font-size: 11.5px; }
}

/* Short landscape screens keep real columns but compact the index into one
   horizontal rail, preserving useful height for evidence and detail. */
@media (max-height: 560px) and (orientation: landscape) {
  :root { --workspace-w: min(42vw, 340px); }
  #workspaceHead #siteNav { gap: 0; padding-inline: 4px; }
  #workspaceHead #siteNav > a { min-height: 44px; padding-inline: 4px; font-size: 11.5px; }
  #workspace #titlebar { padding: 9px 12px 7px; }
  #workspace #titlebar h1 { font-size: 15px; }
  #workspace #titlebar .sub,
  #workspace #titlebar .hint,
  #workspace #evidence { display: none; }
  #workspace #titlebar .stamp { display: block; margin-top: 2px; font-size: 10.5px; }
  #workspace #modeRail {
    position: sticky; top: 0; display: block; min-width: 0;
  }
  #workspace .modeRailCue { display: grid; }
  #workspace #modes {
    display: flex; flex-direction: row; gap: 2px; padding: 4px 7px;
    overflow-x: auto; overflow-y: hidden; touch-action: pan-x;
  }
  #workspace .modeGroup,
  #workspace .modeGroup:first-child,
  #workspace .modeGroup:nth-child(4) {
    display: flex; flex: none; gap: 2px; padding: 0 3px;
    border: 0; border-left: 1px solid var(--rule); grid-template-columns: none;
  }
  #workspace .modeGroup:first-child { border-left: 0; }
  #workspace .modeGroupLabel { display: none; }
  #workspace #modes button { min-height: 44px; padding: 6px 9px; white-space: nowrap; }
  #workspace #mapControls { padding: 4px 9px; }
  #workspace #liveAlertsToggle { min-height: 44px; padding: 6px 10px; }
  #workspace .liveAlertHeading { font-size: 9px; }
  #workspace #liveAlertsSummary { font-size: 10px; }
  #workspace #liveAlertsBody { padding: 11px 13px 14px; }
  #workspace .zoomGroup button,
  #workspace #zoomLevel,
  #workspace #zoomFit,
  #workspace #workspaceRead,
  #workspace #dataViewOpen { min-height: 44px; }
  #workspace #legend { padding: 10px 12px 12px; }
  #workspace #ribbon { max-height: 58%; }
  #workspace #intro { padding: 17px 16px; }
  #workspace #introTitle { font-size: 32px; }
  #workspace .cycleViz svg { max-height: 110px; }
}

/* Reading mode is a deliberate change of task, not a larger floating box. The
   map gives the whole viewport to evidence and leaves one persistent way back.
   Main evidence keeps a book-like measure; selected-feature and project text use
   the same measure even though they sit above the scroller. */
body.workspaceReading #workspace {
  inset: 0; z-index: 40; width: 100vw; height: 100dvh;
  border: 0; box-shadow: none;
}
body.workspaceReading #map,
body.workspaceReading #flow { visibility: hidden; }
body.workspaceReading .workspaceBrand { display: none; }
body.workspaceReading #workspaceRead { display: none; }
body.workspaceReading #dataViewOpen { margin-left: auto; }
body.workspaceReading #workspaceScroll > #titlebar,
body.workspaceReading #workspaceScroll > #modeRail,
body.workspaceReading #workspaceScroll > #mobileModePicker,
body.workspaceReading #workspaceScroll > #mapControls,
body.workspaceReading #workspaceScroll > #liveAlerts,
body.workspaceReading #workspaceScroll > #tooltip,
body.workspaceReading #workspaceScroll > #legend,
body.workspaceReading #workspaceScroll > #ribbon {
  box-sizing: border-box; width: min(760px, 100%); margin-right: auto; margin-left: auto;
}
body.workspaceReading #workspace #panel {
  inset: var(--workspace-head-h, 99px) 0 0;
  padding-right: max(22px, calc((100vw - 760px) / 2));
  padding-left: max(22px, calc((100vw - 760px) / 2));
}
body.workspaceReading #workspace #intro {
  inset: var(--workspace-head-h, 99px) 0 0; height: auto;
  padding-right: max(24px, calc((100vw - 760px) / 2));
  padding-left: max(24px, calc((100vw - 760px) / 2));
}
@media (max-width: 520px) {
  body.workspaceReading #workspace #panel,
  body.workspaceReading #workspace #intro { padding-right: 18px; padding-left: 18px; }
  body.workspaceReading #workspace #titlebar,
  body.workspaceReading #workspace #legend { padding-right: 16px; padding-left: 16px; }
}
