/* LunaCuentos — estilos base. Igual que RobiLab: sin frameworks, con ajustes
   para que dentro de Capacitor se sienta app nativa (safe-area, sin rebote,
   sin flash azul al tocar).

   La paleta NO es inventada: sale del diseño de la marca (logos/entregables
   sep 2026/LEEME.txt): Noche #161826, Acento #9184D9, Luna #F0C987 y Marfil
   #E9E9ED. Las superficies son escalones de la Noche hacia el cielo del icono
   (#232642). Antes se muestreaba del icono viejo, de un morado más saturado;
   se cambió el 24-09-2026 con el logo nuevo. Si cambia la marca otra vez, se
   cambian estas variables — no se retocan colores sueltos por ahí. */

:root {
  --bg: #161826;            /* Noche */
  --bg-alto: #1F2240;       /* la parte de arriba del degradado, la del splash */
  --surface: #20233A;
  /* Un escalón por encima de --surface, para lo que tiene que despegarse de
     una tarjeta que ya está sobre el fondo. Se usaba en dos sitios sin estar
     definida (el icono de las ventajas y el botón de cerrar un dispositivo):
     `var()` de algo que no existe no da error, se salta la propiedad entera,
     así que esos dos fondos llevaban tiempo sin pintarse y nadie lo veía. */
  --surface-alto: #2A2D4A;
  --surface2: #2C2F50;
  --ink: #E9E9ED;           /* Marfil */
  --ink-soft: #A2A3BF;
  --accent: #9184D9;        /* Acento */
  --accent-claro: #CFC7F0;  /* el lila claro de las chispas del logo */
  --luna: #F0C987;          /* Luna: el dorado de la luna y de «Luna» */
  --line: #33365A;
  --radius: 14px;
}

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

/* `display` de una regla propia le gana al atributo hidden, así que sin esto
   un elemento marcado como oculto se sigue viendo. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  background-image: linear-gradient(180deg, var(--bg-alto) 0%, var(--bg) 46%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: -apple-system, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  overscroll-behavior: none;          /* sin rebote de scroll en WebView */
  -webkit-user-select: none;
  user-select: none;
}

.app {
  max-width: 560px;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top, 0px) + 24px) 20px
           calc(env(safe-area-inset-bottom, 0px) + 32px);
  min-height: 100dvh;
}

.top { text-align: center; margin-bottom: 24px; position: relative; }

/* El botón de ayuda, arriba a la derecha. Discreto —es una salida de
   emergencia, no una función que promocionar— pero siempre alcanzable, también
   desde la pantalla de la cuenta: parte de lo que alguien necesita contarnos
   es justo lo que le impide entrar. */
.ayuda {
  position: absolute; top: 0; right: 0;
  background: none; border: 0; padding: 6px;
  color: var(--ink-soft); cursor: pointer; line-height: 0;
  border-radius: 999px;
}
.ayuda:active { color: var(--accent); }
.top h1 {
  margin: 0; font-size: 1.9rem; letter-spacing: -0.01em;
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
/* El logotipo reducido del diseño (el que pide por debajo de 160 px). Es un
   SVG con las letras en contornos: se ve igual sin instalar la tipografía. */
.top h1 .logotipo { display: block; width: 148px; height: auto; }

/* Los iconos son de línea y heredan el color del texto, así que basta con
   alinearlos: no hace falta una versión por color ni por estado. */
.icono { display: inline-block; vertical-align: -0.18em; flex: none; }
.tagline { margin: 4px 0 0; color: var(--ink-soft); font-size: 0.95rem; }

.pantalla { display: none; }
.pantalla.activa { display: block; }

.campo { display: block; margin-top: 16px; }
.campo > span {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 8px;
}

/* Escuchar antes de elegir. Va en la etiqueta y no como otro botón grande:
   es una ayuda, no una acción principal, y compite con "Crear y narrar". */
.oir {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: none; padding: 2px 0;
  color: var(--accent); font-size: 0.82rem; cursor: pointer; white-space: nowrap;
}
.oir:disabled { color: var(--ink-soft); }

/* Todos los campos de texto, no solo type="text": el correo y la contraseña
   son type="email" y type="password" y se quedaban sin estilo, blancos, como
   si fueran de otra página. */
input[type="text"], input[type="email"], input[type="password"], textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  /* Sin esto, el navegador pone SU tipografía de formularios — y en los
     textarea eso es monoespaciada. Se notaba justo donde más duele: en «Tu
     propio texto», donde alguien pega un cuento entero y lo lee como si fuera
     código. */
  font-family: inherit;
  font-size: 1.05rem;
  line-height: 1.5;
  padding: 13px 16px;
  outline: none;
  -webkit-user-select: text;
  user-select: text;
}
input:focus, textarea:focus { border-color: var(--accent); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  font-size: 0.95rem;
  padding: 9px 15px;
  cursor: pointer;
}
.chip.activa { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 700; }

.avanzado summary { color: var(--ink-soft); font-size: 0.9rem; cursor: pointer; }
.avanzado textarea { margin-top: 10px; }

button.principal {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%;
  margin-top: 26px;
  background: var(--accent);
  border: none;
  border-radius: var(--radius);
  color: var(--bg);
  font-size: 1.15rem;
  font-weight: 700;
  padding: 16px;
  cursor: pointer;
}
button.principal:active { transform: scale(0.985); }

/* ── Cuánto falta ─────────────────────────────────────────────────────────
   Una línea de dos píxeles entre el texto y el reloj. Del mismo grosor que
   los separadores de la app a propósito: a oscuras y con un niño al lado,
   esto se mira de reojo — si pesara más competiría con la frase que se está
   iluminando, que es lo único importante de esta pantalla. */
.avance-cuento {
  height: 2px;
  margin-top: 14px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
.avance-cuento span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-claro));
  transition: width 0.5s ease;
}
/* Con el cuento en pausa la barra se apaga igual que el reloj: quieta y
   encendida parecería que sigue avanzando. */
.reloj-cuento.en-pausa ~ .avance-cuento span,
.avance-cuento.en-pausa span { opacity: 0.45; }

@media (prefers-reduced-motion: reduce) { .avance-cuento span { transition: none; } }

/* ── El reloj del cuento ──────────────────────────────────────────────────
   Sutil por diseño, no por descuido. Va debajo del texto, a oscuras, mientras
   un niño escucha: si pesara más que el resaltado de la frase estaría
   robándole la atención a lo único que importa de esta pantalla.

   Cifras tabulares para que los dígitos no bailen al cambiar de segundo — sin
   eso, un "1" siguiendo a un "8" mueve el número entero y el ojo lo nota. */
.reloj-cuento {
  display: block;
  margin-top: 14px;
  text-align: center;
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  opacity: 0.85;
  transition: opacity 0.6s ease;
}
/* En pausa el reloj se apaga un poco. Es la única señal que hace falta: el
   número ya está congelado, y bajarle la luz lo dice sin escribir "en pausa". */
.reloj-cuento.en-pausa { opacity: 0.4; }

/* ── Preguntar dentro de la capa ──────────────────────────────────────────
   Dos botones y, si hace falta, una lista para elegir. Se reutiliza la capa
   que ya existe en vez de montar otro diálogo: un solo sitio donde arreglar
   el foco, el fondo y lo que pase al tocar fuera. */
.capa-botones { display: flex; gap: 10px; margin-top: 18px; }
.capa-botones button {
  flex: 1;
  padding: 13px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: 0.98rem;
  cursor: pointer;
}
/* Gana a la regla global de `button.principal`, que trae `width:100%`,
   `margin-top:26px` y letra más grande — pensadas para un botón solo en medio
   de una pantalla, no para uno de dos en fila. Sin esto los dos botones salen
   de distinto tamaño y desalineados. */
