/* ============================================================
   CÁSCARA DE LOS JUEGOS DE VOZ  (tienda · robot · espacio)

   Es la hermana de /quijotin/juego-layout.css: mismo decorado, misma
   letra y las mismas piezas de cristal, pero para un juego que no es
   de test. Aquí no hay cuatro opciones que pulsar: hay un personaje
   que habla, una escena que mira y un botón de micro abajo.

   La pantalla se parte en cuatro bandas y no hay scroll nunca:

     ┌────────────────┐   CABECERA · nombre del juego y las estrellas
     │   La tienda    │              (altura propia, pegada arriba)
     │   ★★☆☆☆☆       │
     ├────────────────┤
     │ 🧔 ¿Qué quieres?│  ESCENA  · el personaje y su bocadillo
     ├────────────────┤
     │                │   TABLERO · lo pinta la fase; se come TODO el
     │   🍎🍌🍇        │             hueco que sobra
     ├────────────────┤
     │      🎤        │   MICRO  · altura propia, pegado abajo
     └────────────────┘

   Las tres bandas de los extremos se miden solas y por eso caben
   siempre. La del medio da y toma, y se declara `container-type:size`
   para que la fase pueda medir sus dibujos en cqh/cqw —contra el hueco
   que le ha quedado, no contra la ventana—. Eso es lo que sustituye a
   la reserva a ojo (`100dvh - 364px`) que traían robot y espacio: si
   mañana la cabecera cambia de alto, los dibujos se reajustan solos.

   DECORADO. El paisaje sale de la categoría del juego (`conversacion`)
   y lo pone juego-comun.js en `--fondo`/`--cielo`, igual que en los
   juegos de test. El respaldo de aquí es la ruta relativa a ESTA hoja.

   COLOR. También de juego-comun.js, leyendo el `game.json` de cada
   juego: `--acento` tiñe el micro y los botones, así que la tienda
   sale naranja, el robot azul y el espacio morado sin tocar nada.
   ============================================================ */

/* Bree Serif para el título (la misma que el resto de juegos) y Nunito
   para el texto. Se piden desde aquí y no con un <link> en cada
   index.html: los tres index son idénticos y conviene que sigan
   siéndolo. */
@import url('https://fonts.googleapis.com/css2?family=Bree+Serif&family=Nunito:wght@400;700;900&display=swap');

/* Lo personalizable NO se declara: se lee con `var(--x, respaldo)` en
   su punto de uso, para que la hoja de la fase —que carga DESPUÉS, la
   mete el shell— pueda cambiarlo sin pelearse.
   Personalizables así: --fondo --cielo --plato --fuente-titulo --boton */
