/* ── Tinta y papel ─────────────────────────────────────────────────────
   Los tokens llevan nombre de ROL y no de material, porque al invertir el
   tema el material cambia y el rol no: en oscuro el fondo es tinta, en claro
   es papel, pero en los dos sigue siendo "el fondo". Entre parentesis va el
   pigmento del concepto grafico.

   Dos decisiones que no son gusto sino accesibilidad:

   - acierto y fallo NO son verde y rojo. Simulados en deuteranopia, el verde
     #4fd463 y el rojo #ff6b6b daban dE 8.6 -- el mismo color para una de
     cada doce personas, y con ellos se pinta el veredicto de cada tecla.
     Jade y caqui suben el peor caso a 24.6. Aun asi el color NUNCA es la
     unica seÑal: el aceptado se subraya, el equivocado se tacha, y en el
     resumen el fallo es un aro y no un circulo.
   - --acento-texto existe aparte de --acento porque el relleno, usado como
     texto sobre el fondo, no llega al minimo de contraste.
   ------------------------------------------------------------------- */
:root {
  --fondo:         #1e1e2f;   /* (sumi) */
  --superficie:    #2a2a40;
  --separador:     #33334a;
  --borde:         #3a3a55;
  --borde-alto:    #4a4a70;
  --boton:         #3a3a55;
  --boton-alto:    #4a4a70;
  --boton-borde:   transparent;
  --texto:         #f0f0f5;   /* (washi) */
  --texto-claro:   #cfcfe0;
  --texto-tenue:   #a0a0b8;
  --punto:         #555568;   /* el punto aun sin ganar */
  --acento:        #4c4cff;   /* (ai) solo como relleno */
  --acento-foco:   #6a6aff;
  --acento-texto:  #8aa4ff;
  --acierto:       #4fd6a9;   /* (jade) */
  --fallo:         #ff8a5b;   /* (caqui) */
  --hito:          #e3b341;   /* (oro) subir de cubeta */
  --peligro:       #4a2323;
  --peligro-alto:  #5c2b2b;
  --mio:           #33335a;   /* la fila propia en el ranking */
  --sombra-qr:     #ffffff;   /* el QR necesita blanco de verdad */

  --letra: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* La paleta clara se declara UNA vez y se aplica en dos lugares: cuando el
   sistema la pide y nadie eligio lo contrario, y cuando alguien la eligio a
   mano. Declararla dos veces era la forma segura de que se desincronizaran. */
:root {
  --claro-fondo: #fbf8f3;
  --claro-superficie: #ffffff;
  --claro-separador: #ece5d8;
  --claro-borde: #e4ddd0;
  --claro-borde-alto: #d5cbb8;
  --claro-boton: #ffffff;
  --claro-boton-alto: #f2ece1;
  --claro-boton-borde: #d9d0be;
  --claro-texto: #1b2029;
  --claro-texto-claro: #3c4453;
  --claro-texto-tenue: #5b6474;
  --claro-punto: #ded6c8;
  --claro-acento: #3b4fc4;
  --claro-acento-foco: #3b4fc4;
  --claro-acento-texto: #3b4fc4;
  --claro-acierto: #0b7a5e;
  --claro-fallo: #c2410c;
  /* Medido: el oro de antes daba 3.96 contra el fondo claro y el hito del
     dojo se leia a medias. Este da 5.21 sin dejar de ser oro. */
  --claro-hito: #8f5f07;
  --claro-peligro: #f6dcd6;
  --claro-peligro-alto: #eec7bd;
  --claro-mio: #e6e9fb;
}

/* Sin eleccion explicita manda el sistema. El navegador reporta "light"
   tambien cuando no hay preferencia, asi que quien nunca eligio nada ve
   papel -- que es lo correcto de dia y en un salon. */
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) {
    --fondo: var(--claro-fondo);
    --superficie: var(--claro-superficie);
    --separador: var(--claro-separador);
    --borde: var(--claro-borde);
    --borde-alto: var(--claro-borde-alto);
    --boton: var(--claro-boton);
    --boton-alto: var(--claro-boton-alto);
    --boton-borde: var(--claro-boton-borde);
    --texto: var(--claro-texto);
    --texto-claro: var(--claro-texto-claro);
    --texto-tenue: var(--claro-texto-tenue);
    --punto: var(--claro-punto);
    --acento: var(--claro-acento);
    --acento-foco: var(--claro-acento-foco);
    --acento-texto: var(--claro-acento-texto);
    --acierto: var(--claro-acierto);
    --fallo: var(--claro-fallo);
    --hito: var(--claro-hito);
    --peligro: var(--claro-peligro);
    --peligro-alto: var(--claro-peligro-alto);
    --mio: var(--claro-mio);
  }
}