.capa-botones button.principal {
  background: var(--accent);
  border: none;
  color: var(--bg);
  width: auto;
  margin-top: 0;
  font-size: 0.98rem;
  padding: 13px;
}
.capa-botones button:disabled { opacity: 0.45; cursor: default; }

.capa-opciones { display: grid; gap: 8px; margin-top: 16px; text-align: left; }
.capa-opciones button {
  padding: 12px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: 0.95rem;
  cursor: pointer;
  text-align: left;
}
.capa-opciones button.elegida { border-color: var(--accent); background: var(--surface2); }
.capa-opciones small { display: block; color: var(--ink-soft); font-size: 0.8rem; margin-top: 2px; }

/* Los botones de las tiendas, en la pantalla que ve quien abre la app en un
   navegador. Uno debajo de otro y a lo ancho: en un móvil son lo único que
   hay que tocar. */
.tiendas { display: grid; gap: 10px; margin-top: 22px; }
.tiendas a {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  padding: 15px;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--bg);
  font-size: 1.05rem;
  font-weight: 600;
  text-decoration: none;
}
.tiendas a.apagado {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-weight: 400;
  pointer-events: none;
}

.controles { display: flex; gap: 10px; margin-top: 22px; }
.controles button {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font-size: 1rem;
  padding: 14px;
  cursor: pointer;
}
.controles button.principal { margin-top: 0; background: var(--accent); border: none; color: var(--bg); }

/* Guardar el cuento va debajo y pesa menos que pausa o volver: es lo que se
   hace una vez cada muchas noches, no lo que se busca a oscuras. */
.controles.secundarios { margin-top: 10px; }
.controles button.discreto {
  background: transparent;
  border: 1px solid transparent;
  color: var(--ink-soft);
  font-size: 0.9rem;
  padding: 10px;
}
.controles button.discreto:hover { color: var(--ink); border-color: var(--line); }
.controles button.discreto:disabled { opacity: 0.5; cursor: default; }

.escena-actual {
  display: flex; align-items: center; gap: 7px;
  color: var(--accent); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.12em;
}
.texto-cuento {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  line-height: 1.7;
  font-size: 1.08rem;
  max-height: 46dvh;
  overflow-y: auto;
}
/* ── Seguir la lectura ────────────────────────────────────────────────────
   Como un karaoke, pero sin karaoke. Lo que ya se contó se apaga, lo que suena
   se ilumina como el filo de la luna del icono, y lo que viene espera en un
   tono intermedio. Tres estados y ninguna caja de color: a oscuras, un bloque
   resaltado deslumbra, y un niño que está a punto de dormirse no necesita que
   la pantalla le grite dónde va.

   La transición es larga a propósito (0,6 s). Un cambio instantáneo llama la
   atención hacia la pantalla; uno lento se percibe como que el texto respira. */
.texto-cuento .oracion {
  color: var(--ink-soft);
  transition: color 0.6s ease, opacity 0.6s ease;
}
.texto-cuento .oracion.contada { opacity: 0.45; }
.texto-cuento .oracion.actual {
  color: var(--accent-claro);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .texto-cuento .oracion { transition: none; }
}

.nota { color: var(--ink-soft); font-size: 0.8rem; margin-top: 16px; }

/* El aviso de lenguaje del texto propio: ámbar y no rojo, porque la app
   avisa y el adulto decide — un rojo diría "esto está prohibido" y no lo
   está. Pegado al campo (margen corto) para que se lea como parte de él. */
.aviso-lenguaje { color: var(--luna); margin-top: 8px; }

/* El distintivo de "esto no necesita internet". Es una promesa del producto,
   así que se enseña — pero del tamaño de una nota al pie, no de un cartel. */
/* El icono de la escena a la izquierda, el sello a la derecha, y cada uno con
   su propio espaciado: el contenedor ya no puede repartir el hueco entre el
   icono y su texto porque ahora hay un tercer elemento en la fila. */
/* Los sellos BAJAN a otra línea antes que salirse.

   Con `space-between` y `nowrap`, tres sellos y un nombre de temática largo
   —"Noche estrellada"— empujaban el último fuera de la pantalla. Un texto
   cortado por el borde es de las cosas que más barata hacen parecer una app. */
/* Los sellos caben en UNA línea, encogiendo lo justo.

   Con `space-between` y `nowrap`, "funciona sin internet" se salía de la
   pantalla. Con `wrap` dejó de salirse pero bajaba a una segunda línea, y para
   tres sellos pequeños eso es demasiado sitio. La letra ya era diminuta, así
   que lo que cede es el ESPACIADO entre letras —que en mayúsculas sobra— y el
   relleno de la píldora. El texto se lee igual y la fila vuelve a ser una.

   El `wrap` se queda de red: en un teléfono muy estrecho, o con una temática
   de nombre larguísimo, bajar de línea sigue siendo mejor que cortarse. */
.escena-actual { flex-wrap: wrap; justify-content: flex-start; gap: 6px 8px; }
.escena-actual > * { min-width: 0; }
.escena-actual .sello { font-size: 0.58rem; letter-spacing: 0.03em; padding: 3px 7px; }
#player-escena { letter-spacing: 0.08em; }
#player-escena { display: inline-flex; align-items: center; gap: 7px; }
.sello {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--ink-soft); font-size: 0.62rem; letter-spacing: 0.06em;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 9px; text-transform: uppercase; white-space: nowrap;
}

/* Solo aparece cuando algo va mal de verdad — la sesión de audio no quedó en
   modo reproducción y el cuento se va a callar con el teléfono en silencio.
   Ese sí es un aviso que hay que poder leer desde el propio teléfono. */
.aviso {
  margin-top: 14px; padding: 9px 12px;
  background: rgba(232, 197, 106, 0.12);
  border: 1px solid rgba(232, 197, 106, 0.4);
  border-radius: 10px;
  color: var(--luna); font-size: 0.78rem;
}

/* ── Elegir narrador ──────────────────────────────────────────────────────
   Tarjetas y no chips: la voz es la decisión más personal de la app y hay que
   poder oírla antes de elegirla. La onda de sonido a la izquierda, el nombre
   en medio, y el botón de oír a la derecha — que suena SIN cambiar la
   elección, para poder comparar las dos sin comprometerse. */
/* `minmax(0, 1fr)` y no el `auto` implícito: una columna `auto` se estira a lo
   que pida su contenido, así que una descripción larga ensanchaba la tarjeta
   más allá de la hoja y el botón de oír se salía de la pantalla. */
.voces { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }

.voz {
  display: flex; align-items: center; gap: 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  padding: 13px 15px;
  text-align: left;
  cursor: pointer;
}
.voz.activa { border-color: var(--accent); background: var(--surface2); }

.voz-onda { color: var(--ink-soft); display: inline-flex; flex: none; }
.voz.activa .voz-onda { color: var(--accent-claro); }

/* `min-width: 0` no es cosmético: por defecto un elemento flexible no encoge
   por debajo de su contenido, así que la descripción en una sola línea
   empujaba la tarjeta a lo ancho y dejaba el botón de oír fuera de la
   pantalla. Con esto, el texto se recorta con puntos suspensivos y el botón
   se queda donde tiene que estar. */
.voz-texto { flex: 1; min-width: 0; display: block; line-height: 1.3; }
.voz-texto b { display: block; font-size: 1rem; font-weight: 600; }
.voz-texto small { color: var(--ink-soft); font-size: 0.8rem; }

