:root {
  --bg: #0b1220;
  --bg-2: #111a2e;
  --panel: #142036;
  --panel-2: #1a2747;
  --border: #2c4070;
  --text: #f1f5fb;
  --text-dim: #a8bcdb;
  --accent: #5ccbff;
  --accent-2: #6dffc7;
  --ok: #34d164;
  --warn: #f5a623;
  --alert: #f25656;
  --chart-grid: rgba(255,255,255,0.14);
  --shadow: 0 10px 30px rgba(0,0,0,0.40);
  --radius: 14px;
}
[data-theme="light"] {
  --bg: #eef2f8;
  --bg-2: #e1e8f1;
  --panel: #ffffff;
  --panel-2: #f1f5fb;
  --border: #b8c4d8;
  --text: #0a1628;
  --text-dim: #3c4a63;
  --accent: #0a72c4;
  --accent-2: #0e9b6c;
  --ok: #047857;
  --warn: #b45309;
  --alert: #b91c1c;
  --chart-grid: rgba(10,22,40,0.18);
  --shadow: 0 6px 18px rgba(20,40,90,0.12);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background:
    radial-gradient(1200px 600px at -10% -10%, rgba(76,194,255,0.10), transparent 60%),
    radial-gradient(900px 500px at 110% 10%, rgba(109,255,199,0.08), transparent 60%),
    var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Topbar */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: rgba(20, 32, 54, 0.6);
  backdrop-filter: blur(12px);
  position: sticky; top: 0; z-index: 50;
}
[data-theme="light"] .topbar { background: rgba(255,255,255,0.82); }
.topbar-left { display: flex; align-items: center; gap: 64px; min-width: 0; }
.topbar { gap: 22px; }
.logo { display: flex; align-items: center; gap: 12px; }
.logo-mark {
  height: 52px; display: inline-flex; align-items: center;
  flex-shrink: 0;
  opacity: 0.95; transition: opacity .15s ease;
}
.logo-mark:hover { opacity: 1; }
.logo-mark img { height: 52px; width: auto; object-fit: contain; display: block; }
.logo-mark img.logo-color { display: none; }
.logo-mark img.logo-light { display: block; }
[data-theme="light"] .logo-mark img.logo-color { display: block; }
[data-theme="light"] .logo-mark img.logo-light { display: none; }
.logo-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.logo-text strong { font-size: 18px; letter-spacing: 0.4px; line-height: 1.1; }
/* Subtítulo = texto desarrollado de SIMAS, en el recuadro de color (teal) */
.logo-text small {
  display: inline-block; align-self: flex-start;
  color: #07203b;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  font-size: 11px; font-weight: 600; line-height: 1.35; letter-spacing: 0.2px;
  padding: 3px 10px; margin-top: 3px; border-radius: 5px;
  max-width: 480px;
}
.topbar-institutional {
  display: flex; align-items: center; gap: 20px;
  height: 64px;
}
.topbar-institutional .logo-link { display: inline-flex; align-items: center; opacity: 0.95; transition: opacity .15s ease; }
.topbar-institutional .logo-link:hover { opacity: 1; }
.topbar-institutional img { height: 40px; width: auto; object-fit: contain; display: block; }
/* Canelones GA — principal del proyecto (entidad financiadora/operadora),
   ÚNICO de su categoría, el más alto del topbar. */
.topbar-institutional .logo-link.logo-canelones img { height: 56px; }
/* Separación visual entre el principal (Canelones GA) y el bloque académico
   (LCCLA, DEGA, CURE, UdelaR, FUNDACIBA/MSur). */
.topbar-institutional .logo-link.logo-lccla { margin-left: 24px; }
/* LCCLA — académico. Versión "compacto" (logo circular + "LCCLA" sigla),
   más cuadrado que el lockup horizontal anterior. Sin max-width porque el
   aspect natural ya es aproximadamente cuadrado y no se desborda. */
.topbar-institutional .logo-link.logo-lccla img { height: 52px; }
/* DEGA — académico, mismo nivel visual que CURE/UdelaR. Reducido 15% desde 36px
   por pedido del usuario para balance visual con los demás logos del bloque. */
.topbar-institutional .logo-link.logo-dega img { height: 31px; }
/* Stack of two small logos — proporcional al UdelaR (40px stack, ~17px each) */
.logo-stack {
  display: flex; flex-direction: column; justify-content: center;
  gap: 0; height: 40px;
}
.logo-stack .logo-link { height: 17px; }
.logo-stack img { height: 17px !important; width: auto; object-fit: contain; display: block; }
.topbar-institutional img.logo-color { display: none; }
.topbar-institutional img.logo-light { display: block; }
[data-theme="light"] .topbar-institutional img.logo-color { display: block; }
[data-theme="light"] .topbar-institutional img.logo-light { display: none; }
@media (max-width: 1280px) {
  .topbar-institutional { gap: 14px; padding-left: 14px; height: 56px; }
  .topbar-institutional img { height: 32px; }
  .topbar-institutional .logo-link.logo-canelones img { height: 46px; }
  .topbar-institutional .logo-link.logo-lccla img { height: 42px; }
  .topbar-institutional .logo-link.logo-lccla { margin-left: 16px; }
  .topbar-institutional .logo-link.logo-dega img { height: 26px; }
  .logo-stack { height: 32px; }
  .logo-stack .logo-link { height: 14px; }
  .logo-stack img { height: 14px !important; }
}
@media (max-width: 1000px) {
  .topbar-institutional { display: none; }
}

.topbar-right { display: flex; align-items: center; gap: 10px; }
.status-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--border);
  font-size: 12.5px; color: var(--text-dim);
}
.status-pill .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-dim); box-shadow: 0 0 0 4px rgba(138,160,195,0.12);
}
.status-pill.ok .dot { background: var(--ok); box-shadow: 0 0 0 4px rgba(34,197,94,0.18); }
.status-pill.warn .dot { background: var(--warn); }
.status-pill.alert .dot { background: var(--alert); }

/* Sync (exhaustive backfill) indicator pill — also acts as a start/stop
   button. Clicking it toggles the backfill via /api/exhaustive_backfill_*.
   States:
   - "downloading": green dot that pulses — alive. Click stops.
   - "paused": yellow dot, static — work started but not progressing. Click resumes.
   - "done": dim green dot — backfill finished. Click re-runs.
   - "busy": gray dot — request in flight, button disabled.
   - default: hidden via .hidden */
