/* reading-lab/monstruos — el cuento que se pinta. Pantalla de la niña.
   La escena ocupa TODA la pantalla, recortada como un fondo, y la franja de
   papel con el borde rasgado va fija abajo, encima. Sin unidades de
   contenedor ni color-mix(): Safari 15 en el iPad. */
:root {
  color-scheme: only light;
  /* Halloween: es un cuento de monstruos con ilustraciones de noche y farol.
     Franja berenjena de noche, lo leído en calabaza (6,7:1 sobre la franja),
     lo que falta en hueso (12,1:1), y el fondo de la página y el papel de
     la acuarela en negro berenjena: la escena sale de la oscuridad. El
     pincel toma el papel del libro (`papel` en libro.json). */
  --paper: #1a1220; --band: #2b1d3a; --ink: #efe1c6; --coral: #ff8c2a; --gold: #f2c14e;
  /* Lo que lee la pantalla del trofeo del motor (finish.js): el título y el
     botón en calabaza, como lo leído. */
  --acento: #ff8c2a; --acento-fuerte: #c9661a;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--paper); font-family: Nunito, system-ui, sans-serif; color: var(--ink);
             overflow: hidden; -webkit-user-select: none; user-select: none; }

#stage { position: fixed; inset: 0; overflow: hidden; background: var(--paper); }
/* La ilustración a su tamaño natural, y la cámara (monstruos.js, camera) la
   mueve con UN transform: lo anima la GPU sin pasar por el hilo principal,
   que es lo que el pincel de acuarela no dejaba en paz. El origen arriba a la
   izquierda es desde donde se calcula el encuadre. */
#picture { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none;
           will-change: transform; -webkit-backface-visibility: hidden; backface-visibility: hidden; }

/* La franja de papel: fija abajo, fondo sólido para el contraste, y el
   borde de arriba rasgado con un mosaico SVG que empalma consigo mismo. */
#paper { position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; background: var(--band);
         padding: 14px 20px calc(10px + env(safe-area-inset-bottom)); text-align: center;
         box-shadow: 0 -2px 0 rgba(0,0,0,.25);
         transition: transform .5s cubic-bezier(.2,.8,.2,1); }
/* Página leída (monstruos.js, pageDone): la franja entera baja y se va —el
   borde rasgado incluido, que asoma 18px por encima— y vuelve a subir con la
   página siguiente. Al irse acelera y al volver frena: se va porque ya está,
   y llega como quien se asoma. */
#paper.away { transform: translateY(calc(100% + 20px)); transition: transform .6s cubic-bezier(.6,0,.8,.2); }
#paper::before { content: ''; position: absolute; left: 0; right: 0; top: -17px; height: 18px;
                 background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='18' viewBox='0 0 160 18'%3E%3Cpolygon fill='%232b1d3a' points='0,6.9 8,4.8 16,10.8 24,3.9 32,9.4 40,7.4 48,3.7 56,9.1 64,3.4 72,8.2 80,3.8 88,4.1 96,8.1 104,12.9 112,4.5 120,5.7 128,10.5 136,14.4 144,9.9 152,7.8 160,6.9 160,18 0,18'/%3E%3C/svg%3E") repeat-x bottom; }
#line { font-size: clamp(26px, 3.8vw, 46px); font-weight: 900; line-height: 1.22; max-width: 26ch; margin: 0 auto; }
.w { display: inline-block; margin-right: .28em; white-space: nowrap; }
.s { opacity: .55; transition: opacity .15s, color .3s; }
.w.cur .s { opacity: .85; }
.w.cur .s.lit { opacity: 1; }
.w.done .s { opacity: 1; color: var(--coral); }
.w.stuck { animation: tremble .35s; }
@keyframes tremble { 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }

