:root {
  /* Sidebar width is a live variable: dragged via #sidebar-resize (persisted
     in localStorage), consumed by both the sidebar and the globe container. */
  --sidebar-w: 380px;
  --bg: #0d1117;
  --bg2: #161b22;
  --border: #30363d;
  --fg: #e6edf3;
  --fg-dim: #8b949e;
  --accent: #4493f8;
  --accent2: #3fb950;
  --amoc: #f0883e;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg); color: var(--fg);
  overflow: hidden;
}

#cesiumContainer {
  position: absolute; top: 0; left: var(--sidebar-w); right: 0; bottom: 0;
}

#sidebar {
  position: absolute; top: 0; left: 0; bottom: 0; width: var(--sidebar-w);
  background: var(--bg2); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  z-index: 10;
}

/* Drag strip between sidebar and globe: col-resize, widens the hit area a
   little beyond its visible line; double-click resets to the default. */
#sidebar-resize {
  position: absolute; top: 0; bottom: 0; left: calc(var(--sidebar-w) - 3px);
  width: 7px; z-index: 30; cursor: col-resize;
}
#sidebar-resize:hover, #sidebar-resize.dragging { background: rgba(68, 147, 248, 0.35); }

#sidebar header { padding: 14px 16px 0; }
#sidebar h1 { margin: 0; font-size: 22px; letter-spacing: 1px; }
#sidebar h1 .h1-sub { font-size: 12.5px; font-weight: 500; letter-spacing: 0; color: var(--fg-dim); }
#sidebar .tagline { margin: 3px 0 12px; color: var(--fg-dim); font-size: 12.5px; line-height: 1.5; }
.tag-link {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--accent); text-decoration: underline dotted rgba(68,147,248,0.6);
  text-underline-offset: 2px;
}
.tag-link:hover { text-decoration-style: solid; }

/* Ten labels do not fit one row of a 320 px sidebar, so the row wraps
   rather than overflowing — a second row beats a tab you cannot reach. */
nav { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--border); }
/* Tabs size to their labels rather than sharing the width equally: with six of
   them in a 320 px sidebar, an equal split wrapped "Sea level" onto two lines. */
.tab {
  flex: 0 1 auto; padding: 8px 5px; background: none; border: none; color: var(--fg-dim);
  border-bottom: 2px solid transparent; cursor: pointer; font-size: 12.5px;
  white-space: nowrap; min-width: 0;
}
.tab.active { color: var(--fg); border-bottom-color: var(--accent); }

.panel { flex: 1; overflow-y: auto; padding: 12px 16px; }
.panel.hidden { display: none; }
.panel h2 { font-size: 14px; margin: 12px 0 6px; }
.panel p, .panel li { font-size: 12.5px; line-height: 1.5; color: var(--fg-dim); }
.panel a { color: var(--accent); text-decoration: none; }

.control-row { display: flex; align-items: center; gap: 8px; margin: 8px 0; font-size: 13px; }
.control-row.filters { gap: 14px; }
.control-row input[type="date"], #catalog-search, #catalog-domain, #compare-select {
  flex: 1; background: var(--bg); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 8px; font-size: 13px;
}
#catalog-search { width: 100%; margin-bottom: 4px; }

/* The Compare/Aggregate explainer folds away — it's reference material, not a
   control, and at full length it pushed the layer list below the fold. */
.hint-details { margin: 8px 0; }
.hint-details summary {
  cursor: pointer; color: var(--fg-dim); font-size: 12px; user-select: none;
}
.hint-details summary:hover { color: var(--accent); }
.hint-details[open] summary { color: var(--fg); }
.hint-details p.hint { margin: 6px 0 6px 12px; }
.hint-details ul.hint {
  margin: 4px 0 6px 12px; padding-left: 16px; font-size: 11px; color: var(--fg-dim);
}
.hint-details ul.hint li { font-size: 11px; line-height: 1.55; margin-bottom: 5px; }
/* the intro guide reads as a welcome, not fine print */
#intro-guide { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; background: var(--bg); }
#intro-guide summary.hint { font-size: 12.5px; color: var(--fg); }
#intro-guide strong { color: var(--fg); }

.date-steps { gap: 4px; margin-top: -2px; }
.date-steps button {
  flex: 1; background: var(--bg); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 0; font-size: 12px; cursor: pointer;
}
.date-steps button:hover { border-color: var(--accent, #3987e5); color: var(--accent, #3987e5); }
#window-presets { margin-top: -4px; }
/* The ±1d nudges and the typed field. The buttons do NOT flex (unlike the
   preset row's): the field takes the slack, because it is the control you
   aim at, and a hit target either side of it is what makes the arrows
   thumb-usable on a phone. */
.window-nudge { gap: 6px; margin-top: -2px; }
.window-nudge button {
  background: var(--bg); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 11px; font-size: 12px; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.window-nudge button:hover { border-color: var(--accent, #3987e5); color: var(--accent, #3987e5); }
#window-input {
  flex: 1; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 4px 8px; font-size: 12px; text-align: right;
  font-variant-numeric: tabular-nums;
}
#window-input:focus { outline: none; border-color: var(--accent, #3987e5); }
/* No native spinners: the ±1d buttons either side ARE the spinner, at a size
   a thumb can hit, and two sets of arrows for one number is one too many. */
#window-input::-webkit-inner-spin-button, #window-input::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
#window-input { -moz-appearance: textfield; appearance: textfield; }
.window-unit { font-size: 11px; color: var(--fg-dim); }
#window-presets button.active, #eei-smooth button.active {
  border-color: var(--accent, #3987e5); color: var(--accent, #3987e5);
}

.hint { font-size: 11px; color: var(--fg-dim); margin: 6px 0 10px; }

.layer-item {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; margin-bottom: 8px; background: var(--bg);
  position: relative;
}

/* Attention toast — fired when a date-independent layer is enabled, so the
 * user doesn't wonder why the date selector has no effect. Slides down from
 * the top of the globe and gives a quick shake so it can't be missed. */
#toast-host {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 60; display: flex; flex-direction: column; gap: 8px;
  align-items: center; pointer-events: none; width: max-content; max-width: 90%;
}
.toast {
  pointer-events: auto; display: flex; gap: 10px; align-items: flex-start;
  max-width: 460px; background: #1b2333; color: var(--fg);
  border: 1px solid var(--accent); border-left: 4px solid var(--accent);
  border-radius: 10px; padding: 11px 12px 11px 13px; font-size: 12.5px; line-height: 1.5;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  animation: toast-in 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.3),
             toast-shake 0.5s ease 0.36s;
}
.toast.toast-out { animation: toast-out 0.3s ease forwards; }
.toast .toast-ico { font-size: 15px; line-height: 1.35; }
.toast .toast-body { flex: 1; }
.toast .toast-body strong { color: var(--accent); }
.toast .toast-close {
  pointer-events: auto; background: none; border: none; color: var(--fg-dim);
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0 2px; margin: -1px -2px 0 0;
}
.toast .toast-close:hover { color: var(--fg); }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(-16px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(-12px) scale(0.97); }
}
@keyframes toast-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .toast { animation: toast-in 0.2s ease; }
}

