/* ==========================================================================
   Python para ciencia de datos - hoja de estilos unica
   Vocabulario cerrado de clases: ver curso_fuente/GUIA_DE_AUTORIA.md
   ========================================================================== */

/* --- Paleta clara: definicion completa sobre :root ---------------------- */
:root {
  --fondo:          #fbfaf8;
  --superficie:     #ffffff;
  --superficie-2:   #f4f1ec;
  --texto:          #1c1b1a;
  --texto-suave:    #57534e;
  --texto-tenue:    #8a837c;
  --borde:          #e3ded7;
  --borde-fuerte:   #cfc7bc;
  --acento:         #0f5d63;
  --acento-texto:   #ffffff;
  --acento-suave:   #e2f0f0;
  --ok:             #1a6b3c;
  --ok-suave:       #e4f2e9;
  --alerta:         #8a4b12;
  --alerta-suave:   #fbeee0;
  --error:          #9b2226;
  --error-suave:    #fbe9e9;
  --codigo-fondo:   #f4f1ec;
  --salida-fondo:   #1e2124;
  --salida-texto:   #e8e6e3;

  --tok-kw:   #7c3aed;
  --tok-str:  #1a6b3c;
  --tok-num:  #9b2226;
  --tok-com:  #8a837c;
  --tok-fn:   #0f5d63;
  --tok-bi:   #8a4b12;

  --fuente: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue",
            Arial, "Noto Sans", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "Consolas", "SF Mono", "Menlo",
          "DejaVu Sans Mono", monospace;
  --radio: 6px;
  --ancho-prosa: 72ch;
  --ancho-nav: 17rem;
}

/* --- Paleta oscura: solo se redefinen los tokens ------------------------ */
/* Oscuro por preferencia del sistema (salvo que el alumno pida claro) */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --fondo:          #16181a;
    --superficie:     #1e2124;
    --superficie-2:   #22262a;
    --texto:          #e8e6e3;
    --texto-suave:    #b3aca6;
    --texto-tenue:    #857e78;
    --borde:          #33383c;
    --borde-fuerte:   #4a5055;
    --acento:         #5eb6bd;
    --acento-texto:   #10262a;
    --acento-suave:   #17383a;
    --ok:             #6cc48d;
    --ok-suave:       #16301f;
    --alerta:         #d99a5b;
    --alerta-suave:   #33240f;
    --error:          #e8898c;
    --error-suave:    #341a1b;
    --codigo-fondo:   #22262a;
    --salida-fondo:   #0f1113;
    --salida-texto:   #dcd9d5;

    --tok-kw:   #c4a2ff;
    --tok-str:  #8ecfa4;
    --tok-num:  #f0a0a2;
    --tok-com:  #857e78;
    --tok-fn:   #7fd0d6;
    --tok-bi:   #e0b184;
  }
}

/* Oscuro elegido a mano. Mismos tokens: si tocas uno, tocá los dos. */
:root[data-tema="oscuro"] {
  --fondo:          #16181a;
  --superficie:     #1e2124;
  --superficie-2:   #22262a;
  --texto:          #e8e6e3;
  --texto-suave:    #b3aca6;
  --texto-tenue:    #857e78;
  --borde:          #33383c;
  --borde-fuerte:   #4a5055;
  --acento:         #5eb6bd;
  --acento-texto:   #10262a;
  --acento-suave:   #17383a;
  --ok:             #6cc48d;
  --ok-suave:       #16301f;
  --alerta:         #d99a5b;
  --alerta-suave:   #33240f;
  --error:          #e8898c;
  --error-suave:    #341a1b;
  --codigo-fondo:   #22262a;
  --salida-fondo:   #0f1113;
  --salida-texto:   #dcd9d5;

  --tok-kw:   #c4a2ff;
  --tok-str:  #8ecfa4;
  --tok-num:  #f0a0a2;
  --tok-com:  #857e78;
  --tok-fn:   #7fd0d6;
  --tok-bi:   #e0b184;
}

/* --- Base --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--fuente);
  font-size: 17px;
  line-height: 1.65;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--acento); text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--acento);
  outline-offset: 2px;
  border-radius: 3px;
}

.saltar {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--acento);
  color: var(--acento-texto);
  padding: 0.6rem 1rem;
  z-index: 100;
}
.saltar:focus { left: 0; }

/* --- Estructura --------------------------------------------------------- */
.envoltura {
  display: grid;
  grid-template-columns: var(--ancho-nav) minmax(0, 1fr);
  gap: 2.5rem;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 1.5rem 4rem;
  align-items: start;
}

.lateral {
  position: sticky;
  top: 0;
  max-height: 100vh;
  overflow-y: auto;
  padding: 1.5rem 0;
  font-size: 0.9rem;
  border-right: 1px solid var(--borde);
}

.marca {
  display: block;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.3;
  color: var(--texto);
  text-decoration: none;
  margin-bottom: 1.25rem;
  padding-right: 1rem;
}
.marca span { display: block; font-weight: 400; color: var(--texto-tenue); font-size: 0.82rem; }

.nav-unidad { margin-bottom: 1.1rem; }
.nav-unidad > h2 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--texto-tenue);
  margin: 0 0 0.35rem;
  font-weight: 700;
}
.nav-unidad ol { list-style: none; margin: 0; padding: 0; }
.nav-unidad li { margin: 0; }
.nav-unidad a,
.nav-unidad .pendiente {
  display: block;
  padding: 0.2rem 0.6rem 0.2rem 0.55rem;
  border-left: 2px solid transparent;
  text-decoration: none;
  color: var(--texto-suave);
  border-radius: 0 var(--radio) var(--radio) 0;
}
.nav-unidad a:hover { background: var(--acento-suave); color: var(--texto); }
.nav-unidad a[aria-current="page"] {
  border-left-color: var(--acento);
  background: var(--acento-suave);
  color: var(--texto);
  font-weight: 600;
}
.nav-unidad .pendiente { color: var(--texto-tenue); cursor: default; }
.nav-unidad .num { color: var(--texto-tenue); font-variant-numeric: tabular-nums; }