:root {
  /* SÓLO CLARO, Y CON `only`. El WebView de Android TV —TV Bro con su
     interfaz en modo noche— aplica «oscurecimiento algorítmico» a toda página
     que no declare su esquema de color: invierte el texto y los fondos planos y
     deja las imágenes, así que el rótulo del juego salía BLANCO sobre el
     paisaje (visto en un Google TV Streamer el 11 de septiembre de 2026). Esta
     línea le dice que el esquema es claro y que no lo toque. MEDIDO con Chrome
     en auto-dark: `color-scheme: light` a secas NO lo para; `only light` sí, en
     CSS de `:root` o en un <meta name="color-scheme">. Aquí va en la hoja para
     que lo hereden los 25 juegos y los que vengan, sin una línea que recordar;
     los menús, que no cargan esta hoja, llevan el <meta>. */
  color-scheme: only light;
  --canto:  var(--acento-claro, rgba(255,255,255,.92));
  --halo:   0 1px 0 rgba(255,255,255,.9), 0 0 14px rgba(255,255,255,.85);
  --hueco:  clamp(8px, 1.5vh, 16px);
  --margen: max(12px, env(safe-area-inset-left, 0px));
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

/* ── LIENZO ──────────────────────────────────────────────── */
html {
  height: 100%;
  overflow: hidden;
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

body {
  font: 16px/1.4 Nunito, system-ui, sans-serif;
  color: var(--text, #3b3128);
  /* 100dvh y no 100vh: en iOS el vh es el viewport GRANDE (el de la
     barra escondida) y, sin scroll, el micro se quedaría cortado por
     abajo y fuera de alcance. */
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  overscroll-behavior: none;
  user-select: none;
  /* Sólo el color: el paisaje lo pintan los dos pseudoelementos de abajo.
     --cielo es el color del borde de arriba del paisaje y tapa el hueco
     mientras cargan las imágenes. */
  background-color: var(--cielo, #f5ce65);
}

/* ── EL PAISAJE DE ARRANQUE, POR CATEGORÍA ───────────────────
   La tabla que decía qué paisaje y qué cielo lleva cada categoría se fue el 27
   de agosto de 2026 a `categorias.css` de cada VERTICAL, que es de donde son
   esos datos. Allí está el porqué entero.

   Dos motivos. El de fondo: los nombres de las categorías, sus dibujos y sus
   colores son de un producto concreto, y el motor sirve a varios. El
   inmediato: aquí estaba ROTA desde la separación del motor —las rutas eran
   relativas a esta hoja, esta hoja se mudó a /game_engine/ y el arte se quedó
   en la vertical, así que `art/fondos/…` apuntaba a /game_engine/art/fondos/,
   que no existe—. Y estaba DUPLICADA, aquí y en la otra hoja del motor, con un
   comentario en cada una recordando actualizar la otra.

   Las páginas de juego la enlazan ellas, junto a esta hoja:
       <link rel="stylesheet" href="../categorias.css">
   Si falta, no se rompe nada: se ve el paisaje de respaldo hasta que
   `juego-comun.js` pone el bueno, que es como estaba antes de que existiera. */

/* ── EL PAISAJE, EN DOS CAPAS ────────────────────────────────
   Copia exacta de lo que hacen el menú y juego-layout.css, y tiene que
   seguir siendo exacta: los tres juegos de voz comparten el paisaje de
   `conversacion` con la categoría del menú, y basta que uno de los tres
   encuadre distinto para que al entrar se vea el dibujo pegar un salto.
   Aquí había una sola imagen a `cover`, que llena el alto comiéndose los
   lados; el menú dibuja el paisaje entero a lo ancho y rellena el hueco de
   arriba con una versión desenfocada de él mismo. El porqué de las dos capas
   —y de que el desenfoque venga cocido en el jpg en vez de en un `filter`—
   está contado largo en el menú y en juego-layout.css.
   Está repetido y no importado porque estos tres juegos no cargan
   juego-layout.css: su cáscara es otra, y ésta es la única hoja común que
   tienen. */
body::before,
body::after {
  content: '';
  position: fixed;
  pointer-events: none;
  background-repeat: no-repeat;
  /* `fixed` los saca del flujo: no son ítems de la columna flex del body, ni
     los recorta su `overflow: hidden`. */
}
body::before {
  /* Se sale por los cuatro lados: la imagen ya viene desenfocada y su borde
     lavado no debe caer justo en el canto de la ventana. */
  inset: -9vmax;
  z-index: -2;
  /* Sin difusa se pinta la nítida a `cover`, que es lo que había antes.

     Y SIN NINGUNA DE LAS DOS, NADA. Aquí había un tercer respaldo apuntando a
     `../art/fondos/conversacion-fondo-difuso.jpg`, que era el paisaje de una
     categoría de Quijotín escrito dentro del motor. Llevaba roto desde la
     separación del 26 de agosto de 2026 —esta hoja se mudó a /game_engine/ y el
     arte se quedó en la vertical, así que pedía `/game_engine/art/…`— y no se
     notaba porque `juego-comun.js` y `categorias.css` ponen las dos variables
     antes de que haga falta. Se quita en vez de arreglarse: el motor no tiene
     por qué saber que existe un dibujo llamado «conversación». */
  background-image: var(--difuso, var(--fondo, none));
  background-position: center top;
  background-size: cover;
}
body::after {
  inset: 0;
  z-index: -1;
  /* Mismo caso que el de arriba: el respaldo nombraba un dibujo de Quijotín. */
  background-image: var(--fondo, none);
  background-position: center bottom;
  background-size: 100% auto;
  /* Las unidades no son intercambiables: `--hueco` en % (se miden contra el
     alto de esta caja, que es la ventana, y en iOS el vh miente mientras está
     la barra del navegador) y el largo del fundido en vh, donde un error de
     90px da igual. Mezclarlas dentro del clamp es lo que algunos Safari no
     digieren, y una máscara inválida se descarta entera. */
  --hueco:   calc(100% - 100vw / 1.776);
  --fundido: clamp(0px, calc(100vh - 100vw / 1.776), 7vh);
  -webkit-mask-image: linear-gradient(to bottom,
      rgba(0,0,0,0) var(--hueco),
      rgba(0,0,0,1) calc(var(--hueco) + var(--fundido)));
  mask-image: linear-gradient(to bottom,
      rgba(0,0,0,0) var(--hueco),
      rgba(0,0,0,1) calc(var(--hueco) + var(--fundido)));
}

main {
  flex: 1;
  min-height: 0;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hueco);
  padding: 0 var(--margen);
}

/* ── BANDA ALTA · nombre y escalera ──────────────────────────
   Sin caja ni velo: el título va directo sobre el paisaje. Lo que
   garantiza que se lea sobre cualquier fondo es el halo. */
#progreso {
  flex: 0 0 auto;
  text-align: center;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 0 0;
  text-shadow: var(--halo);
}

h1 {
  font-family: var(--fuente-titulo, 'Bree Serif', Georgia, serif);
  font-weight: 400;              /* Bree Serif sólo trae un grosor */
  font-size: clamp(1.4rem, 6.4vw, 2.1rem);
  line-height: 1.15;
  text-wrap: balance;
  /* Hueco a los dos lados para que un nombre largo parta en dos líneas
     en vez de meterse por debajo del botón de volver. Igual a ambos
     lados, así que el título sigue centrado. */
  padding: 0 44px;
  margin-bottom: 4px;
}

/* La escalera: una estrella por partida, hasta la copa. Sin texto,
   porque tiene 6 años y no lee: el nombre del nivel es para el adulto. */
#estrellas { font-size: clamp(19px, 5.4vw, 24px); letter-spacing: 2px; line-height: 1; }
.estrella { opacity: .55; transition: opacity .3s, transform .3s; }
.estrella.ok { opacity: 1; transform: scale(1.15); }
#nivel-nombre { font-size: 13px; opacity: .7; margin-top: 4px; min-height: 18px; }

/* ── ESCENA · el personaje y lo que dice ─────────────────────
   El personaje no lleva halo de texto (sobre un emoji sale un borrón
   de color) sino sombra de figura, que recorta la silueta. */
#escena {
  flex: 0 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 96px;
}

#personaje {
  font-size: clamp(46px, 15vw, 68px);
  line-height: 1;
  filter: drop-shadow(0 8px 10px rgba(60,40,10,.28));
}