.sync-pill {
  cursor: pointer;
  user-select: none;
  transition: background .15s ease, border-color .15s ease, opacity .15s ease;
}
.sync-pill:hover { background: var(--panel-2, var(--panel)); border-color: var(--accent); }
.sync-pill.busy { cursor: progress; opacity: .7; pointer-events: none; }
.sync-pill .dot { background: var(--text-dim); box-shadow: 0 0 0 4px rgba(138,160,195,0.12); }
.sync-pill.downloading .dot {
  background: var(--ok);
  animation: syncPulse 1.4s ease-in-out infinite;
}
.sync-pill.paused .dot { background: var(--warn); box-shadow: 0 0 0 4px rgba(245,158,11,0.18); }
.sync-pill.done .dot { background: var(--ok); opacity: .65; box-shadow: 0 0 0 4px rgba(34,197,94,0.12); }
@keyframes syncPulse {
  0%   { box-shadow: 0 0 0 0   rgba(34,197,94,0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(34,197,94,0);    }
  100% { box-shadow: 0 0 0 0   rgba(34,197,94,0);    }
}

/* Forecast storage pill — recordatorio admin del tamaño del cache de pronóstico
   Open-Meteo. Cuatro estados según el tamaño relativo a los umbrales: */
.forecast-storage-pill {
  user-select: none;
  font-size: 11.5px;
  transition: background .15s ease, border-color .15s ease;
}
.forecast-storage-pill .dot { background: var(--text-dim); }
.forecast-storage-pill.ok .dot { background: var(--ok); box-shadow: 0 0 0 4px rgba(34,197,94,0.12); }
.forecast-storage-pill.warn { border-color: var(--warn); }
.forecast-storage-pill.warn .dot { background: var(--warn); box-shadow: 0 0 0 4px rgba(245,158,11,0.18); }
.forecast-storage-pill.critical { border-color: var(--alert); background: rgba(239,68,68,0.08); }
.forecast-storage-pill.critical .dot {
  background: var(--alert);
  animation: syncPulse 1.6s ease-in-out infinite;
}
.forecast-storage-pill.paused .dot { background: var(--text-dim); opacity: .5; }
.forecast-storage-pill.paused .label { color: var(--text-dim); font-style: italic; }
/* Botón de pausa/reanudar del registro de pronóstico, inline en el pill. */
.forecast-pause-btn {
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  border-radius: 5px;
  padding: 1px 7px;
  font-size: 11px;
  line-height: 1.3;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.forecast-pause-btn:hover {
  color: var(--text);
  border-color: var(--accent);
  background: rgba(99,102,241,0.08);
}

/* Pill admin-only: estado de las estaciones meteo (INUMET, INIA, Grafana, DINAGUA).
   Similar al globalStatus pero usa color cyan/violet para diferenciarse del SIMAS. */
.meteo-status-pill .dot { background: #38bdf8; box-shadow: 0 0 0 4px rgba(56,189,248,0.18); }
.meteo-status-pill.warn .dot { background: var(--warn); box-shadow: 0 0 0 4px rgba(245,158,11,0.18); }
.meteo-status-pill.alert .dot { background: var(--alert); }

/* Pill admin-only: backfill exhaustivo Grafana INUMET. Es más alta que las
   otras pills porque incluye dos progress bars + botón de reset. */
.grafana-backfill-pill {
  flex-direction: column;
  align-items: stretch !important;
  gap: 4px;
  padding: 8px 10px !important;
  font-size: 11px;
}
.grafana-backfill-pill .gbp-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
}
.grafana-backfill-pill .gbp-header .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}
.grafana-backfill-pill .gbp-header .label { flex: 1; }
.grafana-backfill-pill.idle .dot { background: var(--text-dim); opacity: 0.6; }
.grafana-backfill-pill.running .dot {
  background: var(--accent);
  animation: backfill-pulse 2s ease-in-out infinite;
}
.grafana-backfill-pill.done .dot { background: var(--ok); }
@keyframes backfill-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(99,102,241,0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(99,102,241,0); }
}
.grafana-backfill-pill .gbp-reset {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  border-radius: 5px;
  padding: 1px 8px;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.grafana-backfill-pill .gbp-reset:hover {
  color: var(--alert);
  border-color: var(--alert);
  background: rgba(239,68,68,0.08);
}
.grafana-backfill-pill .gbp-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
}
.grafana-backfill-pill .gbp-label {
  min-width: 50px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.grafana-backfill-pill .gbp-bar-wrap {
  flex: 1;
  height: 6px;
  background: var(--panel-2);
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.grafana-backfill-pill .gbp-bar-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #6366f1);
  transition: width 0.5s ease;
}
.grafana-backfill-pill .gbp-pct {
  min-width: 32px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 600;
}
.grafana-backfill-pill .gbp-state {
  margin-top: 5px;
  font-size: 11px;
  color: var(--text-dim);
  line-height: 1.3;
}
/* ERA5 pill: ámbar cuando está pausado (esperando reanudar por rate-limit) */
.grafana-backfill-pill.idle .gbp-state { color: var(--warn, #f59e0b); }

.btn {
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px; padding: 8px 12px;
  cursor: pointer; transition: all .15s ease;
  font-size: 13px; display: inline-flex; align-items: center; gap: 6px;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.ghost { background: transparent; }
.btn.small { padding: 5px 10px; font-size: 12px; }
.btn.lang-btn { font-weight: 700; min-width: 38px; padding: 6px 8px; font-size: 12px; letter-spacing: 0.8px; }

/* Layout */
.layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 18px;
  padding: 18px;
  flex: 1 0 auto; /* grow with content; don't shrink below intrinsic height */
}
/* layout collapse: see @media block at end of file */

/* Shared height for the Map & detail panel — sidebar, map and detail align */
:root { --panel-h: 720px; }

/* Sidebar */
.sidebar {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: var(--shadow);
  height: var(--panel-h);
  position: sticky; top: 80px;
  overflow: auto;
  display: flex; flex-direction: column;
}
.sidebar .station-list { flex: 1; }
.sidebar h3 { margin: 0 0 12px; font-size: 13px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-dim); display: flex; justify-content: space-between; align-items: baseline; }
.sidebar h3 small { color: var(--accent); font-weight: 700; }

.station-list { display: flex; flex-direction: column; gap: 5px; }
.station-group { display: flex; flex-direction: column; gap: 5px; }
.station-group-body { display: flex; flex-direction: column; gap: 5px; }
.station-group[data-collapsed="true"] .station-group-body { display: none; }
.station-group-title {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 6px 0 2px;
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.3px;
  color: var(--accent);
  padding-bottom: 2px; border-bottom: 1px dashed var(--border);
}
.station-group:first-child .station-group-title { margin-top: 0; }
.station-group-title:hover { filter: brightness(1.15); }
/* El nombre de la categoría es su propio target de click (muestra la descripción
   en el detalle, sin colapsar) → se subraya al pasar el mouse para indicarlo. */
.station-group-title .group-label:hover { text-decoration: underline; text-underline-offset: 2px; }
.station-group-title .chev {
  display: inline-block;
  font-size: 11px;
  width: 12px;
  text-align: center;
  transition: transform 0.18s ease;
  color: var(--text-dim);
}
.station-group[data-collapsed="true"] .station-group-title .chev { transform: rotate(-90deg); }
.station-group-title .group-label { flex: 1; }
.station-group-title .group-count {
  font-weight: 500;
  font-size: 10.5px;
  color: var(--text-dim);
  letter-spacing: 0.5px;
}

/* Separador de sección: rótulo temático que agrupa visualmente varios grupos
   (ej. "Clima y meteorología" sobre Meteorología + Pronóstico + Reanálisis).
   No es interactivo ni colapsable — sólo orienta. Centrado con líneas a los
   lados y color tenue para diferenciarse de los títulos de grupo (accent). */
.station-section-sep {
  display: flex; align-items: center; gap: 8px;
  margin: 14px 2px 0;
  color: var(--text-dim); font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.5px; opacity: .85;
}
.station-section-sep::before,
.station-section-sep::after {
  content: ''; height: 1px; flex: 1;
  background: linear-gradient(90deg, transparent, var(--border), transparent);
}
/* El primero (arriba de todo) va más pegado al header "Estaciones". */
.station-section-sep:first-child { margin-top: 4px; }

/* --- Sub-grupos por cuenca (Calidad por cuenca) --- */
.subgroup-actions { display: flex; gap: 6px; margin: 2px 0 4px 4px; }
.subgroup-actions .mini-btn,
.cat-master-actions .mini-btn {
  font-size: 10px; padding: 2px 8px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim); cursor: pointer; transition: filter .15s, border-color .15s;
}
.subgroup-actions .mini-btn:hover,
.cat-master-actions .mini-btn:hover { filter: brightness(1.2); border-color: var(--accent); }
.subgroup-actions .mini-btn.active,
.cat-master-actions .mini-btn.active { border-color: var(--accent); color: var(--text); }

/* Fila MAESTRA de visibilidad de mapa por categoría (al tope del station list).
   Espejo del "todas/ninguna" por cuenca, pero para las 7 categorías. El rótulo
   va arriba y los dos botones en su propia fila DEBAJO (pedido). */
.cat-master-actions {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  margin: 0 0 8px 0; padding-bottom: 7px;
  border-bottom: 1px dashed var(--border);
}
.cat-master-label {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.8px; color: var(--text-dim);
}
.cat-master-buttons { display: flex; gap: 6px; flex-wrap: wrap; }

/* --- Programa de monitoreo (SIMAS Calidad): badge en la tarjeta + chips de
   filtro. El color lo aporta la variable inline --prog-color. --- */
.prog-badge {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  font-size: 9px; font-weight: 700; line-height: 15px; vertical-align: middle;
  border-radius: 999px; white-space: nowrap;
  color: var(--prog-color, var(--text-dim));
  border: 1px solid var(--prog-color, var(--border));
  background: var(--panel-2, rgba(255,255,255,0.04));
}
.prog-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 2px 0 6px 4px; }
.prog-filter-label { font-size: 10px; color: var(--text-dim); margin-right: 2px; }
.prog-chip {
  font-size: 9.5px; font-weight: 600; padding: 1px 7px; border-radius: 999px;
  cursor: pointer; white-space: nowrap; transition: filter .15s, opacity .15s;
  color: var(--prog-color, var(--text-dim));
  border: 1px solid var(--prog-color, var(--border));
  background: transparent;
}
.prog-chip:hover { filter: brightness(1.25); }
.prog-chip:not(.on) {
  color: var(--text-dim); border-color: var(--border);
  opacity: .5; text-decoration: line-through;
}

.station-subgroup { display: flex; flex-direction: column; gap: 4px; margin-left: 4px; }
.station-subgroup-body { display: flex; flex-direction: column; gap: 5px; }
.station-subgroup[data-collapsed="true"] .station-subgroup-body { display: none; }
.station-subgroup-title {
  cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 5px;
  margin: 3px 0 1px; font-size: 11px; font-weight: 600;
  color: var(--text); padding-bottom: 1px;
}
.station-subgroup-title:hover { filter: brightness(1.15); }
.station-subgroup-title .chev {
  display: inline-block; font-size: 10px; width: 11px; text-align: center;
  transition: transform .18s ease; color: var(--text-dim);
}
.station-subgroup[data-collapsed="true"] .station-subgroup-title .chev { transform: rotate(-90deg); }
.station-subgroup-title .subgroup-label { flex: 1; }
.cuenca-eye {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 22px; padding: 0; border: none; border-radius: 5px;
  background: transparent; color: var(--text-dim); cursor: pointer;
  opacity: .5; transition: opacity .15s, color .15s, background .15s;
}
.cuenca-eye:hover { background: var(--panel); color: var(--text); opacity: 1; }
.cuenca-eye.on { color: var(--accent); opacity: 1; }
/* Ojo de visibilidad por CATEGORÍA (header de grupo de primer nivel). Reusa
   .cuenca-eye. Tap target cómodo (26×22) sin dominar el header en mayúsculas.
   Oculta (off) → ojo tenue; encendida → color de acento. */
.station-group-title .category-eye { width: 26px; height: 22px; margin: 0 -2px; flex: 0 0 auto; }
.station-group-title .category-eye svg { width: 13px; height: 13px; }
.station {
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 6px 9px;
  cursor: pointer;
  background: var(--panel-2);
  transition: all .15s ease;
}
.station:hover { border-color: var(--accent); transform: translateY(-1px); }
.station.active {
  border-color: var(--accent);
  background: linear-gradient(135deg, rgba(76,194,255,0.12), rgba(109,255,199,0.08));
  box-shadow: 0 4px 14px rgba(76,194,255,0.15);
}
.station-name { font-weight: 600; font-size: 12.5px; display: flex; align-items: center; gap: 7px; line-height: 1.2; }
.station-name .dot { width: 8px; height: 8px; border-radius: 50%; }
.station-name .dot.ok { background: var(--ok); box-shadow: 0 0 0 3px rgba(34,197,94,0.2); }
.station-name .dot.warn { background: var(--warn); box-shadow: 0 0 0 3px rgba(245,158,11,0.2); }
.station-name .dot.alert { background: var(--alert); box-shadow: 0 0 0 3px rgba(239,68,68,0.2); }
.station-meta { color: var(--text-dim); font-size: 10.5px; margin-top: 2px; font-weight: 500; line-height: 1.2; }
.station-meta a { color: var(--accent); text-decoration: none; }
.station-meta a:hover { text-decoration: underline; }
.station-meta.location { display: flex; align-items: center; gap: 5px; }
.station-meta .pin { flex-shrink: 0; color: var(--text-dim); width: 11px !important; height: 11px !important; }
.station-status {
  font-size: 10px; font-weight: 600; margin-top: 3px;
  padding: 2px 6px; border-radius: 5px; display: inline-block;
  letter-spacing: 0.2px;
}
.station-status.status-ok    { background: rgba(52,209,100,0.14); color: var(--ok); }
.station-status.status-warn  { background: rgba(245,166,35,0.16); color: var(--warn); }
.station-status.status-alert { background: rgba(242,86,86,0.18); color: var(--alert); }

.sidebar-footer { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); color: var(--text-dim); font-size: 11.5px; text-align: center; }
.sidebar-pills {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 10px;
}
.sidebar-pills .status-pill {
  /* Full width inside the narrow sidebar — pills stack vertically. */
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  font-size: 11.5px;
  padding: 6px 10px;
  text-align: left;
  line-height: 1.25;
}
.sidebar-pills .status-pill .label { flex: 1; min-width: 0; }

/* ---- Estado en línea compacto: AUTOMÁTICO + METEO, uno por línea ---- */
/* Apilados (columna): "AUTOMÁTICO 6/6" es largo y no entra lado a lado con
   METEO en el ancho angosto del sidebar (cortaba "METEO NN/NN"). En columna
   cada chip usa el ancho completo y ambos labels se ven enteros. */
.pill-row-inline { display: flex; flex-direction: column; gap: 4px; }
/* flex-basis:auto (no 0) → cada chip parte de su ancho de contenido y crece
   parejo para llenar la fila; así el más largo (METEO NN/NN) no se trunca. */