.contenido { padding: 2.5rem 0 0; min-width: 0; }
.contenido > * { max-width: var(--ancho-prosa); }
.contenido > .ancho-total,
.contenido > figure,
.contenido > table,
.contenido > .tabla-envoltura { max-width: none; }

/* --- Tipografia --------------------------------------------------------- */
h1 { font-size: 2rem; line-height: 1.2; margin: 0 0 0.4rem; letter-spacing: -0.015em; }
h2 {
  font-size: 1.32rem;
  margin: 2.6rem 0 0.7rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--borde);
  letter-spacing: -0.01em;
}
h3 { font-size: 1.08rem; margin: 1.8rem 0 0.5rem; }
p { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.4rem; }
li { margin-bottom: 0.35rem; }
strong { font-weight: 650; }

code {
  font-family: var(--mono);
  font-size: 0.87em;
  background: var(--codigo-fondo);
  padding: 0.12em 0.34em;
  border-radius: 4px;
  border: 1px solid var(--borde);
}
pre code { background: none; padding: 0; border: 0; font-size: inherit; }

.migas {
  font-size: 0.85rem;
  color: var(--texto-tenue);
  margin: 0 0 0.8rem;
}
.migas a { color: var(--texto-suave); }

.bajada {
  font-size: 1.08rem;
  color: var(--texto-suave);
  margin: 0 0 1.6rem;
}

/* --- Franja de prerrequisitos ------------------------------------------ */
.prereq {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.8rem;
  align-items: baseline;
  font-size: 0.86rem;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 0.6rem 0.85rem;
  margin: 0 0 1.8rem;
}
.prereq b { color: var(--texto-suave); font-weight: 650; }
.prereq .ficha {
  display: inline-block;
  padding: 0.08rem 0.5rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 100px;
  text-decoration: none;
  color: var(--acento);
  background: var(--fondo);
}
.prereq .ficha:hover { background: var(--acento-suave); }
.prereq .ficha.pendiente { color: var(--texto-tenue); border-style: dashed; }
.prereq .vacio { color: var(--texto-tenue); }

/* --- Ejemplos de codigo y salida ---------------------------------------- */
figure.ejemplo {
  margin: 1.6rem 0;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
figure.ejemplo > figcaption {
  padding: 0.55rem 0.9rem;
  background: var(--superficie-2);
  border-bottom: 1px solid var(--borde);
  font-size: 0.9rem;
  color: var(--texto-suave);
}
figure.ejemplo > figcaption .etiqueta {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 700;
  color: var(--acento);
  margin-right: 0.5rem;
}
.codigo { position: relative; }
.codigo pre {
  margin: 0;
  padding: 0.9rem 1rem;
  overflow-x: auto;
  background: var(--codigo-fondo);
  font-family: var(--mono);
  font-size: 0.855rem;
  line-height: 1.6;
  tab-size: 4;
}
.copiar {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  font: inherit;
  font-size: 0.74rem;
  padding: 0.18rem 0.55rem;
  color: var(--texto-suave);
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte);
  border-radius: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
}
figure.ejemplo:hover .copiar,
.copiar:focus-visible { opacity: 1; }
.copiar:hover { background: var(--acento-suave); color: var(--texto); }

pre.salida {
  margin: 0;
  padding: 0.85rem 1rem;
  overflow-x: auto;
  background: var(--salida-fondo);
  color: var(--salida-texto);
  font-family: var(--mono);
  font-size: 0.82rem;
  line-height: 1.55;
  border-top: 1px solid var(--borde);
}
pre.salida::before {
  content: "salida";
  display: block;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--texto-tenue);
  margin-bottom: 0.4rem;
}

/* Resaltado (generado en build con tokenize) */
.tok-kw  { color: var(--tok-kw); font-weight: 600; }
.tok-str { color: var(--tok-str); }
.tok-num { color: var(--tok-num); }
.tok-com { color: var(--tok-com); font-style: italic; }
.tok-fn  { color: var(--tok-fn); }
.tok-bi  { color: var(--tok-bi); }

/* --- Recuadros ---------------------------------------------------------- */
.nota, .aviso, .eleccion, .dataset {
  margin: 1.4rem 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radio);
  border: 1px solid var(--borde);
  border-left-width: 4px;
  background: var(--superficie);
  font-size: 0.95rem;
}
.nota   { border-left-color: var(--acento); }
.aviso  { border-left-color: var(--alerta); background: var(--alerta-suave); }
.eleccion { border-left-color: var(--ok); background: var(--ok-suave); }
.dataset { border-left-color: var(--borde-fuerte); background: var(--superficie-2); }
.nota > :last-child, .aviso > :last-child,
.eleccion > :last-child, .dataset > :last-child { margin-bottom: 0; }
.nota > b:first-child, .aviso > b:first-child, .eleccion > b:first-child {
  display: block;
  margin-bottom: 0.3rem;
}

/* --- Tablas ------------------------------------------------------------- */
.tabla-envoltura { overflow-x: auto; margin: 1.4rem 0; }
table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
  background: var(--superficie);
}
caption {
  text-align: left;
  font-size: 0.85rem;
  color: var(--texto-suave);
  padding-bottom: 0.4rem;
}
th, td {
  text-align: left;
  padding: 0.4rem 0.7rem;
  border-bottom: 1px solid var(--borde);
  vertical-align: top;
}
thead th {
  border-bottom: 2px solid var(--borde-fuerte);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--texto-suave);
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* --- Errores frecuentes ------------------------------------------------- */
.errores { margin: 1.4rem 0; }
.errores > div {
  border: 1px solid var(--borde);
  border-left: 4px solid var(--error);
  border-radius: var(--radio);
  padding: 0.7rem 0.9rem;
  margin-bottom: 0.7rem;
  background: var(--superficie);
}
.errores .mensaje {
  display: block;
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--error);
  background: var(--error-suave);
  padding: 0.35rem 0.5rem;
  border-radius: 4px;
  margin-bottom: 0.45rem;
  overflow-x: auto;
}
.errores p { margin: 0 0 0.4rem; font-size: 0.93rem; }
.errores p:last-child { margin-bottom: 0; }

