/* Tipografías Fooxy servidas desde el propio servidor: la web tiene que
   mantener su aspecto sin internet. Google Fonts entrega Inter y Montserrat
   como fuentes VARIABLES, así que un solo fichero por familia y subconjunto
   cubre todos los pesos (de ahí el rango en font-weight). Los unicode-range
   son los que declara Google: con `latin` basta para casi todo y `latin-ext`
   entra solo si la página usa algún carácter que lo necesite. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('/static/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('/static/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat'; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url('/static/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat'; font-style: normal; font-weight: 700 800; font-display: swap;
  src: url('/static/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --blue: #2B80FF;
  --blue-dark: #2b6fd6;
  --blue-glow: rgba(43, 128, 255, 0.15);
  --ink: #1E1E24;
  --bg: #F8F9FA;
  --surface: #FFFFFF;
  --line: #E9ECEF;
  --muted: #6C757D;
  --field: #F5F5F7;
  --ok: #1a7a4a;
  --ok-bg: rgba(26, 122, 74, 0.12);
  --danger: #d64545;
  --danger-bg: rgba(214, 69, 69, 0.10);
  --warn: #b8791b;
  --warn-bg: rgba(245, 158, 11, 0.14);
  --radius: 16px;
  --radius-sm: 10px;
  --font-head: 'Montserrat', system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font-body); font-size: 15px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { font-family: var(--font-head); font-weight: 800; letter-spacing: -0.3px; color: var(--ink); }
h1 { font-size: 1.7rem; margin: 0 0 1.2rem; }
h2 { font-size: 1.05rem; font-weight: 700; margin: 0 0 .4rem; }
a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--blue-dark); text-decoration: underline; }
code { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .86em;
  background: var(--field); padding: .1rem .35rem; border-radius: 5px; }
pre { font-family: ui-monospace, Menlo, monospace; background: var(--ink); color: #e8ebf0;
  padding: .7rem .9rem; border-radius: var(--radius-sm); overflow-x: auto; margin: 0; font-size: .82rem; line-height: 1.5; }

/* ---- Top navigation ---- */
.nav {
  display: flex; align-items: center; gap: 2rem;
  padding: .85rem 1.75rem; background: rgba(255,255,255,0.85);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20;
}
.nav .brand { display: flex; align-items: center; }
.nav .brand img { height: 26px; width: auto; display: block; }
.nav nav { display: flex; gap: .35rem; }
.nav nav a {
  color: var(--muted); font-weight: 600; font-size: .9rem;
  padding: .4rem .8rem; border-radius: 999px; transition: all .18s var(--ease);
}
.nav nav a:hover { color: var(--ink); background: var(--field); text-decoration: none; }
.nav nav a.active { color: var(--blue); background: var(--blue-glow); }
.nav .logout { margin-left: auto; display: flex; align-items: center; gap: .8rem; }
.nav .user { color: var(--muted); font-size: .85rem; font-weight: 500; }

/* ---- Layout ---- */
.container { max-width: 1000px; margin: 0 auto; padding: 2rem 1.75rem 4rem; }
.muted { color: var(--muted); }
.error { color: var(--danger); }
.flash {
  margin: 0 0 1.4rem; padding: .7rem 1rem; border-radius: var(--radius-sm);
  font-size: .9rem; font-weight: 600;
}
.flash-error { background: var(--danger-bg); color: var(--danger); }
.flash-success { background: var(--ok-bg); color: var(--ok); }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
section { margin-top: 2.2rem; }
section > p.muted { margin-top: -.2rem; }

/* ---- Stat chips ---- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin: 0 0 .5rem; }
.stat {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.1rem 1.3rem; text-decoration: none; color: var(--ink);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), border-color .2s var(--ease);
}
a.stat:hover { transform: translateY(-3px); box-shadow: 0 16px 32px rgba(43,128,255,0.08);
  border-color: rgba(43,128,255,0.25); text-decoration: none; }
.stat .num { display: block; font-family: var(--font-head); font-weight: 800; font-size: 2rem; color: var(--blue); line-height: 1.1; }
.stat .label { font-size: .82rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }

/* generic card (tag detail) */
.cards { display: flex; flex-wrap: wrap; gap: 1rem; margin: 1rem 0; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.25rem; min-width: 140px; }
.card .num { display: block; font-family: var(--font-head); font-weight: 800; font-size: 1.9rem; color: var(--blue); }
.card.small { font-size: .88rem; color: var(--muted); }
.card.small strong { color: var(--ink); font-size: .95rem; }