.pill-row-inline .status-pill { flex: 1 1 auto; min-width: 0; width: auto; }
.compact-chip { padding: 5px 7px !important; font-size: 11px !important; gap: 5px !important; }
.compact-chip .label {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

/* ---- Grupo colapsable "Procesos en 2.º plano" (admin) ---- */
.bg-proc {
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel); overflow: hidden;
}
.bg-proc-head {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 6px 10px; background: transparent; border: 0; cursor: pointer;
  color: var(--text-dim); font-size: 11.5px; text-align: left;
}
.bg-proc-head:hover { background: var(--panel-2, rgba(255,255,255,0.03)); }
.bg-proc-chev { display: inline-block; flex-shrink: 0; font-size: 10px; transition: transform .15s ease; }
.bg-proc:not(.collapsed) .bg-proc-chev { transform: rotate(90deg); }
.bg-proc-title { font-weight: 600; color: var(--text); white-space: nowrap; }
.bg-proc-summary {
  margin-left: auto; font-variant-numeric: tabular-nums; letter-spacing: .3px;
  white-space: nowrap; color: var(--text-dim);
}
.bg-proc.all-done .bg-proc-summary { color: var(--ok); }
.bg-proc.has-running .bg-proc-summary { color: var(--accent, #6366f1); }
.bg-proc.has-paused .bg-proc-summary { color: var(--warn); }
.bg-proc.collapsed .bg-proc-body { display: none; }
.bg-proc-body {
  display: flex; flex-direction: column; gap: 3px;
  padding: 4px 9px 7px; border-top: 1px solid var(--border);
}

/* Filas de proceso de UNA línea dentro del grupo: borran el chrome del pill
   (borde/fondo/padding grande) y los reordenan en horizontal compacto. */
.bg-proc-body .status-pill {
  border: 0 !important; background: transparent !important;
  width: 100%; padding: 2px 0 !important; font-size: 11px; line-height: 1.25;
  flex-direction: row !important; align-items: center !important; gap: 5px;
}
.bg-proc-body .bf-multi { flex-direction: column !important; align-items: stretch !important; gap: 2px !important; }
.bg-proc-body .bf-line { display: flex; align-items: center; gap: 5px; }
.bg-proc-body .bf-name {
  flex: 0 1 auto; min-width: 0; max-width: 84px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bg-proc-body .dot { width: 7px; height: 7px; box-shadow: none !important; flex-shrink: 0; }
.bg-proc-body .dot-spacer { width: 7px; flex-shrink: 0; }
.bg-proc-body .gbp-bar-wrap { flex: 1 1 auto; height: 5px; min-width: 40px; }
.bg-proc-body .gbp-pct { min-width: 26px; font-size: 10px; flex-shrink: 0; }
.bg-proc-body .forecast-storage-pill .label,
.bg-proc-body .sync-pill .label {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bg-proc-body .gbp-reset,
.bg-proc-body .forecast-pause-btn { flex-shrink: 0; padding: 0 6px; font-size: 11px; }

/* Tabs */
.tabs {
  display: flex; gap: 4px; padding: 4px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  overflow-x: auto;
}
.tab {
  flex: 1 1 auto;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: transparent; color: var(--text-dim);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 10px 14px; cursor: pointer;
  font-size: 13px; font-weight: 500;
  white-space: nowrap;
  transition: all .15s ease;
}
.tab:hover { color: var(--text); background: var(--panel-2); }
.tab.active {
  color: var(--text);
  background: linear-gradient(135deg, rgba(76,194,255,0.18), rgba(109,255,199,0.10));
  border-color: var(--accent);
  box-shadow: 0 4px 12px rgba(76,194,255,0.12);
}
.tab svg { opacity: 0.9; flex-shrink: 0; }
.tab-badge {
  display: none;
  font-size: 10px; padding: 1px 6px; border-radius: 999px;
  background: var(--accent); color: #07203b; font-weight: 700;
  letter-spacing: 0.3px; margin-left: 2px;
}
.tab-badge.show { display: inline-block; }
.tab-panel { display: none; }
.tab-panel.active { display: flex; flex-direction: column; gap: 18px; animation: fadeIn .18s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Cards / grid */
.content { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 1200px) { .grid-2 { grid-template-columns: 1fr; } }

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--border);
}
.card-head h4 { margin: 0; font-size: 14px; letter-spacing: 0.3px; }
.card-actions, .chart-controls { display: flex; align-items: center; gap: 10px; }
.meta { color: var(--text-dim); font-size: 12px; }

/* Map */
.map-card .card-head .map-legend { display: flex; gap: 12px; font-size: 12px; color: var(--text-dim); }
.map-card .card-head .map-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.map-card .card-head .map-legend i.ok { background: var(--ok); }
.map-card .card-head .map-legend i.warn { background: var(--warn); }
.map-card .card-head .map-legend i.alert { background: var(--alert); }
.map { width: 100%; height: 420px; }
.map-detail-grid { align-items: stretch; grid-template-columns: 2fr 3fr; }
.map-detail-grid .map-card,
.map-detail-grid .detail-card { height: var(--panel-h); display: flex; flex-direction: column; }
.map-detail-grid .map-card .map { flex: 1; height: auto; }
.map-detail-grid .detail-card .detail-body { flex: 1; max-height: none; }
.data-disclaimer {
  margin: 14px 4px 0; text-align: center;
  font-size: 11.5px; color: var(--text-dim); font-style: italic;
  line-height: 1.4;
}
/* Lift the CARTO Dark Matter tiles — they ship near-black for land, which
 * eats too much contrast against the panel background. brightness(1.55)
 * raises both land and water proportionally to a comfortable mid-dark. */
[data-theme="dark"] .leaflet-tile { filter: brightness(1.55); }

/* Detail */
.detail-body { padding: 14px 16px; max-height: 420px; overflow-y: auto; }
.detail-body .empty { color: var(--text-dim); text-align: center; padding: 40px 0; }
/* Atribución de fuente (p. ej. DINAGUA/SIH) — footer tenue del detalle. */
.detail-attribution { margin: 14px 2px 2px; padding-top: 10px; border-top: 1px dashed var(--border); font-size: 11px; font-style: italic; color: var(--text-dim); line-height: 1.4; }
/* Texto de bienvenida (estado inicial del detalle, sin estación seleccionada):
   descripción del dashboard — qué es, origen de datos, uso, utilidad. */
.detail-welcome { color: var(--text-dim); font-size: 13px; line-height: 1.55; padding: 2px 2px 0; }
.detail-welcome h4 { margin: 0 0 10px; font-size: 15px; color: var(--text); line-height: 1.3; }
.detail-welcome p { margin: 0 0 11px; }
.detail-welcome strong { color: var(--text); font-weight: 600; }
.detail-welcome em { color: var(--text); font-style: normal; font-weight: 500; }
.detail-welcome a { color: var(--accent); text-decoration: none; }
.detail-welcome a:hover { text-decoration: underline; }
.detail-welcome a strong { color: var(--accent); }
.detail-welcome + .empty { padding: 14px 0 22px; border-top: 1px solid var(--border); margin-top: 4px; color: var(--accent); }
.sensor-groups { display: flex; flex-direction: column; gap: 14px; }
.sensor-group h5 {
  margin: 0 0 8px; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 1.2px; color: var(--text-dim);
}
.sensor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(125px, 1fr)); gap: 7px; }
.sensor-cell {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 8px 10px;
  cursor: pointer;
  transition: all .15s ease;
  min-height: 0;
}
.sensor-cell:hover { border-color: var(--accent); }
.sensor-cell.selected { border-color: var(--accent-2); background: linear-gradient(135deg, rgba(109,255,199,0.12), rgba(76,194,255,0.06)); }
.sensor-cell .name {
  font-size: 11.5px; color: var(--text-dim); font-weight: 500;
  line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.sensor-cell .value { font-size: 17px; font-weight: 700; margin-top: 3px; color: var(--text); line-height: 1.15; }
.sensor-cell .unit { font-size: 11px; color: var(--text-dim); font-weight: 500; margin-left: 3px; }
.sensor-cell .ts { display: none; }

/* Sub-line en celdas de pronóstico: muestra "pron. para 16:00 · +1h" para que
   se entienda QUÉ horario representa cada valor (no confundirlo con
   "última lectura"). Color tenue + tipografía mono para los tiempos. */
.sensor-cell .forecast-target {
  font-size: 10.5px;
  color: var(--text-dim);
  margin-top: 4px;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  letter-spacing: 0.2px;
  font-style: italic;
}

/* Banda azul claro arriba del detail card cuando es una estación de pronóstico.
   Aclara la temporalidad para evitar la confusión de "últ. conexión 1s atrás"
   que en realidad significa "predicción vigente desde hace 1s". */
.forecast-banner {
  background: linear-gradient(135deg, rgba(76,194,255,0.10), rgba(167,139,250,0.08));
  border: 1px solid rgba(76,194,255,0.35);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0 0 12px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text);
}
.forecast-banner strong { color: var(--accent); margin-right: 4px; }
[data-theme="light"] .forecast-banner {
  background: linear-gradient(135deg, rgba(56,135,189,0.10), rgba(120,90,180,0.06));
  border-color: rgba(56,135,189,0.35);
}
.sensor-group h5 { margin: 0 0 6px; font-size: 11px; }
.sensor-groups { gap: 12px !important; }
.sensor-cell.alert { border-color: var(--alert); }
.sensor-cell.alert .value { color: var(--alert); }

/* Diagnostic sensors — admin-only view. Stripe pattern + dim color signals
   "internal use" without being too loud. Small badge next to the name. */
.sensor-cell.diag {
  border-style: dashed;
  border-color: rgba(138,160,195,0.45);
  opacity: 0.88;
}
.sensor-cell.diag .value { color: var(--text-dim); }
.diag-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-radius: 3px;
  background: rgba(138,160,195,0.18);
  color: var(--text-dim);
  vertical-align: middle;
  line-height: 14px;
}
/* "Diagnóstico" section header — distinct from scientific groups */
.sensor-group:has(.sensor-cell.diag) h5 {
  color: var(--text-dim);
  font-style: italic;
}
/* Health widget diag styling */
.widget-health-sensor.diag { opacity: 0.7; font-style: italic; }
.widget-health-sensor .diag-badge { font-size: 8.5px; }

/* Chart */
.chart-wrap { position: relative; padding: 14px 16px; min-height: 320px; }
.zoom-hint {
  padding: 4px 16px; font-size: 10.5px; color: var(--text-dim);
  font-style: italic; line-height: 1.4;
}
.chart-wrap canvas { width: 100% !important; height: 320px !important; }
.chips { padding: 10px 16px 0; display: flex; flex-wrap: wrap; gap: 6px; min-height: 32px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 10px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text);
  font-size: 12px; font-weight: 500;
}
.chip .swatch { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
/* Color picker swatch: native <input type="color"> styled as a small circle.
   Slightly bigger than the static swatch (9px) so it's a reliable click target
   that opens the OS color picker. */
.chip .swatch-input {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  width: 14px; height: 14px; padding: 0; border: none; border-radius: 50%;
  background: transparent; cursor: pointer;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22);
  transition: box-shadow 0.15s;
}
.chip .swatch-input::-webkit-color-swatch-wrapper { padding: 0; }
.chip .swatch-input::-webkit-color-swatch { border: none; border-radius: 50%; }
.chip .swatch-input::-moz-color-swatch { border: none; border-radius: 50%; }
.chip .swatch-input:hover { box-shadow: 0 0 0 2px var(--accent); }
.chip .chip-label { line-height: 1; }
.chip:hover { border-color: var(--accent); }

.chip-action {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  margin: 0; padding: 0; border-radius: 50%;
  background: transparent; border: none; color: var(--text-dim);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.chip-action:hover { background: var(--panel); color: var(--text); }
.chip-action.chip-remove:hover { color: var(--alert); }
.chip-action.chip-toggle.off { color: var(--text); opacity: 0.55; }

/* Chip showing a hidden series: dim swatch and label */
.chip.hidden-series .swatch { opacity: 0.35; }
.chip.hidden-series .chip-label { opacity: 0.55; text-decoration: line-through; }
.loader { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(20,32,54,0.55); color: var(--text-dim); font-size: 13px; backdrop-filter: blur(2px); }
.empty { color: var(--text-dim); text-align: center; padding: 60px 20px; }
.hidden { display: none !important; }
.chart-controls select {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text); border-radius: 8px; padding: 6px 8px; font-size: 12.5px;
}
/* El selector de paleta no necesita el ancho del rango temporal: se acota a su
   contenido (el desplegable abierto igual muestra el texto completo). */