/* --- Visualizaciones ---------------------------------------------------- */
figure.viz {
  margin: 1.8rem 0;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  overflow: hidden;
}
figure.viz > figcaption {
  padding: 0.55rem 0.9rem;
  background: var(--superficie-2);
  border-bottom: 1px solid var(--borde);
  font-size: 0.9rem;
  color: var(--texto-suave);
}
.viz-lienzo { padding: 1rem; overflow-x: auto; }
.viz-lienzo svg { max-width: 100%; height: auto; display: block; margin: 0 auto; }
.viz-controles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  border-top: 1px solid var(--borde);
  background: var(--superficie-2);
}
.viz-controles button {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.25rem 0.75rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 4px;
  background: var(--superficie);
  color: var(--texto);
  cursor: pointer;
}
.viz-controles button:hover:not(:disabled) { background: var(--acento-suave); }
.viz-controles button:disabled { opacity: 0.45; cursor: default; }
.viz-paso {
  flex: 1 1 12rem;
  font-size: 0.88rem;
  color: var(--texto-suave);
  min-height: 1.5em;
}
.viz-contador { font-variant-numeric: tabular-nums; color: var(--texto-tenue); font-size: 0.82rem; }

/* --- Quiz --------------------------------------------------------------- */
.quiz { margin: 1.5rem 0; }
fieldset.pregunta {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 0.9rem 1rem;
  margin: 0 0 1rem;
  background: var(--superficie);
}
fieldset.pregunta > legend {
  font-weight: 650;
  padding: 0 0.4rem;
  font-size: 0.95rem;
}
fieldset.pregunta .nivel {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
  font-weight: 700;
  margin-left: 0.5rem;
}
.pregunta .opciones { list-style: none; margin: 0.5rem 0 0; padding: 0; }
.pregunta .opciones li { margin: 0 0 0.3rem; }
.pregunta label {
  display: flex;
  gap: 0.55rem;
  align-items: flex-start;
  padding: 0.4rem 0.55rem;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
}
.pregunta label:hover { background: var(--superficie-2); }
.pregunta input[type="radio"] { margin-top: 0.32em; flex-shrink: 0; }
.pregunta label.es-correcta { background: var(--ok-suave); border-color: var(--ok); }
.pregunta label.es-incorrecta { background: var(--error-suave); border-color: var(--error); }
.pregunta.resuelta label { cursor: default; }
.retro {
  margin: 0.6rem 0 0;
  padding: 0.55rem 0.7rem;
  border-radius: 4px;
  font-size: 0.9rem;
  background: var(--superficie-2);
  border-left: 3px solid var(--borde-fuerte);
}
.retro.bien { border-left-color: var(--ok); }
.retro.mal { border-left-color: var(--error); }
.quiz-marcador {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.92rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie-2);
}

/* --- Practicas ---------------------------------------------------------- */
.practicas { display: grid; gap: 0.8rem; margin: 1.4rem 0; }
.practica {
  display: block;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 0.75rem 0.95rem;
  background: var(--superficie);
  text-decoration: none;
  color: inherit;
}
a.practica:hover { border-color: var(--acento); background: var(--acento-suave); }
.practica .titulo { font-weight: 650; display: block; }
.practica .meta { font-size: 0.82rem; color: var(--texto-tenue); }
.dif {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 0.05rem 0.45rem;
  border-radius: 100px;
  border: 1px solid currentColor;
}
.dif-B { color: var(--ok); }
.dif-M { color: var(--alerta); }
.dif-A { color: var(--error); }

/* --- Paginacion --------------------------------------------------------- */
.paginacion {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--borde);
  font-size: 0.9rem;
}
.paginacion a {
  max-width: 46%;
  text-decoration: none;
  color: var(--texto-suave);
}
.paginacion a:hover { color: var(--acento); }
.paginacion .dir {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--texto-tenue);
}
.paginacion .siguiente { text-align: right; margin-left: auto; }

.pie {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--borde);
  font-size: 0.82rem;
  color: var(--texto-tenue);
}

/* --- Indice ------------------------------------------------------------- */
.grafo { margin: 1.5rem 0; overflow-x: auto; }
.grafo svg { display: block; }
.grafo .nodo rect { fill: var(--superficie); stroke: var(--borde-fuerte); }
.grafo .nodo.listo rect { fill: var(--acento-suave); stroke: var(--acento); }
.grafo .nodo text { font-size: 11px; fill: var(--texto); font-family: var(--fuente); }
.grafo .nodo.pendiente text { fill: var(--texto-tenue); }
.grafo .arista { stroke: var(--borde-fuerte); fill: none; }
.grafo .etiqueta-nivel { font-size: 10px; fill: var(--texto-tenue); font-family: var(--fuente); }

.leyenda { display: flex; gap: 1.2rem; font-size: 0.82rem; color: var(--texto-suave); margin: 0.5rem 0 0; }
.leyenda span::before {
  content: "";
  display: inline-block;
  width: 0.75rem; height: 0.75rem;
  margin-right: 0.35rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 2px;
  vertical-align: -1px;
}
.leyenda .l-listo::before { background: var(--acento-suave); border-color: var(--acento); }
.leyenda .l-pendiente::before { background: var(--superficie); border-style: dashed; }

.indice-unidad { margin: 1.8rem 0; }
.indice-unidad ol { list-style: none; padding: 0; }
.indice-unidad li {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--borde);
}
.indice-unidad .num {
  font-variant-numeric: tabular-nums;
  color: var(--texto-tenue);
  min-width: 2.4rem;
  font-size: 0.85rem;
}
.indice-unidad .apis { font-size: 0.8rem; color: var(--texto-tenue); margin-left: auto; text-align: right; }
.indice-unidad .avance {
  font-size: 0.75rem;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 900px) {
  body { font-size: 16px; }
  .envoltura { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 0 1rem 3rem; }
  .lateral {
    position: static;
    max-height: none;
    border-right: 0;
    border-bottom: 1px solid var(--borde);
    padding: 1rem 0;
  }
  .lateral .nav-plegable > summary {
    cursor: pointer;
    font-weight: 650;
    padding: 0.4rem 0;
    list-style: revert;
  }
  .lateral .nav-plegable[open] > summary { margin-bottom: 0.6rem; }
  .contenido { padding-top: 1.5rem; }
  h1 { font-size: 1.6rem; }
}