.voz-oir {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none;
  border: 1px solid var(--line); border-radius: 999px;
  color: var(--accent); background: var(--bg);
}
.voz-oir:active { transform: scale(0.94); }
.voz.activa .voz-oir { border-color: var(--accent); }

/* El acento va SIEMPRE visible, junto al carácter de la voz. Es el dato con
   el que se elige de verdad, y esconderlo para que la lista quede limpia sería
   dejar que alguien descubra el acento cuando ya está el cuento sonando. */
/* El acento en la misma línea que el nombre, como una etiqueta pequeña. Antes
   iba pegado a la descripción y las dos juntas no cabían: cada tarjeta se
   comía tres líneas y catorce voces eran un muro. */
/* El nombre y su acento nunca se parten en dos líneas: si aprieta, se recorta
   la descripción, que es lo que menos falta hace para decidir. */
.voz-linea { display: flex; align-items: baseline; gap: 8px; flex-wrap: nowrap; }
.voz-acento {
  color: var(--ink-soft); font-size: 0.66rem;
  letter-spacing: 0.04em; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 7px;
}
.voz-texto small {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Las premium se enseñan desde el principio, apagadas y con su sello. Que se
   vea lo que hay es parte de la oferta; disfrazarlas de disponibles sería
   mentir, y esconderlas, no vender nada. Se pueden OÍR igual: es el único
   modo de que alguien quiera pagarlas. */
.voz.bloqueada { opacity: 0.78; }
.voz.bloqueada .voz-texto b { font-weight: 500; }
/* Las premium llevan la chispa en vez de la onda: se distinguen de un vistazo
   y no cuesta ni un píxel de ancho. */
.voz.bloqueada .voz-onda { color: var(--accent-claro); }

/* La corona: lo que se paga se ve, lo tengas o no. Quien no lo tiene entiende
   qué le falta; quien sí, ve en qué se le va el dinero — que es la mitad de
   la razón por la que la gente renueva. */
.corona {
  display: inline-flex; align-items: center;
  color: var(--luna); flex: none; margin-left: 1px;
}
/* El micrófono que acompaña a la corona en las voces grabadas por el usuario.
   Va un pelo separado y un pelo más apagado: la corona manda, esto matiza. */
.corona svg + svg { margin-left: 2px; opacity: 0.85; }


/* El separador entre las voces que ya narran y las que llegan con la
   suscripción. Un título dentro de la lista y no dos listas: son la misma
   decisión —quién narra— con dos precios. */
.voces-corte {
  display: flex; align-items: center; gap: 10px;
  margin: 18px 0 2px;
  color: var(--ink-soft); font-size: 0.72rem;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.voces-corte::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* ── La cuenta del adulto ─────────────────────────────────────────────────
   Sobria a propósito: es la única pantalla de la app que no es para el niño,
   y disfrazarla de juego confundiría sobre quién tiene que rellenarla. */
.intro { color: var(--ink-soft); font-size: 0.95rem; line-height: 1.55; margin: 0 0 18px; }

.error {
  background: rgba(210, 90, 110, 0.14);
  border: 1px solid rgba(210, 90, 110, 0.45);
  border-radius: var(--radius);
  color: #F0A8B4;
  font-size: 0.9rem;
  padding: 11px 14px;
  margin: 16px 0 0;
}

.pie-cuenta {
  color: var(--ink-soft); font-size: 0.8rem; text-align: center; margin-top: 22px;
}
.pie-cuenta button {
  background: none; border: none; color: var(--accent);
  font-size: 0.8rem; cursor: pointer; padding: 0;
}

/* ── Elegir temática ──────────────────────────────────────────────────────
   Tarjetas y no chips en fila. Cinco chips se envuelven en 3+2 y el resultado
   parece un accidente del navegador, no una decisión.

   Flex con ancho fijo y centrado, en vez de una rejilla: una rejilla deja la
   última fila pegada a la izquierda cuando no está completa, y con cinco
   elementos nunca lo está. Centrando, cualquier número de temáticas cae
   ordenado — cinco, seis o nueve — sin tocar nada. */
.temas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  /* Se ancla a tres columnas exactas. Sin este tope, en pantallas anchas
     caben cuatro y la quinta temática se queda sola en la fila de abajo, que
     se ve peor que el 3+2. Así la composición es la misma en un iPhone
     pequeño y en un navegador de escritorio. */
  max-width: calc(100px * 3 + 10px * 2);
  margin: 0 auto;
}

.tema-tarjeta {
  /* Más bajas de lo que eran (92 px de alto mínimo y 14 de relleno). La
     pantalla de crear tiene cinco decisiones apiladas y, al añadir la del
     fondo, la última quedaba fuera de la vista en un teléfono normal. Las
     tarjetas eran lo que más sitio ocupaba sin necesitarlo: el icono y una
     palabra caben holgados en 78. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 100px;
  min-height: 78px;
  padding: 10px 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-size: 0.83rem;
  line-height: 1.25;
  text-align: center;
  cursor: pointer;
}

.tema-tarjeta .icono { color: var(--ink-soft); }

.tema-tarjeta.activa {
  border-color: var(--accent);
  background: var(--surface2);
  color: var(--ink);
}
.tema-tarjeta.activa .icono { color: var(--accent-claro); }
.tema-tarjeta:active { transform: scale(0.97); }

/* ── La biblioteca ────────────────────────────────────────────────────────
   Filas anchas y no una rejilla: lo que se busca aquí es un título concreto
   —"el del caracol"— y para eso el ojo baja por una columna mucho mejor de lo
   que recorre una cuadrícula. */
.lista { display: grid; gap: 9px; margin-bottom: 20px; }

.entrada {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  padding: 13px 15px;
  text-align: left;
  cursor: pointer;
}

/* El cuento que se acaba de oír, al volver a la lista. Un resalte corto que
   dice «era este» y se va solo: con cuatrocientos cuentos agrupados por fecha,
   volver a la lista sin nada que mire es volver a buscarlo. */
.entrada.recien-oido {
  animation: recien-oido 2.2s ease-out;
}
@keyframes recien-oido {
  0%, 55% { background: color-mix(in srgb, var(--accent) 22%, transparent); }
  100%    { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .entrada.recien-oido { animation: none; outline: 2px solid var(--accent); outline-offset: 2px; }
}
.entrada .icono { color: var(--accent); flex: none; }
.entrada-texto { flex: 1; line-height: 1.35; }
.entrada-texto b { display: block; font-weight: 600; font-size: 0.98rem; }
.entrada-texto small { color: var(--ink-soft); font-size: 0.79rem; }

button.secundario {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font-size: 1rem;
  padding: 14px;
  cursor: pointer;
}

h2 { font-size: 1.25rem; margin: 0 0 14px; }

/* ── La capa de espera ────────────────────────────────────────────────────
   Dos esperas largas tiene la app: montar el cuento y guardarlo. Antes las dos
   se contaban con una línea de texto suelta, que a la vista parece que la app
   se colgó y alguien dejó ahí un mensaje de depuración.

   Una luna que gira despacio. Despacio importa: a 3 segundos por vuelta
   acompaña la espera, y a 1 segundo la mete prisa. */
.capa {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  background: rgba(10, 10, 24, 0.82);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  padding: 24px;
  animation: capa-entra 0.25s ease;
}
@keyframes capa-entra { from { opacity: 0; } to { opacity: 1; } }

/* LA CAJA NO PUEDE SER MÁS ALTA QUE LA PANTALLA.

   Sin esto, una lista larga de opciones dejaba al usuario ENCERRADO: la caja
   crecía por encima del alto de la pantalla, la capa la centra, y los botones
   de aceptar y cancelar quedaban por debajo del borde sin ninguna forma de
   llegar a ellos ni de cerrar. Le pasó al dueño el 10-09-2026 al pedir el
   cuento con otra voz —doce narradores— y tuvo que cerrar la app: «no me deja
   bajar, si selecciono una voz no me deja confirmar y tampoco me deja salir».

   Es el MISMO fallo que ya se había arreglado en las hojas (ver «TODO lo que
   va dentro de una hoja scrollea dentro de ella»), y aquí no estaba: se
   arregló donde apareció en vez de en todo lo que se abre encima. Ahora la
   caja tiene techo y su contenido se desplaza dentro de ella. */
.capa-caja {
  width: 100%; max-width: 330px; text-align: center;
  max-height: calc(100dvh - 48px);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 30px 24px 24px;
}
.luna-espera { color: var(--accent); animation: gira 3s linear infinite; }
@keyframes gira { to { transform: rotate(360deg); } }

/* SOLO UN AVISO: ni luna girando ni barra.
   La misma capa sirve para esperar y para avisar, y eso estaba diciendo dos
   cosas a la vez: "se cerró tu sesión" con una luna dando vueltas y una barra
   debajo se lee como que algo se está procesando, cuando no hay nada que
   procesar y no hay nada que esperar. */
.capa.aviso .luna-espera { animation: none; }
.capa.aviso .capa-barra { display: none; }
@media (prefers-reduced-motion: reduce) {
  .luna-espera { animation: late 2.4s ease-in-out infinite; }
  @keyframes late { 50% { opacity: 0.45; } }
}

.capa-titulo { font-size: 1.05rem; font-weight: 600; margin: 16px 0 4px; }
.capa-detalle { color: var(--ink-soft); font-size: 0.85rem; margin: 0; min-height: 1.2em; }
/* La nota de «no bloquees todavía»: más pequeña y más apagada que el detalle,
   porque acompaña sin competir con la frase que rota encima. */
/* Más apagada de lo que parece que debería: es un apunte, no un aviso. El
   dueño la vio en su iPhone y dijo «sigue saliendo muy fuerte» (24-09-2026).
   Compite con la frase que rota encima, y esa sí es la que hay que leer. */
/* Cancelar está, pero no compite: quien espera un cuento no tiene que ver un
   botón de salida más fuerte que la barra que avanza. Discreto y suficiente. */
.capa-cancelar {
  margin: 1.1rem auto 0; display: block;
  background: none; border: 0; color: var(--ink-soft);
  font-family: inherit; font-size: 0.82rem; padding: 6px 12px;
  border-radius: 8px; cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px;
}
.capa-cancelar:active { background: var(--surface-alto); }
.capa-confirmar { margin-top: 1.1rem; }
.capa-confirmar p { margin: 0 0 0.8rem; font-size: 0.86rem; color: var(--ink); }
.capa-confirmar-botones { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }
.capa-confirmar-botones button {
  font-family: inherit; font-size: 0.86rem; padding: 9px 16px;
  border-radius: 10px; cursor: pointer;
  background: var(--surface-alto); color: var(--ink); border: 1px solid var(--line);
}
.capa-confirmar-botones .principal { background: var(--accent); color: #17123A; border-color: transparent; }

.capa-nota { color: var(--ink-soft); opacity: 0.42; font-size: 0.72rem;
             margin: 0.75rem 0 0; line-height: 1.35; letter-spacing: 0.01em; }

/* La barra no lleva número. El porcentaje invita a mirarlo bajar, y eso hace
   la espera más larga de lo que es. */
.capa-barra {
  height: 3px; margin-top: 18px; border-radius: 999px;
  background: var(--line); overflow: hidden;
}
.capa-barra > div {
  height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-claro));
  transition: width 0.35s ease;
}
/* Sin porcentaje que enseñar —preparando el motor, convirtiendo— la barra se
   pasea sola en vez de quedarse clavada en cero, que parece atasco. */
.capa-barra.indeterminada > div {
  width: 38%; animation: pasea 1.5s ease-in-out infinite;
}
@keyframes pasea {
  0% { margin-left: -38%; } 100% { margin-left: 100%; }
}

.capa-cerrar {
  margin-top: 18px; background: none; border: 1px solid var(--line);
  border-radius: 10px; color: var(--ink); padding: 9px 20px;
  font-size: 0.9rem; cursor: pointer;
}

/* ── Elegir narrador ──────────────────────────────────────────────────────
   Una fila que dice quién narra hoy, y una hoja que sube desde abajo para
   cambiarlo. Antes las catorce voces vivían desplegadas en la pantalla de
   crear: empujaban el botón de "Crear y narrar" fuera de la vista y
   convertían la decisión más bonita de la app en un listado de inventario.

   La voz se elige una vez y no se vuelve a tocar en meses. Merece estar a un
   toque, no ocupar media pantalla todas las noches. */
.narrador {
  display: flex; align-items: center; gap: 13px; width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  padding: 13px 15px;
  text-align: left;
  cursor: pointer;
}
.narrador .voz-onda { color: var(--accent-claro); }
.narrador-cambiar {
  display: inline-flex; align-items: center; gap: 2px; flex: none;
  color: var(--accent); font-size: 0.82rem;
}

.hoja { position: fixed; inset: 0; z-index: 60; display: flex; align-items: flex-end; }
.hoja-fondo {
  position: absolute; inset: 0;
  background: rgba(10, 10, 24, 0.72);
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
  animation: capa-entra 0.2s ease;
}
.hoja-caja {
  position: relative; width: 100%; height: 84dvh;
  display: flex; flex-direction: column;
  background: var(--bg-alto);
  border-top: 1px solid var(--line);
  border-radius: 22px 22px 0 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  animation: hoja-sube 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes hoja-sube { from { transform: translateY(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .hoja-caja, .hoja-fondo { animation: none; }
}

/* El asa no es decoración: es lo que dice "esto se puede cerrar" antes de que
   nadie tenga que buscar dónde. */
.hoja-asa {
  width: 38px; height: 4px; margin: 4px auto 10px;
  border-radius: 999px; background: var(--line); flex: none;
}
.hoja-cabeza {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 12px; flex: none;
}
.hoja-cabeza h3 { margin: 0; font-size: 1.05rem; }
.hoja-detalle {
  flex: none; margin: -4px 0 12px;
  color: var(--ink-soft); font-size: 0.85rem; line-height: 1.4;
}
.hoja-listo {
  background: none; border: none; padding: 4px 2px;
  color: var(--accent); font-size: 0.95rem; font-weight: 600; cursor: pointer;
}

/* TODO lo que va dentro de una hoja scrollea dentro de ella, no la página.

   Estaba puesto solo en la lista de voces, y por eso la hoja de ayuda se
   "trababa": su contenido pasaba de los 84dvh de la caja y el resto —el botón
   de reportar, los créditos— quedaba debajo del borde, sin ninguna forma de
   llegar. No era la lista larga: era que nunca hubo scroll ahí, y una lista
   corta lo tapaba.

   `min-height: 0` no sobra: dentro de un flex, un hijo no se encoge por debajo
   de su contenido salvo que se le diga, y sin eso el overflow no llega a
   activarse nunca. */
.hoja-caja > #ayuda-info,
.hoja-caja > #ayuda-creditos,
.hoja-caja > #ayuda-licencias,
.hoja-caja > #ayuda-reportar,
.hoja-caja > #pedir-campos {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding-bottom: 8px;
  /* El mismo canalón que la lista de voces, y por lo mismo: aquí también hay
     recuadros que llegan al borde y la barra se les montaba encima. */
  padding-right: 12px; margin-right: -12px;
}

/* La lista que se desplaza necesita un canalón para la barra.

   En iOS el indicador de desplazamiento se dibuja ENCIMA del contenido, no a
   un lado, así que se le montaba justo sobre el borde derecho de cada tarjeta
   de voz: parecía que las tarjetas estuvieran cortadas.

   El canalón sale del margen que ya tenía la hoja, no se le suma: el
   `margin-right` negativo devuelve esos 12 px de ancho y el `padding-right`
   los reserva por dentro. Así la barra cae sobre el hueco de la hoja y las
   tarjetas siguen alineadas exactamente con el título y con los botones de
   arriba, que es lo que se vería descuadrado si solo se añadiera relleno. */
.hoja .voces {
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding-bottom: 4px; margin-top: 12px;
  padding-right: 12px; margin-right: -12px;
  scrollbar-gutter: auto;
}

/* La elegida lleva su marca de verificación: dentro de una lista larga, el
   borde de color solo se ve si la voz está en pantalla. */
.voz-marca { flex: none; color: var(--accent); display: none; }
.voz.activa .voz-marca { display: inline-flex; }

/* ── El ojo de la contraseña ──────────────────────────────────────────────
   Dentro del campo y no al lado: es parte del campo, no otra acción. */
.campo-clave { position: relative; display: block; }
.campo-clave input { width: 100%; padding-right: 46px; }
.ver-clave {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: none; border: none; border-radius: 10px;
  color: var(--ink-soft); cursor: pointer;
}
.ver-clave:active { color: var(--accent); }

/* ── El menú de abajo ─────────────────────────────────────────────────────
   Mismo lenguaje que RobiLab: fijo, icono con etiqueta, activo en color. */
.menu-abajo {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; justify-content: space-around; align-items: stretch; gap: 4px;
  background: var(--bg-alto);
  border-top: 1px solid var(--line);
  padding: 6px 10px calc(6px + env(safe-area-inset-bottom));
}
.menu-boton {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px;
  background: none; border: none; border-radius: 14px;
  color: var(--ink-soft); font-size: 0.68rem; font-weight: 600;
  padding: 6px 2px; cursor: pointer;
}
.menu-boton.activa { color: var(--accent-claro); background: var(--surface); }
/* Hueco bajo el contenido para que el menú fijo no tape el final de la
   pantalla. Va condicionado: sin menú (puerta, reproductor) no hace falta. */
/* Más el borde de abajo del iPhone (la barra del gesto de inicio): el botón
   de «Mi voz» quedaba pegado al menú (dueño, 21-09). */
body.con-menu .app { padding-bottom: calc(112px + env(safe-area-inset-bottom, 0px)); }

/* ── El perfil ────────────────────────────────────────────────────────────/ */
.perfil-tarjeta {
  display: flex; align-items: center; gap: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-top: 14px;
  color: var(--ink);
}
.perfil-tarjeta > span { color: var(--accent); flex: none; }
.perfil-tarjeta b { display: block; font-size: 1.02rem; }
.perfil-tarjeta small { color: var(--ink-soft); display: block; margin-top: 2px; line-height: 1.4; }
#btn-salir, #btn-suscripcion-prueba {
  display: block; width: 100%; margin-top: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--ink);
  padding: 13px; font-size: 0.95rem; cursor: pointer;
}

/* La muestra que no pudo sonar avisa un instante en el propio botón. */
.fallo { color: var(--luna) !important; }

/* ── "Está sonando de verdad" ─────────────────────────────────────────────
   La onda de la tarjeta late mientras hay sonido saliendo. Si el botón está
   en "parar" pero nada late, el fallo es del audio, no del volumen. */
.voz.sonando, .narrador.sonando { border-color: var(--accent); }
.sonando .voz-onda { color: var(--accent-claro); animation: late-onda 1s ease-in-out infinite; }
#oir-tema.sonando { color: var(--accent-claro); animation: late-onda 1s ease-in-out infinite; }
@keyframes late-onda { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
  .sonando .voz-onda, #oir-tema.sonando { animation: none; }
}


/* ── Tu propio texto ──────────────────────────────────────────────────────── */
#in-texto {
  width: 100%; resize: vertical; min-height: 150px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--ink);
  padding: 14px; font-size: 1rem; line-height: 1.6; font-family: inherit;
}
#in-texto:focus { outline: none; border-color: var(--accent); }
.contador { color: var(--ink-soft); font-size: 0.78rem; font-variant-numeric: tabular-nums; }
.contador.al-limite { color: var(--luna); }


