/* menu.css - la portada de la plataforma.
 *
 * Tiene un trabajo y solo uno: decir qué hay y llevar a ello, en los cinco
 * segundos que dura alguien de pie delante de una mesa de feria. Por eso no
 * carga three.js, ni lienzos, ni fuentes de fuera: todo es CSS y aparece de
 * golpe.
 *
 * Los colores de cada juego NO están aquí. Vienen de `juegos.json`, como un
 * `--marca` en línea, por la misma razón que la lista de juegos: dar de alta
 * uno tiene que ser una línea de JSON y salir completo en todas partes.
 *
 * Lo que sí está aquí es la diferencia entre **listo** y **en camino**, que es
 * la información más importante de la página: no todos se pueden jugar hoy, y
 * una portada que lo disimule miente a quien se acerca.
 */

:root {
  --aprendizaje: #5ad1c8;
  --escaparate: #d9a75c;
  --gutter: clamp(18px, 4vw, 44px);
}

* { box-sizing: border-box; }

/* base.css fija `html, body { height: 100%; overflow: hidden }`, que es lo
   correcto para un juego a pantalla completa —allí nada debe desplazarse— y
   justo lo contrario de lo que necesita una portada. Se deshace aquí, y no se
   toca base.css: el kiosco depende de ese comportamiento.

   Sin esto la página se ve entera a simple vista, porque `.portada` desborda,
   pero no se puede bajar y `documentElement.scrollHeight` se queda en el alto
   de la ventana. */
html, body {
  height: auto;
  min-height: 100%;
  overflow: visible;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

/* ================================================================ fondo == */

/* Los halos se salen por los lados y hay que recortarlos. Se recortan AQUÍ y
   no con un `overflow-x` en el body: el overflow del body se propaga al
   viewport, y entonces `documentElement.scrollHeight` se queda en el alto de
   la ventana. La página sigue funcionando, pero cualquier cosa que mida el
   alto —una captura completa, un «ir al final»— la ve cortada por la mitad. */
.fondo {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.halo {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
}

.halo-a {
  top: -24vh; left: -14vw;
  width: 64vw; height: 64vw;
  background: radial-gradient(circle, color-mix(in srgb, var(--aprendizaje) 32%, transparent), transparent 66%);
}

.halo-b {
  top: 6vh; right: -20vw;
  width: 54vw; height: 54vw;
  background: radial-gradient(circle, color-mix(in srgb, var(--escaparate) 24%, transparent), transparent 66%);
}

/* La retícula: la mesa. Muy tenue, y se desvanece hacia abajo para que no
   compita con el texto. */
.retic {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(color-mix(in srgb, var(--ink) 4%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--ink) 4%, transparent) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: linear-gradient(180deg, #000 0%, transparent 72%);
}

.portada {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(26px, 6vh, 60px) var(--gutter) 64px;
}

/* ================================================================= hero == */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
  align-items: center;
  gap: clamp(20px, 5vw, 56px);
  padding-bottom: clamp(10px, 3vh, 26px);
}

.kicker {
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--aprendizaje);
}

.hero h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(42px, 8vw, 82px);
  line-height: .96;
  letter-spacing: -.035em;
  font-weight: 700;
}

.hero h1 em {
  font-style: normal;
  background: linear-gradient(94deg, var(--aprendizaje), var(--escaparate));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lead {
  margin: 20px 0 0;
  max-width: 44ch;
  font-size: clamp(15px, 1.5vw, 18px);
  line-height: 1.62;
  color: var(--ink-2);
}

/* --------------------------------------------------- estado del lector -- */

.enlace {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 26px 0 0;
  padding: 8px 15px 8px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in srgb, var(--panel) 78%, transparent);
  backdrop-filter: blur(8px);
  font-size: 13px;
  color: var(--ink-2);
}

.enlace .punto {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ink-3);
  flex: none;
}