@media (min-width: 901px) {
  .lateral .nav-plegable > summary { display: none; }
}

/* --- Impresion ---------------------------------------------------------- */
@media print {
  :root {
    --fondo: #fff; --superficie: #fff; --superficie-2: #fff;
    --texto: #000; --texto-suave: #333; --texto-tenue: #555;
    --borde: #bbb; --borde-fuerte: #888;
    --codigo-fondo: #f5f5f5; --salida-fondo: #fff; --salida-texto: #000;
    --acento: #000; --acento-suave: #fff;
  }
  body { font-size: 11pt; }
  .lateral, .copiar, .viz-controles, .paginacion, .saltar,
  .quiz-marcador, .quiz-acciones { display: none !important; }
  .envoltura { display: block; max-width: none; padding: 0; }
  .contenido { padding: 0; }
  .contenido > * { max-width: none; }
  pre, pre.salida { white-space: pre-wrap; word-break: break-word; border: 1px solid #bbb; }
  pre.salida { color: #000; }
  figure.ejemplo, figure.viz, fieldset.pregunta, .errores > div,
  .nota, .aviso, .eleccion { break-inside: avoid; }
  h2, h3 { break-after: avoid; }
  .pregunta label { border: 1px solid #bbb; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; color: #555; }
  .viz-pasos-impresos { display: block !important; }
}



/* --- Color por unidad en el grafo --------------------------------------- */
:root {
  --u0: #4a4e69;
  --u1: #a05a2c; --u2: #7a5195; --u3: #1f6f8b; --u4: #0f5d63;
  --u5: #9b2226; --u6: #2f6d3c; --u7: #8a6d1f; --u8: #9d2a6b;
  --u9: #3f4fa0; --u10: #5f5b57;
}
/* Oscuro por preferencia del sistema (salvo que el alumno pida claro) */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --u0: #a3a7c4;
    --u1: #d79a63; --u2: #b795d0; --u3: #6fb3cd; --u4: #5eb6bd;
    --u5: #e8898c; --u6: #7cc48f; --u7: #ceb066; --u8: #e08cbc;
    --u9: #949ee0; --u10: #a9a49e;
  }
}

/* Oscuro elegido a mano. Mismos tokens: si tocas uno, tocá los dos. */
:root[data-tema="oscuro"] {
  --u0: #a3a7c4;
  --u1: #d79a63; --u2: #b795d0; --u3: #6fb3cd; --u4: #5eb6bd;
  --u5: #e8898c; --u6: #7cc48f; --u7: #ceb066; --u8: #e08cbc;
  --u9: #949ee0; --u10: #a9a49e;
}
.grafo .nodo.u0 rect { stroke: var(--u0); }
.grafo .nodo.u1 rect { stroke: var(--u1); }
.grafo .nodo.u2 rect { stroke: var(--u2); }
.grafo .nodo.u3 rect { stroke: var(--u3); }
.grafo .nodo.u4 rect { stroke: var(--u4); }
.grafo .nodo.u5 rect { stroke: var(--u5); }
.grafo .nodo.u6 rect { stroke: var(--u6); }
.grafo .nodo.u7 rect { stroke: var(--u7); }
.grafo .nodo.u8 rect { stroke: var(--u8); }
.grafo .nodo.u9 rect { stroke: var(--u9); }
.grafo .nodo.u10 rect { stroke: var(--u10); }
.grafo .nodo.listo.u0 rect { fill: var(--u0); fill-opacity: 0.14; }
.grafo .nodo.listo.u1 rect { fill: var(--u1); fill-opacity: 0.14; }
.grafo .nodo.listo.u2 rect { fill: var(--u2); fill-opacity: 0.14; }
.grafo .nodo.listo.u3 rect { fill: var(--u3); fill-opacity: 0.14; }
.grafo .nodo.listo.u4 rect { fill: var(--u4); fill-opacity: 0.14; }
.grafo .nodo.listo.u5 rect { fill: var(--u5); fill-opacity: 0.14; }
.grafo .nodo.listo.u6 rect { fill: var(--u6); fill-opacity: 0.14; }
.grafo .nodo.listo.u7 rect { fill: var(--u7); fill-opacity: 0.14; }
.grafo .nodo.listo.u8 rect { fill: var(--u8); fill-opacity: 0.14; }
.grafo .nodo.listo.u9 rect { fill: var(--u9); fill-opacity: 0.14; }
.grafo .nodo.listo.u10 rect { fill: var(--u10); fill-opacity: 0.14; }
.grafo .nodo:hover rect { stroke-width: 2; }

/* --- Figura capturada de un ejemplo ------------------------------------- */
/* El PNG que produce matplotlib tiene fondo blanco y tinta oscura. El sitio
   tiene un interruptor manual de tema, asi que no se puede seguir a
   prefers-color-scheme desde la imagen: la unica salida honesta es apoyarla
   sobre una placa blanca propia en los dos temas. En oscuro el borde la separa
   del fondo para que no parezca un recorte flotando. */
img.figura {
  display: block;
  width: 100%;
  height: auto;
  max-width: 792px;
  margin: 0 auto;
  padding: 0.5rem;
  background: #ffffff;
  border-top: 1px solid var(--borde);
  border-bottom: 1px solid var(--borde);
}
@media print {
  img.figura { break-inside: avoid; page-break-inside: avoid; }
}

/* --- Ejemplo con parametros --------------------------------------------- */
.variantes .selector {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  padding: 0.55rem 0.9rem;
  border-top: 1px solid var(--borde);
  background: var(--superficie-2);
}
.variantes .selector .parametro {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--texto-suave);
  margin-right: 0.2rem;
}
.variantes .selector button {
  font: inherit;
  font-family: var(--mono);
  font-size: 0.8rem;
  padding: 0.2rem 0.7rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 100px;
  background: var(--superficie);
  color: var(--texto-suave);
  cursor: pointer;
}
.variantes .selector button:hover { background: var(--acento-suave); color: var(--texto); }
.variantes .selector button[aria-pressed="true"] {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
  font-weight: 600;
}
.variante-etiqueta {
  margin: 0;
  padding: 0.45rem 0.9rem 0;
  font-size: 0.82rem;
  color: var(--texto-suave);
  background: var(--superficie);
}
.variantes.con-js .variante-etiqueta { display: none; }
.variante[hidden] { display: none; }