/* Hover card: recording period · time interval · spatial granularity */
.layer-tip {
  position: absolute; left: 8px; right: 8px; top: calc(100% - 4px); z-index: 40;
  background: #0d1420; border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; font-size: 11px; line-height: 1.5;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
  opacity: 0; visibility: hidden; transition: opacity 0.15s ease, visibility 0s;
  pointer-events: none;
}
.layer-item:hover .layer-tip { opacity: 1; visibility: visible; transition-delay: 0.35s; }
.layer-tip .tip-sum {
  margin: 0 0 7px; padding-bottom: 7px; border-bottom: 1px solid var(--border);
  color: var(--fg); font-size: 11px; line-height: 1.5;
}
.layer-tip div { display: flex; gap: 8px; }
.layer-tip span {
  flex: 0 0 62px; color: var(--fg-dim); text-transform: uppercase;
  font-size: 9.5px; letter-spacing: 0.4px; padding-top: 1px;
}
.layer-item label { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.layer-item .meta { font-size: 11px; color: var(--fg-dim); margin: 3px 0 0 24px; }
/* The fine tier's live status line: what a 30 m layer is doing at this camera
 * height. Amber while gated (hidden, nothing requested), dim when showing. */
.layer-item .fine-hint { font-size: 11px; color: var(--fg-dim); margin: 3px 0 0 24px; font-variant-numeric: tabular-nums; }
.layer-item .fine-hint.fine-gated { color: #e0a94a; }
/* A layer the aggregation window is hiding, said on the row itself. */
.layer-item .sup-note { font-size: 11px; color: #e0a94a; margin: 3px 0 0 24px; line-height: 1.4; }
.layer-item input[type="range"] { width: 100%; margin-top: 6px; accent-color: var(--accent); }
.alpha-row { display: flex; align-items: center; gap: 6px; margin: 4px 0 0 24px; }
.alpha-row input[type="range"] { flex: 1; width: auto; margin-top: 0; }
.alpha-label { font-size: 10px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.04em; }
/* The family-7 channel picker: one layer paints twenty-three quantities, so
   the choice of which lives in the layer's own row, beside its opacity. */
.chan-row { display: flex; align-items: center; gap: 6px; margin: 4px 0 0 24px; }
.chan-row select { flex: 1; min-width: 0; font-size: 11px; padding: 2px 4px; }
.alpha-val { font-size: 10.5px; color: var(--fg-dim); min-width: 32px; text-align: right; font-variant-numeric: tabular-nums; }
.alpha-half {
  background: none; border: 1px solid var(--border); color: var(--fg-dim);
  border-radius: 4px; font-size: 11px; line-height: 1; padding: 2px 5px; cursor: pointer;
}
.alpha-half:hover { color: var(--accent); border-color: var(--accent); }

button.wide {
  width: 100%; padding: 8px; margin-top: 8px;
  background: var(--bg); color: var(--fg); border: 1px solid var(--border);
  border-radius: 8px; cursor: pointer; font-size: 13px;
}
button.wide:hover { border-color: var(--accent); }

.cat-item {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; margin-bottom: 6px; background: var(--bg);
}
.cat-item .cat-name { font-size: 13px; font-weight: 600; }
.cat-item .cat-name a { color: var(--fg); }
.cat-item .cat-name a:hover { color: var(--accent); }
.cat-item .cat-provider { font-size: 11px; color: var(--fg-dim); }
.cat-item .cat-note { font-size: 11.5px; color: var(--fg-dim); margin-top: 3px; }
.badge {
  display: inline-block; font-size: 9.5px; padding: 1px 6px; border-radius: 10px;
  margin-left: 5px; vertical-align: 1px;
}
.badge.amoc { background: rgba(240,136,62,.15); color: var(--amoc); border: 1px solid var(--amoc); }
.badge.globe { background: rgba(63,185,80,.15); color: var(--accent2); border: 1px solid var(--accent2); }

footer {
  padding: 8px 16px; font-size: 10.5px; color: var(--fg-dim);
  border-top: 1px solid var(--border);
}
footer a { color: var(--fg-dim); }

/* The build marker in About: present so a user can answer "did my reload
   actually get the new code?" without opening dev tools, but quiet enough
   that nobody reads it who isn't looking for it. */
.build-line { font-size: 11px; color: var(--fg-dim); }
.build-line code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ---- scale bar ----
   Bottom-left, at the legend's height so the two read as a pair, and above
   the Cesium credit line (.cesium-viewer-bottom) rather than over it. The
   bar is a bracket, not a box: it measures the ground, so it should look
   like a ruler laid on it. */
#scalebar {
  position: absolute; left: 12px; bottom: 34px; z-index: 20;
  pointer-events: none; user-select: none;
  font-size: 11px; color: var(--fg);
  text-shadow: 0 0 3px rgba(0, 0, 0, 0.95), 0 0 6px rgba(0, 0, 0, 0.8);
}
#scalebar .sb-row { display: flex; align-items: flex-end; gap: 6px; }
#sb-label { font-variant-numeric: tabular-nums; line-height: 1; }
#sb-bar {
  height: 6px; width: 80px;
  border: 2px solid rgba(255, 255, 255, 0.92); border-top: none;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.9);
}
#sb-view {
  margin-top: 3px; font-size: 10px; color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}

/* Cesium widget tweaks */
.cesium-viewer-bottom { left: 8px !important; }
.cesium-widget-credits { font-size: 10px !important; }

@media (max-width: 720px) {
  #sidebar { width: 100%; height: 45%; bottom: auto; border-right: none; border-bottom: 1px solid var(--border); }
  #cesiumContainer { left: 0; top: 45%; }
  #sidebar-resize { display: none; }   /* stacked layout: no column to drag */
}

/* ---- zoom controls ---- */
#zoom-controls {
  position: absolute; right: 12px; top: 70px; z-index: 20;
  display: flex; flex-direction: column; gap: 6px;
}
#zoom-controls button {
  width: 36px; height: 36px; border-radius: 8px;
  background: rgba(22, 27, 34, 0.88); color: var(--fg);
  border: 1px solid var(--border); font-size: 18px; line-height: 1;
  cursor: pointer;
}
#zoom-controls button:hover { border-color: var(--accent); }