.enlace[data-estado="ok"] .punto { background: var(--ok); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 20%, transparent); }
.enlace[data-estado="no"] .punto { background: var(--warn); }
.enlace[data-estado="buscando"] .punto { animation: latido 1.5s ease-in-out infinite; }

@keyframes latido { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

/* ------------------------------------------ la tarjeta sobre el lector -- */

.hero-art {
  display: grid;
  place-items: center;
  min-height: 290px;
}

.lector {
  position: relative;
  width: 270px;
  height: 270px;
  display: grid;
  place-items: center;
}

/* La base: el lector visto en perspectiva. */
.lector .base {
  position: absolute;
  bottom: 48px;
  width: 190px;
  height: 190px;
  border-radius: 26px;
  background:
    radial-gradient(60% 60% at 50% 45%, color-mix(in srgb, var(--aprendizaje) 14%, transparent), transparent 70%),
    linear-gradient(150deg, var(--raised), var(--panel));
  border: 1px solid var(--line-2);
  transform: rotateX(62deg) rotateZ(45deg);
  box-shadow: 0 30px 60px rgba(0, 0, 0, .55);
}

/* Las ondas: el campo de 13,56 MHz. Tres, desfasadas, para que se lea como
   una emisión continua y no como un parpadeo. */
.lector .onda {
  position: absolute;
  bottom: 48px;
  width: 190px;
  height: 190px;
  border-radius: 26px;
  border: 1px solid var(--aprendizaje);
  transform: rotateX(62deg) rotateZ(45deg);
  animation: onda 3s ease-out infinite;
  opacity: 0;
}

.lector .o2 { animation-delay: 1s; }
.lector .o3 { animation-delay: 2s; }

@keyframes onda {
  0%   { opacity: .7; transform: rotateX(62deg) rotateZ(45deg) scale(.62); }
  100% { opacity: 0;  transform: rotateX(62deg) rotateZ(45deg) scale(1.5); }
}

/* La tarjeta: baja, se posa, y vuelve a subir. */
.lector .tarjeta {
  position: relative;
  width: 148px;
  height: 94px;
  border-radius: 11px;
  background: linear-gradient(140deg, #f4f1ea, #cfc8ba);
  box-shadow: 0 16px 34px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .7);
  transform: rotateX(58deg) rotateZ(45deg);
  animation: posar 3s ease-in-out infinite;
}

@keyframes posar {
  0%, 100% { transform: rotateX(58deg) rotateZ(45deg) translate3d(0, -46px, 0); }
  42%, 62% { transform: rotateX(58deg) rotateZ(45deg) translate3d(0, -6px, 0); }
}

.lector .chip {
  position: absolute;
  top: 18px; left: 18px;
  width: 26px; height: 20px;
  border-radius: 4px;
  background: linear-gradient(135deg, #cba14e, #8d6a28);
}

.lector .linea {
  position: absolute;
  left: 18px;
  height: 5px;
  border-radius: 3px;
  background: rgba(40, 36, 30, .3);
}

.lector .l1 { bottom: 30px; width: 84px; }
.lector .l2 { bottom: 18px; width: 52px; }

/* =============================================================== pasos == */

/* Tres frases que explican el aparato entero. Ocupan poco y ahorran el párrafo
   que nadie lee de pie. */
.pasos {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1px;
  margin: clamp(26px, 5vh, 48px) 0 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--line);
}

.paso {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  padding: 20px;
  background: color-mix(in srgb, var(--panel) 86%, transparent);
}

.paso .n {
  flex: none;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--aprendizaje) 40%, transparent);
  color: var(--aprendizaje);
  font-size: 12px;
  font-weight: 600;
}

.paso b { display: block; font-size: 14.5px; margin-bottom: 3px; }
.paso span { font-size: 13px; line-height: 1.55; color: var(--ink-3); }

/* ============================================================ familias == */

.familias { margin-top: clamp(34px, 7vh, 62px); }

.familia { margin-bottom: clamp(34px, 6vh, 56px); }