/* --- Widget transformacion-celda ---------------------------------------- */
table.celdas { width: auto; min-width: 16rem; font-size: 0.9rem; }
table.celdas th { font-family: var(--mono); text-transform: none; letter-spacing: 0; }
table.celdas td.clave {
  font-family: var(--mono);
  color: var(--texto-tenue);
  font-size: 0.85rem;
}
table.celdas td.celda {
  font-family: var(--mono);
  border-left: 3px solid transparent;
  transition: background-color 0.25s, border-color 0.25s;
}
.estado-texto   { color: var(--texto); border-left-color: var(--borde-fuerte) !important; }
.estado-sospechoso {
  color: var(--alerta);
  background: var(--alerta-suave);
  border-left-color: var(--alerta) !important;
  font-weight: 650;
}
.estado-nulo {
  color: var(--texto-tenue);
  background: var(--superficie-2);
  border-left-color: var(--texto-tenue) !important;
  font-style: italic;
}
.estado-numero {
  color: var(--ok);
  background: var(--ok-suave);
  border-left-color: var(--ok) !important;
  font-weight: 650;
}
@keyframes destello-celda {
  from { box-shadow: inset 0 0 0 2px var(--acento); }
  to   { box-shadow: inset 0 0 0 2px transparent; }
}
td.celda.destello { animation: destello-celda 0.7s ease-out; }
@media (prefers-reduced-motion: reduce) {
  td.celda.destello { animation: none; }
}

p.viz-leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  margin: 0.8rem 0 0;
  font-size: 0.8rem;
}
p.viz-leyenda span {
  padding: 0.1rem 0.5rem;
  border-radius: 4px;
  border-left: 3px solid transparent;
}
/* Sin JavaScript la lista de pasos ES el contenido: se ve. Con JavaScript
   la reemplaza la animacion navegable, y vuelve a aparecer al imprimir. */
.viz-pasos-impresos {
  display: block;
  margin: 0;
  padding: 0.6rem 0.9rem 0.9rem 2.4rem;
  font-size: 0.9rem;
}
.viz-pasos-impresos li { margin-bottom: 0.7rem; }
figure.viz.con-js .viz-pasos-impresos { display: none; }
.viz-estatico { padding: 1rem; }
.nota-noscript { font-size: 0.85rem; color: var(--texto-suave); margin-bottom: 0.6rem; }

.quiz-acciones { margin-top: 0.8rem; }
.quiz-acciones button {
  font: inherit;
  font-size: 0.88rem;
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio);
  background: var(--superficie);
  color: var(--texto);
  cursor: pointer;
}
.quiz-acciones button:hover { background: var(--acento-suave); }
.quiz-marcador { margin-bottom: 1rem; }
fieldset.pregunta legend pre {
  margin: 0.6rem 0 0;
  padding: 0.6rem 0.8rem;
  background: var(--codigo-fondo);
  border: 1px solid var(--borde);
  border-radius: 4px;
  font-size: 0.8rem;
  overflow-x: auto;
  white-space: pre;
  font-weight: 400;
}

/* --- Codigo de cada paso de la animacion -------------------------------- */
.viz-codigo {
  margin: 0;
  padding: 0.6rem 0.9rem;
  border-top: 1px solid var(--borde);
  background: var(--codigo-fondo);
  font-family: var(--mono);
  font-size: 0.83rem;
  line-height: 1.55;
  overflow-x: auto;
  white-space: pre;
}
.viz-codigo[hidden] { display: none; }
.viz-pasos-impresos .viz-codigo {
  margin-top: 0.35rem;
  border: 1px solid var(--borde);
  border-radius: 4px;
  font-size: 0.8rem;
}

/* --- El boton de reproducir late hasta que lo tocan --------------------- */
.viz-controles button.reproducir {
  font-weight: 600;
  border-color: var(--acento);
  color: var(--acento);
}
.viz-controles button.reproducir:hover { background: var(--acento-suave); }
@keyframes latido-boton {
  0%, 100% { box-shadow: 0 0 0 0 var(--acento-suave); }
  35%      { box-shadow: 0 0 0 6px var(--acento-suave); }
}
.viz-controles button.reproducir.llama-atencion {
  animation: latido-boton 1.5s ease-in-out infinite;
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
}
@media (prefers-reduced-motion: reduce) {
  .viz-controles button.reproducir.llama-atencion { animation: none; }
}

/* --- Selector de tema ---------------------------------------------------- */
.tema {
  display: none;          /* sin JavaScript no se muestra un boton muerto */
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 1.1rem;
}
html.js .tema { display: flex; }
.tema button {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.22rem 0.6rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 100px;
  background: var(--superficie);
  color: var(--texto-suave);
  cursor: pointer;
}
.tema button:hover { background: var(--acento-suave); color: var(--texto); }
.tema button[aria-pressed="true"] {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
  font-weight: 600;
}
@media print { .tema { display: none !important; } }

/* --- Marcador global de avance ------------------------------------------ */
.progreso {
  display: none;              /* sin JavaScript diria 0 % siempre: no se muestra */
  margin: 0 0 1.2rem;
}
html.js .progreso { display: block; }
.progreso .barra {
  height: 6px;
  border-radius: 100px;
  background: var(--superficie-2);
  border: 1px solid var(--borde);
  overflow: hidden;
}
.progreso .barra span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--acento);
  transition: width 0.35s ease-out;
}
.progreso[data-completo="si"] .barra span { background: var(--ok); }
.progreso-texto {
  margin: 0.35rem 0 0;
  font-size: 0.76rem;
  color: var(--texto-tenue);
  line-height: 1.35;
}
@media (prefers-reduced-motion: reduce) {
  .progreso .barra span { transition: none; }
}