/* ---- comparison split ---- */
#split-handle {
  position: absolute; top: 0; bottom: 0; left: 50%; width: 4px; z-index: 19;
  background: rgba(255, 255, 255, 0.65); cursor: ew-resize;
  touch-action: none;
}
#split-handle::after {
  content: "⇔"; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg2); color: var(--fg); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 13px;
}
/* ---- active-layer chips (top-left of the globe) ----
   One chip per layer that is currently on, so a layer can be switched off
   from anywhere — including from the Temp / AMOC / Catalog tabs, where the
   layer list isn't on screen at all. Doubles as a "what am I looking at"
   readout. --chips-h is published by updateActiveChips() so the comparison
   labels below can step out of the way. */
/* ---- place search (top-left, above the chips) ----
   The globe answers "what is happening here"; this is the only control that
   answers "take me to here". It shares the top-left corner with the chips
   rather than the top-right, which Cesium's scene-mode picker owns. */
#place-search {
  position: absolute; top: 12px; left: 12px; z-index: 21;
  width: min(280px, 46vw);
}
.ps-bar {
  display: flex; align-items: center;
  background: rgba(22, 27, 34, 0.92); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden;
}
.ps-bar:focus-within { border-color: var(--accent); }
#ps-input {
  flex: 1; min-width: 0; padding: 7px 9px;
  background: none; border: none; color: var(--fg);
  font-size: 13px; font-family: inherit;
}
#ps-input:focus { outline: none; }
#ps-input::-webkit-search-cancel-button { display: none; }
#ps-clear {
  background: none; border: none; color: var(--fg-dim);
  font-size: 17px; line-height: 1; padding: 4px 9px; cursor: pointer;
}
#ps-clear:hover { color: var(--fg); }
#ps-results {
  margin: 5px 0 0; padding: 4px; list-style: none;
  background: rgba(22, 27, 34, 0.96); border: 1px solid var(--border);
  border-radius: 8px; max-height: 46vh; overflow-y: auto;
}
#ps-results.hidden { display: none; }
.ps-hit {
  display: flex; flex-direction: column; gap: 1px;
  padding: 5px 8px; border-radius: 6px; cursor: pointer;
}
.ps-hit:hover, .ps-cursor { background: rgba(121, 192, 255, 0.14); }
.ps-name { font-size: 13px; }
/* Country and population, because a search for "Springfield" is a
   disambiguation problem before it is a navigation problem. */
.ps-where { font-size: 11px; color: var(--fg-dim); }
.ps-empty { padding: 6px 8px; font-size: 12px; color: var(--fg-dim); }