.familia-cab {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
}

.familia-cab h2 {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--marca);
  white-space: nowrap;
}

.familia-cab h2::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 2px;
  background: var(--marca);
  box-shadow: 0 0 12px var(--marca);
}

.familia-cab .lema {
  font-size: 14px;
  color: var(--ink-3);
  white-space: nowrap;
}

.familia-cab .raya {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--marca) 40%, transparent), transparent);
}

.rejilla {
  /* `auto-fill`, no `auto-fit`: con una sola tarjeta —Matescanner hoy—,
     `auto-fit` colapsa las pistas vacías y la estira a todo lo ancho, con lo
     que un juego solitario parece destacado en vez de solitario. */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 18px;
}

/* ============================================================= tarjeta == */

.juego {
  --marca: var(--accent);
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(158deg, var(--panel-2), var(--panel) 62%);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
}

/* ---- la escena: el trozo de «imagen» de cada tarjeta ------------------ */

/* Dibujada, no fotografiada. Una captura de pantalla envejece en cuanto el
   juego cambia y hay que acordarse de rehacerla; esto sale del color y del
   icono que ya están en el registro, así que un juego nuevo trae la suya sin
   que nadie prepare nada.

   El icono empezó siendo una marca de agua enorme detrás del texto, y en las
   dos posiciones que probé se cruzaba con algo: abajo con el botón de Jugar,
   arriba con la frase. Un fondo decorativo que hay que leer por encima no es
   un fondo, es ruido. Con una banda propia no pisa nada y se ve entero. */
.juego .escena {
  position: relative;
  height: 132px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 120%, color-mix(in srgb, var(--marca) 30%, transparent), transparent 62%),
    linear-gradient(180deg, color-mix(in srgb, var(--marca) 7%, transparent), transparent);
  border-bottom: 1px solid var(--line);
}

/* Dos arcos concéntricos: el campo del lector otra vez, muy tenue. Repiten el
   gesto del hero y atan la página. */
.juego .escena::before,
.juego .escena::after {
  content: '';
  position: absolute;
  bottom: -78px;
  left: 50%;
  translate: -50% 0;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--marca) 24%, transparent);
}

.juego .escena::before { width: 190px; height: 190px; }
.juego .escena::after  { width: 290px; height: 290px; opacity: .5; }

.juego .motivo {
  position: relative;
  width: 56px;
  height: 56px;
  color: var(--marca);
  filter: drop-shadow(0 8px 20px color-mix(in srgb, var(--marca) 45%, transparent));
  transition: transform .35s cubic-bezier(.2, .8, .2, 1);
}

/* ---- el cuerpo -------------------------------------------------------- */

.juego .cuerpo {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 20px 22px 22px;
}

.juego h3 {
  margin: 0;
  font-size: 21px;
  letter-spacing: -.015em;
}

.juego .frase {
  margin: 9px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-2);
}

.juego .pie-tarjeta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 20px;
}

.etiqueta {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-3);
}

/* -------------------------------------------------------------- listo -- */

/* Lo que se puede jugar HOY tiene que verse distinto de un vistazo, no
   leerse. */
.juego.listo {
  border-color: color-mix(in srgb, var(--marca) 30%, transparent);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .32);
  transition: transform .22s cubic-bezier(.2, .8, .2, 1),
              border-color .22s ease, box-shadow .22s ease;
}

a.juego:hover,
a.juego:focus-visible {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--marca) 62%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--marca) 20%, transparent),
              0 28px 62px rgba(0, 0, 0, .5);
  outline: none;
}

a.juego:hover .motivo { transform: scale(1.1) translateY(-3px); }

.jugar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  padding: 8px 15px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--marca) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--marca) 34%, transparent);
  color: var(--marca);
  font-size: 13px;
  font-weight: 600;
}

.jugar .flecha { transition: transform .22s ease; }
a.juego:hover .jugar .flecha { transform: translateX(4px); }

/* --------------------------------------------------------- en camino -- */