/* --- Lo aprendido, tachado ---------------------------------------------- */
.nav-unidad li.aprendida > a,
.indice-unidad li.aprendida > a {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  color: var(--texto-tenue);
}
.nav-unidad li.aprendida > a::before,
.indice-unidad li.aprendida > a::before {
  content: "\2713\00a0";
  color: var(--ok);
  text-decoration: none;
  display: inline-block;
}
.grafo .nodo.aprendida rect { fill: var(--ok); fill-opacity: 0.2; stroke: var(--ok); }
.grafo .nodo.aprendida text { fill: var(--texto-suave); }

/* --- Boton de marcar como aprendida ------------------------------------- */
.aprender {
  display: none;              /* sin JavaScript seria un boton muerto */
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 0.9rem;
  margin: 2.4rem 0 0;
  padding: 0.85rem 1rem;
  border: 1px solid var(--borde);
  border-left: 4px solid var(--acento);
  border-radius: var(--radio);
  background: var(--superficie);
}
html.js .aprender { display: flex; }
.aprender .marcar {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.35rem 1rem;
  border: 1px solid var(--acento);
  border-radius: var(--radio);
  background: var(--superficie);
  color: var(--acento);
  cursor: pointer;
}
.aprender .marcar:hover { background: var(--acento-suave); }
.aprender .marcar[aria-pressed="true"] {
  background: var(--ok);
  border-color: var(--ok);
  color: var(--acento-texto);
}
.aprender-nota { font-size: 0.8rem; color: var(--texto-tenue); }
@media print { .aprender { display: none !important; } }

/* --- Nivel de las explicaciones ----------------------------------------- */
.modo {
  display: none;              /* sin JavaScript cada ELI5 se abre solo */
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin: 0 0 1.2rem;
}
html.js .modo { display: flex; }
.modo[hidden] { display: none !important; }
.modo-titulo {
  flex: 1 0 100%;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
  font-weight: 700;
  margin-bottom: 0.1rem;
}
.modo button {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.22rem 0.6rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: 100px;
  background: var(--superficie);
  color: var(--texto-suave);
  cursor: pointer;
}
.modo button:hover { background: var(--acento-suave); color: var(--texto); }
.modo button[aria-pressed="true"] {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
  font-weight: 600;
}

/* --- Bloque ELI5 --------------------------------------------------------- */
details.eli5 {
  margin: 1.1rem 0 1.6rem;
  border: 1px dashed var(--borde-fuerte);
  border-radius: var(--radio);
  background: var(--superficie);
}
details.eli5 > summary {
  cursor: pointer;
  padding: 0.5rem 0.85rem;
  font-size: 0.88rem;
  color: var(--texto-suave);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
details.eli5 > summary::-webkit-details-marker { display: none; }
details.eli5 > summary::after {
  content: "▾";
  margin-left: auto;
  color: var(--texto-tenue);
  transition: transform 0.15s;
}
details.eli5[open] > summary::after { transform: rotate(180deg); }
details.eli5 > summary:hover { background: var(--acento-suave); color: var(--texto); }
details.eli5[open] > summary { border-bottom: 1px dashed var(--borde-fuerte); }
.eli5-tag {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.45rem;
  border-radius: 100px;
  background: var(--acento);
  color: var(--acento-texto);
}
.eli5-cuerpo {
  padding: 0.85rem;
  font-size: 1.02rem;
  line-height: 1.7;
}
.eli5-cuerpo > :last-child { margin-bottom: 0; }
.eli5-cuerpo ul { margin-bottom: 0.6rem; }
@media (prefers-reduced-motion: reduce) {
  details.eli5 > summary::after { transition: none; }
}
@media print {
  details.eli5 { break-inside: avoid; }
  details.eli5 > summary::after { display: none; }
}

/* --- Descargas de una practica ------------------------------------------ */
.descargas {
  margin: 1.6rem 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie-2);
}
.descargas h3 { margin: 0 0 0.5rem; font-size: 0.95rem; }
.descargas ul { list-style: none; margin: 0; padding: 0; }
.descargas li { margin-bottom: 0.35rem; font-size: 0.92rem; }
.descargas li b {
  display: inline-block;
  min-width: 5.6rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--texto-tenue);
}

/* --- La accion de cada paso de una animacion ---------------------------- */
/* El gesto que hace el alumno (una tecla, un click) va en una etiqueta
   aparte del texto: en el depurador el paso se entiende antes por el gesto
   que por la frase. */
.viz-accion {
  display: inline-block;
  margin-right: 0.5rem;
  padding: 0.05rem 0.45rem;
  border: 1px solid var(--acento);
  border-radius: 4px;
  background: var(--acento-suave);
  color: var(--acento);
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

/* --- Widget depurador ---------------------------------------------------- */
.dbg {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 0.8rem;
  align-items: start;
}
.dbg-editor, .dbg-panel {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  overflow: hidden;
}
/* Cabecera de panel: la comparten el depurador, el explorador y el join. */
.dbg-titulo,
.jn-titulo,
.gr-titulo {
  padding: 0.3rem 0.7rem;
  background: var(--superficie-2);
  border-bottom: 1px solid var(--borde);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}
.dbg-lineas {
  margin: 0;
  padding: 0.35rem 0;
  list-style: none;
  font-family: var(--mono);
  font-size: 0.82rem;
  line-height: 1.65;
  overflow-x: auto;
}
.dbg-linea {
  display: flex;
  align-items: baseline;
  gap: 0.1rem;
  padding: 0 0.6rem 0 0;
  border-left: 3px solid transparent;
  white-space: pre;
  transition: background-color 0.2s;
}
/* La canaleta: el espacio a la izquierda del numero donde se hace click para
   poner el breakpoint. Se dibuja siempre, aunque este vacia, porque el alumno
   tiene que reconocer *donde* clickear. */
.dbg-canaleta {
  flex: 0 0 1.1rem;
  height: 1.65em;
  position: relative;
}
.dbg-punto > .dbg-canaleta::before {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 0.52em;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--error);
}
.dbg-num {
  flex: 0 0 1.9rem;
  text-align: right;
  padding-right: 0.7rem;
  color: var(--texto-tenue);
  font-variant-numeric: tabular-nums;
  user-select: none;
}
.dbg-linea > code { font-family: inherit; font-size: inherit; background: none; padding: 0; }
.dbg-actual {
  background: var(--alerta-suave);
  border-left-color: var(--alerta);
}
/* La flecha de "aca esta parada la ejecucion", en el lugar donde la dibuja el
   IDE: en la canaleta, encima del breakpoint si lo hay. La canaleta ya es
   position:relative, asi que la flecha se ancla ahi y no en el viewport. */