/* Cristal, como las pastillas de los juegos de test: deja pasar el
   paisaje y no se pelea con el tinte de cada juego. */
#bocadillo {
  position: relative;
  background: var(--plato, rgba(255,255,255,.84));
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 3px solid var(--canto);
  border-radius: 18px;
  box-shadow: 0 6px 16px rgba(60,40,10,.14);
  padding: 10px 14px;
  font-size: clamp(16px, 4.6vw, 20px);
  font-weight: 700;
  max-width: 62%;
  min-height: 28px;
}

/* El pico, apuntando al personaje. Dos triángulos: el de fuera hace de
   borde y el de dentro lleva el mismo relleno que la pastilla. */
#bocadillo::before,
#bocadillo::after {
  content: '';
  position: absolute;
  top: 50%;
  border-style: solid;
  border-color: transparent;
}
#bocadillo::before {
  left: -14px; margin-top: -9px;
  border-width: 9px 14px 9px 0;
  border-right-color: var(--canto);
}
#bocadillo::after {
  left: -9px; margin-top: -7px;
  border-width: 7px 10px 7px 0;
  border-right-color: var(--plato, rgba(255,255,255,.84));
}

/* ── BANDA MEDIA · el hueco que sobra ────────────────────────
   Aquí pinta la fase, y aquí se mide: `container-type: size` hace que
   1cqh sea el 1% de ESTE hueco. La fase no necesita saber cuánto miden
   la cabecera ni el micro. */