/* No se esconden: una plataforma con tres cosas y un hueco se lee como una
   plataforma en marcha. Pero tampoco se disfrazan de jugables. */
.juego.pendiente { border-style: dashed; }
.juego.pendiente .escena { filter: saturate(.3); opacity: .5; }
.juego.pendiente h3 { color: var(--ink-2); }
.juego.pendiente .frase { color: var(--ink-3); }

/* Neutro a propósito. Con el color de la marca parecía un estado activo, que
   es justo lo contrario de lo que dice. */
.sello {
  margin-left: auto;
  padding: 7px 13px;
  border: 1px dashed var(--line-2);
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--ink-3);
}

/* Cuántos hay listos, dicho una vez y sin adornos. */
.recuento {
  margin: -6px 0 24px;
  font-size: 13.5px;
  color: var(--ink-3);
}

.recuento b { color: var(--ink-2); font-weight: 600; }

/* ================================================================== pie == */

.pie {
  margin-top: 18px;
  padding-top: 34px;
  border-top: 1px solid var(--line);
}

.destinos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 22px;
}

.destino h4 {
  margin: 0 0 7px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.destino p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-3);
}

.pie .nota {
  max-width: 64ch;
  margin: 30px 0 0;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  line-height: 1.65;
  color: var(--ink-3);
}

/* Mientras llega el catálogo: huecos del tamaño de las tarjetas.
   No dice «cargando» porque no da tiempo a leerlo; lo que se evita es el
   salto de la página al aparecer las tarjetas de golpe. */
.esqueleto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 18px;
}

.hueco {
  height: 296px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(158deg, var(--panel-2), var(--panel) 62%);
  opacity: .5;
  animation: respira 1.6s ease-in-out infinite;
}

.hueco:nth-child(2) { animation-delay: .15s; }
.hueco:nth-child(3) { animation-delay: .3s; }

@keyframes respira { 0%, 100% { opacity: .3; } 50% { opacity: .6; } }

/* Esto sí es un mensaje que hay que leer: el catálogo no se pudo leer. */
.cargando {
  padding: 18px 20px;
  border: 1px dashed var(--line-2);
  border-radius: 14px;
  color: var(--ink-2);
  line-height: 1.6;
}

@media (prefers-reduced-motion: reduce) { .hueco { animation: none; } }

/* =============================================================== móvil == */

@media (max-width: 820px) {
  .hero {
    grid-template-columns: 1fr;
    padding-bottom: 8px;
  }
  /* El lector va primero: es lo que explica de qué va esto. */
  .hero-art { order: -1; min-height: 220px; }
  .lector { transform: scale(.82); }
}

@media (prefers-reduced-motion: reduce) {
  .lector .tarjeta, .lector .onda, .enlace[data-estado="buscando"] .punto { animation: none; }
  .lector .onda { opacity: .28; }
  .lector .tarjeta { transform: rotateX(58deg) rotateZ(45deg) translate3d(0, -6px, 0); }
  .juego, .juego .motivo, .jugar .flecha { transition: none; }
}

/* ========================================================== versiones == */

/* El saltador entre las cuatro portadas.
   Andamio para decidir viéndolas, no una función del producto: cuando haya una
   elegida, esto se borra de las cuatro y la elegida pasa a ser `index.html`. */
.versiones {
  position: fixed; z-index: 30;
  top: 14px; right: 14px;
  display: flex; gap: 2px;
  padding: 4px;
  border-radius: 999px;
  font-size: 12px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .14);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.versiones a, .versiones .ver-actual {
  padding: 5px 13px; border-radius: 999px;
  color: rgba(255, 255, 255, .5);
  text-decoration: none;
  transition: color .2s, background .2s;
}
.versiones a:hover { color: #fff; background: rgba(255, 255, 255, .1); }
.versiones .ver-actual {
  color: #0b0d12; background: rgba(255, 255, 255, .9); font-weight: 600;
}