/* Y la eleccion a mano gana en los dos sentidos. */
:root[data-tema="claro"] {
    --fondo: var(--claro-fondo);
    --superficie: var(--claro-superficie);
    --separador: var(--claro-separador);
    --borde: var(--claro-borde);
    --borde-alto: var(--claro-borde-alto);
    --boton: var(--claro-boton);
    --boton-alto: var(--claro-boton-alto);
    --boton-borde: var(--claro-boton-borde);
    --texto: var(--claro-texto);
    --texto-claro: var(--claro-texto-claro);
    --texto-tenue: var(--claro-texto-tenue);
    --punto: var(--claro-punto);
    --acento: var(--claro-acento);
    --acento-foco: var(--claro-acento-foco);
    --acento-texto: var(--claro-acento-texto);
    --acierto: var(--claro-acierto);
    --fallo: var(--claro-fallo);
    --hito: var(--claro-hito);
    --peligro: var(--claro-peligro);
    --peligro-alto: var(--claro-peligro-alto);
    --mio: var(--claro-mio);
}


/* Atkinson Hyperlegible, del Braille Institute: la eligio la forma de sus
   digitos. Aqui todo lo que se teclea son numeros y un digito de mas cuenta
   como fallo, asi que el 1 no puede parecerse al 7 ni el 0 a la O. */
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: local("Atkinson Hyperlegible"), url("atkinson-regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: local("Atkinson Hyperlegible Bold"), url("atkinson-bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

/* Sin esto, dos taps rápidos en móvil (ej. "1" "1" para el 11) los toma el
   navegador como doble-tap-para-zoom en vez de dos toques al botón. */
button {
  touch-action: manipulation;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 24px;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--letra);
  /* 18px de piso: el dojo lo usan ninios de siete anios y adultos de setenta,
     y 14px "para que quepa" deja fuera a los segundos. */
  font-size: 18px;
  line-height: 1.5;
}

h1 {
  font-size: 1.4rem;
  margin: 0;
}

.hidden {
  display: none !important;
}