#tablero {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--hueco);
  container-type: size;

  /* EL MISMO HUECO, EN UNIDADES DE VENTANA · para quien no tenga unidades de
     contenedor (Safari < 16, o sea el iPad de casa con iPadOS 15). Allí `1cqh`
     no existe, y una fase que mida SÓLO en cqh se queda sin tamaño: sus
     dibujos caen al cuerpo de texto heredado, 16px. Es el mismo fallo que
     `juego-layout.css` cuenta largo en su bloque del respaldo, y por el mismo
     motivo: el valor va dentro de una VARIABLE, así que el truco de las dos
     declaraciones seguidas no lo salva y hay que preguntar con `@supports`.

     Se publica AQUÍ y no copiado en las tres fases porque es la cáscara la que
     decide cuánto hueco sobra: si mañana crece la cabecera, la cifra se
     corrige en un sitio. Misma idea que los `--aviso-*` de `report/aviso.js`.

     Las cifras están MEDIDAS, no puestas a ojo: con la cabecera y el micro de
     hoy la cáscara se come 418px en talla iPad y 270px en talla móvil. El
     escalón va en 490px porque es donde deja de crecer `--boton`
     (`clamp(84px, 22vw, 108px)` se topa a 22vw = 108 → 491px). Y los 24px que
     se le quitan al ancho son el margen lateral: a 390px de ventana la sala
     mide 366. Comprobado contra el valor bueno en las tres fases y en dos
     tallas cada una: el respaldo cae dentro del 3%.

     Redondeadas A LA BAJA a propósito, que es la regla de la casa para esto:
     un respaldo que se queda corto se lee; uno que se pasa se sale de la caja. */
  --hueco-alto:  calc(100dvh - 420px);
  --hueco-ancho: min(calc(100vw - 24px), 616px);
}
/* Por debajo del escalón de `--boton`, la cáscara ocupa bastante menos. */
@media (max-width: 490px) {
  #tablero { --hueco-alto: calc(100dvh - 285px); }
}

/* ── BANDA BAJA · hablar ─────────────────────────────────────
   El botón se tiñe con el color del juego (--acento, del game.json).
   Un color por estado: acento = te toca, rojo = te oigo, gris = espera. */
footer {
  flex: 0 0 auto;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  padding: var(--hueco) var(--margen)
           calc(env(safe-area-inset-bottom, 0px) + var(--hueco));
  --boton: clamp(84px, 22vw, 108px);
}

#oido {
  font-size: 14px; font-weight: 700; opacity: .8;
  min-height: 20px; margin-bottom: 6px; text-shadow: var(--halo);
}

/* El anillo late con su voz. Es la señal de "te oigo" que se entiende
   a los 6 sin leer nada. */
#micro { position: relative; display: inline-block; }
#anillo {
  position: absolute; top: 50%; left: 50%;
  width: var(--boton); height: var(--boton); border-radius: 50%;
  transform: translate(-50%, -50%) scale(1);
  background: rgba(227, 51, 51, .28); opacity: 0;
  transition: transform .07s linear, opacity .2s;
  pointer-events: none;
}
[data-estado="oyendo"] #anillo { opacity: 1; }