.dbg-actual > .dbg-canaleta::after {
  content: "\27A4";
  position: absolute;
  left: 0.05rem;
  top: 0;
  line-height: 1.65em;
  font-size: 0.85em;
  color: var(--alerta);
}
.dbg-lado { display: grid; gap: 0.8rem; }
table.dbg-vars { width: 100%; font-size: 0.82rem; margin: 0; }
table.dbg-vars td {
  padding: 0.25rem 0.7rem;
  border-bottom: 1px solid var(--borde);
  vertical-align: top;
}
table.dbg-vars tr:last-child td { border-bottom: none; }
table.dbg-vars td.clave { font-family: var(--mono); color: var(--acento); white-space: nowrap; }
table.dbg-vars td.celda { font-family: var(--mono); word-break: break-word; }
table.dbg-vars td.dbg-tipo {
  color: var(--texto-tenue);
  font-size: 0.76rem;
  text-align: right;
  white-space: nowrap;
}
td.dbg-vacio, span.dbg-vacio {
  color: var(--texto-tenue);
  font-style: italic;
  font-size: 0.8rem;
}
pre.dbg-consola {
  margin: 0;
  padding: 0.5rem 0.7rem;
  min-height: 6.5rem;
  max-height: 14rem;
  overflow: auto;
  background: var(--salida-fondo);
  color: var(--salida-texto);
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.55;
  white-space: pre-wrap;
}
pre.dbg-consola .dbg-entrada { color: var(--tok-fn); font-weight: 600; }
@keyframes destello-linea {
  from { background-color: var(--acento-suave); }
  to   { background-color: transparent; }
}
.dbg-linea.destello:not(.dbg-actual) { animation: destello-linea 0.7s ease-out; }

/* --- Widget panel-datos -------------------------------------------------- */
.dex {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
.dex-barra {
  padding: 0.35rem 0.75rem;
  background: var(--superficie-2);
  border-bottom: 1px solid var(--borde);
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--texto-suave);
}
table.dex-tabla { width: 100%; margin: 0; font-size: 0.84rem; }
table.dex-tabla th.dex-col {
  background: var(--acento-suave);
  color: var(--acento);
}
table.dex-tabla td.dex-col { background: var(--acento-suave); }
table.dex-tabla td.dex-col.estado-sospechoso { background: var(--alerta-suave); }
table.dex-tabla td.dex-col.estado-nulo { background: var(--superficie-2); }
.dex-resumen { border-top: 1px solid var(--borde); }
@keyframes destello-fila {
  from { background-color: var(--acento-suave); }
  to   { background-color: transparent; }
}
table.dex-tabla tr.destello { animation: destello-fila 0.6s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .dbg-linea.destello, table.dex-tabla tr.destello { animation: none; }
}

/* En pantallas angostas el depurador se apila: primero el codigo, despues los
   paneles. Es el mismo orden en que se lee. */
@media (max-width: 780px) {
  .dbg { grid-template-columns: minmax(0, 1fr); }
}

/* --- Teclas ------------------------------------------------------------- */
/* Las lecciones de herramientas nombran atajos todo el tiempo: una tecla
   tiene que distinguirse de un nombre de funcion a primera vista. */
kbd {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--borde-fuerte);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--superficie-2);
  color: var(--texto);
  font-family: var(--mono);
  font-size: 0.82em;
  line-height: 1.5;
  white-space: nowrap;
}

/* --- Widget mascara ------------------------------------------------------ */
table.msk-tabla { width: 100%; margin: 0; font-size: 0.85rem; }
table.msk-tabla th.msk-col {
  background: var(--acento-suave);
  color: var(--acento);
  font-family: var(--mono);
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
}
table.msk-tabla th.msk-vacia { background: var(--superficie-2); color: var(--texto-tenue); }
td.msk-valor {
  font-family: var(--mono);
  font-weight: 650;
  text-align: center;
  border-left: 2px solid var(--borde-fuerte);
  min-width: 4.5rem;
}
td.msk-si { color: var(--ok); background: var(--ok-suave); }
td.msk-no { color: var(--texto-tenue); background: var(--superficie-2); }
/* La fila que no cumple no se borra: se apaga. Ver que sigue ahi es lo que
   explica que el filtro no busca, sino que selecciona. */
tr.msk-fuera > td { opacity: 0.4; text-decoration: line-through; }
tr.msk-fuera > td.msk-valor { text-decoration: none; }
.msk-cuenta {
  margin: 0.7rem 0 0;
  font-size: 0.85rem;
  color: var(--texto-suave);
}
td.msk-valor.destello { animation: destello-celda 0.7s ease-out; }
@media (prefers-reduced-motion: reduce) {
  td.msk-valor.destello { animation: none; }
}