#active-layers {
  position: absolute; top: 56px; left: 12px; z-index: 20;
  display: flex; flex-wrap: wrap; gap: 6px;
  max-width: min(560px, 55%); max-height: 34%; overflow-y: auto;
}
#active-layers.hidden { display: none; }
.chip {
  display: flex; align-items: stretch; overflow: hidden;
  background: rgba(22, 27, 34, 0.92); border: 1px solid var(--border);
  border-radius: 15px; font-size: 12px; line-height: 1;
}
.chip:hover { border-color: var(--accent); }
.chip-warn { border-color: #d29922; }
.chip button {
  background: none; border: none; color: var(--fg);
  font-size: 12px; font-family: inherit; cursor: pointer; padding: 0;
}
/* Pill padding is deliberately generous, and was raised TWICE: on a full
 * pill the corner sweeps through the text's own line, so an inset that
 * measures fine still reads as cramped. 18px left against a 15px radius is
 * the value that finally looked right at 12px type. */
.chip-label { padding: 8px 6px 8px 18px; white-space: nowrap; }
.chip-label:hover { color: var(--accent); }
.chip-x {
  padding: 8px 15px 8px 7px; color: var(--fg-dim) !important;
  font-size: 14px !important;
}
.chip-x:hover { color: #f85149 !important; }
.chip-clear {
  border-style: dashed; color: var(--fg-dim);
}
.chip-clear .chip-label { padding: 8px 18px; color: var(--fg-dim); }
.chip-clear:hover .chip-label { color: #f85149; }
/* ---- pixel inspector card (right side of the globe) ----
   One card composing everything the app knows about a clicked point:
   live weather + 7-day forecast, every GIBS raster at the current date,
   climatology normals with anomalies, and nearby context. */
#pixel-card {
  position: absolute; top: 56px; right: 56px; z-index: 22;
  width: 300px; max-height: calc(100% - 90px); overflow-y: auto;
  background: rgba(22, 27, 34, 0.96); border: 1px solid var(--border);
  border-radius: 10px; font-size: 12px; box-shadow: 0 6px 24px rgba(0,0,0,0.5);
}
#pixel-card.hidden { display: none; }
.px-head {
  position: sticky; top: 0; display: flex; align-items: center; gap: 6px;
  padding: 9px 12px; background: rgba(22, 27, 34, 0.98);
  border-bottom: 1px solid var(--border); font-size: 12.5px;
}
.px-close {
  margin-left: auto; background: none; border: none; color: var(--fg-dim);
  font-size: 16px; cursor: pointer; padding: 0 2px; line-height: 1;
}
.px-close:hover { color: #f85149; }
.px-body { padding: 6px 12px 10px; }
.px-loading { color: var(--fg-dim); padding: 10px 0; }
.px-sec { margin: 8px 0; }
.px-sec-title {
  font-weight: 600; margin-bottom: 4px; color: var(--fg);
  display: flex; align-items: baseline; gap: 6px;
}
.px-src { font-weight: 400; font-size: 10.5px; color: var(--fg-dim); margin-left: auto; }
.px-row { display: flex; flex-wrap: wrap; gap: 2px 8px; padding: 2px 0; }
/* Every value carries WHEN it was observed. The card is 300px, so "2026-08-03
 * 18:30 UTC · just now" does not fit beside a long value: wrap lets the stamp
 * right-align on the value's own line when it fits and drop to its own line
 * when it doesn't, instead of squeezing the number. */
.px-when {
  margin-left: auto; font-size: 10px; color: var(--fg-dim);
  white-space: nowrap; align-self: baseline;
}
.px-label { color: var(--fg-dim); flex: 0 0 46%; }
.px-val { color: var(--fg); }
.px-warm { color: #f0883e; }
.px-cool { color: #58a6ff; }
.px-forecast { display: flex; flex-direction: column; margin-top: 5px; }
.px-day {
  display: flex; gap: 8px; padding: 1px 0; color: var(--fg-dim); font-size: 11.5px;
}
.px-day span:first-child { flex: 0 0 44px; }
.px-day span:nth-child(2) { flex: 0 0 60px; color: var(--fg); }
.px-profile { display: block; margin: 2px 0 4px; }
.px-note { margin-top: 8px; font-size: 10.5px; color: var(--fg-dim); }
/* Two notes about sources, and they mean opposite things. Still loading is
 * transient and expected — accent, and it pulses so it reads as motion rather
 * than as a warning that has stopped changing. Didn't answer is final. */
.px-loading { border-left: 2px solid var(--accent); padding-left: 7px;
  animation: px-pulse 1.6s ease-in-out infinite; }
@keyframes px-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .px-loading { animation: none; } }
.px-late { border-left: 2px solid var(--warn, #d19a3a); padding-left: 7px; }
.px-note a { color: var(--accent); text-decoration: none; }

/* Briefly highlights the layer's row after "find in sidebar". */
.layer-item.flash {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px;
}
@media (prefers-reduced-motion: no-preference) {
  .layer-item.flash { transition: outline-color 0.2s; }
}

#split-labels { position: absolute; top: calc(56px + var(--chips-h, 0px)); left: 0; right: 0; z-index: 18; pointer-events: none; }
#split-labels span {
  position: absolute; top: 0; padding: 3px 10px; border-radius: 12px;
  background: rgba(22, 27, 34, 0.88); border: 1px solid var(--border);
  font-size: 12px; color: var(--fg);
}
#split-label-left { left: 12px; }
#split-label-right { right: 60px; }

/* ---- pick card ---- */
#pick-card {
  position: absolute; left: 12px; bottom: 34px; z-index: 20; max-width: 300px;
  background: rgba(22, 27, 34, 0.94); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 12px; font-size: 12.5px; line-height: 1.5;
  color: var(--fg);
}
#pick-card a { color: var(--accent); text-decoration: none; }

/* ---- AMOC dashboard ---- */
.stat-row { display: flex; gap: 8px; margin: 10px 0 4px; }
.stat {
  flex: 1; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 6px; text-align: center;
}
.stat-value { font-size: 20px; font-weight: 650; color: var(--fg); }
.stat-sub { font-size: 9.5px; color: var(--fg-dim); margin-top: 2px; }
#amoc-chart-wrap { position: relative; margin: 8px 0 4px; }
#amoc-chart { display: block; width: 100%; }
#amoc-tooltip {
  position: absolute; top: -6px; padding: 2px 8px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 11px; color: var(--fg); white-space: nowrap; pointer-events: none;
}
.hidden { display: none !important; }

/* ---- legends ---- */
#legend-panel {
  position: absolute; right: 12px; bottom: 34px; z-index: 20;
  display: flex; flex-direction: column; gap: 6px; width: 300px;
}
.legend-item {
  background: rgba(22, 27, 34, 0.92); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 8px;
}
.legend-title { font-size: 10.5px; color: var(--fg-dim); margin-bottom: 4px; }
.legend-item img {
  display: block; width: 100%; background: #f2f2f0;
  border-radius: 4px; padding: 2px 3px; box-sizing: border-box;
}
.legend-note { font-size: 9.5px; color: var(--fg-dim); margin-top: 3px; }
.delta-scale { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--fg); }
.delta-bar {
  flex: 1; height: 10px; border-radius: 5px; border: 1px solid var(--border);
  background: linear-gradient(to right,
    rgb(37, 99, 235) 0%, rgba(37, 99, 235, 0) 50%,
    rgba(230, 59, 46, 0) 50%, rgb(230, 59, 46) 100%);
}

/* ---- interactive legend bars ---- */
.legend-bar-wrap { position: relative; }
.legend-bar {
  display: block; width: 100%; border-radius: 4px; cursor: crosshair;
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.legend-tip {
  position: absolute; top: -22px; padding: 1px 7px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 10.5px; color: var(--fg); white-space: nowrap; pointer-events: none;
  z-index: 21;
}
.legend-range {
  display: flex; justify-content: space-between;
  font-size: 9.5px; color: var(--fg-dim); margin-top: 3px;
}
.delta-bar { cursor: crosshair; }

/* ---- classification legends (OPERA disturbance): labelled swatches, not a
   gradient — the classes have no ordering a bar could imply ---- */
.legend-classes { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 8px; }
.legend-class { display: flex; align-items: center; gap: 5px; min-width: 0; }
.legend-swatch {
  flex: none; width: 11px; height: 11px; border-radius: 2px;
  border: 1px solid rgba(255, 255, 255, 0.18);
}
.legend-class-label {
  font-size: 9.5px; color: var(--fg-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A class the union is looking through: the swatch goes hollow (it is not
   being painted) and the label is struck, so "absent from the map" is a
   state you can SEE rather than infer. */
.legend-class.seen-through .legend-swatch { opacity: 0.35; }
.legend-class.seen-through .legend-class-label {
  text-decoration: line-through; opacity: 0.7;
}
.legend-toggle {
  display: block; width: 100%; margin-top: 5px; text-align: left;
  background: var(--bg); color: var(--fg-dim); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 6px; font-size: 9.5px; cursor: pointer;
  font-family: inherit;
}
.legend-toggle:hover { border-color: var(--accent, #3987e5); color: var(--accent, #3987e5); }

/* ---- clickable layer titles ---- */
.layer-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.layer-head .title-link { color: var(--fg); text-decoration: none; }
.layer-head .title-link:hover { color: var(--accent); text-decoration: underline; }
.layer-head .title-link::after { content: " ↗"; font-size: 10px; color: var(--fg-dim); }

/* ---- ensemble spread legend ---- */
.spread-bar, .legend-item .spread-bar {
  display: block; width: 100%; height: 12px; border-radius: 4px; cursor: crosshair;
  border: 1px solid rgba(255,255,255,0.12);
  background: linear-gradient(to right,
    rgb(8,48,107) 0%, rgb(33,145,140) 35%, rgb(253,231,37) 70%, rgb(240,59,46) 100%);
}

/* ---- aggregation slider ---- */
#window-days { flex: 1; accent-color: var(--accent); }
.window-value { font-size: 11px; color: var(--fg-dim); min-width: 78px; text-align: right; }

/* ---- sea-level dashboard ---- */
#sl-chart-wrap { position: relative; margin: 8px 0 4px; }
#sl-chart { display: block; width: 100%; }

/* Tides tab: the animated map fills the panel width; buttons echo .tab */
#td-map-wrap { margin: 8px 0 2px; background: #0a0f16; border-radius: 6px; overflow: hidden; }
#td-map { display: block; width: 100%; cursor: crosshair; }
.td-btn { background: #21262d; color: #c9d1d9; border: 1px solid #30363d;
  border-radius: 6px; padding: 3px 12px; cursor: pointer; font-size: 14px; }
.td-btn:hover { background: #30363d; }
#td-curve { display: block; width: 100%; background: #0a0f16; border-radius: 6px; margin-top: 4px; }
/* Next high / low water — the tab's headline answer, so it sits ABOVE the
 * curve and reads as two facts, not as chart furniture. The left rule takes
 * the globe's own colours: red is water above mean, blue below. */
.td-hl {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 8px 12px; margin-top: 6px;
  background: var(--bg2); border: 1px solid var(--border);
  border-left-width: 3px; border-radius: 7px;
}
.td-high { border-left-color: #e34948; }
.td-low { border-left-color: #3b82f6; }
.td-hl-k {
  flex: 0 0 96px; font-size: 10.5px; color: var(--fg-dim);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.td-hl-t { font-size: 15px; font-weight: 650; font-variant-numeric: tabular-nums; }
.td-hl-v { font-size: 13px; color: var(--fg-dim); font-variant-numeric: tabular-nums; }
.td-hl-in {
  margin-left: auto; font-size: 12px; color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
/* The invitation stands where the chart will be, at chart size — a hint line
 * under the fold was invisible (reported 2026-08-07: "I don't know where to
 * find the next high tide and the curve"). */
#td-empty {
  margin: 10px 0 2px; padding: 20px 16px; text-align: center;
  border: 1px dashed var(--border); border-radius: 8px;
  color: var(--fg-dim); font-size: 12.5px; line-height: 1.55;
}
#td-empty.hidden { display: none; }
#td-empty strong { display: block; color: var(--fg); font-size: 13.5px; margin-bottom: 3px; }
.td-hl-z { font-size: 11px; font-weight: 400; color: var(--fg-dim); }
.td-place { color: var(--accent); font-size: 13px; }
#td-tz { font-size: 10.5px; color: var(--fg-dim); margin-top: 5px; line-height: 1.45; }

/* Tick labels under a COMPRESSED colour bar: absolutely placed at the tick
 * they name, because the bar's ends are not the numbers (the ramp runs on
 * past ±2.5 m). The tide legend previously used two class names — legend-labels
 * and legend-read — that no stylesheet defined, so its three labels rendered
 * as one run-on line. */
.legend-ticks { position: relative; height: 12px; margin-top: 3px; }
.legend-ticks span {
  position: absolute; transform: translateX(-50%);
  font-size: 9.5px; color: var(--fg-dim); white-space: nowrap;
}
.legend-read { font-size: 10px; color: var(--fg); margin-top: 2px; }
.legend-read.hidden { display: none; }
#tides-controls select { background: #21262d; color: #c9d1d9; border: 1px solid #30363d; border-radius: 4px; }
#sl-tooltip {
  position: absolute; top: -4px; padding: 4px 8px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 10.5px; line-height: 1.5; color: var(--fg); white-space: nowrap; pointer-events: none;
}
.sl-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 4px 0 8px; }
.sl-legend span { font-size: 10.5px; color: var(--fg-dim); }
.sl-legend b { font-weight: 600; }

/* ---- species selector ---- */
#species-select { flex: 1; background: var(--bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12px; }
#species-select optgroup { color: var(--fg-dim); font-style: normal; font-weight: 600; background: var(--bg); }
#species-select option { color: var(--fg); font-weight: 400; background: var(--bg); }

/* ---- hover value probe ---- */
#value-probe {
  position: absolute; z-index: 22; pointer-events: none;
  background: rgba(13, 17, 23, 0.92); border: 1px solid var(--border);
  border-radius: 8px; padding: 5px 9px; color: var(--fg);
}
#value-probe .vp-val { font-size: 17px; font-weight: 650; }
#value-probe .vp-unit { font-size: 12px; color: var(--fg-dim); }
#value-probe .vp-nd { font-size: 13px; font-weight: 500; color: var(--fg-dim); }
/* a class name is a phrase, not a number — it needs room and a smaller face */
#value-probe .vp-class { font-size: 12.5px; font-weight: 600; line-height: 1.25; }
#value-probe .vp-meta { font-size: 10px; color: var(--fg-dim); margin-top: 2px; line-height: 1.35; }

/* ---- temperature dashboard (reuses sea-level chart styles) ---- */
#temp-chart-wrap, #eei-chart-wrap, #eei-rate-chart-wrap { position: relative; margin: 8px 0 4px; }
#temp-chart, #eei-chart, #eei-rate-chart { display: block; width: 100%; }
#eei-tooltip, #eei-rate-tooltip {
  position: absolute; padding: 4px 8px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 10.5px; line-height: 1.5; color: var(--fg); white-space: nowrap; pointer-events: none;
}
#temp-tooltip {
  position: absolute; top: -4px; padding: 4px 8px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border);
  font-size: 10.5px; line-height: 1.5; color: var(--fg); white-space: nowrap; pointer-events: none;
}

/* ---- inline checkbox rows ---- */
.check-inline { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--fg); cursor: pointer; }
.check-inline input { flex: none; }

/* ---- glacier change legend ---- */
#glacier-mode { flex: 1; background: var(--bg); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12px; }
.glacier-legend { margin: 4px 0 2px; }
.glacier-scale {
  height: 10px; border-radius: 5px; border: 1px solid var(--border);
  background: linear-gradient(to right, #f22 0%, #f2bf26 45%, #8fb0d0 60%, #388ff2 100%);
}
.glacier-scale-labels { display: flex; justify-content: space-between; font-size: 9px; color: var(--fg-dim); margin-top: 2px; }

/* ---- Play tab (E-041): the transport for the date clock. Everything here is
 * either a primitive that already exists (.control-row, .td-btn, .hint) or one
 * of the four things the panel needs that no primitive covers: a left column
 * the four rows can line up on, a full-width scrub, a transport row whose
 * three buttons are the same size, and a readout with room for two lines. */
#panel-play .control-row > label:first-child { flex: 0 0 44px; }
#pb-step, #pb-speed {
  flex: 1; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px;
}
/* three prose labels in a 320 px sidebar: smaller face, equal shares, no wrap */
#pb-presets { gap: 4px; margin-top: -2px; }
#pb-presets .td-btn { flex: 1 1 0; padding: 4px 2px; font-size: 11px; white-space: nowrap; }
/* ⏮ ▶ ⏭ read as one control, so they share the row evenly and sit taller than
 * an ordinary button — this is the thing a finger aims at. */
#pb-transport { gap: 6px; margin-top: 2px; }
#pb-transport .td-btn { flex: 1; padding: 5px 0; font-size: 16px; line-height: 1.2; }
#pb-transport .td-btn.playing { border-color: var(--accent); color: var(--accent); }
/* the scrub is the frame axis: it spans the panel, not a label's leftovers */
#pb-scrub { display: block; width: 100%; margin: 8px 0 2px; accent-color: var(--accent); }
/* frame / date on line one, the per-layer provenance stamp on line two — sized
 * for both so the box does not jump as the stamp appears and disappears */
#pb-readout {
  min-height: 54px; padding: 7px 10px; margin: 4px 0 2px;
  background: var(--bg2); border: 1px solid var(--border); border-radius: 7px;
  font-size: 12.5px; line-height: 1.45; color: var(--fg);
  font-variant-numeric: tabular-nums;
}
#pb-readout .pb-when { color: var(--fg-dim); font-size: 11px; display: block; margin-top: 2px; }
#pb-readout .pb-frame { color: var(--fg-dim); }
/* The playback read-out that rides in the chip row. It is not a layer — no ×,
 * nothing to click — so it takes the right-hand padding the missing close
 * button would have provided, and wears the accent so it reads as a state the
 * app is IN rather than one more thing that is switched on. */
.chip-play { border-color: var(--accent); }
.chip-play .chip-label { padding-right: 18px; color: var(--accent); cursor: default; }
.chip-play .chip-label:hover { color: var(--accent); }

/* ---- Cones tab (E-069). Same primitives as Tides and Play (.stat-row,
 * .control-row, .td-btn, .hint); the only things this panel needs of its own
 * are a full-width lag scrub, a preset row that fits four place names in a
 * 320 px sidebar, and a cross-section canvas that scales like #td-curve. */
#panel-cones .control-row > label:first-child { flex: 0 0 44px; }
#cn-family {
  flex: 1; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px;
}
#cn-lag { flex: 1; min-width: 0; accent-color: var(--accent); }
#cn-lag-read {
  font-variant-numeric: tabular-nums; color: var(--fg); font-size: 12.5px; margin: 2px 0 6px;
}
/* Six presets now — the globe's, not one basin's — and six do not fit across a
 * 380 px sidebar. A 30% basis puts three on a row and wraps the rest, so the
 * block is two even rows at any sidebar width rather than one row that
 * overflows or a ragged five-plus-one. */