.screen {
  width: min(440px, 95vw);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.hint {
  color: var(--texto-tenue);
  margin: 4px 0;
  text-align: center;
}

.hint.small {
  font-size: 0.8rem;
  margin: 0;
}

/* El reloj de la sala de espera: la carátula queda fija -las marcas de las
   12/3/6/9 dan la referencia- y solo giran las manecillas, rápido y sin
   parar, como un cronómetro corriendo. Distinto a proposito del reloj de
   "se acabó el tiempo" (chico, quieto, color de fallo): este es grande, del
   acento, y su único mensaje es "esto sigue corriendo", no un veredicto. */
.espera-ilustracion {
  color: var(--acento-texto);
  margin: 4px 0;
}

.espera-ilustracion svg {
  width: 110px;
  height: 110px;
}

.espera-manecillas {
  transform-origin: 50px 50px;
  animation: espera-gira 1.8s linear infinite;
}

@keyframes espera-gira {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* El aviso de medición. Abajo y discreto: se dice, no se pide permiso, y
   no puede tapar el botón que la persona vino a tocar. */
.aviso-medicion {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  background: var(--superficie);
  border-top: 1px solid var(--borde);
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  font-size: 0.82rem;
  color: var(--texto-tenue);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.aviso-medicion p { margin: 0; max-width: 46ch; }

.aviso-botones { display: flex; gap: 8px; }

.aviso-medicion button {
  background: var(--boton);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: 7px 14px;
  font-size: 0.82rem;
  font-family: inherit;
  cursor: pointer;
}

.aviso-medicion button:hover { background: var(--boton-alto); }

/* Durante la tanda estorba: todo tiene que caber sin scroll. */
body[data-jugando="si"] .aviso-medicion { display: none; }

/* La curva de velocidad: el dato que hace volver al día siguiente. */
.velocidad {
  text-align: center;
  margin: 10px 0 4px;
  font-size: 0.95rem;
  color: var(--texto);
}

/* El color acompaña, pero el texto ya lo dice: nadie depende de verlo. */
.velocidad[data-tendencia="mejor"] { color: var(--acierto); }
.velocidad[data-tendencia="primera"] { color: var(--hito); }

.mode-btn {
  background: var(--boton);
  border: 1px solid var(--boton-borde);
  color: var(--texto);
  border-radius: 8px;
  padding: 10px 18px;
  font-size: 1rem;
  cursor: pointer;
  width: 100%;
  /* .mode-btn viste tambien enlaces, y un <a> no centra su texto solo. */
  text-align: center;
  text-decoration: none;
  display: block;
}

.mode-btn:hover {
  background: var(--boton-alto);
}

.mode-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Un camino secundario, no una segunda puerta: mismo tamaño de toque, mucho
   menos peso visual. El mapa y "cambiar de persona" viven aquí ahora. */
.mode-btn.secundario {
  background: none;
  border-color: transparent;
  color: var(--texto-tenue);
  font-size: 0.9rem;
}

.mode-btn.secundario:hover {
  background: none;
  text-decoration: underline;
}

/* El home: cuatro tarjetas grandes en vez de botones en fila, cada una con
   su propio ícono -- se leen de un vistazo, sin tener que leer el texto de
   las cuatro para saber cuál toca. */
.home-acciones {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-top: 14px;
}

.home-tarjeta {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  aspect-ratio: 1;
  padding: 16px 10px;
  border-radius: 20px;
  background: var(--boton);
  border: 1px solid var(--boton-borde);
  color: var(--texto);
  font-size: 0.95rem;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  /* .home-tarjeta viste tambien enlaces (dojo.html), y un <a> no llega
     neutro por su cuenta. */
  text-decoration: none;
}

.home-tarjeta:hover {
  background: var(--boton-alto);
}

.home-tarjeta-icono {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
}

/* Seleccionado va con texto blanco y no con el de siempre: en claro el
   acento es azul oscuro y --texto es casi negro, o sea oscuro sobre oscuro.
   Y el fondo se repite en :hover porque `.mode-btn:hover` tiene la misma
   especificidad y va antes, asi que si no, gana el gris. */
.mode-btn.is-selected,
.mode-btn.is-selected:hover {
  background: var(--acento);
  border-color: var(--acento);
  color: #ffffff;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  justify-content: center;
}

.chip {
  background: var(--boton);
  border: 1px solid var(--boton-borde);
  color: var(--texto);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 0.9rem;
  cursor: pointer;
}

.chip:hover {
  background: var(--boton-alto);
}

.chip:disabled {
  opacity: 0.6;
  cursor: default;
}

.chip.is-selected,
.chip.is-selected:hover {
  background: var(--acento);
  border-color: var(--acento);
  color: #ffffff;
}

.toggle-row {
  display: flex;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  border: 2px solid var(--borde);
}

.toggle-btn {
  flex: 1;
  background: transparent;
  color: var(--texto-tenue);
  border: none;
  padding: 8px 0;
  font-size: 0.95rem;
  cursor: pointer;
}

.toggle-btn.is-selected {
  background: var(--boton);
  border: 1px solid var(--boton-borde);
  color: var(--texto);
}

.operand-config {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--superficie);
  border-radius: 8px;
  padding: 10px;
}

.operand-config .toggle-row {
  border-color: var(--borde-alto);
}

.operand-config input[type="number"] {
  width: 100%;
  font-size: 1.1rem;
  text-align: center;
  padding: 8px;
  border-radius: 8px;
  border: 2px solid var(--borde);
  background: var(--fondo);
  color: var(--texto);
}

.table-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  width: 100%;
}

.table-grid .mode-btn {
  padding: 10px 4px;
  font-size: 0.95rem;
}

input[type="text"] {
  width: 100%;
  font-size: 1.1rem;
  text-align: center;
  padding: 10px;
  border-radius: 8px;
  border: 2px solid var(--borde);
  background: var(--superficie);
  color: var(--texto);
}

input[type="text"]:focus {
  outline: none;
  border-color: var(--acento-foco);
}

.room-code {
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: 0.15em;
  color: var(--acento-texto);
}

.qr-image {
  width: 220px;
  height: 220px;
  border-radius: 12px;
  background: var(--sombra-qr;)
  padding: 10px;
}

#progress {
  color: var(--texto-claro);
  font-variant-numeric: tabular-nums;
}