/* ── Segmentos: el selector de la casa ────────────────────────────────────
   UN componente para los cinco selectores de opciones: contenedor hundido y
   una pastilla que se DESLIZA hasta la opción activa (el patrón de los
   controles segmentados de iOS). La seriedad visual no está en decorar cada
   control: está en que todos sean exactamente el mismo. */
.segmentos {
  position: relative;
  display: flex;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 4px;
}
.segmentos .pastilla {
  position: absolute; top: 4px; bottom: 4px; left: 0; width: 0;
  background: var(--surface2);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1),
              width 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);

  /* EL ORDEN DE PINTADO, DICHO A MANO. En el WebView de Android la pastilla
     se pintaba ENCIMA del texto del segmento activo —a veces sí y a veces
     no—: al animarse con transform, el compositor la promueve a su propia
     capa y deja de respetar el orden que da `position: relative` sin más.
     Se comprobó que no era maquetación: los textos estaban en el DOM con su
     ancho, su color y opacidad 1, y aun así no se veían.

     Con `z-index` explícito en las dos partes y `will-change` en la que se
     mueve, la decisión de capas deja de ser una suposición del navegador. */
  z-index: 0;
  will-change: transform, width;
}
.segmento {
  /* La capa propia (translateZ) es lo que garantiza que el texto quede por
     encima de la pastilla también cuando el compositor de Android decide
     promoverla a ella. Ver la nota de .pastilla. */
  position: relative; z-index: 2; flex: 1;
  transform: translateZ(0);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px;
  background: none; border: none; border-radius: 10px;
  color: var(--ink-soft); font-size: 0.85rem; font-weight: 600;
  padding: 9px 4px; line-height: 1.25; cursor: pointer;
  white-space: nowrap;
  transition: color 0.2s ease;
}
.segmento.activa { color: var(--ink); }
.segmento small { font-size: 0.64rem; opacity: 0.7; font-weight: 500; }
.segmento .corona {
  position: absolute; top: 3px; right: 6px;
  display: inline-flex;
}