#cn-presets { gap: 4px; flex-wrap: wrap; margin-top: -2px; }
#cn-presets button {
  flex: 1 1 30%; min-width: 0; background: #21262d; color: #c9d1d9; border: 1px solid #30363d;
  border-radius: 6px; padding: 4px 2px; font-size: 11px; white-space: nowrap; cursor: pointer;
}
#cn-presets button:hover { background: #30363d; }
#cn-presets button.active { border-color: var(--accent); color: var(--accent); }
#cn-section { display: block; width: 100%; background: #0a0f16; border-radius: 6px; margin-top: 6px; }
/* The lag read-out is two lines now (lag + date, then the anchor cell), and
 * it turns red on a HELD-OUT year — 2009, 2017 and 2023 are the three the
 * model was never trained on, so a cone standing on one of them is a
 * different claim from a cone standing on a training year. */
#cn-lag-read .cn-anchor-read { color: var(--fg-dim); font-size: 11.5px; }
#cn-lag-read.cn-held { color: #ff9a90; }
.cn-held-tag {
  display: inline-block; margin-left: 5px; padding: 0 5px; border-radius: 4px;
  background: rgba(248, 81, 73, 0.16); border: 1px solid rgba(248, 81, 73, 0.5);
  color: #ff9a90; font-size: 10px; vertical-align: 1px;
}
/* The what-if badge: the panel's loudest element, deliberately. A drawing of
 * a model that is not the model looks entirely plausible, so the only defence
 * is a line that says so. */