/* ---- Panels & tables ---- */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.panel > table { margin: 0; }
table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
th, td { text-align: left; padding: .7rem .9rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
thead th { color: var(--muted); font-weight: 700; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; background: #fbfcfd; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: #fbfcfe; }

/* ---- Forms & buttons ---- */
input, select, button { font: inherit; }
input, select {
  background: var(--field); color: var(--ink); border: 1px solid transparent;
  border-radius: var(--radius-sm); padding: .5rem .65rem; transition: box-shadow .18s ease, background .18s ease;
}
input:focus, select:focus { outline: none; background: var(--surface); box-shadow: 0 0 0 3px rgba(43,128,255,0.22); }
label { display: inline-flex; flex-direction: column; gap: .25rem; font-size: .78rem; font-weight: 600; color: var(--muted); }
button {
  background: var(--blue); color: #fff; border: 0; border-radius: var(--radius-sm);
  padding: .55rem 1.05rem; font-weight: 600; font-size: .9rem; cursor: pointer;
  box-shadow: 0 6px 18px rgba(43,128,255,0.28); transition: transform .15s var(--ease), filter .15s ease, box-shadow .15s ease;
}
button:hover { filter: brightness(1.05); transform: translateY(-1px); }
button:active { transform: translateY(0); }
button.danger { background: var(--danger); box-shadow: 0 6px 18px rgba(214,69,69,0.25); }
button.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
button.ghost:hover { border-color: var(--blue); color: var(--blue); }
button.link { background: none; color: var(--blue); padding: 0; font-weight: 600; box-shadow: none; }
button.link:hover { text-decoration: underline; transform: none; }
button.link.danger { color: var(--danger); box-shadow: none; }

.inline-form { display: inline-flex; gap: .55rem; align-items: flex-end; flex-wrap: wrap; margin: .4rem 0; }
.inline-form input[type=text], .inline-form input[type=email] { min-width: 240px; }
.actions { display: flex; gap: 1rem; align-items: center; }
.actions form { display: inline; margin: 0; }

/* ---- Badges ---- */
.badge { display: inline-block; padding: .12rem .6rem; border-radius: 999px; font-size: .74rem; font-weight: 700; letter-spacing: .02em; }
.badge.ok, .badge.status-done { background: var(--ok-bg); color: var(--ok); }
.badge.blocked, .badge.status-failed { background: var(--danger-bg); color: var(--danger); }
.badge.status-pending, .badge.status-running { background: var(--warn-bg); color: var(--warn); }
.badge.status-cancelled { background: rgba(108, 117, 125, 0.14); color: var(--muted); }

/* ---- Panel "Estado de cola y del servidor" (cancelar-generacion-modelo) ---- */
.queue-panel { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.2rem 1.4rem; }
.queue-panel h2 { margin-bottom: .9rem; }

.queue-server { display: flex; align-items: center; gap: .55rem; margin: 0 0 1.1rem;
  font-size: .88rem; font-weight: 600; color: var(--ink); }
.queue-server.is-down { color: var(--danger); }
.queue-dot { width: .55rem; height: .55rem; border-radius: 50%; flex: none;
  background: var(--ok); }
.queue-server.is-down .queue-dot { background: var(--danger); }

.queue-flow { display: flex; align-items: stretch; gap: 1.2rem; flex-wrap: wrap; }
.queue-group { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.queue-divider { width: 1px; background: var(--line); align-self: stretch;
  min-height: 3.5rem; }

.queue-stage { display: flex; flex-direction: column; align-items: flex-start;
  gap: .15rem; min-width: 84px; }
.queue-stage .num { font-family: var(--font-head); font-weight: 800; font-size: 1.7rem;
  line-height: 1.05; }
.queue-stage .label { font-size: .78rem; color: var(--muted); font-weight: 600; }
.queue-arrow { color: var(--line); font-size: 1.3rem; align-self: center; }

.queue-stage.state-queued .num, .queue-stage.state-running .num { color: var(--warn); }
.queue-stage.state-done .num { color: var(--ok); }
.queue-stage.state-failed .num { color: var(--danger); }
.queue-stage.state-cancelled .num { color: var(--muted); }

@media (max-width: 600px) {
  .queue-flow { flex-direction: column; align-items: stretch; }
  .queue-divider { width: auto; height: 1px; min-height: 0; margin: .2rem 0; }
  .queue-group { justify-content: space-between; }
}
.tag-link { font-weight: 600; }
.tag-none { color: var(--muted); font-size: .85rem; }

/* ---- Alert (new device key) ---- */
.alert { background: #eef5ff; border: 1px solid rgba(43,128,255,0.3); border-radius: var(--radius);
  padding: 1.1rem 1.25rem; margin: 1rem 0; }
.alert strong { color: var(--ink); }
.alert pre { margin-top: .6rem; }

/* ---- Login ---- */
.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 1.5rem;
  background: radial-gradient(1200px 600px at 50% -10%, #eaf2ff 0%, var(--bg) 55%); }
.login-card { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 24px; padding: 2.5rem 2.25rem; box-shadow: 0 30px 60px rgba(0,0,0,0.07); text-align: center; }
.login-card .logo { height: 34px; margin-bottom: 1.1rem; }
.login-card p.muted { margin: 0 0 1.6rem; font-size: .9rem; }
.login-card form { display: flex; flex-direction: column; gap: 1rem; text-align: left; }
.login-card label { color: var(--ink); font-size: .82rem; }
.login-card input { padding: .65rem .7rem; }
.login-card button { margin-top: .3rem; padding: .7rem; box-shadow: 0 8px 22px rgba(43,128,255,0.3); }
.login-card .error { margin: 0 0 1rem; background: var(--danger-bg); padding: .6rem .8rem; border-radius: var(--radius-sm); font-size: .88rem; font-weight: 600; }

@media (max-width: 600px) {
  .nav { gap: 1rem; padding: .7rem 1rem; }
  .nav nav { gap: 0; }
  .container { padding: 1.25rem 1rem 3rem; }
}

/* ==========================================================================
   VISUALIZACIÓN DE DATOS DEL TAG (gráfica spo/hr + mapa GPS)
   ========================================================================== */
.viz-controls { display: flex; flex-direction: column; gap: .8rem; margin: .6rem 0 1.1rem; }
.viz-chips { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.viz-chips .chips-label {
  font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin-right: .3rem;
}
.chip {
  font-family: var(--font-body); font-size: .82rem; font-weight: 600;
  padding: .38rem .7rem; border-radius: 999px; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); transition: all .18s var(--ease);
}
.chip:hover { border-color: var(--blue); color: var(--blue); }
.chip.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.chip .chip-sub { opacity: .7; font-weight: 500; margin-left: .35rem; font-size: .76rem; }
.chip.active .chip-sub { opacity: .85; }

/* Selector multi-día/sesión de "Generar modelo" (models-selection-lifecycle,
   ADR-1): mismo look de `.chip` en forma de checkbox, no de botón de un
   clic — deja claro que se puede marcar varios sin que se desactiven entre
   sí. */
.chip-checkbox { display: inline-flex; align-items: center; gap: .4rem; }
.chip-checkbox input[type="checkbox"] { margin: 0; accent-color: var(--blue); }
.chip-checkbox input[type="checkbox"]:disabled { opacity: .4; }
.model-all-toggle {
  display: inline-flex; align-items: center; gap: .5rem; font-weight: 600;
  margin-bottom: .7rem;
}
.model-days {
  display: flex; flex-direction: column; gap: .15rem; margin-bottom: .8rem;
  max-height: 340px; overflow-y: auto; padding: .2rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.model-day-row {
  display: flex; flex-direction: column; gap: .3rem;
  padding: .35rem .3rem; border-radius: var(--radius-sm);
}
.model-day-row:hover { background: var(--field); }
.model-day-main { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.model-day-main .chip-checkbox { font-weight: 700; }
/* Sesiones del día (models-selection-lifecycle, ajuste UX): ya no viven tras
   un desplegable — se cargan y muestran solas al pintar el día (RF-1 sigue
   usando `/series` como única fuente), en chips más pequeños que los del
   día para que la jerarquía visual quede clara sin más adorno. El checkbox
   del día controla los de sesión (y viceversa via `indeterminate`, patrón
   nativo de HTML, sin JS de terceros). */
.model-day-sessions {
  display: flex; flex-wrap: wrap; gap: .3rem; margin-left: 1.75rem;
}
.model-day-sessions .chip {
  font-size: .74rem; padding: .22rem .55rem; font-weight: 500;
}
.model-day-sessions .muted { font-size: .74rem; }
.model-actions { display: flex; flex-direction: column; gap: .4rem; }
.model-actions .inline-form { display: flex; gap: .35rem; align-items: center; }

/* Renombrado inline de modelo (models-selection-lifecycle, ajuste UX): el
   nombre vive en la columna NOMBRE junto a un botón-lápiz; al pulsarlo se
   sustituye por el `<input>` in situ, en vez de una columna ACCIONES con un
   input duplicado siempre visible. Mismo cuidado que en `.viz-toggle[hidden]`
   (ver `gps-crudo-guardado`): cualquier `display` de autor le gana al
   `[hidden]` del navegador, así que se repite explícito aquí. */
.model-name-view { display: inline-flex; align-items: center; gap: .4rem; }
.model-name-view[hidden] { display: none; }
.model-rename-form[hidden] { display: none; }
.model-rename-form input[type="text"] { max-width: 150px; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.7rem; height: 1.7rem; padding: 0; line-height: 1;
  font-size: .82rem; color: var(--muted); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  cursor: pointer; transition: all .18s var(--ease);
}
.icon-btn:hover { border-color: var(--blue); color: var(--blue); }
.icon-btn.danger { color: var(--danger); }
.icon-btn.danger:hover { border-color: var(--danger); background: var(--danger-bg); }

.viz-range { display: flex; flex-wrap: wrap; gap: .6rem; align-items: end; }
.viz-range label { display: flex; flex-direction: column; font-size: .72rem; font-weight: 600;
  color: var(--muted); gap: .2rem; }
.viz-range input { font-family: var(--font-body); font-size: .85rem; padding: .45rem .6rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); }
.btn-csv {
  margin-left: auto; align-self: end; font-size: .82rem; font-weight: 600;
  padding: .5rem .9rem; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink);
}
.btn-csv:hover { border-color: var(--blue); color: var(--blue); text-decoration: none; }

.viz-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: .7rem; margin-bottom: 1rem; }
.viz-stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: .7rem .85rem; }
.viz-stat .v { font-family: var(--font-head); font-weight: 800; font-size: 1.25rem; letter-spacing: -0.5px; }
.viz-stat .v.warn { color: var(--warn); }
.viz-stat .v.danger { color: var(--danger); }
.viz-stat .k { font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); margin-top: .1rem; }

.viz-panels { display: flex; flex-direction: column; gap: 1rem; }
.viz-chart-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .8rem; height: 250px; position: relative; }
/* Perfil de elevación: más bajo que la gráfica principal, es un apoyo. */
.viz-elev-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .8rem; height: 140px; position: relative; }
.inline-check { display: inline-flex; align-items: center; gap: .35rem; font-size: .85rem; color: var(--muted); }