#paletteSelect { max-width: 150px; }
.chart-controls label { font-size: 12px; color: var(--text-dim); display: inline-flex; align-items: center; gap: 6px; }

/* Custom date range row (aparece cuando el usuario elige "Personalizado" en el selector) */
.custom-range-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 8px 16px 0;
  padding: 10px 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.custom-range-row label {
  font-size: 12px; color: var(--text-dim);
  display: inline-flex; align-items: center; gap: 6px;
}
.custom-range-row input[type="datetime-local"] {
  background: var(--panel); border: 1px solid var(--border);
  color: var(--text); border-radius: 6px; padding: 5px 8px;
  font-size: 12.5px;
  color-scheme: dark;
}
[data-theme="light"] .custom-range-row input[type="datetime-local"] { color-scheme: light; }
.custom-range-hint {
  font-size: 11.5px; color: var(--text-dim);
  font-style: italic; flex: 1; min-width: 200px;
}

/* KPIs */
.kpi-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px; padding: 16px;
}
.kpi {
  background: linear-gradient(135deg, var(--panel-2), var(--panel));
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
  position: relative;
  overflow: hidden;
}
.kpi::after {
  content: ""; position: absolute; right: -20px; top: -20px;
  width: 80px; height: 80px; border-radius: 50%;
  background: radial-gradient(circle, rgba(76,194,255,0.18), transparent 70%);
}
.kpi .label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; }
.kpi .value { font-size: 22px; font-weight: 700; margin-top: 4px; }
.kpi .sub { font-size: 11px; color: var(--text-dim); margin-top: 2px; }

/* Footer */
.footer {
  padding: 10px 22px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  text-align: center;
  background: var(--panel);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.footer-logos {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 40px;
}
.footer-logos a {
  display: inline-flex; align-items: center; justify-content: center;
  height: 64px;
  opacity: 0.92; transition: opacity .15s ease, transform .15s ease;
}
.footer-logos a:hover { opacity: 1; transform: translateY(-1px); }
.footer-logos img { width: auto; object-fit: contain; display: block; }
/* Logos are pre-trimmed manually so the visible mark fills the frame.
   All three render at the same height for visual consistency. */
.footer-logos img { height: 54px; }
.footer-logos img.logo-color { display: none; }
.footer-logos img.logo-light { display: block; }
[data-theme="light"] .footer-logos img.logo-color { display: block; }
[data-theme="light"] .footer-logos img.logo-light { display: none; }
.footer-credits { font-size: 12px; color: var(--text-dim); line-height: 1.35; display: block; }
.footer a { color: var(--accent); text-decoration: none; font-weight: 500; }
.footer a:hover { text-decoration: underline; }

/* Leaflet tooltip in dark theme */
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
  background: var(--panel); color: var(--text); border: 1px solid var(--border);
}
.leaflet-popup-content { margin: 10px 14px; font-size: 12.5px; }
.leaflet-popup-content b { color: var(--accent); }

/* Messages panel */
.msg-editor {
  padding: 14px 16px; border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 12px;
  background: var(--panel-2);
}
.msg-editor.hidden { display: none; }
.msg-editor .row { display: flex; gap: 12px; flex-wrap: wrap; }
.msg-editor .row > .grow { flex: 1 1 200px; }
.msg-editor label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-dim); font-weight: 500; }
.msg-editor input, .msg-editor textarea, .msg-editor select {
  background: var(--panel); border: 1px solid var(--border);
  color: var(--text); border-radius: 8px;
  padding: 8px 10px; font-size: 13px; font-family: inherit; outline: none;
}
.msg-editor input:focus, .msg-editor textarea:focus, .msg-editor select:focus { border-color: var(--accent); }
.msg-editor textarea { resize: vertical; min-height: 80px; line-height: 1.5; }
.msg-editor-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* Editor de textos descriptivos (admin-only, pestaña Mensajes) */
#siteTextsCard { margin-top: 14px; }
.sitetext-help { margin: 2px 0 12px; font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }
.sitetext-status { font-size: 12px; color: var(--text-dim); margin-right: 8px; }
.sitetext-status.ok { color: var(--ok, #38d39f); }
.sitetext-status.err { color: var(--alert, #ff6b6b); }
.sitetext-editor { display: flex; flex-direction: column; gap: 12px; }
.sitetext-item {
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 12px;
  background: rgba(255,255,255,0.015);
}
.sitetext-item-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.sitetext-item-title { margin: 0; font-size: 13.5px; color: var(--text); font-weight: 600; }
.sitetext-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.sitetext-field:last-child { margin-bottom: 0; }
.sitetext-lang { font-size: 11px; color: var(--text-dim); font-weight: 500; text-transform: uppercase; letter-spacing: .03em; }
.sitetext-ta {
  width: 100%; box-sizing: border-box;
  background: var(--input-bg, rgba(0,0,0,0.25));
  border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); padding: 8px 10px;
  font: 12.5px/1.5 ui-monospace, 'Cascadia Code', Consolas, monospace;
  resize: vertical; min-height: 64px;
}
.sitetext-ta:focus { border-color: var(--accent); outline: none; }

/* Editor visual (WYSIWYG) de textos descriptivos */
.sitetext-toolbar-wrap { position: sticky; top: -2px; z-index: 3; margin-bottom: 10px; }
.sitetext-toolbar {
  display: flex; flex-wrap: wrap; gap: 4px;
  padding: 6px;
  background: rgba(17, 34, 56, 0.97);
  border: 1px solid var(--border); border-radius: 8px;
}
.sitetext-linkbar {
  display: flex; gap: 6px; align-items: center;
  margin-top: 6px; padding: 6px;
  background: rgba(17, 34, 56, 0.97);
  border: 1px solid var(--accent); border-radius: 8px;
}
.sitetext-linkbar.hidden { display: none; }
.sitetext-linkinput {
  flex: 1 1 auto; min-width: 0;
  background: var(--input-bg, rgba(0,0,0,0.25));
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--text); padding: 6px 9px; font-size: 13px;
}
.sitetext-linkinput:focus { border-color: var(--accent); outline: none; }
.st-tool {
  min-width: 30px; height: 28px; padding: 0 9px;
  border: 1px solid var(--border); border-radius: 6px;
  background: rgba(255,255,255,0.05); color: var(--text);
  font-size: 13px; font-weight: 600; line-height: 1; cursor: pointer;
}
.st-tool:hover { background: var(--accent); color: #07203b; border-color: var(--accent); }
.sitetext-rte {
  width: 100%; box-sizing: border-box;
  min-height: 80px; max-height: 340px; overflow-y: auto;
  background: var(--input-bg, rgba(0,0,0,0.25));
  border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); padding: 10px 12px;
  font-size: 13px; line-height: 1.55;
}
.sitetext-rte:focus { border-color: var(--accent); outline: none; }
.sitetext-rte h4 { margin: 0 0 8px; font-size: 15px; color: var(--text); }
.sitetext-rte p { margin: 0 0 9px; }
.sitetext-rte p:last-child { margin-bottom: 0; }
.sitetext-rte ul { margin: 0 0 9px; padding-left: 20px; }
.sitetext-rte a { color: var(--accent); }
.sitetext-rte img { max-width: 100%; height: auto; border-radius: 6px; margin: 4px 0; }

.msg-lang-block {
  position: relative;
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 16px 12px 10px;
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(255,255,255,0.02);
}
[data-theme="light"] .msg-lang-block { background: rgba(0,0,0,0.02); }
.msg-lang-tag {
  position: absolute; top: -8px; left: 12px;
  background: var(--panel-2); padding: 0 6px;
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-dim); font-weight: 600;
}

.msg-list { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.msg-list .empty { color: var(--text-dim); text-align: center; padding: 40px 0; }

.msg-item {
  border: 1px solid var(--border); border-left: 4px solid var(--text-dim);
  border-radius: 10px; background: var(--panel-2);
  padding: 12px 14px;
}
.msg-item.info   { border-left-color: var(--accent); }
.msg-item.aviso  { border-left-color: var(--warn); }
.msg-item.alerta { border-left-color: var(--alert); }
.msg-item-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.msg-item-title { font-size: 14.5px; font-weight: 700; color: var(--text); margin: 0; }
.msg-item-meta { font-size: 11.5px; color: var(--text-dim); display: flex; align-items: center; gap: 8px; }
.msg-type-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 10px;
  letter-spacing: 0.6px; text-transform: uppercase; font-weight: 700;
}
.msg-type-badge.info   { background: rgba(92,203,255,0.18); color: var(--accent); }
.msg-type-badge.aviso  { background: rgba(245,166,35,0.20); color: var(--warn); }
.msg-type-badge.alerta { background: rgba(242,86,86,0.22); color: var(--alert); }
.msg-item-body {
  margin: 8px 0 0; font-size: 13.5px; line-height: 1.55; color: var(--text);
  white-space: pre-wrap;
}
.msg-item-body a { color: var(--accent); text-decoration: underline; }
.msg-item-body strong { font-weight: 700; }
.msg-item-body em { font-style: italic; }
.msg-item-body ul { margin: 6px 0; padding-left: 22px; }
.msg-item-actions { display: flex; gap: 6px; }
.msg-item-actions .btn { padding: 4px 10px; font-size: 11.5px; }

/* Sanitizer note (below time-series chart) */
.sanitizer-note { padding: 8px 14px 12px; }
.sanitizer-note:empty { display: none; }
.sanitizer-note .san-title {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-dim); margin-bottom: 6px; font-weight: 600;
}
.sanitizer-note .san-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.sanitizer-note .san-list li {
  font-size: 11.5px; color: var(--text-dim); line-height: 1.5;
  display: flex; align-items: flex-start; gap: 6px;
}
.sanitizer-note .san-list li b { color: var(--text); }
.sanitizer-note .san-swatch {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  flex-shrink: 0; margin-top: 4px;
}

/* Chat panel */
.chat-card .card-head h4 { display: flex; align-items: center; gap: 8px; }
.engine-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text-dim); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.8px;
}
.engine-badge.claude { background: linear-gradient(135deg, rgba(76,194,255,0.18), rgba(109,255,199,0.12)); color: var(--accent); border-color: var(--accent); }