/* --- Widget join --------------------------------------------------------- */
.jn-tablas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.9rem;
  align-items: start;
}
.jn-lado {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
table.jn-tabla { width: 100%; margin: 0; font-size: 0.82rem; }
table.jn-tabla th.jn-clave {
  background: var(--acento-suave);
  color: var(--acento);
}
table.jn-tabla td:first-child { font-weight: 650; }
.jn-resultado {
  margin-top: 0.9rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
.jn-cuenta {
  margin: 0.7rem 0 0;
  font-size: 0.85rem;
  color: var(--texto-suave);
}
@keyframes destello-fila-jn {
  from { background-color: var(--acento-suave); }
  to   { background-color: transparent; }
}
table.jn-tabla tr.destello { animation: destello-fila-jn 0.6s ease-out; }
@media (prefers-reduced-motion: reduce) {
  table.jn-tabla tr.destello { animation: none; }
}

/* --- Widget grupos ------------------------------------------------------- */
/* Cinco colores que se repiten. No codifican nada: solo separan grupos
   contiguos, y por eso son suaves y de luminosidad parecida. */
:root {
  --g0: #0f5d63; --g1: #a05a2c; --g2: #7a5195;
  --g3: #2f6d3c; --g4: #8a6d1f;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --g0: #5eb6bd; --g1: #d79a63; --g2: #b795d0;
    --g3: #7cc48f; --g4: #ceb066;
  }
}
:root[data-tema="oscuro"] {
  --g0: #5eb6bd; --g1: #d79a63; --g2: #b795d0;
  --g3: #7cc48f; --g4: #ceb066;
}
table.gr-tabla { width: 100%; margin: 0; font-size: 0.84rem; }
table.gr-tabla th.gr-clave { background: var(--acento-suave); color: var(--acento); }
td.gr-0 { border-left: 3px solid var(--g0); color: var(--g0); }
td.gr-1 { border-left: 3px solid var(--g1); color: var(--g1); }
td.gr-2 { border-left: 3px solid var(--g2); color: var(--g2); }
td.gr-3 { border-left: 3px solid var(--g3); color: var(--g3); }
td.gr-4 { border-left: 3px solid var(--g4); color: var(--g4); }
/* En la tabla de grupos, la barra de color va solo en la primera celda de la
   fila: el color ya lo lleva el texto de las demas. En reshape NO se aplica,
   porque ahi cada celda tiene su propio color y hay que verlos todos. */
table.gr-tabla td.gr-0 ~ td, table.gr-tabla td.gr-1 ~ td,
table.gr-tabla td.gr-2 ~ td, table.gr-tabla td.gr-3 ~ td,
table.gr-tabla td.gr-4 ~ td { border-left-color: transparent; }
.gr-resultado {
  margin-top: 0.9rem;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
.gr-cuenta { margin: 0.7rem 0 0; font-size: 0.85rem; color: var(--texto-suave); }
table.gr-tabla tr.destello { animation: destello-fila-jn 0.6s ease-out; }
@media (prefers-reduced-motion: reduce) {
  table.gr-tabla tr.destello { animation: none; }
}

/* --- Widget reshape ------------------------------------------------------ */
/* El mismo color en las dos tablas: asi se sigue una celda de ancho a largo. */
.rs-origen, .rs-resultado {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--superficie);
}
.rs-resultado { margin-top: 0.9rem; border-color: var(--borde-fuerte); }
table.rs-tabla { width: 100%; margin: 0; font-size: 0.84rem; }
.rs-cuenta { margin: 0.7rem 0 0; font-size: 0.85rem; color: var(--texto-suave); }
table.rs-tabla tr.destello { animation: destello-fila-jn 0.6s ease-out; }
@media (prefers-reduced-motion: reduce) {
  table.rs-tabla tr.destello { animation: none; }
}

/* --- Widget: vectorizacion ---------------------------------------------- */
.vec { border: 1px solid var(--borde); border-radius: var(--radio);
       overflow: hidden; background: var(--superficie); padding: 0.9rem; }
table.vec-tabla { width: 100%; margin: 0; font-size: 0.9rem;
                  table-layout: fixed; }
table.vec-tabla th.vec-etiqueta {
  width: 6.5rem; text-align: right; padding-right: 0.7rem;
  font-weight: 600; color: var(--texto-suave); background: transparent;
  border: 0; font-size: 0.8rem;
}
td.vec-celda {
  text-align: center; font-family: var(--mono); font-variant-numeric: tabular-nums;
  border: 1px solid var(--borde); background: var(--superficie-2);
  transition: background 0.15s ease, color 0.15s ease;
}
td.vec-celda.vec-hueco { color: transparent; background: transparent;
                         border-style: dashed; }
td.vec-celda.vec-actual {
  background: var(--acento-suave); color: var(--acento);
  border-color: var(--acento); font-weight: 600;
}
td.vec-celda.destello { animation: destello-celda 0.6s ease-out; }
.vec-contador { margin: 0.8rem 0 0; font-size: 0.85rem;
                color: var(--texto-suave); }
@media (prefers-reduced-motion: reduce) {
  td.vec-celda.destello { animation: none; }
  td.vec-celda { transition: none; }
}

/* --- Widget: broadcasting ------------------------------------------------ */
.brd { border: 1px solid var(--borde); border-radius: var(--radio);
       overflow: hidden; background: var(--superficie); padding: 0.9rem; }
.brd-titulo { font-family: var(--mono); font-size: 0.9rem;
              color: var(--texto-suave); margin-bottom: 0.7rem; }
table.brd-tabla { width: 100%; margin: 0; font-size: 0.85rem; }
td.brd-valor { font-family: var(--mono); text-align: center;
               font-variant-numeric: tabular-nums; }
td.brd-nota { color: var(--texto-suave); font-size: 0.82rem; }
tr.brd-igual > td { background: var(--superficie-2); }
tr.brd-estira > td { background: var(--ok-suave); color: var(--ok); }
tr.brd-falta > td { background: var(--acento-suave); }
tr.brd-choca > td { background: var(--error-suave); color: var(--error);
                    font-weight: 600; }
tr.brd-tabla-destello, table.brd-tabla tr.destello {
  animation: destello-fila-jn 0.6s ease-out;
}
.brd-resultado { margin: 0.8rem 0 0; font-size: 0.88rem;
                 font-family: var(--mono); color: var(--texto-suave); }
.brd-resultado.brd-falla { color: var(--error); }
@media (prefers-reduced-motion: reduce) {
  table.brd-tabla tr.destello { animation: none; }
}