/* La colocación no tiene un total fijo de problemas: mostrar 1/10 ahí sería
   inventar un número que no existe. */
body[data-colocando="si"] #progress-conteo {
  display: none;
}

/* Las cintas recién ganadas, una fila por cinta. */
.cinta-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: center;
  padding: 6px 0;
  font-weight: 700;
}

.cinta-fila .insignia-cinta {
  width: 16px;
  height: 16px;
}

/* El mapa completo: la ganada se rellena, la pendiente queda como aro (ver
   dot-bad más abajo) y su texto se apaga -- la forma dice lo mismo que el
   color, no solo el color. */
.cinta-fila.cinta-pendiente {
  font-weight: 400;
  color: var(--texto-tenue);
}

/* El mapa horizontal del home: siete medallas en fila, unidas por una
   línea, con la más avanzada ya ganada marcada por "estás aquí" debajo.
   El indicador vive DENTRO de la celda de su medalla (position:absolute,
   fuera del flujo) -- no en una fila de grid aparte. Antes sí lo estaba, y
   el texto "Estás aquí" (más ancho que 1/7 del mapa en un teléfono)
   estiraba esa columna sin estirar la de las medallas: dos grids que
   debían medir igual y no medían igual, y la flecha apuntaba entre dos
   cintas en vez de a una. */
.mapa-cintas {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  align-items: center;
  margin: 14px 0 40px;
}

.paso-cinta {
  position: relative;
  display: flex;
  justify-content: center;
}

.paso-cinta:not(:first-child)::before {
  content: "";
  position: absolute;
  top: 15px;
  right: 50%;
  width: 100%;
  height: 2px;
  background: var(--separador);
  z-index: 0;
}

.paso-cinta .insignia-cinta {
  position: relative;
  z-index: 1;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.aqui-marca {
  position: absolute;
  z-index: 2;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--acento-texto);
  line-height: 1.15;
  white-space: nowrap;
}

.aqui-flecha {
  font-size: 0.75rem;
}

/* Lo que significa cada cinta, al tocarla -- un botón real reemplaza al
   title de siempre porque en un teléfono no hay hover que lo revele. */
.cinta-tooltip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 4px 0 12px;
  text-align: center;
}

.cinta-tooltip strong {
  font-size: 0.95rem;
}

.cinta-tooltip-estado {
  font-size: 0.75rem;
  color: var(--texto-tenue);
  font-weight: 700;
}

#timer-bar-wrap {
  width: 100%;
  height: 6px;
  background: var(--separador);
  border-radius: 3px;
  overflow: hidden;
}

#timer-bar {
  height: 100%;
  width: 100%;
  background: var(--acento);
}

#word-display {
  font-size: clamp(2.4rem, 12vw, 4rem);
  font-weight: 700;
  min-height: 2.6em;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

#respuesta-fila {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

