/* Base de la torre de control de InterEIDAS: fuente, tokens de color en claro y oscuro, controles y diálogos.
   La comparten el panel (index.html) y la página de entrada (entrar.html).

   Marca: la de la web nueva (../web/src/styles/base.css). Geist Sans 400/500/600, tinta #0c1222, papel, niebla,
   filete y dos grises de texto; un acento por app. Filetes en lugar de tarjetas, radios mínimos, sin sombras de
   adorno, sin degradados. El oscuro es tinta: el fondo es la propia tinta de la marca y el texto, papel.

   Contraste medido con el validador de la skill dataviz (contrast()):
     claro  — tinta 18,7:1 · texto 10,5:1 · meta 4,7:1 · borde de control 3,5:1 sobre papel
     oscuro — tinta 17,0:1 · texto 11,7:1 · meta 7,2:1 · borde de control 3,9:1 sobre tinta
   Los estados llevan siempre palabra y forma (sano, vigilar, revisar): el color es el segundo canal, nunca el único. */

/* Geist Sans variable (© Vercel, SIL OFL 1.1, /fuentes/OFL-geist.txt), servida por la propia torre (CSP 'self'). */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/fuentes/geist-sans-variable.woff2) format("woff2");
}

:root {
  color-scheme: light dark;

  /* Pares claro / oscuro en bruto: light-dark() los elige y el bloque @supports de abajo los reutiliza. */
  --papel-c: #ffffff;      --papel-o: #0c1222;
  --niebla-c: #f5f5f4;     --niebla-o: #121a2d;
  --niebla2-c: #ececeb;    --niebla2-o: #1a2339;
  --filete-c: #e6e7ea;     --filete-o: #242d42;
  --borde-c: #858a95;      --borde-o: #6b7387;
  --tinta-c: #0c1222;      --tinta-o: #f3f4f7;
  --texto-c: #3a3f4b;      --texto-o: #c9cdd6;
  --meta-c: #6e7380;       --meta-o: #9aa1b0;
  --bien-c: #1d7a46;       --bien-o: #7fd4a0;
  --aviso-c: #8a5a00;      --aviso-o: #f3c56b;
  --mal-c: #b42318;        --mal-o: #ff9b91;
  --m-revisar-c: #d03b3b;  --m-revisar-o: #e5484d;
  --vacio-c: #9ba0aa;      --vacio-o: #5d6578;
  /* Marcas de estado sin palabra al lado (la luz en el móvil, las marcas de las secciones): ≥ 3:1 (WCAG 1.4.11). El
     anillo de «sin datos» es más oscuro que --vacio (2,6:1) y el triángulo ámbar de «vigilar» (1,8:1 sobre el papel)
     lleva en claro un filete ámbar oscuro (5,9:1); en oscuro, el ámbar ya da 10:1 y el filete es el propio ámbar. */
  --m-vacio-c: #7f8591;    --m-vacio-o: #5d6578;
  --m-vigilar-borde-c: #8a5a00; --m-vigilar-borde-o: #fab219;
  /* Superficie de los diálogos: en claro, el papel; en oscuro, un paso sobre la tinta (un diálogo de tinta sobre una
     página de tinta no se separaba del fondo). */
  --superficie-c: #ffffff; --superficie-o: #172036;
  --velo-c: rgb(12 18 34 / .5); --velo-o: rgb(0 0 0 / .6);
  /* Divergente de la paleta validada (azul ↔ rojo con gris neutro): tono de las respuestas de las IAs. */
  --pos-c: #2a78d6;        --pos-o: #3987e5;
  --neg-c: #e34948;        --neg-o: #e66767;

  --papel: light-dark(var(--papel-c), var(--papel-o));
  --niebla: light-dark(var(--niebla-c), var(--niebla-o));
  --niebla-2: light-dark(var(--niebla2-c), var(--niebla2-o));
  --filete: light-dark(var(--filete-c), var(--filete-o));
  --borde: light-dark(var(--borde-c), var(--borde-o));
  --tinta: light-dark(var(--tinta-c), var(--tinta-o));
  --texto: light-dark(var(--texto-c), var(--texto-o));
  --meta: light-dark(var(--meta-c), var(--meta-o));
  --bien: light-dark(var(--bien-c), var(--bien-o));
  --aviso: light-dark(var(--aviso-c), var(--aviso-o));
  --mal: light-dark(var(--mal-c), var(--mal-o));
  --m-revisar: light-dark(var(--m-revisar-c), var(--m-revisar-o));
  --vacio: light-dark(var(--vacio-c), var(--vacio-o));
  --m-vacio: light-dark(var(--m-vacio-c), var(--m-vacio-o));
  --m-vigilar-borde: light-dark(var(--m-vigilar-borde-c), var(--m-vigilar-borde-o));
  --pos: light-dark(var(--pos-c), var(--pos-o));
  --neg: light-dark(var(--neg-c), var(--neg-o));
  --superficie: light-dark(var(--superficie-c), var(--superficie-o));
  --velo: light-dark(var(--velo-c), var(--velo-o));
  /* Fondos del mapa de calor de las IAs: tintes del divergente sobre el papel; en oscuro, más cargados para que
     positivo, neutro y negativo se distingan también sobre la tinta. El texto encima es siempre tinta o papel. */
  --geo-pos: light-dark(color-mix(in oklab, var(--pos-c) 30%, #ffffff), color-mix(in oklab, var(--pos-o) 48%, #0c1222));
  --geo-neu: light-dark(color-mix(in oklab, var(--meta-c) 22%, #ffffff), color-mix(in oklab, var(--meta-o) 30%, #0c1222));
  --geo-neg: light-dark(color-mix(in oklab, var(--neg-c) 34%, #ffffff), color-mix(in oklab, var(--neg-o) 46%, #0c1222));
  /* Marcas de estado de la paleta de referencia (dataviz): iguales en los dos modos salvo el rojo, que se aclara en
     tinta para pasar de 3:1. Van siempre con su palabra al lado. */
  --m-sano: #0ca30c;
  --m-vigilar: #fab219;

  /* Sobre un botón de tinta, el texto es papel (y al revés en oscuro). */
  --sobre-tinta: var(--papel);
  /* Color de los datos: la tinta (sin app, el acento es la tinta, como en la web). Cada vista o app lo cambia. */
  --serie: var(--tinta);

  --sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --radio: 2px;
  --radio-control: 6px;
  --toque: 2.75rem;
  /* Movimiento: los verbos de la marca (frenar y encajar), cortos. */
  --frenar: cubic-bezier(.2, .8, .2, 1);
  --encajar: cubic-bezier(.3, .9, .3, 1);

  font-family: var(--sans);
  font-feature-settings: "ss01", "cv11";
  accent-color: var(--tinta);
  scrollbar-color: light-dark(#c3c6cc, #3a4358) transparent;
}

/* Navegadores sin light-dark() (Safari < 17.5): claro por defecto; oscuro por el sistema o por el ajuste de tema. */
@supports not (color: light-dark(#000, #fff)) {
  :root {
    --papel: var(--papel-c); --niebla: var(--niebla-c); --niebla-2: var(--niebla2-c); --filete: var(--filete-c);
    --borde: var(--borde-c); --tinta: var(--tinta-c); --texto: var(--texto-c); --meta: var(--meta-c);
    --bien: var(--bien-c); --aviso: var(--aviso-c); --mal: var(--mal-c); --m-revisar: var(--m-revisar-c);
    --vacio: var(--vacio-c); --pos: var(--pos-c); --neg: var(--neg-c); --superficie: var(--superficie-c); --velo: var(--velo-c);
    --m-vacio: var(--m-vacio-c); --m-vigilar-borde: var(--m-vigilar-borde-c);
    --geo-pos: color-mix(in oklab, var(--pos-c) 30%, #ffffff); --geo-neu: color-mix(in oklab, var(--meta-c) 22%, #ffffff);
    --geo-neg: color-mix(in oklab, var(--neg-c) 34%, #ffffff);
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-tema="light"]) {
      --papel: var(--papel-o); --niebla: var(--niebla-o); --niebla-2: var(--niebla2-o); --filete: var(--filete-o);
      --borde: var(--borde-o); --tinta: var(--tinta-o); --texto: var(--texto-o); --meta: var(--meta-o);
      --bien: var(--bien-o); --aviso: var(--aviso-o); --mal: var(--mal-o); --m-revisar: var(--m-revisar-o);
      --vacio: var(--vacio-o); --pos: var(--pos-o); --neg: var(--neg-o); --superficie: var(--superficie-o); --velo: var(--velo-o);
      --m-vacio: var(--m-vacio-o); --m-vigilar-borde: var(--m-vigilar-borde-o);
      --geo-pos: color-mix(in oklab, var(--pos-o) 48%, #0c1222); --geo-neu: color-mix(in oklab, var(--meta-o) 30%, #0c1222);
      --geo-neg: color-mix(in oklab, var(--neg-o) 46%, #0c1222);
    }
  }
  :root[data-tema="dark"] {
    --papel: var(--papel-o); --niebla: var(--niebla-o); --niebla-2: var(--niebla2-o); --filete: var(--filete-o);
    --borde: var(--borde-o); --tinta: var(--tinta-o); --texto: var(--texto-o); --meta: var(--meta-o);
    --bien: var(--bien-o); --aviso: var(--aviso-o); --mal: var(--mal-o); --m-revisar: var(--m-revisar-o);
    --vacio: var(--vacio-o); --pos: var(--pos-o); --neg: var(--neg-o); --superficie: var(--superficie-o); --velo: var(--velo-o);
    --m-vacio: var(--m-vacio-o); --m-vigilar-borde: var(--m-vigilar-borde-o);
    --geo-pos: color-mix(in oklab, var(--pos-o) 48%, #0c1222); --geo-neu: color-mix(in oklab, var(--meta-o) 30%, #0c1222);
    --geo-neg: color-mix(in oklab, var(--neg-o) 46%, #0c1222);
  }
}

/* El ajuste de tema (Ajustes) fija el esquema; sin él, manda el sistema. tema.js lo aplica antes de pintar. */
:root[data-tema="light"] { color-scheme: light; }
:root[data-tema="dark"] { color-scheme: dark; }

/* Tamaño de letra elegido en Ajustes (tema.js lo aplica antes de pintar). Porcentajes: respetan el tamaño base que
   la persona tenga en su navegador. Todo el panel mide en rem, así que crece entero. */
:root[data-letra="pequena"] { font-size: 93.75%; }
:root[data-letra="grande"] { font-size: 112.5%; }
:root[data-letra="muy-grande"] { font-size: 125%; }

@media (prefers-contrast: more) {
  :root { --meta-c: #4f5461; --meta-o: #c9cdd6; --filete-c: #b9bcc3; --filete-o: #4a5368; }
}

/* ── base ── */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-block-start: 7rem; }
body {
  margin: 0;
  background: var(--papel);
  color: var(--texto);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { margin: 0; color: var(--tinta); font-weight: 500; line-height: 1.2; letter-spacing: -.015em; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
strong, b { color: var(--tinta); font-weight: 600; }
a { color: var(--tinta); text-underline-offset: .2em; text-decoration-thickness: 1px; text-decoration-color: color-mix(in srgb, currentColor 40%, transparent); }
a:hover { text-decoration-color: currentColor; }
ul, ol { margin: 0; padding: 0; }
img, svg { display: block; max-inline-size: 100%; }
svg { overflow: visible; }
button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; }
code { font: 500 .875em/1.4 ui-monospace, SFMono-Regular, Consolas, monospace; overflow-wrap: anywhere; }
kbd {
  display: inline-block; min-inline-size: 1.6em; padding: .05em .4em; text-align: center;
  font: 500 .8125em/1.5 var(--sans); color: var(--tinta);
  border: 1px solid var(--filete); border-block-end-width: 2px; border-radius: 4px; background: var(--niebla);
}
::selection { background: color-mix(in srgb, var(--tinta) 18%, transparent); }

/* Foco visible siempre (teclado): anillo de tinta con aire. En oscuro, la tinta es papel. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 3px;
  border-radius: var(--radio);
}

.visualmente-oculto:where(:not(:focus-within, :active)) {
  position: absolute !important; inline-size: 1px !important; block-size: 1px !important; margin: -1px !important;
  padding: 0 !important; border: 0 !important; overflow: hidden !important; clip-path: inset(50%) !important;
  white-space: nowrap !important;
}
.saltar {
  position: fixed; inset-inline-start: 1rem; inset-block-start: .75rem; z-index: 100;
  padding: .6rem .9rem; background: var(--tinta); color: var(--sobre-tinta); border-radius: var(--radio); text-decoration: none;
}

/* Iconos de trazo del sprite (dom.js → icono()). Heredan el color del texto. */
.ic { inline-size: 1.125rem; block-size: 1.125rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.ic.relleno { fill: currentColor; stroke: none; }

/* Cifras: proporcionales en sueltas, tabulares solo donde se alinean en columna. */
.num { font-variant-numeric: tabular-nums; }

/* ── controles ── */
.boton {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-block-size: var(--toque); padding: .45rem 1rem;
  border: 1px solid var(--borde); border-radius: var(--radio-control);
  background: var(--papel); color: var(--tinta);
  font-weight: 500; font-size: .9375rem; line-height: 1.2; text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color .15s, border-color .15s, color .15s, transform .1s;
}
.boton:hover { background: var(--niebla); }
.boton:active { transform: translateY(1px); }
.boton.primario { background: var(--tinta); border-color: var(--tinta); color: var(--sobre-tinta); }
.boton.primario:hover { background: color-mix(in oklab, var(--tinta) 86%, var(--papel)); }
.boton.fantasma { border-color: transparent; background: transparent; }
.boton.fantasma:hover { background: var(--niebla); }
.boton.peligro { color: var(--mal); }
.boton.pequeno { min-block-size: 2.25rem; padding: .25rem .75rem; font-size: .875rem; }
.boton.icono { inline-size: var(--toque); padding: 0; border-color: transparent; background: transparent; color: var(--texto); }
.boton.icono:hover { background: var(--niebla); color: var(--tinta); }
.boton[aria-busy="true"] { cursor: progress; }
.boton:disabled, .boton[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.boton[aria-busy="true"] .ic-giro { animation: girar 1s linear infinite; }
@keyframes girar { to { transform: rotate(1turn); } }

label { display: block; font-weight: 500; color: var(--tinta); font-size: .9375rem; }
.campo { display: grid; gap: .35rem; }
.pista { font-size: .875rem; color: var(--meta); }
input:where(:not([type=checkbox], [type=radio])), select, textarea {
  inline-size: 100%; min-block-size: var(--toque); padding: .55rem .75rem;
  border: 1px solid var(--borde); border-radius: var(--radio-control);
  background: var(--papel); color: var(--tinta); font-size: 1rem;
  transition: border-color .15s, box-shadow .15s;
}
input:where(:not([type=checkbox], [type=radio])):focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--tinta); outline-offset: 1px;
}
:is(input, select, textarea):user-invalid { border-color: var(--mal); }
select { appearance: auto; }
textarea { resize: vertical; line-height: 1.5; }
input[type=checkbox], input[type=radio] { inline-size: 1.125rem; block-size: 1.125rem; margin: 0; flex: none; }

/* ── diálogos (nativos, modales) ── */
dialog {
  inline-size: min(34rem, calc(100vw - 2rem));
  max-block-size: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: 1.5rem;
  border: 1px solid var(--filete);
  border-radius: 4px;
  background: var(--superficie);
  color: var(--texto);
  box-shadow: 0 24px 48px -16px rgb(12 18 34 / .35);
}
dialog.ancho { inline-size: min(48rem, calc(100vw - 2rem)); }
dialog::backdrop { background: var(--velo); }
/* Dentro del diálogo, lo que usa el papel como fondo (botones, campos, anillo de las marcas) usa su superficie. */
dialog { --papel: var(--superficie); }
dialog h2 { font-size: 1.25rem; margin-block-end: .5rem; }
/* Un título que recibe el foco al abrir (diálogo largo) no es un control: sin anillo, como el h1 de cada vista. */
dialog h2[tabindex="-1"] { outline: none; }
.botonera { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .5rem; margin-block-start: 1.25rem; }

/* Entrada y salida de los diálogos: aparece desde abajo, sin rebote. Donde no hay transición de `display`, aparece
   sin más (Firefox); dom.js cierra con `data-cerrando` para que también allí se anime la salida. */
@media (prefers-reduced-motion: no-preference) {
  dialog {
    opacity: 0; translate: 0 .75rem;
    transition: opacity .2s var(--frenar), translate .24s var(--frenar), display .24s allow-discrete, overlay .24s allow-discrete;
  }
  dialog:is([open]):where(:not([data-cerrando])) {
    opacity: 1; translate: 0 0;
    @starting-style { opacity: 0; translate: 0 .75rem; }
  }
  dialog::backdrop { opacity: 0; transition: opacity .2s, display .24s allow-discrete, overlay .24s allow-discrete; }
  dialog:is([open]):where(:not([data-cerrando]))::backdrop {
    opacity: 1;
    @starting-style { opacity: 0; }
  }
}

/* ── aviso flotante (dom.js → avisar) ── */
.aviso-flotante {
  position: fixed; inset-block-end: max(1rem, env(safe-area-inset-bottom)); inset-inline-start: 50%; z-index: 90;
  display: flex; align-items: center; gap: .6rem;
  max-inline-size: min(32rem, calc(100vw - 2rem));
  padding: .7rem 1rem;
  background: var(--tinta); color: var(--sobre-tinta); border-radius: 4px;
  font-size: .9375rem; font-weight: 500;
  translate: -50% 1rem; opacity: 0; pointer-events: none;
  transition: opacity .2s var(--frenar), translate .25s var(--frenar);
}
.aviso-flotante.visible { opacity: 1; translate: -50% 0; }
.aviso-flotante[data-tipo="error"] .ic { color: light-dark(#ff9b91, #b42318); }
.aviso-flotante[data-tipo="bien"] .ic { color: light-dark(#7fd4a0, #1d7a46); }

/* ── movimiento: nada si la persona pide menos ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

@media (forced-colors: active) {
  .boton { border: 1px solid ButtonText; }
  .ic { stroke: CanvasText; }
  .ic.relleno { fill: CanvasText; }
}