/* Engine selector toggle (Parser / Claude) */
.engine-toggle {
  display: inline-flex; border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-2); padding: 2px; gap: 0;
}
.engine-toggle-btn {
  background: transparent; border: none;
  color: var(--text-dim); cursor: pointer;
  font-size: 11px; font-weight: 600; letter-spacing: 0.4px;
  padding: 4px 12px; border-radius: 999px;
  transition: background 0.15s, color 0.15s;
  font-family: inherit;
}
.engine-toggle-btn:hover { color: var(--text); }
.engine-toggle-btn.active {
  background: var(--accent); color: var(--bg);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.engine-toggle-btn.unavailable {
  opacity: 0.55; text-decoration: line-through;
}
.engine-toggle-btn.unavailable.active {
  opacity: 1; text-decoration: none;
  background: var(--alert); color: #fff;
}

.engine-help {
  display: flex; gap: 8px;
  padding: 8px 14px; margin: 0 0 4px;
  background: rgba(76,194,255,0.06);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-dim); line-height: 1.5;
}
.engine-help > span > div + div { margin-top: 3px; }
.engine-help b { color: var(--text); }
.engine-help i { color: var(--text-dim); font-style: italic; }
.engine-help code {
  background: var(--panel); padding: 1px 5px; border-radius: 4px;
  font-size: 10.5px; border: 1px solid var(--border); color: var(--text);
}
.engine-help-icon {
  color: var(--accent); font-size: 14px; flex-shrink: 0; line-height: 1.5;
}
[data-theme="light"] .engine-help { background: rgba(15,92,140,0.06); }
.chat-body { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 10px; }
.chat-messages {
  max-height: 320px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  padding-right: 4px;
}
.chat-msg {
  padding: 10px 12px; border-radius: 12px; font-size: 13.5px; line-height: 1.45;
  border: 1px solid var(--border); background: var(--panel-2);
  max-width: 92%;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.chat-msg p { margin: 0 0 6px; }
.chat-msg p:last-child { margin-bottom: 0; }
.chat-msg .small { font-size: 11.5px; color: var(--text-dim); }
.chat-msg code { background: rgba(0,0,0,0.25); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
.chat-msg.user {
  align-self: flex-end;
  background: linear-gradient(135deg, rgba(76,194,255,0.18), rgba(109,255,199,0.12));
  border-color: var(--accent);
}
.chat-msg.assistant { align-self: flex-start; }
.chat-msg.system { align-self: stretch; max-width: 100%; opacity: 0.85; }
.chat-msg.error { border-color: var(--alert); color: var(--alert); }
.chat-msg.loading { color: var(--text-dim); font-style: italic; }
.chat-msg .badge {
  display: inline-block; font-size: 10px; padding: 1px 6px;
  border-radius: 999px; background: rgba(76,194,255,0.15); color: var(--accent);
  margin-right: 6px; vertical-align: middle; letter-spacing: 0.5px;
}
.chat-form { display: flex; gap: 8px; }
.chat-form input {
  flex: 1; padding: 9px 12px; border-radius: 10px;
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text); font-size: 13.5px; outline: none;
}
.chat-form input:focus { border-color: var(--accent); }
.chat-chart-wrap {
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px; position: relative;
}
.chat-chart-wrap canvas { width: 100% !important; height: 240px !important; }
.chat-chart-wrap.hidden { display: none; }
.chat-body.hidden { display: none; }

/* Custom map markers */
.marker-pin {
  width: 22px; height: 22px;
  border-radius: 50% 50% 50% 0;
  background: var(--ok);
  transform: rotate(-45deg);
  border: 3px solid #fff;
  box-shadow: 0 4px 10px rgba(0,0,0,0.4);
}
.marker-pin.warn { background: var(--warn); }
.marker-pin.alert { background: var(--alert); }
/* Marcador resaltado: el sitio seleccionado en el sidebar pulsa, escala y se
   trae al frente (z-index vía setZIndexOffset en JS). El halo usa el color de
   acento; el pin conserva su rotación -45° (teardrop). */
.marker-pin.selected {
  border-color: #fff;
  animation: markerSelPulse 1.5s ease-in-out infinite;
}
@keyframes markerSelPulse {
  0%, 100% {
    transform: rotate(-45deg) scale(1.15);
    box-shadow: 0 4px 10px rgba(0,0,0,0.45), 0 0 0 0 rgba(99,102,241,0.65);
  }
  50% {
    transform: rotate(-45deg) scale(1.3);
    box-shadow: 0 4px 12px rgba(0,0,0,0.45), 0 0 0 9px rgba(99,102,241,0);
  }
}

/* Marcador SUTIL: ubica un punto del Plan Permanente cuyo grupo (cuenca/programa)
   no está activo en el mapa. Apenas un puntito tenue — sólo marca el lugar. */
.marker-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(150,180,220,0.42);
  border: 1px solid rgba(255,255,255,0.30);
  box-shadow: 0 1px 2px rgba(0,0,0,0.35);
  transition: transform .12s ease, background .12s ease;
}
.marker-dot:hover { transform: scale(1.5); background: rgba(180,205,240,0.75); }
/* Grupo/sub-grupo SELECCIONADO en el sidebar → puntito resaltado (cyan acento,
   sutil pero claramente distinto al gris "apagado"; no es un pin de estado). */
.marker-dot.hl {
  width: 13px; height: 13px;
  background: rgba(56,189,248,0.60);
  border: 1.5px solid rgba(56,189,248,0.95);
  box-shadow: 0 0 6px rgba(56,189,248,0.6);
}
.marker-dot.hl:hover { transform: scale(1.35); background: rgba(56,189,248,0.85); }

/* Mini-leyenda de TIPOS de marcador (control Leaflet abajo-izq, colapsable).
   Distinta de la leyenda de estado del header (colores). Explica los niveles:
   pin activo / puntito sutil (capa apagada) / cluster / seleccionado. */