#cn-whatif {
  margin: 6px 0 2px; padding: 5px 9px; border-radius: 6px; font-size: 11.5px;
  background: rgba(240, 216, 97, 0.12); border: 1px solid rgba(240, 216, 97, 0.55);
  color: #f0d861;
}
#cn-date { flex: 1 1 0; min-width: 0; }
#cn-time-speed { flex: 1 1 60px; min-width: 0; accent-color: var(--accent); }
#cn-time-speed-read { flex: 0 0 auto; white-space: nowrap; }
#cn-time-play.playing { border-color: var(--accent); color: var(--accent); }
/* Stacked, not side by side: "follow the cone — drive the globe's date" is a
 * sentence, and a 320 px sidebar shared with "loop" folds it into a column of
 * single words. */
.cn-checks { flex-direction: column; align-items: flex-start; gap: 5px; margin-top: 2px; }
.cn-checks label { display: flex; align-items: center; gap: 6px; font-size: 11.5px; }
.cn-checks input[type="checkbox"] { flex: 0 0 auto; margin: 0; }
/* One row per knob — label · slider · value — so nine constants fit a phone. */
.cn-param { display: flex; align-items: center; gap: 8px; margin: 5px 0; font-size: 11.5px; }
.cn-param label { flex: 0 0 82px; color: var(--fg-dim); }
.cn-param input[type="range"] { flex: 1; min-width: 0; accent-color: var(--accent); }
.cn-param-val {
  flex: 0 0 88px; text-align: right; font-variant-numeric: tabular-nums;
  color: var(--fg); font-size: 11px;
}
#cn-reset { width: 100%; margin-top: 6px; padding: 6px 0; }
#cn-reset.active { border-color: var(--accent); color: var(--accent); }

/* ---- Cones tab · DATA MODE (E-069 samples). The geometry block above draws
 * the cone's shape; this one puts the tensor's own numbers in it. Three
 * elements it needs of its own: a legend that states the numeric range (a
 * colour without a scale is decoration), a read-out panel that names the
 * pixel and the DATE the value came from — the same "which pixel answered"
 * discipline as the probe — and a heat strip for the 42 x 9 patch. */
#cn-data-anchor, #cn-stencil, #cn-channel {
  flex: 1; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px;
}
#cn-legend { margin: 8px 0 4px; }
#cn-legend .cn-bar {
  height: 10px; border-radius: 3px; border: 1px solid var(--border);
}
#cn-legend .cn-scale {
  display: flex; justify-content: space-between; font-size: 10.5px;
  color: var(--fg-dim); font-variant-numeric: tabular-nums; margin-top: 2px;
}
#cn-legend .cn-unit { font-size: 11px; color: var(--fg-dim); margin-top: 1px; }
#cn-readout {
  margin: 6px 0; padding: 7px 9px; border-radius: 6px; font-size: 11.5px;
  line-height: 1.55; background: #0a0f16; border: 1px solid var(--border);
  color: var(--fg); font-variant-numeric: tabular-nums;
}
#cn-readout .cn-ro-k { color: var(--fg-dim); }
#cn-readout .cn-ro-miss { color: #f0d861; }
#cn-readout .cn-ro-inval { color: #ff9a90; }
#cn-strip { display: block; width: 100%; background: #0a0f16; border-radius: 6px; }
#cn-data-hint strong { color: var(--fg); }

/* The model climatology's row: two pickers and a downloads fold. The same
   Downloads block also sits in its hover card (informational there — the card
   takes no pointer events, so the CSV button lives in the row). */