/* La decisión principal —qué narramos— lleva la pastilla en color. Las demás
   (duración, ritmo, género) son ajustes y van en tono neutro: una pantalla
   con cinco controles gritando en acento no tiene ninguna jerarquía. */
.segmentos.primaria .pastilla { background: var(--accent); border-color: var(--accent); }
.segmentos.primaria .segmento.activa { color: var(--bg); }

/* ── La biblioteca: buscar y grupos de tiempo ─────────────────────────────── */
.buscador-caja { position: relative; display: block; }
.buscador-lupa {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  color: var(--ink-soft); display: inline-flex; pointer-events: none;
}
.buscador-caja input {
  width: 100%; padding: 13px 14px 13px 42px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--ink); font-size: 1rem;
  -webkit-appearance: none; appearance: none;
}
.buscador-caja input:focus { outline: none; border-color: var(--accent); }

/* Los rótulos de grupo, como en Fotos o Mensajes: pequeños, en versalitas,
   con aire arriba. La lista deja de ser un volcado y se vuelve una línea de
   tiempo que se lee de un vistazo. */
.lista-grupo {
  margin: 20px 2px 8px; font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft);
}
.lista-grupo:first-child { margin-top: 14px; }

/* "Mostrar más" al pie de la biblioteca: un botón tranquilo que dice cuánto
   queda, en vez de un scroll infinito que esconde el fondo. */