.map-legend-control {
  background: rgba(16,22,38,0.86); border: 1px solid var(--border);
  border-radius: 8px; padding: 5px 9px 6px; margin: 0 0 6px 6px;
  font-size: 11px; color: var(--text-dim); line-height: 1.2;
  box-shadow: 0 2px 8px rgba(0,0,0,0.45);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
[data-theme="light"] .map-legend-control { background: rgba(255,255,255,0.92); }
.map-legend-control .mlc-head {
  display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .8px;
  color: var(--text);
}
.map-legend-control .mlc-chev {
  display: inline-block; transition: transform .18s ease; font-size: 10px; color: var(--text-dim);
}
.map-legend-control.collapsed .mlc-chev { transform: rotate(-90deg); }
.map-legend-control.collapsed .mlc-body { display: none; }
.map-legend-control .mlc-body { margin-top: 5px; display: flex; flex-direction: column; gap: 4px; }
.map-legend-control .mlc-row { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.map-legend-control .lg-swatch {
  width: 16px; height: 16px; flex: 0 0 16px;
  display: inline-flex; align-items: center; justify-content: center;
}
.map-legend-control .lg-pin, .map-legend-control .lg-sel {
  width: 11px; height: 11px; border-radius: 50% 50% 50% 0;
  background: var(--ok); border: 2px solid #fff; transform: rotate(-45deg);
}
.map-legend-control .lg-sel { box-shadow: 0 0 0 2px rgba(99,102,241,0.7); }
.map-legend-control .lg-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(150,180,220,0.6); border: 1px solid rgba(255,255,255,0.45);
}
.map-legend-control .lg-cluster {
  width: 16px; height: 16px; border-radius: 50%;
  background: rgba(110,204,57,0.78); color: #14361a; font-size: 8px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid rgba(255,255,255,0.6);
}

/* Banner NO-BLOQUEANTE de sesión expirada (reemplaza el alert() modal). */
.session-notice {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 4000; display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-radius: 10px;
  background: var(--panel, #1a2336); border: 1px solid var(--border, #2c4070);
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  color: var(--text, #e8eefc); font-size: 13px;
  animation: sessionNoticeIn .2s ease;
}
@keyframes sessionNoticeIn { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }
.session-notice-msg { color: var(--warn, #f59e0b); font-weight: 600; }
.session-notice-login {
  border: 1px solid var(--accent, #6366f1); background: transparent;
  color: var(--accent, #8aa0ff); border-radius: 7px; padding: 3px 10px;
  font-size: 12px; cursor: pointer; transition: background .15s, color .15s;
}
.session-notice-login:hover { background: var(--accent, #6366f1); color: #fff; }
.session-notice-close {
  border: 0; background: transparent; color: var(--text-dim, #8aa0c3);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.session-notice-close:hover { color: var(--text, #fff); }

/* Botón del mapa "Ver todos los sitios visibles" (control Leaflet custom). */
.leaflet-fit-all-btn {
  width: 30px; height: 30px; line-height: 30px; text-align: center;
  font-size: 16px; cursor: pointer; display: block;
  background: var(--panel, #fff); color: var(--text, #222);
  border-radius: 6px; box-shadow: 0 1px 5px rgba(0,0,0,0.4);
  border: 1px solid var(--border, rgba(0,0,0,0.2)); text-decoration: none;
}
.leaflet-fit-all-btn:hover { background: var(--panel-2, #eee); color: var(--accent, #6366f1); }

/* Responsive: collapse to single column on narrow viewports */
@media (max-width: 1000px) {
  .layout { grid-template-columns: 1fr; padding: 12px; gap: 12px; }
  .sidebar { position: static; max-height: none; top: auto; overflow: visible; }
  .map { height: 320px; }
  .topbar { padding: 12px 14px; }
  .logo-text small { display: none; }
  .chart-wrap canvas { height: 260px !important; }
  .detail-body { max-height: none; }
}

/* =============================================================
   Auth UI — login button, user badge in topbar, modal overlay.
   The modal handles two modes via a single form:
   - "setup" (first-run): username + password + confirm password
   - "login":           username + password
   Mode is toggled by JS adding/removing classes.
   ============================================================= */

.auth-btn { font-size: 12.5px; }
.portal-link { font-size: 12.5px; text-decoration: none; }
.portal-link:hover { text-decoration: none; }
.auth-btn.logged-in {
  background: var(--accent-soft, rgba(99,179,237,0.12));
  border-color: var(--accent);
  color: var(--text);
}
.auth-btn.logged-in .role-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  background: var(--accent);
  color: var(--bg);
  letter-spacing: 0.4px;
}

.auth-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(8, 11, 18, 0.72);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  animation: authFadeIn .15s ease-out;
}
.auth-modal-overlay.hidden { display: none; }

.auth-modal {
  width: min(440px, calc(100vw - 32px));
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 26px 28px 22px;
  box-shadow: 0 14px 56px rgba(0,0,0,0.4);
  animation: authSlideIn .2s ease-out;
}
.auth-modal h3 { margin: 0 0 6px; font-size: 17px; }
.auth-modal-subtitle {
  margin: 0 0 18px;
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.45;
}
.auth-field {
  display: flex; flex-direction: column;
  gap: 5px;
  margin-bottom: 14px;
}
.auth-field span {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
}
.auth-field input {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 11px;
  font-size: 13.5px;
  font-family: inherit;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.auth-field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(99,179,237,0.18);
}
/* Textarea del formulario de feedback — mismo look que los inputs. */
.auth-field textarea {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 11px;
  font-size: 13.5px;
  font-family: inherit;
  resize: vertical;
  min-height: 92px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.auth-field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(99,179,237,0.18);
}
/* Honeypot anti-spam: fuera de pantalla — invisible para humanos, presente
   para bots que llenan todos los campos. Si llega con algo, el server descarta. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  top: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Wrap around password fields so an "eye" toggle can sit inside the input
   without breaking layout. Padding-right on the input reserves space for
   the button. */
.password-wrap { position: relative; display: flex; flex-direction: column; }
.password-wrap input { padding-right: 38px !important; }
.password-toggle {
  position: absolute;
  right: 4px;
  bottom: 0;
  height: 38px;
  width: 32px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text-dim);
  padding: 0;
  border-radius: 6px;
  transition: color .12s ease, background .12s ease;
}
.password-toggle:hover { color: var(--text); background: rgba(255,255,255,0.05); }
.password-toggle:focus { outline: none; color: var(--accent); }
.password-toggle svg { display: block; width: 18px; height: 18px; }
.auth-hint { margin: -4px 0 12px; font-size: 11.5px; color: var(--text-dim); }
.auth-error {
  background: rgba(239,68,68,0.12);
  border: 1px solid rgba(239,68,68,0.4);
  color: var(--alert);
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 12.5px;
  margin-bottom: 12px;
}
.auth-success {
  background: rgba(34,197,94,0.12);
  border: 1px solid rgba(34,197,94,0.4);
  color: var(--ok);
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 12.5px;
  margin-bottom: 12px;
}
.auth-links {
  margin-top: 14px;
  text-align: center;
  font-size: 12px;
}
.auth-links a { color: var(--accent); text-decoration: none; }
.auth-links a:hover { text-decoration: underline; }
.auth-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 6px;
}
.auth-actions .btn { font-size: 13px; padding: 9px 14px; }
.auth-actions .btn.primary {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
  font-weight: 600;
}
.auth-actions .btn.primary:hover { filter: brightness(1.1); }
.auth-actions .btn.primary:disabled { opacity: .55; cursor: not-allowed; }

/* In "setup" mode we hide the cancel button — first-run is blocking. */
.auth-modal.setup-mode .auth-actions #authCancelBtn { display: none; }

@keyframes authFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes authSlideIn {
  from { opacity: 0; transform: translateY(-8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

/* =============================================================
   Administration tab (admin role only).
   ============================================================= */

.admin-card .admin-body { padding: 4px 4px 8px; }
.admin-body h5 { margin: 0 0 6px; font-size: 14px; }
.admin-body h6 { margin: 16px 0 8px; font-size: 12.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; }
.admin-help { margin: 0 0 14px; font-size: 12.5px; color: var(--text-dim); line-height: 1.45; }

/* Mis apuntes (scratchpad editable del admin) */
.notes-area {
  width: 100%; box-sizing: border-box; min-height: 260px; resize: vertical;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; font-size: 13px; line-height: 1.5;
  font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
}
.notes-area:focus { outline: none; border-color: var(--accent, #38bdf8); }
#notesStatus.notes-ok  { color: #22c55e; }
#notesStatus.notes-err { color: #ef4444; }

.admin-section { margin-bottom: 18px; }

.admin-checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
}
.admin-checkbox {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.admin-checkbox:hover { border-color: var(--accent); }
.admin-checkbox input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}
.admin-checkbox.dirty {
  border-color: var(--warn);
  background: rgba(245,158,11,0.06);
}

.admin-stations-list { display: flex; flex-direction: column; gap: 12px; }
.admin-station-block {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
}
/* --- Grupos de estaciones en el panel admin (misma clasificación que el
   sidebar). Cada grupo es colapsable como un todo; su checkbox prende/apaga la
   visibilidad de todas sus estaciones. --- */
.admin-group {
  border: 1px solid var(--border); border-radius: 10px;
  margin-bottom: 10px; background: rgba(255, 255, 255, 0.015);
}
.admin-group-head {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; cursor: pointer; user-select: none;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.1px;
  color: var(--accent);
}
.admin-group-head:hover { filter: brightness(1.12); }
.admin-group-chev {
  display: inline-block; width: 12px; text-align: center; font-size: 11px;
  color: var(--text-dim); transition: transform 0.18s ease;
}
.admin-group[data-collapsed="true"] .admin-group-chev { transform: rotate(-90deg); }
.admin-group-check { cursor: pointer; flex-shrink: 0; }
.admin-group-label { flex: 1; }
.admin-group-count { font-weight: 500; font-size: 10.5px; color: var(--text-dim); letter-spacing: 0.5px; }
.admin-group-body { display: flex; flex-direction: column; gap: 8px; padding: 0 10px 10px; }
.admin-group[data-collapsed="true"] .admin-group-body { display: none; }

/* Colapsado: el header (chevron + checkbox + nombre) sigue visible. La grilla
   de sensores se oculta. Eso permite scrollear más rápido por las N estaciones. */
.admin-station-block[data-collapsed="true"] .admin-station-sensors { display: none; }
.admin-station-block[data-collapsed="true"] { padding-bottom: 6px; }
.admin-station-block[data-collapsed="true"] .admin-station-head { margin-bottom: 0; }
.admin-station-head {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 10px;
  margin-bottom: 8px;
  cursor: default;
}
/* Chevron de toggle: ▾ apunta abajo cuando expandido. Rotamos -90° para
   colapsado para que apunte a la derecha (afordance "click para expandir"). */
.admin-station-chev {
  display: inline-block;
  width: 16px;
  text-align: center;
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12px;
  user-select: none;
  transition: transform 0.15s ease, color 0.15s ease;
  flex-shrink: 0;
}
.admin-station-chev:hover { color: var(--text); }
.admin-station-block[data-collapsed="true"] .admin-station-chev {
  transform: rotate(-90deg);
}
.admin-station-name { font-weight: 600; font-size: 13.5px; }
.admin-station-meta { font-size: 11px; color: var(--text-dim); margin-left: 6px; }
.admin-station-sensors {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 6px;
  padding-left: 22px;
  border-left: 2px dashed var(--border);
}
/* Barra de acciones bulk arriba del listado de estaciones */
.admin-stations-bulk {
  display: flex; gap: 8px; margin-bottom: 8px;
  font-size: 12px;
}
.admin-stations-bulk-link {
  background: none; border: none;
  color: var(--accent);
  cursor: pointer;
  padding: 2px 6px;
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.admin-stations-bulk-link:hover { color: var(--text); }
.admin-sensor-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 6px;
  cursor: pointer;
}
.admin-sensor-row:hover { background: var(--panel); }
.admin-sensor-row input[type="checkbox"] {
  width: 14px; height: 14px;
  accent-color: var(--accent);
  cursor: pointer;
}
.admin-sensor-row.dirty { color: var(--warn); }
.admin-sensor-row.dirty span { font-weight: 600; }

.admin-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 16px; padding-top: 12px;
  border-top: 1px solid var(--border);
}

.admin-save-result {
  margin-top: 12px;
  padding: 9px 11px;
  border-radius: 8px;
  font-size: 12.5px;
}
.admin-save-result.ok {
  background: rgba(34,197,94,0.12);
  border: 1px solid rgba(34,197,94,0.4);
  color: var(--ok);
}
.admin-save-result.err {
  background: rgba(239,68,68,0.12);
  border: 1px solid rgba(239,68,68,0.4);
  color: var(--alert);
}

/* Admin-only elements default to hidden; JS reveals when role === 'admin' */
.admin-only.hidden { display: none !important; }

/* Tabs the admin hid from the public — only applies to anon viewers */
.tab.hidden-by-visibility { display: none !important; }

/* Optional widgets shown inside the Resumen tab when admin enables them. */

.widget-card { border-left: 3px solid var(--accent); }
.widget-card .card-head h4 { font-size: 14px; }
.widget-subtitle {
  font-size: 11.5px;
  color: var(--text-dim);
  margin-left: 8px;
}

/* Widget 1: Santa Lucía river level */
.widget-river-body {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 16px;
  align-items: stretch;
}
@media (max-width: 900px) {
  .widget-river-body { grid-template-columns: 1fr; }
}
/* Controls bar in the widget card-head: trend label + range selector + reset zoom */
.widget-river-controls {
  display: inline-flex; align-items: center; gap: 12px;
  font-size: 12px;
}
.widget-river-controls label {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--text-dim);
}
.widget-river-controls select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
}
.widget-river-controls .btn.small { font-size: 11.5px; padding: 4px 8px; }
.widget-zoom-hint {
  margin: -6px 0 8px;
  font-size: 10.5px;
  color: var(--text-dim);
  font-style: italic;
  line-height: 1.4;
  text-align: center;
}

/* Container for one-or-more KPI cards (when Santa Lucía has multiple level
   sensors). Stacks vertically — compact enough for typical 2-3 sensors. */
.widget-river-kpis {
  display: flex; flex-direction: column;
  gap: 8px;
  align-items: stretch;
}
.widget-river-kpis .widget-river-meta { margin-top: 6px; text-align: center; }
.widget-river-kpi {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  text-align: center;
}
.widget-river-value {
  font-size: 36px;
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.widget-river-value.warn { color: var(--warn); }
.widget-river-value.alert { color: #f97316; }
.widget-river-value.critical { color: var(--alert); }
.widget-river-kpi .widget-river-value {
  font-size: 28px; /* compact when multiple KPIs stack */
}
.widget-river-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 600;
  margin-bottom: 4px;
  display: inline-flex; align-items: center; gap: 5px;
}
.widget-river-ts {
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
/* Note for derived/estimated sensors. Same color as the timestamp above
   (var(--text-dim)) but in bold so it's noticeable without being loud. */
.widget-river-derived-note {
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 700;
  font-style: italic;
  line-height: 1.3;
}
.river-series-swatch {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
}
.widget-river-meta {
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--text-dim);
  line-height: 1.4;
}
.widget-river-chart {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px;
  min-height: 220px;
  position: relative;
}
.widget-river-chart canvas { width: 100% !important; height: 220px !important; }

/* Widget 2: Station health monitor */
.widget-health-legend {
  display: flex; flex-wrap: wrap;
  gap: 16px;
  margin: 4px 0 14px;
  font-size: 11.5px;
  color: var(--text-dim);
}
.widget-health-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.health-dot {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.health-dot.health-ok       { background: var(--ok); }
.health-dot.health-warn     { background: var(--warn); }
.health-dot.health-alert    { background: #f97316; }
.health-dot.health-critical { background: var(--alert); }
.widget-health-grid {
  display: flex; flex-direction: column;
  gap: 14px;
}
.widget-health-station {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
}
.widget-health-station-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
  transition: background .12s ease;
  padding: 4px 6px;
  margin: -4px -6px 4px;
  border-radius: 6px;
}
.widget-health-station-head:hover { background: rgba(255,255,255,0.04); }
.widget-health-station-head .station-meta-small {
  font-size: 11px; color: var(--text-dim); font-weight: normal;
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 8px;
}
/* Per-station status pill (dot + count) — colored to match the legend.
   Uses the same .health-dot helper plus a count number next to it. */
.station-status-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 6px; border-radius: 999px;
  background: rgba(255,255,255,0.04);
  font-size: 11.5px; font-weight: 600;
  color: var(--text);
  line-height: 1;
}
.station-status-pill .health-dot {
  width: 8px; height: 8px; border-radius: 50%;
  display: inline-block;
}
.station-status-pill .health-count { font-variant-numeric: tabular-nums; }
.widget-health-station-head .station-chevron {
  display: inline-flex; align-items: center;
  color: var(--text-dim);
  transition: transform .15s ease;
}
.widget-health-station.collapsed .station-chevron { transform: rotate(-90deg); }
.widget-health-station.collapsed .widget-health-sensors { display: none; }
.widget-health-station.collapsed .widget-health-station-head { margin-bottom: -4px; }
.widget-health-sensors {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 12px;
}
.widget-health-sensor {
  display: flex; align-items: center;
  gap: 8px;
  font-size: 11.5px;
  padding: 4px 0;
}
.widget-health-sensor .sensor-name {
  flex: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.widget-health-sensor .sensor-age {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  flex-shrink: 0;
}
.widget-health-sensor.warn .sensor-age { color: var(--warn); }
.widget-health-sensor.alert .sensor-age { color: #f97316; }
.widget-health-sensor.critical .sensor-age { color: var(--alert); }

/* "Caído" — más severo que crítico (telemetría sin datos por días = sensor
   probablemente fuera de servicio). Magenta para diferenciarlo del rojo crítico. */
.health-dot.health-down { background: #c026d3; box-shadow: 0 0 0 3px rgba(192,38,211,0.25); }
.widget-health-sensor.down .sensor-age { color: #e879f9; font-weight: 600; }
.down-badge {
  display: inline-block; margin-left: 6px; padding: 0 5px;
  font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  border-radius: 4px; background: #c026d3; color: #fff; vertical-align: middle;
}
.station-status-pill.down { background: rgba(192,38,211,0.16); }

/* Alerta PROMINENTE de sensores caídos (banner arriba del grid del widget). */
.widget-health-alert {
  margin: 0 0 14px; padding: 10px 12px;
  border: 1px solid #c026d3; border-left-width: 4px;
  border-radius: 8px; background: rgba(192,38,211,0.10);
}
.widget-health-alert.hidden { display: none; }
.widget-health-alert .wha-head {
  font-weight: 700; font-size: 12.5px; color: #e879f9; margin-bottom: 6px;
}
.widget-health-alert .wha-list {
  margin: 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 2px 14px;
}
.widget-health-alert .wha-list li {
  font-size: 11.5px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.widget-health-alert .wha-age {
  color: #e879f9; font-variant-numeric: tabular-nums; font-size: 10.5px;
}
.widget-health-alert .wha-more { margin-top: 5px; font-size: 11px; color: var(--text-dim); }

/* Admin widget config sub-blocks (thresholds) */
.admin-widgets-title { margin-top: 22px; padding-top: 14px; border-top: 1px dashed var(--border); }
.admin-widget-block {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.admin-widget-config {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin-top: 10px;
  padding-left: 22px;
  border-left: 2px dashed var(--border);
}
.admin-widget-config label {
  display: flex; flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--text-dim);
}
.admin-widget-config input[type="number"] {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 12.5px;
  font-family: inherit;
  width: 100%;
  box-sizing: border-box;
}
.admin-widget-config input[type="number"]:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(99,179,237,0.18);
}

/* Drag handle inside admin reorderable items.
   Native HTML5 drag and drop (no libs). Item with class .draggable carries
   draggable=true; the dragging item gets .dragging; the row currently being
   hovered over gets .drag-over. */
.drag-handle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  cursor: grab;
  color: var(--text-dim);
  opacity: 0.5;
  user-select: none;
  flex-shrink: 0;
  transition: opacity .12s ease, color .12s ease;
}
.admin-checkbox:hover .drag-handle,
.admin-sensor-row:hover .drag-handle { opacity: 1; color: var(--accent); }
.drag-handle:active { cursor: grabbing; }
.drag-handle svg { width: 14px; height: 14px; display: block; }

.draggable.dragging { opacity: 0.45; }
.draggable.drag-over {
  outline: 2px dashed var(--accent);
  outline-offset: -2px;
}

/* Scope selector on top of the admin panel */
.admin-scope-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px; padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12.5px;
}
.admin-scope-row strong { color: var(--text); }
.admin-scope-row label {
  display: inline-flex; align-items: center; gap: 5px;
  cursor: pointer;
  margin-left: 4px;
}
.admin-scope-row input[type="radio"] {
  width: 14px; height: 14px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Admin · Grafana INUMET (Fase 2 discover) */
.admin-grafana-status {
  font-size: 12px;
  color: var(--text-dim);
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin: 10px 0;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}
/* Backfill exhaustivo histórico — controles */
.admin-grafana-exhaustive-row {
  align-items: center;
}
.admin-grafana-exhaustive-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-dim);
}
.admin-grafana-exhaustive-input {
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  color-scheme: dark light;
}
.admin-grafana-exhaustive-status {
  font-size: 12.5px;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-top: 10px;
}
.admin-grafana-exhaustive-summary > div {
  margin: 4px 0;
}
.admin-grafana-exhaustive-summary .small {
  font-size: 11px;
  color: var(--text-dim);
}
.admin-grafana-exhaustive-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  margin: 6px 0;
}
.admin-grafana-exhaustive-bar .label {
  display: inline-block;
  min-width: 70px;
  font-weight: 600;
}
.admin-grafana-exhaustive-bar .bar-wrap {
  flex: 1;
  display: inline-block;
  height: 10px;
  background: var(--panel-2);
  border-radius: 5px;
  overflow: hidden;
  border: 1px solid var(--border);
  min-width: 120px;
}
.admin-grafana-exhaustive-bar .bar-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #6366f1);
  transition: width 0.5s ease;
}
.admin-grafana-exhaustive-bar .pct {
  font-variant-numeric: tabular-nums;
  min-width: 38px;
  text-align: right;
  font-weight: 600;
}
.admin-grafana-result {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  margin-top: 12px;
}
.admin-grafana-meta { margin-bottom: 12px; }
.admin-grafana-meta .small { font-size: 11px; color: var(--text-dim); }
.admin-grafana-result h6 {
  margin: 12px 0 6px;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--accent);
}
.admin-grafana-list {
  margin: 0 0 6px;
  padding-left: 18px;
  font-size: 12.5px;
  line-height: 1.6;
}
.admin-grafana-list li { padding: 1px 0; }
.admin-grafana-list code {
  font-size: 11px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--panel-2);
  color: var(--accent);
}
.admin-grafana-empty { color: var(--text-dim); font-style: italic; }
.admin-grafana-error {
  color: var(--alert);
  font-weight: 600;
  padding: 8px;
  background: rgba(239,68,68,0.08);
  border-radius: 6px;
}
.muted { color: var(--text-dim); font-weight: normal; }

/* Admin Grafana inspect — botón inline en cada dashboard de la lista */
.admin-grafana-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.admin-grafana-inspect-btn {
  flex-shrink: 0;
  font-size: 11px;
  padding: 3px 9px;
}
.admin-grafana-inspect-result {
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: 8px;
  max-height: 420px;
  overflow-y: auto;
}
.admin-grafana-inspect-header h6 {
  margin: 0 0 4px;
  color: var(--accent);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.admin-grafana-panel {
  margin: 10px 0;
  padding: 8px 10px;
  background: var(--panel);
  border-radius: 6px;
  border-left: 3px solid var(--accent);
}
.admin-grafana-panel-head {
  font-size: 12px;
  margin-bottom: 4px;
}
.admin-grafana-panel-head code {
  font-size: 10.5px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--panel-2);
}
.admin-grafana-targets {
  font-size: 10.5px;
  line-height: 1.35;
  background: var(--bg);
  color: var(--text-dim);
  padding: 6px 8px;
  margin: 4px 0 0;
  border-radius: 4px;
  max-height: 220px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  border: 1px solid var(--border);
}

/* =============================================================
   Pestaña "Cuenca Santa Lucía" — mapa de seguimiento del nivel.
   Tarjetitas de NIVEL (valor + desvío vs promedio + sparkline 7d)
   ancladas a su coordenada, y badges de LLUVIA (24 h / 7 d).
   ============================================================= */
.cuenca-map { width: 100%; height: 62vh; min-height: 380px; }
.cuenca-selector {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-dim);
}
.cuenca-selector select {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 4px 8px; font-size: 12px; font-family: inherit; cursor: pointer;
  max-width: 280px;
}
.cuenca-basin-note { display: block; margin-top: 6px; font-style: italic; }
.cuenca-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  padding: 8px 16px; border-bottom: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-dim);
}
.cuenca-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.cuenca-leg-title { font-weight: 700; }
.cuenca-leg-sep { opacity: 0.5; }
.cl-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
.cl-dot.cl-below { background: #38bdf8; }
.cl-dot.cl-above { background: #facc15; }
.cl-dot.cl-high  { background: #fb923c; }
.cl-dot.cl-vhigh { background: #ef4444; }
.cl-rain {
  display: inline-block; width: 12px; height: 12px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #c4b5fd, #7c3aed);
}
.cuenca-status { padding: 12px 16px; color: var(--text-dim); font-size: 12.5px; }
.cuenca-note {
  margin: 0; padding: 10px 16px 14px;
  font-size: 11.5px; line-height: 1.5; color: var(--text-dim);
  border-top: 1px solid var(--border);
}

/* divIcon contenedor: sin caja blanca default de Leaflet */
.cuenca-div { background: none; border: none; }

/* Tarjetita de NIVEL */
.cuenca-niv {
  --cn-accent: #38bdf8;
  width: 104px;
  background: rgba(13, 22, 40, 0.92);
  border: 1.5px solid var(--cn-accent);
  border-radius: 9px;
  padding: 5px 6px 4px;
  box-shadow: 0 3px 10px rgba(0,0,0,0.45);
  color: #eef4fc;
  line-height: 1.25;
}
[data-theme="light"] .cuenca-niv { background: rgba(255,255,255,0.95); color: #0a1628; }
.cuenca-niv.cl-below { --cn-accent: #38bdf8; }
.cuenca-niv.cl-above { --cn-accent: #eab308; }
.cuenca-niv.cl-high  { --cn-accent: #fb923c; }
.cuenca-niv.cl-vhigh { --cn-accent: #ef4444; }
.cuenca-niv.cl-na    { --cn-accent: #64748b; }
.cuenca-niv.cl-stale { opacity: 0.75; border-style: dashed; }
.cn-head { display: flex; justify-content: space-between; align-items: baseline; gap: 4px; }
.cn-name {
  font-size: 9px; font-weight: 600; letter-spacing: 0.2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 60px; opacity: 0.85;
}
.cn-val { font-size: 11.5px; font-weight: 800; color: var(--cn-accent); white-space: nowrap; }
.cn-anom { font-size: 8.5px; opacity: 0.8; margin: 1px 0 2px; white-space: nowrap; }
.cn-spark { display: block; }
.cn-sparkline { fill: none; stroke: var(--cn-accent); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.cn-meanline { stroke: currentColor; stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.45; }

/* Tarjetita de LLUVIA (acumulado del período + barras de mm/día) */
.cuenca-rain {
  --cr-accent: #38bdf8;
  width: 96px;
  background: rgba(13, 22, 40, 0.92);
  border: 1.5px solid var(--cr-accent);
  border-radius: 9px;
  padding: 5px 6px 4px;
  box-shadow: 0 3px 10px rgba(0,0,0,0.45);
  color: #eef4fc;
  line-height: 1.25;
}
[data-theme="light"] .cuenca-rain { background: rgba(255,255,255,0.95); color: #0a1628; }
/* Lluvia en familia VIOLETA — máximo contraste con el azul→rojo del nivel
   (pedido: más contraste entre los datos de lluvia y los de nivel). */
.cuenca-rain.cr0 { --cr-accent: #8b85a8; }   /* seco — violeta apagado */
.cuenca-rain.cr1 { --cr-accent: #a78bfa; }
.cuenca-rain.cr2 { --cr-accent: #8b5cf6; }
.cuenca-rain.cr3 { --cr-accent: #7c3aed; }
.cuenca-rain.cr4 { --cr-accent: #6d28d9; }
.cr-head { display: flex; justify-content: space-between; align-items: baseline; gap: 4px; }
.cr-name {
  font-size: 9px; font-weight: 600; letter-spacing: 0.2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 52px; opacity: 0.85;
}
.cr-val { font-size: 11.5px; font-weight: 800; color: var(--cr-accent); white-space: nowrap; }
.cr-sub { font-size: 8.5px; opacity: 0.8; margin: 1px 0 2px; white-space: nowrap; }
.cr-spark { display: block; }
.cr-bar { fill: var(--cr-accent); opacity: 0.92; }
/* Fecha del último dato (nivel + lluvia) */
.cn-date, .cr-date { font-size: 7.5px; opacity: 0.7; margin-top: 1px; white-space: nowrap; }

/* Estación SIN datos en el rango: marcador apagado (no etiquetado); su estado
   aparece al pasar el mouse por encima (tooltip). */
.cuenca-off {
  width: 11px; height: 11px; border-radius: 50%;
  background: rgba(148, 163, 184, 0.4);
  border: 1px solid rgba(148, 163, 184, 0.7);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.cuenca-off-tip { font-size: 11px; line-height: 1.3; }

/* Dot del SITIO real (cuando la tarjeta se desplaza para no solaparse y se une
   con una línea guía). Coloreado con el acento de su tarjeta (--ca). */
.cuenca-anchor {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--ca, #38bdf8);
  border: 1.5px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}
[data-theme="light"] .cuenca-anchor { border-color: #0a1628; }

/* =============================================================
   MP2 / PROVI — ficha de evaluación visual de ribera (detalle)
   ============================================================= */
.provi-banner {
  background: linear-gradient(180deg, rgba(34,197,94,0.13), rgba(34,197,94,0.04));
  border: 1px solid rgba(34,197,94,0.35);
  border-radius: 8px; padding: 8px 11px; margin-bottom: 10px;
  font-size: 12px; line-height: 1.45;
}
.provi-banner strong { color: var(--text, #e5e7eb); }
.provi-banner span { color: var(--text-dim, #9ca3af); }
.provi-meta {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  margin-bottom: 10px; font-size: 12px;
}
.provi-metarow .provi-k { color: var(--text-dim, #9ca3af); }
.provi-metarow .provi-v { color: var(--text, #e5e7eb); font-weight: 600; }
.provi-sheet { display: flex; flex-direction: column; gap: 7px; }
.provi-row {
  border: 1px solid var(--border, rgba(255,255,255,0.12)); border-radius: 8px;
  padding: 7px 10px; background: rgba(255,255,255,0.02);
}
.provi-row .provi-q {
  font-size: 11px; color: var(--text-dim, #9ca3af); line-height: 1.35; margin-bottom: 3px;
}
.provi-row .provi-a {
  font-size: 12.5px; color: var(--text, #e5e7eb); font-weight: 600; line-height: 1.4;
}
.provi-row.provi-num { border-left: 3px solid var(--accent, #38bdf8); }
.provi-row.provi-num .provi-a { font-variant-numeric: tabular-nums; }

/* Valor integrado del PROVI (índice visual de ribera) — tarjeta destacada al
   comienzo de la ficha. El color de la banda llega por --prov-band (inline). */
.provi-index {
  border: 1px solid var(--prov-band, #38bdf8);
  border-left: 5px solid var(--prov-band, #38bdf8);
  border-radius: 10px; padding: 12px 14px; margin-bottom: 12px;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
}
[data-theme="light"] .provi-index { background: linear-gradient(180deg, rgba(0,0,0,0.04), rgba(0,0,0,0.01)); }
.provi-index-head { display: flex; align-items: center; gap: 13px; }
.provi-index-badge {
  display: flex; align-items: baseline; gap: 1px; flex: 0 0 auto;
  background: var(--prov-band, #38bdf8); color: #fff;
  border-radius: 9px; padding: 7px 13px; min-width: 50px; justify-content: center;
  box-shadow: 0 1px 5px rgba(0,0,0,0.35);
}
.provi-index-val { font-size: 27px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.provi-index-max { font-size: 12px; font-weight: 600; opacity: 0.85; }
.provi-index-band { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.provi-index-label { font-size: 16px; font-weight: 800; color: var(--prov-band, #38bdf8); line-height: 1.15; }
.provi-index-name { font-size: 11px; color: var(--text-dim, #9ca3af); }
.provi-index-desc { margin-top: 9px; font-size: 12px; line-height: 1.5; color: var(--text, #e5e7eb); }
.provi-index-method { margin-top: 7px; font-size: 10.5px; font-style: italic; color: var(--text-dim, #9ca3af); line-height: 1.4; }

/* Botón "Actualizar ahora" (#refreshBtn): gira el ícono ↻ mientras refresca, así
   el clic da feedback EN el botón (antes el único aviso era el pill del footer
   del sidebar, lejos del botón, y un refresh rápido parecía no hacer nada). */
@keyframes simasSpin { to { transform: rotate(360deg); } }
#refreshBtn.refreshing svg { animation: simasSpin 0.7s linear infinite; transform-origin: 50% 50%; }
#refreshBtn.refreshing { color: var(--accent, #38bdf8); border-color: var(--accent, #38bdf8); }
#refreshBtn:disabled { cursor: default; }

/* Botón "Actualizar datos ahora" reubicado al footer del sidebar, junto al
   contador "Próxima actualización" (su par lógico) y achicado — antes estaba en
   la topbar y se confundía con "recargar la página". */
.next-refresh-row { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.refresh-mini {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border-radius: 5px;
  background: transparent; border: 1px solid var(--border, rgba(255,255,255,0.15));
  color: var(--text-dim, #9ca3af); cursor: pointer;
  transition: color .15s, border-color .15s;
}
.refresh-mini svg { display: block; }
.refresh-mini:hover { color: var(--accent, #38bdf8); border-color: var(--accent, #38bdf8); }
.next-refresh-row #nextRefreshLabel { margin: 0; }

/* =============================================================
   RESPONSIVE MÓVIL — capa para celular (Opción A: misma página, el
   layout se reacomoda solo). Dos cortes:
     ≤768px  teléfono → el panel "Estaciones" pasa a ser un CAJÓN
             deslizable (botón ☰); mapa y detalle apilados a alto
             de viewport; tabs con scroll horizontal.
     ≤480px  teléfono chico → aún más compacto (botón de sesión
             sólo ícono, modales casi a todo el ancho).
   El bloque @media (max-width:1000px) de más arriba cubre el tramo
   TABLET (sidebar estático apilado). Estos bloques van AL FINAL del
   archivo para ganar en el cascade sobre aquél a anchos de teléfono.
   ============================================================= */

/* Hamburguesa + backdrop: ocultos en escritorio; se activan sólo en
   el corte de teléfono. */
.sidebar-toggle { display: none; }
.sidebar-backdrop { display: none; }

@media (max-width: 768px) {
  /* ---- Topbar compacto ---- */
  .topbar { padding: 10px 12px; gap: 10px; }
  .topbar-left { gap: 10px; }
  .logo-text strong { font-size: 16px; }
  .topbar-right { gap: 6px; }

  /* Mostrar la hamburguesa (cuadrada, buen tap target ≥42px). */
  .sidebar-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 8px; min-width: 42px; min-height: 42px;
  }

  /* ---- Layout: una sola columna; el cajón sale del flujo ---- */
  .layout { display: block; padding: 10px; }

  /* ---- Sidebar = cajón deslizable (drawer) ---- */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(86vw, 340px);
    height: 100%; max-height: 100%;
    margin: 0; border-radius: 0; border: none;
    border-right: 1px solid var(--border);
    z-index: 1200;
    overflow: auto;
    transform: translateX(-100%);
    transition: transform .25s ease;
    box-shadow: 6px 0 28px rgba(0,0,0,0.45);
  }
  body.sidebar-open .sidebar { transform: none; }
  /* Bloquear el scroll del fondo mientras el cajón está abierto. */
  body.sidebar-open { overflow: hidden; }

  /* Backdrop oscuro: aparece con el cajón; tap = cerrar. */
  .sidebar-backdrop {
    position: fixed; inset: 0;
    background: rgba(6, 10, 18, 0.55);
    z-index: 1150;
  }
  body.sidebar-open .sidebar-backdrop { display: block; }

  /* ---- Mapa + detalle apilados, a alto de viewport ---- */
  /* Forzar UNA columna: .map-detail-grid trae grid-template-columns:2fr 3fr sin
     media query, que de otro modo gana (mismo specificity, fuente posterior)
     sobre el colapso de .grid-2 y dejaría las dos tarjetas lado a lado en el
     celular. En escritorio/tablet sigue siendo 2fr|3fr. */
  .map-detail-grid { grid-template-columns: 1fr; }
  .map-detail-grid .map-card,
  .map-detail-grid .detail-card { height: auto; }
  .cuenca-map { height: 56vh; min-height: 300px; }
  .map-detail-grid .map-card .map,
  .map { height: 56vh; min-height: 300px; max-height: 66vh; flex: 0 0 auto; }
  .detail-body { max-height: none; }

  /* ---- Tabs: scroll horizontal en vez de apretarse ---- */
  .tabs { gap: 4px; -webkit-overflow-scrolling: touch; }
  .tab { flex: 0 0 auto; padding: 9px 12px; font-size: 12.5px; min-height: 42px; }

  /* ---- Cabeceras de tarjeta y controles: envolver, no desbordar ---- */
  .card-head { flex-wrap: wrap; gap: 8px; }
  .card-actions, .chart-controls { flex-wrap: wrap; row-gap: 8px; }
  .custom-range-row { flex-wrap: wrap; }

  /* ---- Tap targets cómodos para el dedo ---- */
  .btn { min-height: 42px; }
  .btn.small { min-height: 36px; }
  .cuenca-eye, .category-eye { min-width: 32px; min-height: 28px; }

  /* ---- Footer compacto ---- */
  .footer-credits { font-size: 10.5px; line-height: 1.5; }
}

@media (max-width: 480px) {
  /* Teléfono chico: liberar todavía más ancho. */
  .topbar { padding: 8px 10px; }
  .logo-text strong { font-size: 15px; }
  /* El botón de sesión y el link al Portal quedan sólo con su ícono (el texto ocuparía mucho). */
  .auth-btn span, .portal-link span { display: none; }
  .auth-btn { padding: 8px; min-width: 42px; }
  .portal-link { padding: 8px; min-width: 42px; }

  .map-detail-grid .map-card .map,
  .map { height: 52vh; min-height: 260px; }

  .tab { padding: 8px 10px; font-size: 12px; }
  .tab svg { width: 15px; height: 15px; }

  /* Modales casi a todo el ancho, con padding más chico. */
  .auth-modal { padding: 20px 16px 16px; }

  .footer { padding-left: 12px; padding-right: 12px; }
}
