/* LA NAVEGACIÓN COMÚN DE ZAXFUN — barra de arriba y «más de esto» de abajo.
   ---------------------------------------------------------------------------
   Hasta ahora cada juguete era un callejón: se entraba por Google, se jugaba y
   el único enlace de la página era «← zaxfun». Quien terminaba el test de
   reflejos no llegaba a saber que existían los otros cinco. Esto pone lo mismo
   en las siete páginas: una barra arriba con la marca, y al pie un anuncio de
   otro juguete con los demás en una línea.

   HAY UNA SOLA COPIA. Cada juguete la enlaza con un symlink
   (`css/nav.css → ../../zaxfun/comun/css/nav.css`) para poder trabajar solo en
   su servidor local, y `publicar.sh` materializa el enlace al desplegar — igual
   que `anim.js` y que el `base.css` de las pruebas.

   El HTML de dentro NO se escribe a mano: lo pone `herramientas/rejilla.js` al
   publicar, leyendo `js/juguetes.js`. Aquí solo está el aspecto.

   Los colores van con valor de reserva (`var(--texto, #e9edfb)`) a propósito:
   las tres pruebas comparten la paleta de `pruebas/css/base.css`, pero cada
   juego declara la suya y no todos tienen los mismos nombres. Sin la reserva,
   la barra se veía negra sobre negro en «el pulso». */

.zx-barra {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: max(.5rem, env(safe-area-inset-top)) .9rem .5rem;
  background: rgba(6, 8, 20, .72);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
}

/* En la portada la barra no se ve hasta que se baja: arriba está el `h1` con la
   marca en grande y las dos juntas eran la misma palabra dos veces en la misma
   pantalla. `visibility` además de la opacidad para que no se pueda tocar a
   ciegas lo que hay debajo mientras está fuera. */
.zx-barra.zx-al-bajar {
  transform: translateY(-100%);
  opacity: 0;
  visibility: hidden;
  transition: transform .25s ease, opacity .25s ease, visibility .25s;
}
.zx-barra.zx-al-bajar.zx-vista {
  transform: none;
  opacity: 1;
  visibility: visible;
}

/* La marca es TAMBIÉN el botón de volver. Antes había dos cosas que hacían lo
   mismo —el `#atras` flotante y la marca— pegadas en la misma esquina; la
   convención del sitio es que solo haya un camino de vuelta a la vista. En las
   páginas de juguete lleva la flecha delante; en la portada no, porque de ahí
   no se vuelve a ningún sitio. */