/* Filtros client-side de tablas (index.html/users.html, filtros-usuarios-dispositivos). */
.filters { display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap; margin: .8rem 0; }
.filters label { display: flex; flex-direction: column; gap: .2rem; font-size: .8rem; color: var(--muted); }
.filters .inline-check { flex-direction: row; }

/* Checkboxes de grupo (users.html) en vez de <select multiple>. */
.group-checkboxes { display: flex; flex-wrap: wrap; gap: .5rem .9rem; border: 1px solid var(--line);
  border-radius: var(--radius); padding: .5rem .7rem; margin: 0; }
.group-checkboxes legend { font-size: .78rem; color: var(--muted); padding: 0 .3rem; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.viz-map { height: 480px; border-radius: var(--radius); border: 1px solid var(--line); overflow: hidden;
  background: var(--bg); position: relative; }
/* Los avisos van SOBRE el lienzo del mapa (posición absoluta): MapLibre es
   dueño del interior del contenedor y un hijo en flujo normal lo descuadraría. */
.viz-map-empty { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center;
  justify-content: center; color: var(--muted); font-size: .9rem; text-align: center;
  padding: 1rem; background: rgba(248, 249, 250, .82); pointer-events: none; }
.viz-map-note { position: absolute; left: .6rem; bottom: .6rem; z-index: 2; max-width: 60%;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: .35rem .6rem; font-size: .78rem; color: var(--muted); pointer-events: none; }
/* Controles de MapLibre con las esquinas y la tipografía de la casa. */
.viz-map .maplibregl-ctrl-group { border-radius: var(--radius-sm); overflow: hidden;
  box-shadow: 0 1px 3px rgba(30, 30, 36, .12); }
.viz-map .maplibregl-ctrl-attrib, .viz-map .maplibregl-ctrl-scale {
  font-family: var(--font-body); font-size: .72rem; }
.viz-empty { padding: 1rem 0; }
/* Interruptores de los trazos del mapa, bajo él. La leyenda de cada uno imita
   la línea que enciende, para no tener que explicar cuál es cuál. */
.viz-toggle { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin: .6rem 0 0; font-size: .85rem; }
/* Sin esto el interruptor sale SIEMPRE, también en los tags que no traen el
   dato. El `hidden` del HTML lo aplica el navegador con `[hidden]{display:none}`
   en su hoja por defecto, y CUALQUIER `display` de autor (el `flex` de arriba)
   le gana. Se vio en un tag sin GPS crudo: la casilla aparecía y no encendía
   nada, porque no había nada que encender. */
.viz-toggle[hidden] { display: none; }
/* `flex-direction` explícito y no por omisión: la regla global de `label`
   (arriba, para los campos de formulario) pone `column`, y esta no la anulaba
   ⇒ casilla, texto y leyenda salían apilados en tres filas. */
.viz-toggle label { display: inline-flex; flex-direction: row; align-items: center;
  gap: .4rem; cursor: pointer; }
.viz-toggle label::after { content: ''; width: 26px; }
.viz-toggle .muted { font-size: .78rem; }
/* La guardada se colorea por SpO₂, así que su leyenda es el degradado entero
   de la paleta (rojo → ámbar → verde), no un color plano. */
.viz-saved label::after { height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, rgb(214,69,69), rgb(230,180,0), rgb(26,122,74)); }
.viz-raw label::after { border-top: 2px dashed #8A94A6; }
/* La enganchada lleva DOS colores según cómo se iba: a pie se colorea por SpO₂
   como la guardada, y en vehículo va de morado plano. La muestra enseña los dos
   mitad y mitad, que es lo que se ve en el mapa. */
.viz-match label::after { height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, rgb(214,69,69), rgb(26,122,74) 50%,
    #7A5AF8 50%, #7A5AF8); }

/* Mismo cuidado que con `.viz-toggle`: declarar `display` en la clase de un
   elemento que se oculta con el atributo `hidden` lo rompe en silencio. */
.viz-toggle-nota { margin: -.35rem 0 .2rem 2.1rem; font-size: .78rem; }
.viz-toggle-nota[hidden] { display: none; }
.viz-clave-guiones { border-bottom: 2px dashed #7A5AF8; }

/* La leyenda: qué es cada trazo (medido o calculado) y por qué se enseña el que
   se enseña. Va en un recuadro tenue para que se lea como aparato de medida y
   no como texto de relleno.
   IMPORTANTE, y es la trampa que ya rompió `.viz-raw` en silencio: aquí NO se
   declara `display`. Este elemento se oculta con el atributo `hidden`, y
   cualquier `display` de autor le gana al `[hidden]{display:none}` del
   navegador. El apilado de las líneas va en el hijo, que no se oculta nunca. */
.viz-leyenda { margin: .6rem 0 .2rem; padding: .5rem .7rem; font-size: .78rem;
  line-height: 1.5; border: 1px solid var(--line); border-left: 3px solid #8A94A6;
  border-radius: var(--radius-sm); background: var(--surface); }
.viz-leyenda[hidden] { display: none; }
.viz-leyenda-linea { display: block; }
.viz-leyenda-linea + .viz-leyenda-linea { margin-top: .25rem; }

@media (max-width: 800px) {
  .viz-panels { grid-template-columns: 1fr; }
  .btn-csv { margin-left: 0; }
}

/* ==========================================================================
   MARCADO / PAPELERA (eliminar-datos-por-franja): botones de marcar por día
   y por sesión, arrastre sobre el gráfico, y el diálogo de confirmación
   compartido por los tres niveles.
   ========================================================================== */
.viz-mark-bar { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin: -.2rem 0 .4rem; }
.viz-mark-bar .muted { font-size: .78rem; }
.viz-trash-link { font-size: .85rem; }

.viz-mark-dialog {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.3rem;
  max-width: 420px; box-shadow: 0 12px 32px rgba(30,30,36,.18);
}
.viz-mark-dialog::backdrop { background: rgba(30,30,36,.35); }
.viz-mark-dialog p { margin: 0 0 .8rem; font-size: .92rem; line-height: 1.5; }
.viz-mark-actions { display: flex; justify-content: flex-end; gap: .6rem; }

/* El rectángulo de selección del arrastre (Fase C), sobre el propio lienzo:
   `.viz-chart-wrap` ya es `position: relative`, así que el rectángulo se
   ancla a él sin mover nada más. */
.viz-drag-select {
  position: absolute; top: .8rem; bottom: .8rem; z-index: 3;
  background: rgba(214,69,69,.12); border: 1px solid var(--danger);
  border-radius: 4px; pointer-events: none;
}