#controls { display: flex; align-items: center; justify-content: center; margin-top: 6px; }
#controls button { font: inherit; border: 0; background: transparent; cursor: pointer; padding: 0; color: var(--ink); }
#controls #start { display: flex; align-items: center; gap: 8px; height: 52px; padding: 0 8px; border-radius: 26px; }
#controls #start:active { transform: translateY(2px); }
#start .mic { width: 30px; height: 40px; fill: var(--coral); stroke: var(--coral); }
/* LAS RAYITAS DEL MICRO: TRES ESTADOS, Y LOS TRES SON VERDAD (15/09/2026).
     · puntos apagados «···»  Safari NO tiene el audio abierto: sin tocar, en
                              pleno arranque, reiniciándose, o en pausa
                              mientras habla el personaje
     · puntos encendidos «···» tiene el audio abierto y no le llega nada que
                              sepa escribir
     · rayas que bailan «|||»  está escribiendo lo que oye (cada hipótesis
                              nueva de la voz, pulseBars en monstruos.js)
   Hasta ese día, escuchando, se quedaban a media altura (`scaleY(.6)`) y
   parecían rayas aunque no llegara nada; el usuario: «no entiendo por qué
   salen desplegadas cuando estoy en silencio… sin una señal de que el iPad
   escucha es imposible diferenciar un "no me escucha" de un "no me
   entiende"». Y el encendido dependía de `.on`, que sigue puesto durante la
   pausa del personaje: con Safari sin volver, decía «escucho» sin escuchar.
   Ahora lo pone `.ears`, que es `onListening` a secas.
   ⚠ No es un medidor de volumen, y no puede serlo: en iOS un segundo
   getUserMedia mata la Web Speech. Un ruido, o una voz que Safari no sabe
   convertir en palabras, deja los puntos quietos. Bailan cuando ENTIENDE
   algo, lo que sea; si bailan y la palabra no se enciende, ha entendido otra
   cosa (la línea 👂 dice cuál). Se anima la altura y no un transform: un
   punto escalado en vertical sale ovalado, y son seis elementos en una caja
   de alto fijo, que no mueven nada alrededor. */
#start .bars { display: flex; align-items: center; gap: 4px; height: 24px; }
#start .bars i { display: block; width: 5px; height: 5px; border-radius: 3px; background: var(--coral); opacity: .3;
                 transition: height .45s ease-in, opacity .3s; }
#start.ears .bars i { opacity: 1; }
/* Tocado, pero Safari aún no oye (monstruos.js, «El toque no es escuchar»):
   el micro respira y las barras apagadas. Cuando llega el audio se encienden
   las barras (.on), suena el «¡ya!» y aparece la frase. */
body.waking #start .mic { animation: breathe 1.1s ease-in-out infinite; }
/* LA FRASE SÓLO SE VE CUANDO SE ESCUCHA (body.hearing, 14/09/2026). Antes
   estaba a la vista desde que se abría el cuento, y el niño se lanzaba a
   leerla sin saber que había que tocar el micro ni esperar a la señal: lo
   que leía antes no lo oía nadie. Ahora aparece con el «¡ya!» y se va si el
   micro se para. Con opacity y no display, para que la franja no cambie de
   alto al aparecer. */
#line, #heard { transition: opacity .4s; }
body:not(.hearing) #line, body:not(.hearing) #heard { opacity: 0; }
@keyframes breathe { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
/* Lo que oye Safari (maqueta, se quita con el diario): pequeño y apagado,
   debajo de la frase, en una sola línea que enseña el final si es larga. */
#heard { font-size: 15px; font-weight: 700; line-height: 1.3; min-height: 1.3em; margin-top: 2px; color: rgba(239,225,198,.6);
         white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#hint { margin-top: 4px; font-size: 13px; font-weight: 700; opacity: .6; min-height: 1.2em; }

[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) { body.waking #start .mic { animation: none; opacity: .5; }
  #paper, #paper.away { transition: opacity .4s; } #paper.away { transform: none; opacity: 0; } }

/* El paso de página: un velo de papel que sube y baja en medio segundo. */
#turn { position: absolute; inset: 0; background: var(--paper); opacity: 0; pointer-events: none; transition: opacity .6s ease; }
#turn.on { opacity: 1; }