#capture-display {
  flex: 1;
  min-width: 0;
  min-height: 3.2em;
  font-size: clamp(2rem, 10vw, 3.2rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 10px;
  border-radius: 8px;
  border: 2px solid var(--borde);
  background: var(--superficie);
  outline: none;
  font-variant-numeric: tabular-nums;
}

/* El color NUNCA es la unica seÑal: quien no distingue jade de caqui lee el
   veredicto igual, por el subrayado y la tacha. */
#capture-display .digit.ok {
  color: var(--acierto);
  border-bottom: 3px solid var(--acierto);
}

#capture-display .digit.bad {
  color: var(--fallo);
  text-decoration: line-through;
  text-decoration-thickness: 3px;
}

/* La caja tiembla en el fallo -- el color no es la única señal, tampoco
   aquí, y quien no distingue jade de caqui igual siente que algo se
   resistió. */
@keyframes temblor-caja {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

.capture-shake {
  animation: temblor-caja 0.4s ease-in-out;
}

/* El dojo no colorea tecla por tecla: el veredicto es un check o una cruz
   al final del problema, FUERA de la caja de respuesta -- no antes, y no
   adentro. Va al lado, no debajo: agregar una fila nueva empujaba el
   teclado hacia abajo y en una pantalla corta el último botón dejaba de
   verse. */
.veredicto-icono {
  min-width: 28px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* El mismo ancho que el ícono, pero invisible y del otro lado: sin esto la
   caja se recortaba solo por la derecha y quedaba descentrada. */
.veredicto-espaciador {
  min-width: 28px;
  flex-shrink: 0;
}

.veredicto-icono.acierto {
  color: var(--acierto);
}

.veredicto-icono.fallo {
  color: var(--fallo);
}

#feedback-display {
  min-height: 1.5em;
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--fallo);
}

#keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  width: 100%;
}

.key-btn {
  background: var(--boton);
  border: 1px solid var(--boton-borde);
  color: var(--texto);
  border-radius: 8px;
  /* 56px de alto: es el minimo que se acierta sin mirar, con dedo de ninio
     o con mano que tiembla. */
  min-height: 56px;
  padding: 14px 0;
  font-size: 1.4rem;
  font-weight: 600;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.key-btn:hover {
  background: var(--boton-alto);
}

.key-btn.key-zero {
  grid-column: span 2;
}

/* El dojo no tiene tecla de signo: el cero se queda con la fila entera. */
.key-btn.key-zero-wide {
  grid-column: span 3;
}

.countdown-number {
  font-size: 5rem;
  font-weight: 800;
  color: var(--acento-texto);
}

ul.participant-list {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

ul.participant-list li {
  background: var(--superficie);
  border-radius: 6px;
  padding: 8px 12px;
}

/* Mismo trato que "Salir de la cuenta" en la casa: un enlace apagado, no
   un botón -- terminar la sesión no compite con elegir a alguien. */
.salir {
  background: none;
  border: none;
  color: var(--texto-tenue);
  font-size: 0.92rem;
  text-decoration: underline;
  cursor: pointer;
  padding: 8px 0;
  font-family: inherit;
  width: 100%;
}

.dots-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

.dots-row.centered {
  justify-content: center;
  gap: 6px;
}

.dots-row.centered .dot {
  width: 18px;
  height: 18px;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--punto);
  flex-shrink: 0;
}

.dot.dot-ok {
  background: var(--acierto);
}

/* Aro y no relleno: la forma dice lo mismo que el color. */
.dot.dot-bad {
  background: transparent;
  box-shadow: inset 0 0 0 3px var(--fallo);
}

.danger-btn {
  background: var(--peligro);
}

.danger-btn:hover {
  background: var(--peligro-alto);
}

/* Top 5 en vivo, estilo "bar chart race": cada fila es un elemento persistente
   que se reposiciona con transform (no se recrea), así el cambio de orden se
   ve como una animación de rebase en vez de un parpadeo. */
#live-leaderboard {
  position: relative;
  width: 100%;
  height: 220px;
  margin-bottom: 4px;
}

.leaderboard-row {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 36px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: transform 0.5s ease;
}