.clim-rows .chan-row + .chan-row { margin-top: 3px; }
.clim-dl { margin: 4px 0 0 24px; font-size: 11px; color: var(--fg-dim); }
/* the pentad climatology's span: two year fields and a leave-out list (E-093) */
.poy-rows .chan-row input[type="number"], .f7-rows .chan-row input[type="number"] { width: 5.2em; font-size: 11px; padding: 2px 4px; }
.poy-rows .chan-row input[type="text"], .f7-rows .chan-row input[type="text"] { flex: 1; min-width: 0; font-size: 11px; padding: 2px 4px; }
/* the Global tensor's mode switch (E-093): the climatology rows only show in
 * the climatology and anomaly modes, the years only for the per-pentad kind */
.f7-rows [hidden] { display: none; }
.f7-rows .chan-row > .alpha-label { min-width: 5.5em; }
.poy-note { margin: 3px 0 0 24px; font-size: 11px; color: var(--fg-dim); line-height: 1.4; }
.poy-note:empty { display: none; }
.clim-dl summary { cursor: pointer; }
.clim-dl ul, .layer-tip .tip-dl-body ul { margin: 3px 0 0; padding-left: 16px; }
.clim-dl li, .layer-tip .tip-dl-body li { margin: 1px 0; line-height: 1.45; }
.clim-dl a, .layer-tip .tip-dl-body a { color: var(--accent); }
.clim-dl-head { color: var(--fg); margin-top: 3px; }
.clim-csv {
  background: none; border: 1px solid var(--border); color: var(--accent);
  border-radius: 4px; font-size: 11px; padding: 2px 6px; cursor: pointer;
}
.clim-csv:hover { border-color: var(--accent); }
.layer-tip .tip-dl-body, .layer-tip .tip-dl-body div { display: block; }

/* ---- Data tab (E-084 §3). The same primitives as Cones and Play
 * (.control-row, .td-btn, .hint, .hint-details); what this panel needs of its
 * own: a label column the rows line up on, chip rows that WRAP (twelve months
 * and up to 128 channels must fit a 360 px phone without a sideways scroll),
 * a 2×2 box grid, the estimate line, and a progress bar. */
#panel-data .control-row > label:first-child { flex: 0 0 72px; color: var(--fg-dim); font-size: 12px; }
#panel-data .dt-wrap { flex-wrap: wrap; row-gap: 6px; }
#panel-data .dt-tight { gap: 6px; }
#dt-store, #dt-group, #dt-step, #dt-res, #dt-format, #dt-pv-chan {
  flex: 1 1 140px; min-width: 0; max-width: 100%; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px;
}
#dt-format { flex: 1 1 90px; }
#dt-store-about { margin: 2px 0 8px; line-height: 1.5; overflow-wrap: anywhere; }
#dt-store-about .dt-code, .dt-code {
  font-size: 10.5px; color: var(--fg-dim); background: #0a0f16; border: 1px solid var(--border);
  border-radius: 4px; padding: 0 4px;
}
.dt-k { color: var(--fg-dim); }
#dt-store-about .dt-k { color: #6e7681; }
.dt-head { font-size: 12px; color: var(--fg-dim); margin: 10px 0 4px; display: flex;
  flex-wrap: wrap; align-items: center; gap: 6px; }