.mostrar-mas {
  display: block; width: 100%; margin-top: 14px;
  background: none; border: 1px dashed var(--line);
  border-radius: var(--radius); color: var(--accent);
  padding: 13px; font-size: 0.9rem; cursor: pointer;
}


/* ── Cuenta: enlaces, espera y ajustes ─────────────────────────────────── */

/* Un botón que se lee como enlace: para lo secundario de verdad («olvidé mi
   contraseña», «usar otro correo»). Es <button> y no <a> porque no navega a
   ningún sitio; parecerlo es cosa del estilo, no del marcado. */
.enlace {
  display: block; width: 100%; margin-top: 12px;
  background: none; border: 0; color: var(--ink-soft);
  font-size: 0.9rem; font-family: inherit; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
  padding: 8px;
}
.enlace:active { color: var(--accent); }

/* El sobre de la pantalla de espera y el visto de «recibido»: el mismo
   círculo, que ya se reconoce de la capa de espera. */
.espera-luna {
  width: 76px; height: 76px; margin: 8px auto 18px;
  border-radius: 999px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line);
  color: var(--accent);
}

.nota-espera {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  color: var(--ink-soft); font-size: 0.9rem; margin: 18px 0;
}
/* El punto que late: dice «esto sigue vivo» sin prometer un plazo. Una barra
   de progreso aquí mentiría —no sabemos cuánto tarda alguien en abrir su
   correo— y además metería prisa. */
.latido {
  width: 9px; height: 9px; border-radius: 999px; background: var(--accent);
  animation: latir 1.6s ease-in-out infinite;
}
@keyframes latir { 0%, 100% { opacity: 1; transform: scale(1); }
                   50% { opacity: 0.35; transform: scale(0.75); } }
@media (prefers-reduced-motion: reduce) { .latido { animation: none; } }

/* El mismo punto, dentro del botón principal. Ahí el fondo YA es el color
   acento, así que un punto de ese color sería invisible: hereda el del texto.
   Y el botón ocupado no se apaga del todo —uno medio borrado parece
   estropeado— sino lo justo para que se note que está esperando. */
.principal .latido { background: currentColor; }
.principal:disabled { cursor: progress; opacity: 0.85; }

/* El fondo del cuento va dentro del mismo campo que las temáticas —es la
   misma decisión: dónde pasa y cómo suena— pero necesita respirar. Sin este
   margen quedaba pegado a la fila de tarjetas, como si se hubiera caído ahí. */
#sel-fondo { margin-top: 14px; }

.titulo-seccion {
  margin: 26px 0 4px; font-size: 0.78rem; color: var(--ink-soft);
  text-transform: uppercase; letter-spacing: 0.09em; font-weight: 600;
}

/* Una fila de ajuste: icono, texto en dos líneas y flecha. Mismo aire que
   .perfil-tarjeta para que la pantalla no parezca dos pantallas. */
.fila-ajuste {
  display: flex; align-items: center; gap: 14px; width: 100%;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px 16px; margin-top: 10px;
  color: var(--ink); font-family: inherit; font-size: 1rem;
  text-align: left; cursor: pointer;
}
.fila-ajuste > span:first-child { color: var(--accent); flex: none; line-height: 0; }
.fila-ajuste > span:last-child { color: var(--ink-soft); flex: none; line-height: 0; }
.fila-ajuste > span:nth-child(2) { flex: 1; }
.fila-ajuste b { display: block; font-size: 0.98rem; font-weight: 600; }
.fila-ajuste small { color: var(--ink-soft); display: block; margin-top: 2px; font-size: 0.82rem; }
.fila-ajuste:active { border-color: var(--accent); }

/* ── Hoja de ayuda ─────────────────────────────────────────────────────── */
.ayuda-marca { display: flex; align-items: center; gap: 14px; margin: 4px 0 18px; }
.ayuda-marca img { border-radius: 15px; flex: none; }
.ayuda-marca b { display: block; font-size: 1.15rem; }
.ayuda-marca small { color: var(--ink-soft); display: block; margin-top: 2px; }

/* El selector de servidor (modo pruebas). Una línea discreta bajo la marca:
   es para quien prueba, no para las familias. */
.ayuda-servidor {
  display: block; width: 100%; margin: -8px 0 16px; padding: 10px 12px;
  background: var(--surface); border: 1px dashed var(--line); border-radius: var(--radius);
  color: var(--ink-soft); font: inherit; font-size: 0.82rem; text-align: left; cursor: pointer;
  overflow-wrap: anywhere;
}
.ayuda-servidor[hidden] { display: none; }

/* La banda del servidor de pruebas: pequeña, arriba, sin tapar toques. */
.aviso-servidor {
  position: fixed; z-index: 90; left: 50%; transform: translateX(-50%);
  top: calc(env(safe-area-inset-top) + 2px);
  max-width: calc(100% - 32px); padding: 2px 10px; border-radius: 999px;
  background: var(--luna); color: var(--bg);
  font-size: 0.7rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none; opacity: 0.92;
}
.aviso-servidor[hidden] { display: none; }

.ayuda-parrafo { color: var(--ink-soft); font-size: 0.92rem; line-height: 1.6; margin: 0 0 18px; }

/* Las bondades de la app, en Ayuda.

   Sustituyen a tres cuadritos con números sueltos. Cada fila es un icono, una
   frase corta en claro y una línea que la explica en gris: se puede leer solo
   lo negrita y quedarse con la idea, o leerlo todo. El icono va en su propia
   caja para que la columna de texto quede alineada aunque el icono cambie. */
/* DOS COLUMNAS, no una lista larga.

   En una sola columna, ocho beneficios con su explicación medían más de dos
   pantallas: se leía como un folleto y el dueño lo dijo con esa palabra, que
   parecía hecho al apuro. En rejilla ocupa la mitad, se abarca de un vistazo y
   se parece a lo que hace cualquier página de producto — que es exactamente el
   aire que le faltaba.

   `auto-fit` con un mínimo: en un teléfono estrecho vuelve a una columna solo,
   sin necesidad de una media query que se olvide de actualizar. */