.leaderboard-position {
  width: 1.2em;
  flex-shrink: 0;
  font-weight: 800;
  color: var(--acento-texto);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.leaderboard-name {
  width: 64px;
  flex-shrink: 0;
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leaderboard-row .dots-row,
.ranking-row .dots-row {
  flex: 1;
  flex-wrap: nowrap;
  margin-top: 0;
  justify-content: flex-start;
}

.ranking-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--separador);
}

.ranking-stats {
  flex-shrink: 0;
  font-size: 0.8rem;
  color: var(--texto-claro);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

table.ranking {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

table.ranking td, table.ranking th {
  padding: 8px;
  border-bottom: 1px solid var(--separador);
  text-align: left;
}

table.ranking tr.is-me {
  background: var(--mio);
}

table.ranking td.position {
  font-weight: 800;
  color: var(--acento-texto);
  width: 2em;
}

#screen-ranking,
#screen-practice-result {
  position: relative;
  overflow: hidden;
}

#confetti,
#practice-confetti {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.confetti-piece {
  position: absolute;
  top: -20px;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  animation-name: confettiFall;
  animation-timing-function: ease-in;
  animation-fill-mode: forwards;
}

@keyframes confettiFall {
  0% { transform: translateY(-20px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(420px) rotate(360deg); opacity: 0; }
}

/* --- dojo --- */

.pickable {
  cursor: pointer;
}

.pickable:hover {
  background: var(--borde);
}

ul.participant-list li.pickable {
  padding: 12px;
  border-radius: 8px;
}

/* Fila de tema. NO reusa .leaderboard-row: esa es absoluta porque anima el
   rebase del top 5 en el concurso, y aquí solo hay una lista que fluye. */
.topic-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 6px;
  border-radius: 8px;
  background: var(--superficie);
}

.topic-row .topic-name {
  flex: 0 0 40%;
  text-align: left;
  font-weight: 600;
}

.topic-row .dots-row {
  flex: 1;
  flex-wrap: nowrap;
  margin-top: 0;
  justify-content: flex-start;
  gap: 3px;
}

.topic-row .dots-row .dot {
  width: 10px;
  height: 10px;
}

.topic-row .topic-count {
  flex: 0 0 3.5em;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--texto-tenue);
}

#topic-list {
  width: 100%;
}

.topic-row .topic-actions {
  flex: 0 0 auto;
  display: flex;
  gap: 4px;
}

/* Discretas a propósito: las dos tiran progreso, y la fila es para practicar. */
.topic-action {
  background: none;
  border: none;
  color: var(--texto-tenue);
  font-size: 1.1rem;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 6px;
  cursor: pointer;
}

.topic-action:hover {
  background: var(--borde);
  color: var(--texto);
}

#ask-topic {
  display: flex;
  gap: 8px;
  width: 100%;
  align-items: center;
}

#ask-topic select,
#ask-topic input {
  flex: 1;
  background: var(--superficie);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: 10px;
  font-size: 1rem;
}

#ask-topic .mode-btn {
  flex: 0 0 auto;
  width: auto;
  margin: 0;
}

/* Subir de cubeta es el hito del dojo: es lo unico que se lleva el oro. */
#promoted .hint {
  color: var(--hito);
  font-weight: 700;
}

/* Foco visible en TODO lo que se pueda tabular. Sin esto, quien navega con
   teclado -- o con un switch -- no sabe donde esta parado. */
button:focus-visible,
input:focus-visible,
select:focus-visible,
li.pickable:focus-visible,
.topic-row:focus-visible {
  outline: 3px solid var(--acento-foco);
  outline-offset: 2px;
}

/* El confeti y las transiciones se apagan solos para quien lo pidio. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  #confetti, .confetti-piece { display: none; }
}

/* Discreto y siempre en el mismo lugar: no compite con el problema, pero se
   encuentra sin buscarlo. 44px es el minimo que se acierta con el pulgar. */
#btn-tema {
  position: fixed;
  top: 10px;
  right: 10px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--boton-borde);
  background: var(--boton);
  color: var(--texto-tenue);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  z-index: 10;
}