.dt-head-note { font-size: 11px; color: #6e7681; }
.dt-num {
  flex: 0 1 72px; width: 72px; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.dt-num.dt-hr { flex-basis: 56px; width: 56px; }
.dt-text { flex: 1 1 140px; min-width: 0; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 6px; font-size: 12.5px; }
.dt-to { font-size: 12px; color: var(--fg-dim); }
.hint.dt-inline { margin: 0; flex: 1 1 100%; }
.dt-chips { display: flex; flex-wrap: wrap; gap: 4px; }
#dt-channels { max-height: 132px; overflow-y: auto; }
.dt-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 7px; border-radius: 12px;
  background: #21262d; border: 1px solid var(--border); font-size: 11.5px; color: #c9d1d9;
  cursor: pointer; max-width: 100%; overflow-wrap: anywhere;
}
.dt-chip input { margin: 0; accent-color: var(--accent); }
.dt-chip:has(input:checked) { border-color: var(--accent); color: var(--fg); }
.dt-months button {
  flex: 1 0 calc(16.66% - 4px); min-width: 0; padding: 4px 0; border-radius: 6px; font-size: 11.5px;
  background: #21262d; color: #8b949e; border: 1px solid var(--border); cursor: pointer;
}
.dt-months button.active { border-color: var(--accent); color: var(--fg); background: rgba(68, 147, 248, 0.14); }
.dt-mini {
  background: none; border: 1px solid var(--border); color: var(--accent); border-radius: 4px;
  font-size: 10.5px; padding: 1px 6px; cursor: pointer;
}
.dt-mini:hover { border-color: var(--accent); }
/* the normals' three splits: chips big enough to tap */
.dt-preset-chip { font-size: 11.5px; padding: 3px 9px; border-radius: 12px; }
.dt-preset-chip.active { background: var(--accent); color: var(--bg); border-color: var(--accent); }
/* which path a time mean reads (E-088): precomputed sums or every native map */
.dt-path { margin: 4px 0 2px; font-size: 12px; color: var(--fg); }
.dt-path.dt-path-native { color: var(--fg-dim); }
.dt-paper-files table { border-collapse: collapse; font-size: 11.5px; margin: 4px 0 8px; }
.dt-paper-files th, .dt-paper-files td { border: 1px solid var(--border); padding: 2px 6px; text-align: left; }
.dt-paper-files th { color: var(--fg-dim); font-weight: normal; }
@media (max-width: 600px) { .dt-paper-files table { font-size: 10.5px; } .dt-paper-files th, .dt-paper-files td { padding: 2px 3px; } }
.dt-box { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; }
.dt-box label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-dim); }
.dt-box input {
  flex: 1; min-width: 0; background: var(--bg); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 5px 6px; font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.td-btn.dt-btn { font-size: 12px; padding: 4px 10px; }
.td-btn:disabled, .dt-mini:disabled { opacity: 0.45; cursor: not-allowed; }
.td-btn.dt-go:not(:disabled) { border-color: var(--accent); color: var(--fg); }
#dt-presets { gap: 4px; flex-wrap: wrap; margin-top: 2px; }
#dt-presets button {
  flex: 1 1 30%; min-width: 0; background: #21262d; color: #c9d1d9; border: 1px solid #30363d;
  border-radius: 6px; padding: 4px 2px; font-size: 11px; white-space: nowrap; cursor: pointer;
}
#dt-presets button:hover { background: #30363d; }
.dt-estimate {
  margin: 10px 0 4px; padding: 7px 10px; border-radius: 7px; font-size: 12px; line-height: 1.5;
  background: #0a0f16; border: 1px solid var(--border); color: var(--fg-dim);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.dt-estimate strong { color: var(--fg); font-weight: 600; }
.dt-estimate.dt-busy { opacity: 0.6; }
.dt-estimate.dt-over { border-color: rgba(240, 216, 97, 0.55); color: #f0d861; }
.dt-estimate .dt-why { margin-top: 4px; color: #f0d861; }
.dt-estimate a { color: var(--accent); }
#dt-progress { display: block; width: 100%; height: 8px; margin: 4px 0 2px; accent-color: var(--accent); }
#dt-status { overflow-wrap: anywhere; }
/* progress for the longer reads (DtProgress): a bar, one line of counts, one
 * line of why; the bar is a fraction when a total is known and indeterminate
 * when not. Everything wraps inside the panel — no width of its own. */
.dt-prog { margin: 4px 0; font-size: 11.5px; color: var(--fg-dim); min-width: 0; }
.dt-prog-top { display: flex; align-items: center; gap: 6px; }
.dt-prog-bar { flex: 1 1 auto; min-width: 0; height: 8px; appearance: none; -webkit-appearance: none;
  border: 0; border-radius: 4px; background: rgba(139, 148, 158, 0.25); overflow: hidden; }
.dt-prog-bar::-webkit-progress-bar { background: rgba(139, 148, 158, 0.25); border-radius: 4px; }
.dt-prog-bar::-webkit-progress-value { background: var(--accent); border-radius: 4px; }
.dt-prog-bar::-moz-progress-bar { background: var(--accent); border-radius: 4px; }
.dt-prog-bar:indeterminate { background: repeating-linear-gradient(-45deg, rgba(88, 166, 255, 0.55) 0 8px,
  rgba(139, 148, 158, 0.2) 8px 16px); background-size: 200% 100%; animation: dt-prog-slide 1.2s linear infinite; }
.dt-prog-bar:indeterminate::-webkit-progress-bar { background: transparent; }
@keyframes dt-prog-slide { from { background-position: 0 0; } to { background-position: -45px 0; } }
@media (prefers-reduced-motion: reduce) { .dt-prog-bar:indeterminate { animation: none; } }
.dt-prog-cancel { flex: 0 0 auto; padding: 2px 8px; }
.dt-prog-label { margin-top: 2px; color: var(--fg); overflow-wrap: anywhere; }
.dt-prog-line { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.dt-prog-why { color: #f0d861; overflow-wrap: anywhere; }
.dt-prog-why:empty { display: none; }
.dt-prog[data-state="done"] .dt-prog-cancel, .dt-prog[data-state="cancelled"] .dt-prog-cancel { visibility: hidden; }
.dt-estimate .dt-prog { margin: 0; }
#dt-status.dt-error, .dt-missing { color: #ff9a90; }
#dt-legend { margin: 6px 0; font-size: 11.5px; }
#dt-legend .dt-lg-name { color: var(--fg); margin-bottom: 3px; overflow-wrap: anywhere; }
#dt-legend .dt-lg-bar { height: 10px; border-radius: 3px; border: 1px solid var(--border); }
#dt-legend .dt-lg-scale {
  display: flex; justify-content: space-between; font-size: 10.5px; color: var(--fg-dim);
  font-variant-numeric: tabular-nums; margin-top: 2px;
}
#dt-legend .dt-lg-unit { font-size: 11px; color: var(--fg-dim); margin-top: 1px; overflow-wrap: anywhere; }
.clim-to-data, .clim-recipe { margin-top: 4px; }
#panel-data .hint.dt-note { margin: 0 0 6px; color: #8b949e; }
.dt-estimate .dt-how { margin-top: 4px; font-size: 11px; color: #8b949e; }
.dt-sub { font-size: 11px; color: #8b949e; margin: 6px 0 3px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.dt-levels button {
  flex: 0 1 auto; min-width: 44px; padding: 3px 6px; border-radius: 6px; font-size: 11px;
  background: #21262d; color: #8b949e; border: 1px solid var(--border); cursor: pointer; font-variant-numeric: tabular-nums;
}
.dt-levels button.active { border-color: var(--accent); color: var(--fg); background: rgba(68, 147, 248, 0.14); }
#dt-reg-error .dt-reg-line { color: #f0d861; margin: 2px 0; overflow-wrap: anywhere; }
#dt-reg-coming { color: #8b949e; font-size: 11px; overflow-wrap: anywhere; }
#dt-store-about .dt-attrib { display: block; font-size: 10.5px; color: #8b949e; margin-top: 2px; overflow-wrap: anywhere; }
#dt-store optgroup { color: var(--fg-dim); font-style: normal; }

/* drawing the Data tab's box on the globe: the armed button, and the chip
 * over the globe that says what to do next and offers a way out */
#dt-draw.active { border-color: #f0d861; color: #f0d861; }
.dt-draw-chip { position: absolute; top: 56px; left: 50%; transform: translateX(-50%); z-index: 30;
  display: flex; align-items: center; gap: 8px; max-width: calc(100% - 32px);
  padding: 6px 8px 6px 12px; border-radius: 16px; font-size: 12.5px;
  background: rgba(13, 17, 23, 0.92); color: #f0d861; border: 1px solid rgba(240, 216, 97, 0.6); }
.dt-draw-chip-text { overflow-wrap: anywhere; }
.dt-draw-chip-x { flex: 0 0 auto; background: transparent; color: var(--fg); border: 1px solid var(--border);
  border-radius: 12px; padding: 2px 10px; font-size: 12px; cursor: pointer; }
/* on a phone the top of the globe holds the search box and the layer chips:
 * the drawing chip sits above the scale bar instead */
@media (max-width: 600px) {
  .dt-draw-chip { top: auto; bottom: 64px; }
}

/* Data tab: the period as one slider with two handles (two overlaid ranges;
   only the thumbs take the pointer, so either can be grabbed). */
.dt-yslide { position: relative; height: 28px; margin: 2px 2px 6px; }
.dt-yslide::before { content: ""; position: absolute; left: 0; right: 0; top: 12px; height: 4px;
  border-radius: 2px; background: var(--border); }
.dt-yslide-fill { position: absolute; top: 12px; height: 4px; border-radius: 2px; background: #4493f8; }
.dt-yslide input[type=range] { position: absolute; left: 0; top: 0; width: 100%; height: 28px; margin: 0;
  background: none; pointer-events: none; -webkit-appearance: none; appearance: none; }
.dt-yslide input[type=range]::-webkit-slider-runnable-track { background: none; height: 28px; }
.dt-yslide input[type=range]::-moz-range-track { background: none; }
.dt-yslide input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: auto;
  width: 22px; height: 22px; margin-top: 3px; border-radius: 50%; background: #4493f8;
  border: 2px solid var(--bg); cursor: pointer; }
.dt-yslide input[type=range]::-moz-range-thumb { pointer-events: auto; width: 18px; height: 18px;
  border-radius: 50%; background: #4493f8; border: 2px solid var(--bg); cursor: pointer; }