.bondades {
  list-style: none; margin: 0 0 18px; padding: 0;
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.bondades li {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 13px; padding: 12px 12px 13px;
}
.bondad-icono {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 9px; margin-bottom: 8px;
  background: var(--surface-alto); color: var(--accent-claro);
}
.bondades b { display: block; font-size: 0.88rem; font-weight: 600; margin-bottom: 2px; }
.bondades small { display: block; color: var(--ink-soft); font-size: 0.79rem; line-height: 1.45; }

/* Créditos (rehechos el 25-09-2026: «se ve muy mal… algo bonito, así sean
   los créditos»). Grupos como los de los ajustes del teléfono: un rótulo
   pequeño en versalitas y una tarjeta con una fila por sitio de origen. La
   fila entera es el enlace; la licencia, una pastilla a la derecha. Tamaños
   escritos aquí y no heredados: antes la negrita salía del tamaño que le
   tocara y en el iPhone los nombres se veían enormes.
   El desplazamiento lo da la regla de las caras de la hoja, de arriba: esta
   cara no estaba en la lista y por eso no se podía bajar. */
.cred-cabecera { text-align: center; padding: 6px 8px 4px; }
.cred-logo { width: 132px; height: auto; display: block; margin: 0 auto 10px; }
.cred-cabecera p {
  margin: 0 auto; max-width: 30ch;
  color: var(--ink-soft); font-size: 0.84rem; line-height: 1.5;
}
.cred-seccion { margin-top: 22px; }
.cred-rotulo {
  margin: 0 4px 8px;
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.cred-grupo {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.cred-fila {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 12px 12px 14px;
  color: var(--ink); text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.cred-fila + .cred-fila { border-top: 1px solid var(--line); }
.cred-fila:active { background: var(--surface-alto); }
.cred-fila:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cred-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cred-texto b { font-size: 0.9rem; font-weight: 600; line-height: 1.3; }
.cred-texto small { font-size: 0.76rem; line-height: 1.4; color: var(--ink-soft); }
.cred-licencia {
  flex: none; white-space: nowrap;
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.02em;
  padding: 3px 8px; border-radius: 999px;
  color: var(--accent-claro); background: rgba(145, 132, 217, 0.14);
}
.cred-flecha { flex: none; display: inline-flex; color: var(--ink-soft); opacity: 0.7; }
#btn-volver-creditos { display: block; margin: 22px auto 4px; }

.ayuda-pie {
  margin: 22px 0 6px; text-align: center;
  color: var(--ink-soft); font-size: 0.86rem; line-height: 1.6;
}
.ayuda-pie b { color: var(--ink); }
.ayuda-pie small { font-size: 0.76rem; opacity: 0.85; }

.gracias-titulo { text-align: center; margin: 0 0 10px; font-size: 1.2rem; }
#ayuda-gracias { text-align: center; }
#ayuda-gracias .ayuda-parrafo { text-align: center; }
#ayuda-gracias .secundario, #ayuda-gracias button {
  display: block; width: 100%; margin-top: 8px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--ink);
  padding: 13px; font-size: 0.95rem; cursor: pointer; font-family: inherit;
}

/* La hoja de pedir es corta: no necesita ocupar 84dvh como la de voces. */
#hoja-pedir .hoja-caja { height: auto; max-height: 88dvh; }
#hoja-pedir .campo, #hoja-ayuda .campo { margin-bottom: 4px; }


/* ── El plan de la cuenta ──────────────────────────────────────────────── */

/* La insignia de premium, al lado del nombre. Dorada y pequeña: tiene que
   reconocerse de un vistazo sin gritar. */
.insignia {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 8px; padding: 2px 8px 2px 6px;
  border-radius: 999px;
  background: rgba(232, 197, 106, 0.14);
  border: 1px solid rgba(232, 197, 106, 0.5);
  color: var(--luna);
  font-size: 0.68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  vertical-align: middle;
}

.plan {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-top: 14px;
}
/* Con suscripción, el borde se tiñe: la tarjeta entera se siente distinta,
   que es justo lo que se está pagando. */
.plan.activa { border-color: rgba(232, 197, 106, 0.45); }
.plan.activa #plan-icono { color: var(--luna); }

.plan-cabeza { display: flex; align-items: flex-start; gap: 14px; }
.plan-cabeza > span { color: var(--accent); flex: none; line-height: 0; margin-top: 2px; }
.plan-cabeza b { display: block; font-size: 1.02rem; }
.plan-cabeza small { color: var(--ink-soft); display: block; margin-top: 3px; line-height: 1.45; }

.ventajas { list-style: none; margin: 14px 0 0; padding: 0; }
.ventajas li {
  display: flex; align-items: flex-start; gap: 9px;
  color: var(--ink-soft); font-size: 0.89rem; line-height: 1.45;
  padding: 5px 0;
}
.ventajas li span { color: var(--accent); flex: none; line-height: 0; margin-top: 3px; }
.plan.activa .ventajas li span { color: var(--ok, #7BD88F); }

/* Los dispositivos de la cuenta. Fila por dispositivo: nombre, cuándo se usó y —si no
   es este— el botón de cerrarla. El de aquí no lleva botón a propósito: para
   salir de este teléfono ya está "Cerrar sesión" abajo, y dos maneras de hacer
   lo mismo en la misma pantalla solo hacen dudar. */
.dispositivos { display: grid; gap: 8px; margin-top: 8px; }
.dispositivo {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 14px;
}
.dispositivo > span[data-icono] { color: var(--ink-soft); flex: none; }
.dispositivo div { flex: 1; min-width: 0; }
.dispositivo b { display: block; font-size: 0.95rem; font-weight: 600; }
.dispositivo small { display: block; color: var(--ink-soft); font-size: 0.8rem; }
.dispositivo.este { border-color: var(--accent); }
/* "Este dispositivo" va en el renglón de debajo y no junto al nombre: pegado
   al nombre parte la línea en cualquier teléfono, y una etiqueta que se
   descoloca es justo lo contrario de lo que se buscaba. */
.dispositivo .es-este { color: var(--accent); font-weight: 600; }
.dispositivo .cerrar-dispositivo {
  flex: none; background: transparent; border: 1px solid var(--line);
  color: var(--ink-soft); border-radius: 9px; padding: 6px 11px;
  font-size: 0.82rem; font-family: inherit; cursor: pointer;
}
.dispositivo .cerrar-dispositivo:active { background: var(--surface-alto); }
.titulo-seccion small {
  text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--ink-soft);
}


/* El aviso de "estoy preparando la frase siguiente".

   Discreto a propósito: es información, no una alarma. Aparece bajo la escena
   y sobre el texto, que es justo donde está mirando quien se pregunta por qué
   no suena nada. La luna gira para que se vea que algo pasa aunque el texto
   no cambie. */
.esperando {
  display: flex; align-items: center; gap: 8px;
  margin: 2px 0 10px; color: var(--ink-soft); font-size: 0.85rem;
}
.esperando [data-icono] { display: inline-flex; animation: gira 1.1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .esperando [data-icono] { animation: none; }
}


/* Cuánto lleva preparado el cuento, en la pantalla de crear.

   Solo sale en dispositivos donde el motor genera más despacio de lo que se
   escucha. No bloquea nada: se puede pulsar "Crear y narrar" cuando se quiera.
   Lo que dice es "si esperas un poco más, el cuento sonará seguido", que es
   una información que el adulto merece tener por delante en vez de
   descubrirla con un silencio a mitad de cuento. */

/* ── «Mi voz» ─────────────────────────────────────────────────────────── */
/* El aviso del final de la hoja de voces, donde las clonadas no suenan (web,
   Android). Informa, no alarma: mismo tono que una ficha de voz apagada. */
.voces-nota {
  grid-column: 1 / -1;
  display: flex; gap: 12px; align-items: flex-start;
  margin-top: 10px; padding: 14px 16px; border-radius: 16px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line);
}
.voces-nota > span { color: var(--accent); flex: none; margin-top: 2px; }
.voces-nota b { display: block; font-size: 0.96rem; }
.voces-nota small { display: block; color: var(--ink-soft); margin-top: 4px; line-height: 1.5; }

.mi-voz-ficha {
  display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 12px;
  padding: 14px 14px 14px 16px; border-radius: 18px;
  background: linear-gradient(160deg, rgba(145, 132, 217, 0.14), var(--surface) 70%);
  border: 1px solid var(--line);
}
.mi-voz-ficha.activa { border-color: var(--accent); }
.mi-voz-ficha-icono {
  width: 46px; height: 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); background: rgba(145, 132, 217, 0.14);
}
.mi-voz-ficha b { display: block; font-size: 1.08rem; }
.mi-voz-ficha small { display: block; color: var(--ink-soft); margin-top: 2px; font-size: 0.82rem; }
.mi-voz-ficha .mi-voz-usar { display: inline-block; margin-top: 6px; color: var(--accent-claro, var(--accent)); font-size: 0.85rem; background: none; border: 0; padding: 0; font-family: inherit; cursor: pointer; }
/* «en tu cuenta»: el distintivo que contesta la única pregunta que importa de
   una voz grabada —¿la pierdo si pierdo el teléfono?—. Discreto a propósito:
   es una buena noticia, no una alarma. */
.mi-voz-nube {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 7px;
  padding: 3px 9px 3px 7px; border-radius: 999px;
  font-size: 0.74rem; letter-spacing: 0.02em;
  color: var(--ink-soft); background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
}
.mi-voz-nube svg { opacity: 0.85; }
.mi-voz-oir, .mi-voz-quitar {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--accent); font: inherit;
}
.mi-voz-oir { background: var(--accent); color: var(--bg); border-color: transparent; }
.mi-voz-oir:disabled { opacity: 0.7; }
.mi-voz-quitar { color: var(--ink-soft); }
.mi-voz-quitar:active { color: #e07a8a; }
.mi-voz-pasos { display: flex; gap: 6px; margin: 4px 0 14px; }
.mi-voz-pasos span { flex: 1; height: 4px; border-radius: 2px; background: var(--line); }
.mi-voz-pasos span.hecho { background: var(--accent); }
.mi-voz-pasos span.actual { background: var(--accent-claro, var(--accent)); opacity: 0.6; }
.mi-voz-frase {
  font-size: 1.3rem; line-height: 1.55; margin: 10px 0 22px;
  padding: 18px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line);
}
.mi-voz-centro { text-align: center; }
.mi-voz-mic {
  width: 84px; height: 84px; border-radius: 50%; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--bg); box-shadow: 0 0 0 10px rgba(145, 132, 217, 0.12);
  transition: transform 120ms ease;
}
.mi-voz-mic:active { transform: scale(0.96); }
.mi-voz-mic.grabando { background: #e07a8a; color: #fff; animation: mi-voz-late 1.2s ease-in-out infinite; }
@keyframes mi-voz-late { 50% { box-shadow: 0 0 0 18px rgba(224, 122, 138, 0.10); } }
.mi-voz-medidor { height: 6px; border-radius: 3px; background: var(--surface); overflow: hidden; margin: 18px auto 0; max-width: 260px; }
#mi-voz-nivel { height: 100%; width: 0; background: var(--accent); transition: width 80ms linear; }
.mi-voz-reloj { margin-top: 8px; min-height: 1.2em; font-variant-numeric: tabular-nums; }
.mi-voz-boton-texto { margin-top: 2px; }
.mi-voz-veredicto {
  margin: 16px 0 0; padding: 12px 14px; border-radius: 12px; font-size: 0.92rem;
  background: rgba(145, 132, 217, 0.12); color: var(--ink);
}
.mi-voz-veredicto.error { background: rgba(210, 90, 110, 0.14); }
.mi-voz-fila { display: flex; gap: 10px; margin-top: 14px; }
.mi-voz-fila > button { flex: 1; margin-top: 0; }
.mi-voz-tiempo { height: 4px; border-radius: 2px; background: var(--surface); overflow: hidden; margin: 8px auto 0; max-width: 260px; }
#mi-voz-tiempo-barra { height: 100%; width: 0; background: #6fcf97; transition: width 200ms linear, background 300ms; }
#mi-voz-tiempo-barra.cerca { background: #e8c46a; }
#mi-voz-tiempo-barra.pasado { background: #e07a8a; }

/* El splash animado de la app (ver «EL SPLASH ANIMADO» en main.js). Llena la
   pantalla recortando los lados, igual que la imagen quieta del sistema, para
   que la luna caiga en el mismo sitio y el relevo no se note. */
#carga {
  position: fixed; inset: 0; z-index: 2147483647;
  background: #161826;
  transition: opacity .6s ease;
}
#carga img { width: 100%; height: 100%; object-fit: cover; display: block; }
#carga.fuera { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { #carga { transition: none; } }