#btn-tema:hover {
  background: var(--boton-alto);
  color: var(--texto);
}

/* ── Que la tanda quepa entera ────────────────────────────────────────────
   Una tecla que hay que ir a buscar con scroll ya costo el problema, y el
   cero es la que caia fuera: a 375x640 quedaba 40px abajo del borde.

   La causa era que los altos estaban en em, asi que crecian con la letra y
   ninguna pieza cedia. Se invierte: el teclado NUNCA se encoge y lo que cede
   es el aire alrededor del problema. Los tamanios de letra se limitan por el
   ALTO disponible (vh) y no por el ancho, que es de donde venia el aprieto.
   ------------------------------------------------------------------- */
body[data-jugando="si"] .screen {
  flex: 1 1 auto;
  min-height: 0;
  /* El teclado al fondo: ahi llega el pulgar sin recorrer el telefono. */
  justify-content: space-between;
  gap: 8px;
}

body[data-jugando="si"] #word-display {
  min-height: 0;
  flex: 0 1 auto;
  font-size: clamp(2rem, 9vh, 4rem);
}

body[data-jugando="si"] #capture-display {
  /* En em y no en px: reserva el alto de una linea de SU propia letra. Sin
     esto la caja vacia colapsa y el teclado da un salto con la primera
     tecla -- justo cuando se esta mirando el problema. */
  min-height: 1.5em;
  padding: 8px 10px;
  font-size: clamp(1.6rem, 7vh, 3.2rem);
}

/* Lo ultimo que se sacrifica. */
body[data-jugando="si"] #keypad {
  flex: 0 0 auto;
}

/* En pantallas cortas se van primero los adornos, no los botones. */
@media (max-height: 700px) {
  body[data-jugando="si"] {
    padding: 8px;
    gap: 8px;
  }
  body[data-jugando="si"] h1 {
    display: none;
  }
  body[data-jugando="si"] #phase-hint {
    display: none;
  }
  body[data-jugando="si"] .key-btn {
    padding: 8px 0;
  }
  /* El renglon del resultado correcto reserva menos: sigue cabiendo un
     numero de dos cifras, que es lo mas largo que muestra. */
  body[data-jugando="si"] #feedback-display {
    min-height: 1.2em;
    font-size: 1rem;
  }
  body[data-jugando="si"] .screen {
    gap: 6px;
  }
}

/* Apaisado, o una ventana muy achatada: 4 filas de 56px son 248 de 438 y ya
   no cabe nada mas. La tecla baja a 44px, que sigue siendo el minimo con el
   que se acierta sin mirar, antes que dejar el cero fuera de la pantalla. */
@media (max-height: 520px) {
  body[data-jugando="si"] .key-btn {
    min-height: 44px;
    padding: 4px 0;
    font-size: 1.2rem;
  }
  body[data-jugando="si"] #keypad {
    gap: 6px;
  }
  body[data-jugando="si"] #word-display {
    font-size: clamp(1.6rem, 7vh, 2.6rem);
  }
  body[data-jugando="si"] #capture-display {
    font-size: clamp(1.4rem, 6vh, 2.2rem);
  }
  body[data-jugando="si"] .screen {
    gap: 4px;
  }
  body[data-jugando="si"] #feedback-display {
    min-height: 1em;
    font-size: 0.95rem;
  }
}

/* La hoja de estudio: lo que viste, con su respuesta. Sobria a proposito --
   es material de consulta, no un marcador. */
.hoja {
  width: 100%;
  display: grid;
  gap: 2px;
  margin-top: 6px;
}

.hoja-fila {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 8px 12px;
  border-radius: 6px;
  background: var(--superficie);
  font-variant-numeric: tabular-nums;
}

.hoja-fila b {
  color: var(--acierto);
  font-size: 1.1rem;
}

/* Lo fallado se marca por el filo, no por el color del numero: la respuesta
   correcta sigue siendo correcta aunque la hayas fallado. */
.hoja-fila.fallado {
  border-left: 3px solid var(--fallo);
}