.zx-marca {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .1rem;
  color: var(--texto, #e9edfb);
  font: 700 1.02rem/1 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  letter-spacing: -.02em;
  text-decoration: none;
}
.zx-marca .zx-flecha { color: var(--texto-tenue, #8e97b8); font-weight: 500; }

/* ---------- EL BOTÓN «JUEGOS» Y SU PANEL ----------

   El menú del sitio. Vive pegado a la marca, a la IZQUIERDA de la barra: la
   esquina derecha ya es del botón de silencio en las pruebas y del de idioma en
   la portada, los dos fijos y con más `z-index` que la barra. Un menú debajo de
   otro botón es un menú que no se toca.

   Lo que se abre no es un cajón colgando de la barra —eso ya se probó en agosto
   y era una lista de nombres— sino la rejilla de la portada en pequeño: por
   estantes, con miniatura y una frase. Va ENCIMA de la página, con su propio
   desplazamiento, así que crecer no lo rompe. */

.zx-menu {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .34rem .7rem .34rem .55rem;
  border: 1px solid var(--panel-borde, rgba(255, 255, 255, .12));
  border-radius: 999px;
  background: rgba(255, 255, 255, .05);
  color: var(--texto-tenue, #8e97b8);
  font: 600 .82rem/1 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}

/* El icono: seis cuadritos, que es lo que hay dentro. Un icono de rejilla dice
   «aquí hay cosas para elegir»; las tres rayas de la hamburguesa dicen
   «opciones», y aquí no hay ninguna opción que tocar. */
.zx-menu-rejilla {
  display: grid;
  grid-template-columns: repeat(3, 3px);
  grid-auto-rows: 3px;
  gap: 2px;
}
.zx-menu-rejilla i {
  display: block;
  width: 3px;
  height: 3px;
  border-radius: 1px;
  background: currentColor;
  opacity: .75;
}

/* ---------- EL MISMO BOTÓN, SUELTO EN LA ESQUINA (los cuatro juegos) -------

   Los juegos no tienen barra: cada uno llena la pantalla con su canvas y ya
   trae su propia cápsula de vuelta arriba a la izquierda. Meterles la barra
   sería una segunda salida diciendo lo mismo. Lo que se lleva es solo el
   botón, fijo AL LADO del de volver, para que el menú esté en el mismo sitio
   en las once páginas del sitio.

   La distancia a la izquierda la pone cada juego con `--zx-menu-izq`, porque
   su cápsula de volver no mide lo mismo en los cuatro (de «← zaxfun» a
   «← Volver», y con tipografías distintas). Aquí solo hay un valor de reserva
   por si un juguete nuevo se olvida de declararlo: se verá algo separado, pero
   nunca encima del otro botón.

   El fondo se repite en vez de heredarlo de `.zx-menu` porque aquí no hay
   barra difuminada debajo: suelto sobre el juego, la cápsula tiene que
   sostenerse sola sobre un cielo estrellado o sobre una ciudad de noche. */
.zx-menu-suelto {
  position: fixed;
  top: var(--zx-menu-arriba, max(.9rem, env(safe-area-inset-top)));
  left: var(--zx-menu-izq, 8rem);
  z-index: 31;                /* con el silencio de las pruebas, por encima de todo lo demás */
  background: rgba(8, 11, 26, .78);
  backdrop-filter: blur(8px);
}

/* Abierto, el botón se queda encendido: si no, con el panel delante parece que
   lo que hay abajo no es suyo. */
.zx-menu[aria-expanded="true"] {
  color: var(--texto, #e9edfb);
  border-color: rgba(185, 140, 255, .55);
  background: rgba(185, 140, 255, .14);
}
.zx-menu:focus-visible {
  outline: 2px solid rgba(185, 140, 255, .9);
  outline-offset: 3px;
}

/* ---------- El panel ---------- */

/* `[hidden]` explícito y con `!important`: el atributo lo pisa cualquier
   `display` de esta hoja, y esa trampa ya se pagó con el botón de instalar de
   la portada. Si el JavaScript no llegara a correr, el panel tiene que quedarse
   cerrado y no tapar el juego. */
.zx-panel[hidden] { display: none !important; }

.zx-panel {
  position: fixed;
  inset: 0;
  z-index: 40;              /* por encima de la barra (30) y del silencio (31) */
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: max(3.4rem, calc(env(safe-area-inset-top) + 3rem)) .8rem 1rem;
}

.zx-panel-velo {
  position: absolute;
  inset: 0;
  background: rgba(4, 6, 16, .72);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity .22s ease;
}

/* La caja baja un poco al abrirse y se va igual. Es lo único que se mueve: el
   panel tapa la página entera y una entrada con rebote, sobre un juego, se lee
   como que algo se rompió. */
.zx-panel-caja {
  position: relative;
  width: 100%;
  max-width: 30rem;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .9rem;
  border: 1px solid rgba(185, 140, 255, .26);
  border-radius: 20px;
  background: linear-gradient(180deg, #141936, #0b0e20 60%);
  box-shadow: 0 26px 60px rgba(0, 0, 0, .55);
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity .22s ease, transform .22s ease;
}

.zx-panel.zx-abierto .zx-panel-velo { opacity: 1; }
.zx-panel.zx-abierto .zx-panel-caja { opacity: 1; transform: none; }

.zx-panel-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .8rem;
  margin-bottom: .5rem;
  padding: 0 .25rem;
}

.zx-panel-que {
  margin: 0;
  color: var(--texto-tenue, #8e97b8);
  font-size: .74rem;
  letter-spacing: .13em;
  text-transform: uppercase;
}

.zx-panel-cerrar {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--panel-borde, rgba(255, 255, 255, .12));
  border-radius: 50%;
  background: rgba(255, 255, 255, .04);
  color: var(--texto-tenue, #8e97b8);
  font-size: .85rem;
  cursor: pointer;
}
.zx-panel-cerrar:focus-visible {
  outline: 2px solid rgba(185, 140, 255, .9);
  outline-offset: 2px;
}

/* Los estantes. Es la única jerarquía del menú y por eso el nombre va en
   pequeño y en mayúsculas: separa sin competir con los juegos, que son lo que
   se viene a tocar. */
.zx-panel-estante + .zx-panel-estante { margin-top: .85rem; }

.zx-panel-estante-titulo {
  margin: 0 0 .3rem;
  padding: 0 .25rem;
  color: rgba(185, 140, 255, .85);
  font: 700 .7rem/1 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* Cada juguete: miniatura, nombre, una frase y la flecha. La miniatura es la
   misma que en la portada — es lo que hace que se reconozca de un vistazo el
   que ya se jugó, que en una lista de nombres se pierde. */
.zx-panel-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .45rem .55rem;
  border: 1px solid transparent;
  border-radius: 14px;
  color: var(--texto, #e9edfb);
  text-decoration: none;
}

.zx-panel-item img {
  flex: 0 0 auto;
  width: 78px;
  aspect-ratio: 16 / 9;
  border-radius: 9px;
  object-fit: cover;
  background: rgba(255, 255, 255, .05);
}

.zx-panel-cuerpo { min-width: 0; flex: 1 1 auto; }

.zx-panel-item b {
  display: block;
  font: 700 .93rem/1.2 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  letter-spacing: -.01em;
}

/* Dos líneas y punto. La frase entera está en la tarjeta de la portada; aquí lo
   que decide es el nombre y el dibujo. A UNA línea, en el móvil se cortaban seis
   de los siete ganchos a media palabra y el menú entero se leía como algo que no
   cabe; a dos, entran completos y no llegan a ser un párrafo. */
.zx-panel-gancho {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  margin-top: .12rem;
  overflow: hidden;
  color: var(--texto-tenue, #8e97b8);
  font-size: .78rem;
  line-height: 1.35;
}

.zx-panel-flecha {
  flex: 0 0 auto;
  color: rgba(185, 140, 255, .55);
  font-size: 1rem;
}

/* Dónde estás parado. No es un enlace —llevaría a esta misma página— y por eso
   se ve apagado: en un menú, la fila que no hace nada tiene que explicar por
   qué. */
.zx-panel-aqui {
  border-color: rgba(185, 140, 255, .28);
  background: rgba(185, 140, 255, .08);
  cursor: default;
}
.zx-panel-aqui img { opacity: .55; }

/* Va en la segunda línea, donde los demás llevan el gancho. Como pastilla a la
   derecha le comía el ancho al nombre y «Test de secuencia» se partía en dos. */
.zx-panel-punto {
  display: inline-block;
  margin-top: .18rem;
  padding: .16rem .5rem;
  border-radius: 999px;
  background: rgba(185, 140, 255, .18);
  color: rgba(216, 190, 255, .95);
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .04em;
  white-space: nowrap;
}

/* La puerta a la portada, al final y sin peso: el menú resuelve el salto de un
   juguete a otro, y quien quiere verlo todo grande va a la portada. */
.zx-panel-todo {
  display: block;
  margin-top: .85rem;
  padding: .6rem;
  border-top: 1px solid var(--panel-borde, rgba(255, 255, 255, .09));
  color: var(--texto-tenue, #8e97b8);
  font-size: .82rem;
  text-align: center;
  text-decoration: none;
}

@media (hover: hover) {
  .zx-menu:hover { color: var(--texto, #e9edfb); border-color: rgba(185, 140, 255, .5); }
  .zx-panel-item:not(.zx-panel-aqui):hover {
    border-color: rgba(185, 140, 255, .34);
    background: rgba(185, 140, 255, .09);
  }
  .zx-panel-cerrar:hover { color: var(--texto, #e9edfb); }
  .zx-panel-todo:hover { color: var(--texto, #e9edfb); }
}

/* Con el panel abierto la página de abajo no se mueve: en el móvil, un panel
   con desplazamiento propio encima de una página larga arrastra las dos. */
body.zx-panel-abierto { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .zx-panel-velo, .zx-panel-caja { transition: none; }
}

/* ---------- «Más de esto», al pie ---------- */

/* Esto es lo que sube las páginas por visita. Va UNO GRANDE con su dibujo y una
   invitación a tocarlo, y los demás en una línea de enlaces: cinco tarjetas del
   mismo tamaño eran un catálogo, y un catálogo se pasa de largo.

   SEPARADO DEL JUEGO, con aire y una raya. Pegado debajo de la zona de juego se
   metía en el rabillo del ojo mientras se jugaba: un bloque violeta que además
   late y brilla, justo al lado de donde hay que fijarse. La raya dice «aquí
   acaba lo tuyo y empieza otra cosa». */
.zx-mas {
  margin-top: 3.4rem;
  padding-top: 2rem;
  border-top: 1px solid var(--panel-borde, rgba(255, 255, 255, .09));
}

.zx-mas-titulo {
  margin: 0 0 .9rem;
  font: 600 1.18rem/1.25 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  color: var(--texto, #e9edfb);
  letter-spacing: -.01em;
}

/* ---------- El anuncio ---------- */

/* Un solo bloque, con el dibujo del juguete y el marco encendido: es el mismo
   formato del puente a «el pulso», que era lo único de este pie que la gente
   tocaba de verdad. */
/* EN EL MÓVIL VA EN COLUMNA, con la portada entera arriba. Tumbado, entre la
   miniatura y el botón le quedaban al texto unos 120 px: el título se partía en
   dos líneas y del gancho se leían cuatro palabras. Como es UN solo bloque y no
   cinco, puede permitirse el alto. */
.zx-anuncio {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  overflow: hidden;
  padding: .6rem;
  border: 1px solid rgba(185, 140, 255, .32);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(185, 140, 255, .13), rgba(185, 140, 255, .04));
  color: inherit;
  text-decoration: none;
}

/* El medio segundo en que el anuncio cambia de juguete. Se apaga y vuelve, en
   vez de sustituir el contenido de golpe: sin esto el salto parecía un fallo de
   carga. */
.zx-anuncio img,
.zx-anuncio .zx-anuncio-cuerpo { transition: opacity .26s ease; }
.zx-anuncio.zx-cambiando img,
.zx-anuncio.zx-cambiando .zx-anuncio-cuerpo { opacity: 0; }

.zx-anuncio img {
  flex: 0 0 auto;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  object-fit: cover;
  background: rgba(255, 255, 255, .04);
}

/* En columna, el texto y el botón comparten fila: el botón a la derecha, donde
   cae el pulgar. */
.zx-anuncio-cuerpo {
  min-width: 0;
  flex: 1 1 auto;
  padding: 0 .25rem .3rem;
}

.zx-anuncio b {
  display: block;
  margin-bottom: .15rem;
  font: 700 1rem/1.2 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  color: var(--violeta, #b98cff);
}

/* El gancho a dos líneas: el texto entero es el de la portada, y ahí tiene una
   tarjeta para él solo. */
.zx-anuncio-gancho {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  color: var(--texto-tenue, #8e97b8);
  font-size: .85rem;
  line-height: 1.4;
}

/* «Jugar», latiendo. Es la invitación a tocar, y late en lugar de moverse de
   sitio para no empujar el texto de al lado en cada pulso. */
.zx-anuncio-toca {
  flex: 0 0 auto;
  align-self: center;
  padding: .5rem .9rem;
  border-radius: 999px;
  background: linear-gradient(180deg, #d9bcff, var(--violeta, #b98cff));
  color: #1e0f38;
  font: 700 .85rem/1 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  animation: zx-latido 2.4s ease-in-out infinite;
  animation-play-state: paused;
}

@keyframes zx-latido {
  0%, 62%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(185, 140, 255, .55); }
  76%           { transform: scale(1.07); box-shadow: 0 0 0 9px rgba(185, 140, 255, 0); }
}

/* Un brillo que cruza la tarjeta cada tanto. Es lo que hace que el ojo vuelva
   ahí sin que nada se mueva de su sitio. */
.zx-anuncio::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .11) 50%, transparent 62%);
  transform: translateX(-120%);
  animation: zx-brillo 4.6s ease-in-out infinite;
  animation-play-state: paused;
  pointer-events: none;
}

/* NADA SE MUEVE HASTA QUE EL BLOQUE ESTÁ DE VERDAD EN PANTALLA. Mientras se
   juega asoma por abajo, y un latido en el borde de la vista distrae justo en
   lo que estas páginas miden. Lo enciende `nav.js` con un observador. */
.zx-mas.zx-vivo .zx-anuncio-toca,
.zx-mas.zx-vivo .zx-anuncio::after { animation-play-state: running; }

@keyframes zx-brillo {
  0%, 55% { transform: translateX(-120%); }
  85%, 100% { transform: translateX(120%); }
}

/* La fila de abajo del bloque en columna: gancho a la izquierda, botón a la
   derecha. Se hace con el propio flex del anuncio poniendo cuerpo y botón en la
   misma línea. */
.zx-anuncio-pie {
  display: flex;
  align-items: center;
  gap: .8rem;
}

/* De tablet para arriba vuelve a tumbarse: ahí sí hay ancho para la portada, el
   texto entero y el botón en la misma línea. */
@media (min-width: 560px) {
  .zx-anuncio { flex-direction: row; align-items: center; gap: 1.1rem; padding: .75rem; }
  .zx-anuncio img { width: 190px; }
  .zx-anuncio-cuerpo { padding: 0; }
  .zx-anuncio b { font-size: 1.1rem; }
}

/* ---------- «Jugar otro parecido» (dentro de la pantalla de fin) ----------

   Va debajo de «Otra vez» y «Compartir», nunca encima: quien acaba de morir
   quiere volver a intentarlo, y ofrecerle otro juego antes que el botón de
   revancha es empujarlo fuera del que ya le gusta. Por eso tampoco es un botón
   —es una tarjeta plana, del mismo aire que el puente de las pruebas—: al lado
   de los botones del juego tiene que perder.

   El color es el violeta de la casa y no el del juguete: esto no es una acción
   de esta partida, es una salida hacia otro sitio. */

.zx-parecido {
  position: relative;
  display: block;
  width: 100%;
  max-width: 22rem;
  margin: .9rem auto 0;
  /* Hueco a la derecha para la flecha, que va absoluta: sin él, la segunda
     línea del gancho le pasa por debajo. */
  padding: .8rem 2.6rem .8rem 1rem;
  border: 1px solid rgba(185, 140, 255, .3);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(185, 140, 255, .12), rgba(185, 140, 255, .04));
  text-align: left;
  text-decoration: none;
  color: var(--texto, #e9edfb);
}

.zx-parecido:focus-visible {
  outline: 2px solid rgba(185, 140, 255, .9);
  outline-offset: 3px;
}

/* La etiqueta pequeña de arriba: dice qué es esto antes de decir cuál es. Sin
   ella, el nombre de otro juego dentro del panel del final parece un mensaje
   del juego que acabas de jugar. */
.zx-parecido-que {
  display: block;
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(185, 140, 255, .85);
}

.zx-parecido b {
  display: block;
  margin: .1rem 0 .15rem;
  font: 700 1rem/1.2 var(--tipo-titulo, 'Space Grotesk', system-ui, sans-serif);
  color: var(--texto, #e9edfb);
}

.zx-parecido-gancho {
  display: block;
  font-size: .84rem;
  line-height: 1.4;
  color: var(--texto-tenue, #8e97b8);
}

.zx-parecido::after {
  content: '→';
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  color: rgba(185, 140, 255, .9);
  font-size: 1.15rem;
}

@media (prefers-reduced-motion: reduce) {
  .zx-parecido { transition: none; }
}

/* ---------- El pasar por encima ----------
   Un solo bloque y encerrado en `@media (hover: hover)`: en un teléfono el
   navegador dispara `:hover` al TOCAR y lo deja puesto, así que sin esto el
   anuncio del pie que acabas de tocar se queda encendido. El levantarse, el
   hundirse al pulsar y el aro no están aquí: son el gesto común de la casa y
   viven en `comun/css/tacto.css`. Aquí queda solo el color de esta hoja. */
@media (hover: hover) {
  .zx-marca:hover .zx-flecha { color: var(--texto, #e9edfb); }
  .zx-anuncio:hover  { border-color: rgba(185, 140, 255, .62); }
  .zx-parecido:hover { border-color: rgba(185, 140, 255, .6); }
}

/* ---------- Hueco para la barra ---------- */

/* La barra es fija y tapa lo que haya arriba del todo. Cada página se aparta lo
   que mide, y las pruebas ya reservaban ese hueco para el `#atras` flotante que
   la barra sustituye. */
body.zx-con-barra { padding-top: 3.05rem; }
body.zx-con-barra .hoja { padding-top: 1.4rem; }

/* En los juguetes de pantalla completa la barra desaparece al empezar a jugar,
   igual que ya hacía el `#atras`: dentro de la cabina no puede haber nada por
   encima del canvas. */
body.jugando .zx-barra { opacity: 0; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .zx-barra, .zx-tarjeta, .zx-abre .zx-chevron { transition: none; }
}

/* ---------- Toda la casa es oscura ----------

   Va en este archivo porque es lo único que cargan las siete páginas. Sin
   `color-scheme`, el navegador da por hecho que la página es clara y pinta de
   BLANCO todo lo suyo: se veía un carril blanco de arriba abajo pegado al
   tablero de «un piso más», que es donde el menú se desborda y saca barra de
   desplazamiento. Declararlo oscuro arregla también el fondo del rebote al
   llegar al final y los controles nativos, sin tocar una regla más. */
:root { color-scheme: dark; }