/* El icono de «preparando» de las voces propias gira: es lo que distingue
   «se está haciendo» de «hay que descargarla» sin tener que leer nada. */
.girando { display: inline-flex; animation: girar 0.9s linear infinite; }
@keyframes girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .girando { animation: none; } }

/* El enlace a las licencias: pequeño y al fondo, donde lo busca quien lo
   busca y no molesta a nadie más. */
.cred-licencias-enlace {
  display: block; margin: 6px auto 4px; padding: 6px 10px;
  background: none; border: none; cursor: pointer;
  color: var(--ink-soft); font-size: 0.72rem; opacity: 0.8;
  text-decoration: underline; text-underline-offset: 2px;
}
.cred-licencias-intro { color: var(--ink-soft); font-size: 0.8rem; line-height: 1.5; margin: 4px 2px 12px; }
.cred-avisos {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.cred-avisos li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  padding: 9px 14px; font-size: 0.78rem; line-height: 1.35;
}
.cred-avisos li + li { border-top: 1px solid var(--line); }
.cred-avisos small { flex: none; color: var(--ink-soft); font-size: 0.7rem; }
#licencias-textos { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.cred-texto-licencia summary {
  cursor: pointer; font-size: 0.8rem; color: var(--ink-soft); padding: 4px 2px;
}
.cred-texto-licencia pre {
  white-space: pre-wrap; word-break: break-word;
  font-size: 0.66rem; line-height: 1.45; color: var(--ink-soft);
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; margin: 6px 0 0; max-height: 50vh; overflow: auto;
}
#btn-volver-licencias { display: block; margin: 20px auto 4px; }

/* Los chips de cada cuento en la biblioteca: cuánto dura y a qué ritmo se
   contó. Pequeños y del color del acento, para que se lean de un vistazo sin
   competir con el título. */
.entrada-texto .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 6px; border-radius: 999px;
  font-size: 0.68rem; font-weight: 600; line-height: 1.5;
  font-variant-numeric: tabular-nums;
  color: var(--accent-claro); background: rgba(145, 132, 217, 0.14);
}
.chip svg { opacity: 0.85; flex: none; }
/* La fecha, en el color del texto: es lo primero que se busca en la lista. */
.chip.fecha { color: var(--ink); background: rgba(233, 233, 237, 0.08); }
/* La aproximada, un punto más tenue: se lee igual pero no presume de exacta. */
.chip.estimada { background: rgba(145, 132, 217, 0.08); color: var(--ink-soft); }

/* El aviso de la web arriba de «Cuentos»: crear y grabar se hace en la app. */
.biblioteca-web {
  margin: 0 0 16px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.biblioteca-web p { margin: 0; color: var(--ink-soft); font-size: 0.86rem; line-height: 1.45; }
.biblioteca-web-tiendas { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.biblioteca-web-tiendas:empty { display: none; }

/* reCAPTCHA (solo web): la insignia flotante tapaba la barra de abajo. Se
   oculta y el aviso va en texto junto al formulario (#aviso-recaptcha), que
   es lo que permiten las condiciones de Google. */
.grecaptcha-badge { visibility: hidden !important; }