#hablar {
  position: relative; z-index: 1;
  width: var(--boton); height: var(--boton); border-radius: 50%; border: 0;
  font-size: calc(var(--boton) * .43);
  font-family: inherit;
  background: var(--acento, #ff8a5b); color: #fff; cursor: pointer;
  box-shadow: 0 6px 0 var(--acento-fuerte, #d8663c),
              0 10px 22px rgba(60,40,10,.22);
  transition: background .15s;
}
#hablar:active { transform: translateY(4px);
                 box-shadow: 0 2px 0 var(--acento-fuerte, #d8663c); }

[data-estado="esperando"] #hablar { animation: invita 2.2s ease-in-out infinite; }
[data-estado="oyendo"]    #hablar { background: #e33;
                                    box-shadow: 0 6px 0 #a11, 0 10px 22px rgba(60,40,10,.22); }
[data-estado="pensando"]  #hablar { background: #bbb; cursor: default;
                                    box-shadow: 0 6px 0 #999, 0 10px 22px rgba(60,40,10,.22);
                                    animation: gira 1s linear infinite; }

/* "espera": el micro está apagado (escena o victoria). Gris y atenuado,
   sin invitar ni girar: se lee como "ahora no te toca". */
[data-estado="espera"] #hablar {
  background: #cfc4ac; box-shadow: 0 6px 0 #b3a888; cursor: default;
  filter: grayscale(1); opacity: .55; animation: none;
}
[data-estado="espera"] #anillo { opacity: 0; }

@keyframes invita { 50% { transform: scale(1.07); } }
@keyframes gira   { to  { transform: rotate(360deg); } }

#ayuda-uso {
  margin-top: 10px; font-size: 15px; font-weight: 700; opacity: .8;
  min-height: 20px; text-shadow: var(--halo);
}

/* Quien haya pedido menos movimiento en su sistema, que no vea latir
   nada. */
@media (prefers-reduced-motion: reduce) {
  [data-estado="esperando"] #hablar,
  [data-estado="pensando"]  #hablar { animation: none; }
}

/* ── Pantalla baja de pie (iPhone SE y compañía) ─────────────
   Aquí no sobra un pixel: la escena más cargada de la tienda —tres
   pedidos, seis frutas en el mostrador y doce en la cesta— más el
   nombre del juego arriba no caben con las medidas de un móvil de hoy.
   Como no hay scroll, lo que no cabe no se ve, así que se encoge todo
   lo que es marco (título, personaje, micro y aire) y el hueco que se
   libera va al tablero, que es donde está el juego. La fase se entera
   sola: mide en cqh. */
@media (orientation: portrait) and (max-height: 700px) {
  :root        { --hueco: clamp(6px, 1.2vh, 12px); }
  #progreso    { padding-top: calc(env(safe-area-inset-top, 0px) + 6px); }
  h1           { font-size: clamp(1.15rem, 5.4vw, 1.5rem); margin-bottom: 2px; }
  #estrellas   { font-size: 18px; }
  #nivel-nombre { font-size: 12px; margin-top: 2px; min-height: 16px; }
  #escena      { min-height: 0; }
  #personaje   { font-size: clamp(38px, 12vw, 52px); }
  #bocadillo   { font-size: clamp(14px, 4.2vw, 17px); padding: 8px 12px; }
  footer       { --boton: clamp(68px, 20vw, 88px); padding-top: 6px; }
  #oido        { font-size: 13px; min-height: 17px; margin-bottom: 4px; }
  #ayuda-uso   { font-size: 13px; min-height: 17px; margin-top: 6px; }
}

/* ── Móvil tumbado ───────────────────────────────────────────
   Tumbado no hay alto para nada: se recorta todo lo que es texto para
   el adulto y se encoge el micro, que el hueco del medio lo necesita
   la escena. Sin esto el botón de hablar se sale por abajo, y como
   aquí no hay scroll se quedaría fuera de alcance. */
@media (orientation: landscape) and (max-height: 560px) {
  main, footer { max-width: 900px; }
  #progreso   { padding-top: calc(env(safe-area-inset-top, 0px) + 2px); }
  h1          { font-size: clamp(1.05rem, 3.4vh, 1.45rem); margin-bottom: 2px;
                padding: 0 52px; }
  #estrellas  { font-size: 17px; }
  #nivel-nombre { display: none; }
  #escena     { min-height: 0; }
  #personaje  { font-size: clamp(34px, 12vh, 52px); }
  #bocadillo  { font-size: clamp(14px, 4.2vh, 17px); padding: 7px 11px; }
  footer      { --boton: clamp(58px, 17vh, 80px); padding-top: 4px; }
  #oido       { min-height: 0; font-size: 12px; margin-bottom: 3px; }
  #ayuda-uso  { min-height: 0; font-size: 12px; margin-top: 4px; }
}
