/* ============================================================
   Frasly Music · Hoja de estilos (v2, comunidad)
   Estilo: minimalista, limpio, centrado en la experiencia.
   ============================================================ */

/* Las variables de color de toda la app. El 5-sep-2026 se probó un modo
   claro y Ramón lo descartó: "quita el modo claro, déjalo como estaba
   antes". Se quitó la paleta clara y el botón, pero se dejaron los nombres
   (--velo-*, --sobre-acento, --titulo-*, --bien...) que salieron de aquel
   trabajo: eran rgba() y hex sueltos repetidos por el archivo, y tenerlos
   en un solo sitio no estorba y evita descuadres. */
:root {
  --bg: #0d0d12;
  --bg-soft: #15151d;
  --bg-card: #1a1a24;
  --text: #ececf1;
  --text-dim: #9a9aa8;
  --line: rgba(255, 255, 255, 0.08);
  --accent: #8b7cf6;
  --accent-2: #67e8f9;
  /* Texto que va ENCIMA del color de acento (botones de degradado). El
     acento es claro en los dos temas, así que esto se queda oscuro
     siempre: si se aclarara en modo claro, no se leería. */
  --sobre-acento: #0d0d12;
  --titulo-1: #ececf1;
  --titulo-2: #c7c7f0;
  --bien: #4ade80;
  --malo: #f87171;
  --megusta: #f47;
  --velo-1: rgba(255, 255, 255, 0.04);
  --velo-2: rgba(255, 255, 255, 0.06);
  --velo-3: rgba(255, 255, 255, 0.10);
  --velo-borde: rgba(255, 255, 255, 0.12);
  --lavado-estado: 0.35;   /* cuánto se nota el color del estado en su tarjeta */
  --radius: 18px;
  --shadow: 0 14px 50px rgba(0, 0, 0, 0.45);
}
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
input, textarea, select {
  font-family: inherit;
  color: var(--text);
  background: var(--velo-1);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 11px 13px;
  width: 100%;
  transition: border-color 0.2s ease, background 0.2s ease;
}
/* 44px de alto en todo lo que se toca con el dedo (5-sep-2026, prueba de
   usuario): los campos medían 41 y los desplegables de "Crear estado" 18.
   Las casillas de marcar se quedan como están: ahí lo que se pulsa es la
   etiqueta entera, no el cuadradito. */
input:not([type="checkbox"]):not([type="radio"]),
textarea, select { min-height: 44px; }
input:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--velo-2);
}
label { display: block; font-size: 0.82rem; color: var(--text-dim); margin-bottom: 4px; }
.optional { margin-top: 10px; }

.hidden { display: none !important; }
/* El atributo HTML "hidden" (elemento.hidden = true) es distinto de la
   clase .hidden de arriba, y sin esto pierde contra CUALQUIER regla de
   display más específica -- confirmado en producción: .primary-btn
   {display:inline-block} y .ad-banner{display:flex} lo anulaban, así
   que instalarBtn.hidden=true (lib/instalar.js) y adBanner.hidden=true
   (lib/banner.js) no ocultaban nada en la práctica. */
[hidden] { display: none !important; }

.consent-row { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; min-height: 44px; }
/* 5-sep-2026: 20px de casilla (antes "auto", o sea 13px del sistema) y la
   fila entera de 44px. No se centra: la casilla va arriba, alineada con la
   primera línea del texto, que puede ocupar dos. */
.consent-row input[type="checkbox"] { width: 20px; height: 20px; margin-top: 3px; flex: none; }
.consent-row span { color: var(--text-dim); font-size: 0.82rem; }
.consent-row a { color: var(--accent); text-decoration: underline; }

.danger-btn { color: var(--malo); border-color: rgba(248, 113, 113, 0.35); }

.mood-card.is-disabled { opacity: .4; pointer-events: none; }

.is-disabled { color: var(--text-dim); cursor: default; }

/* ---------- Header / menú ---------- */
.app-header {
  max-width: 1180px;
  margin: 0 auto;
  padding: 34px 24px 10px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
.logo-mark {
  width: 44px; height: 44px; border-radius: 22%;
  box-shadow: 0 4px 18px rgba(139, 124, 246, 0.45);
  flex-shrink: 0; display: block; object-fit: cover;
}
.app-header-inner { flex: 1; }
/* El degradado del título va de casi blanco a lila claro: sobre el fondo
   claro no se leía NADA (5-sep-2026). En claro se invierte a un degradado
   oscuro. Los dos extremos son variables para no repetir el truco. */
.menu-title {
  font-size: clamp(1.6rem, 3.5vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  background: linear-gradient(90deg, var(--titulo-1), var(--titulo-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.menu-subtitle { color: var(--text-dim); font-size: 0.95rem; margin-top: 2px; }

.top-nav { display: flex; gap: 12px; flex-wrap: wrap; }
.top-link {
  font-size: 0.85rem;
  border: 1px solid var(--line);
  padding: 9px 15px;
  border-radius: 999px;
  color: var(--text-dim);
  transition: all 0.2s ease;
}
.top-link:hover { border-color: var(--accent); color: var(--text); }

/* ---------- Parrilla de secciones (3-sep-2026) ----------
   Antes las secciones (Ruta, Comunidad, Crear estado, Premium) eran
   enlaces-palabra en la cabecera, uno al lado de otro. Ahora son tarjetas
   iguales en cuadrícula, con icono y nombre, al principio del contenido:
   más ordenado y dedo amable en móvil. */
/* 18-sep-2026, Ramón, con una flecha señalando el hueco a la derecha: con
   "auto-fill" el grid crea tantas columnas como caben en la pantalla ANCHA
   (escritorio), aunque solo haya 4 fichas -- las columnas de más quedan
   vacías pero siguen ocupando sitio, así que las cuatro fichas se quedaban
   pegadas a la izquierda con un hueco muerto a la derecha. "auto-fit" hace
   que esas columnas vacías se cierren del todo, y con justify-content:
   center el bloque de fichas (ya no estirado) queda centrado de verdad. El
   tope de 160px evita que, con pocas fichas, cada una se estire para
   rellenar el ancho libre. */
.secciones-nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 160px));
  justify-content: center;
  gap: 10px;
  margin: 0 0 18px;
}
.seccion-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 7px; padding: 15px 10px;
  border: 1px solid var(--line); border-radius: 16px;
  background: var(--bg-card); color: var(--text);
  text-align: center;
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
/* Cuando falta una ficha de las cuatro (Premium, oculta dentro de la app
   Android nativa -- ver lib/menu-flotante.js/index.html), la rejilla de 2
   columnas dejaba un hueco vacío donde estaba (4-sep-2026, foto de Ramón:
   "este espacio no puede estar vacío"). Con un número impar de fichas, la
   última pasa a ocupar el ancho entero en vez de dejar la mitad en blanco. */
.secciones-nav .seccion-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
.seccion-tile:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow); }
.seccion-tile:active { transform: translateY(0); }
.seccion-tile-icono { font-size: 1.55rem; line-height: 1; color: var(--accent); }
.seccion-tile-icono .fm-icono { width: 26px; height: 26px; display: block; }
.seccion-tile-nombre { font-size: 0.85rem; font-weight: 600; }

/* padding-bottom generoso (30-ago-2026): sitio de sobra reservado para que
   el menú flotante único, fijo abajo a la derecha, nunca coincida con la
   última tarjeta o botón real de la pantalla al llegar al final del
   scroll (confirmado con una captura real: tapaba la opción "Corta"). */
.container { max-width: 1180px; margin: 0 auto; padding: 18px 24px 100px; }
.container-narrow { max-width: 720px; }
.container-wide { max-width: 1240px; }

@media (max-width: 640px) { .app-header { padding-top: 20px; } }

/* ---------- Menú de estados ---------- */
.moods-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 20px;
}
/* "Tus favoritos" (6-sep-2026). Va antes de la rejilla de siempre, con
   una raya debajo que lo separa: sin ella, con las mismas tarjetas arriba
   y abajo, parece que la lista empieza repetida. Las tarjetas son las
   MISMAS clases, para que no haya dos aspectos de lo mismo. */
.favoritos-bloque {
  margin-bottom: 26px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}
.favoritos-titulo {
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 2px;
}
.favoritos-sub {
  font-size: 0.82rem;
  color: var(--text-dim);
  margin: 0 0 14px;
}

.mood-card {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-soft);
  color: var(--text);
  text-align: left;
  padding: 0;
  min-height: 190px;
  transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
  box-shadow: var(--shadow);
}
.mood-card:hover {
  transform: translateY(-5px);
  border-color: var(--c);
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.55);
}
.mood-card-bg {
  position: absolute; inset: 0; opacity: var(--lavado-estado);
  transition: opacity 0.4s ease, transform 0.7s ease;
}
.mood-card:hover .mood-card-bg { opacity: 0.55; transform: scale(1.05); }
.mood-card-body { position: relative; padding: 24px 20px; display: flex; flex-direction: column; gap: 8px; }
.mood-icon { font-size: 1.6rem; opacity: 0.95; }
/* Los 20 estados de casa ya no llevan emoji sino SVG de línea (ver
   lib/iconos.js): toman el color del estado, pesan lo mismo todos y se
   ven igual en cualquier móvil. Los estados que crea el usuario siguen
   siendo su emoji, y para esos manda el font-size de arriba. */
.mood-icon .fm-icono { width: 32px; height: 32px; display: block; color: var(--c); }
.mood-name { font-size: 1.25rem; font-weight: 700; }
.mood-desc { color: var(--text-dim); font-size: 0.86rem; flex: 1; }
.mood-styles {
  font-size: 0.72rem; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--c); margin-top: 8px; opacity: 0.9;
}
/* EL COLOR DE CADA ESTADO, LEGIBLE (5-sep-2026).

   Los veinte colores se eligieron mirando la tarjeta entera, no la línea de
   géneros. Medidos uno a uno contra el fondo oscuro, varios no llegaban al
   mínimo legible de 4,5: Pasión daba 2,0 y Descarga 1,45. Así que se aclaran
   lo justo para leerse, sin dejar de ser el color de ese estado. El icono se
   toca menos: como dibujo le basta con 3.

   Esto NO es del modo claro (que se descartó): arregla un fallo que llevaba
   ahí desde siempre en el tema de casa.

   El color plano de respaldo va PRIMERO: si el navegador no entiende
   color-mix (Chrome anterior a la 111), se queda en un gris que se lee
   seguro, en vez de en un color que no se ve. */
.mood-styles { color: var(--text-dim); }
@supports (color: color-mix(in srgb, red 50%, black)) {
  .mood-styles { color: color-mix(in srgb, var(--c) 60%, #ffffff); }
  .mood-icon .fm-icono { color: color-mix(in srgb, var(--c) 80%, #ffffff); }
}
.badge {
  position: absolute; top: 12px; right: 12px;
  font-size: 0.62rem; padding: 4px 9px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.45); border: 1px solid var(--line); color: var(--text-dim);
}

.app-footer { text-align: center; padding: 18px; color: var(--text-dim); font-size: 0.78rem; }

/* ---------- Barra inferior de navegación (4-sep-2026, Ramón: "en el pie
   debería tener iconos: inicio, archivos, reproductor, estados") ----------
   Fija abajo, en las 4 páginas principales. body-con-nav-inferior deja
   hueco al final para que no tape el último contenido; env(safe-area...)
   es el margen del gesto/la barra del móvil (iPhone con muesca, Android
   con barra de gestos). */
body.con-nav-inferior { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
.nav-inferior {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; background: var(--bg-card); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.nav-inferior a {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: 58px;
  padding: 8px 2px; text-decoration: none; color: var(--text-dim);
  font-size: 0.66rem; letter-spacing: 0.01em; white-space: nowrap;
}
/* 5-sep-2026, Ramón: "los iconos no sean tan pequeños que no se vean...
   ahora son un desastre" -- los emojis (🏠📁▶️🎭) dependían de la fuente
   de emoji de cada móvil: en unos se ven grandes y en color, en otros
   chiquitos o desiguales entre sí, y encima no cambiaban de color al
   marcar la pestaña activa. Se sustituyen por los MISMOS iconos
   dibujados (SVG, un solo trazo) en las 5 páginas -- tamaño idéntico
   siempre, y ahora sí se iluminan con el color de acento al estar
   activos, porque usan currentColor igual que el texto. */
.nav-inferior a .nav-inferior-icono { width: 23px; height: 23px; display: block; }
.nav-inferior a .nav-inferior-icono svg { width: 100%; height: 100%; display: block; }
.nav-inferior a.is-active { color: var(--accent); }
.nav-inferior a:active { opacity: 0.7; }

/* ---------- "¿Sabes que puedes...?" (lib/tips.js, 5-sep-2026) ----------
   Banda, no ventana: se lee o se ignora, pero no bloquea. Va justo encima
   de la barra de abajo, y entra deslizándose para que se note sin dar un
   susto. En pantalla ancha se queda a la izquierda, del tamaño de una
   tarjeta, en vez de cruzar los mil píxeles de lado a lado. */
.tip-banda {
  position: fixed; z-index: 45;
  left: 12px; right: 12px; bottom: calc(64px + env(safe-area-inset-bottom) + 10px);
  max-width: 420px;
  display: flex; align-items: flex-start; gap: 8px;
  padding: 13px 10px 13px 15px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 14px; box-shadow: var(--shadow);
  transform: translateY(14px); opacity: 0;
  transition: transform 0.25s ease, opacity 0.25s ease;
  /* Mientras no esté dentro no atrapa ni un toque: si por lo que sea se
     quedara invisible, no puede tapar nada. */
  pointer-events: none;
}
.tip-banda.is-dentro { pointer-events: auto; }
.tip-banda.is-dentro { transform: translateY(0); opacity: 1; }
.tip-cuerpo { flex: 1; min-width: 0; }
.tip-etiqueta {
  display: block; font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--accent); font-weight: 700;
}
.tip-texto { margin: 4px 0 0; color: var(--text); font-size: 0.88rem; line-height: 1.45; }
.tip-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.tip-ver {
  min-height: 40px; display: inline-flex; align-items: center; padding: 0 14px;
  border-radius: 999px; background: var(--accent); color: var(--sobre-acento);
  font-size: 0.82rem; font-weight: 700;
}
.tip-nunca {
  min-height: 40px; padding: 0 12px; border: none; background: transparent;
  color: var(--text-dim); font-size: 0.78rem; text-decoration: underline;
}
.tip-cerrar {
  flex: none; width: 40px; height: 40px; padding: 0;
  background: transparent; border: none; color: var(--text-dim);
  font-size: 1.4rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.tip-cerrar:hover { color: var(--text); }

/* La ficha del tutorial a la que lleva un aviso, recién abierta: un
   resplandor corto para que se vea a cuál has llegado. */
.ayuda-ficha.recien-llegado { animation: ayuda-resalte 1.6s ease-out 1; }
@keyframes ayuda-resalte {
  0%   { background: rgba(139, 124, 246, 0.16); }
  100% { background: transparent; }
}

/* ---------- "Cómo se usa" (ayuda.html, 5-sep-2026) ----------
   Cada cosa que sabe hacer la app es un <details>: cerrado se lee de un
   vistazo, abierto da los pasos. El icono es el mismo que se ve en la app,
   para reconocerlo cuando llegues allí.

   OJO CON EL <summary>: no lleva display:flex. En iPhone eso hace
   desaparecer el triángulo y deja el desplegable sin abrir (ya pasó en el
   Centro de la zona de alumnos). El reparto en filas lo hace un <span> de
   dentro, que sí puede ser flex sin problema. */
.ayuda-entradilla { color: var(--text-dim); font-size: 0.9rem; margin: 0 0 18px; line-height: 1.55; }
.ayuda-bloque { margin-bottom: 16px; }
.ayuda-bloque .panel-title { margin-bottom: 6px; }

.ayuda-ficha { border-top: 1px solid var(--line); }
.ayuda-ficha:first-of-type { border-top: none; }
.ayuda-ficha > summary {
  cursor: pointer; padding: 14px 0; list-style: none;
  min-height: 44px;   /* zona de toque: es lo que hay que acertar con el dedo */
}
.ayuda-ficha > summary::-webkit-details-marker { display: none; }
.ayuda-sumario { display: flex; gap: 14px; align-items: flex-start; }
.ayuda-icono { flex: 0 0 auto; display: flex; color: var(--accent); margin-top: 2px; }
.ayuda-icono .fm-icono { width: 24px; height: 24px; display: block; }
.ayuda-sumario-texto { flex: 1; }
.ayuda-sumario-texto strong { display: block; color: var(--text); font-size: 0.98rem; }
.ayuda-resumen { display: block; margin-top: 3px; color: var(--text-dim); font-size: 0.86rem; line-height: 1.5; }
/* La flecha: apunta a la derecha cerrada, abajo abierta. */
.ayuda-sumario::after {
  content: ""; flex: 0 0 auto; align-self: center;
  width: 9px; height: 9px; margin-left: 4px;
  border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim);
  transform: rotate(-45deg); transition: transform 0.2s ease;
}
.ayuda-ficha[open] .ayuda-sumario::after { transform: rotate(45deg); }
.ayuda-ficha[open] .ayuda-sumario-texto strong { color: var(--accent); }

.ayuda-detalle { padding: 0 0 16px 38px; }
.ayuda-pasos { margin: 0; padding-left: 20px; display: grid; gap: 8px; }
.ayuda-pasos li { color: var(--text-dim); font-size: 0.87rem; line-height: 1.55; }
.ayuda-pasos li::marker { color: var(--accent); font-weight: 700; }
.ayuda-nota {
  margin: 14px 0 0; padding: 10px 12px;
  background: var(--velo-2); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text-dim); font-size: 0.82rem; line-height: 1.5;
}
.ayuda-pie { color: var(--text-dim); font-size: 0.82rem; text-align: center; margin: 20px 0 0; }

@media (max-width: 640px) {
  .ayuda-detalle { padding-left: 0; }
}

/* ---------- Paneles comunes ---------- */
.panel {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
  margin-bottom: 20px;
  box-shadow: var(--shadow);
}
.panel-head { margin-bottom: 18px; }
.panel-title { font-size: 1.35rem; font-weight: 700; }
.panel-sub { color: var(--text-dim); font-size: 0.9rem; margin-top: 4px; }

.primary-btn, .secondary-btn {
  display: inline-block;
  border: none;
  border-radius: 12px;
  padding: 12px 20px;
  font-size: 0.92rem;
  font-weight: 600;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.primary-btn { background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: var(--sobre-acento); }
.secondary-btn { background: var(--velo-2); color: var(--text); border: 1px solid var(--line); }
.primary-btn:hover, .secondary-btn:hover { transform: translateY(-2px); opacity: 0.92; }
.primary-btn:disabled, .secondary-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Las tres formas de entrar en Frasly Lab (5-sep-2026): la accion arriba y
   debajo, en pequeno, que te llevas. Sin ese renglon, "Premium, 19 EUR/ano"
   al lado de "Pruebalo gratis" solo dice el precio, no lo que compras.
   display:flex y no display:block del .primary-btn de arriba, para que las
   dos lineas se apilen centradas en cualquier ancho. */
.primary-btn.lab-op {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  text-align: center;
  line-height: 1.3;
}
/* La lista de "donde lo guardo" (5-sep-2026). Se limita a la mitad de la
   pantalla y hace scroll dentro: con quince bibliotecas y estados, si no, el
   ultimo boton se sale por abajo y no se alcanza. */
.destino-lista {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 50vh;
  overflow-y: auto;
}
.secondary-btn.destino-op {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  text-align: center;
  line-height: 1.3;
}
.lab-op-nota {
  font-size: 0.78rem;
  font-weight: 500;
  /* Sobre el degradado del boton, no sobre el fondo de la tarjeta: el color
     tiene que salir de --sobre-acento, atenuado, o se pierde. */
  opacity: 0.85;
}
/* En el boton secundario el fondo es claro y el texto ya es --text: bajar la
   opacidad ahi lo deja gris sobre gris. Se usa el color atenuado de la casa,
   que ya esta medido para leerse. */
.secondary-btn.destino-op .lab-op-nota {
  opacity: 1;
  color: var(--text-dim);
}

/* ---------- Top bar del player ---------- */
/* EL SCROLL DE LA PANTALLA DE ELEGIR (31-ago-2026).
   Aqui ponia "overflow: hidden" a secas, junto con la altura fija de la
   ventana. Pensado para el reproductor a pantalla completa, donde no debe
   moverse nada. Pero esta MISMA clase la lleva la pantalla de "¿Donde quieres
   escucharlo? / ¿Cuanto quieres?", que en un movil mide 1.254 px de alto en
   una ventana de 812: los ultimos 442 px, con el boton "Empezar" dentro,
   quedaban fuera de alcance y la pagina no se dejaba bajar. En el ordenador
   no se veia, porque ahi la ventana es mas alta y cabe.
   Se conserva el hidden HORIZONTAL, que es el que evita que algo se salga por
   los lados, y se permite bajar. Con el reproductor puesto el contenido cabe,
   asi que ahi no aparece barra ninguna.
   Comprobado en un movil de 375x812 antes de publicarlo: se llega al boton,
   se pulsa y arranca la musica. */
.player-page { overflow-x: hidden; overflow-y: auto; }
.player-backdrop { position: fixed; inset: 0; z-index: -1; transition: background 1s ease; }
.player-top {
  max-width: 1180px; margin: 0 auto; padding: 20px 24px 6px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
/* 5-sep-2026, Ramón: "se hace dificil encontrar como volver a tras, lo
   pones muy pequeño arriba" -- antes era texto suelto del mismo tamaño
   que el resto del encabezado. Ahora es un botón redondo con fondo
   propio, para que se vea de un vistazo que ahí se vuelve atrás. */
/* 44px (5-sep-2026): es el "volver" de todas las pantallas, justo lo que
   Ramón dijo que costaba encontrar y acertar. Medía 39. */
.back-link {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  min-height: 44px;
  padding: 8px 14px 8px 10px; border-radius: 999px;
  background: var(--velo-2); border: 1px solid var(--line);
  font-weight: 600; opacity: 0.92; font-size: 0.88rem;
  transition: opacity 0.2s, color 0.2s, background 0.2s;
}
.back-link .back-arrow { font-size: 1.25rem; line-height: 1; }
.back-link:hover, .back-link:active { opacity: 1; color: var(--accent); background: var(--velo-3); }
.player-mood-info { flex: 1; display: flex; flex-direction: column; }
.player-mood-name { font-weight: 700; font-size: 1.02rem; }
.player-style-name { color: var(--text-dim); font-size: 0.78rem; }
/* Guardar y Compartir de la cabecera: no tenían regla propia (eran solo un
   emoji suelto). Ahora llevan dibujo, así que necesitan tamaño y una zona
   de toque de 44px como el resto (5-sep-2026). */
.share-native-btn {
  width: 44px; height: 44px; flex: none; padding: 0;
  background: transparent; border: 1px solid var(--line); border-radius: 50%;
  color: var(--text-dim); display: flex; align-items: center; justify-content: center;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.share-native-btn:hover { border-color: var(--accent); color: var(--accent); }
.share-native-btn .fm-icono { width: 20px; height: 20px; display: block; }
.ver-contrasena .fm-icono { width: 20px; height: 20px; display: block; }

.share-btn {
  min-height: 44px; display: inline-flex; align-items: center;
  border: 1px solid var(--accent); color: var(--accent);
  background: transparent; padding: 9px 16px; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  transition: all 0.2s ease;
}
.share-btn:hover { background: var(--accent); color: var(--sobre-acento); }

/* Acciones sobre la canción que suena (5-sep-2026): guardar, compartir por
   WhatsApp, prestar y publicar en la comunidad. Estaban en la cabecera y la
   reventaban; aquí van en su propia fila, centradas y con aire. Se ocultan
   solas cuando no aplican (sin sesión, sin canción), y la fila desaparece
   entera si no queda ninguna visible. */
.acciones-cancion {
  display: flex; flex-wrap: wrap; gap: 10px;
  align-items: center; justify-content: center;
  margin: 14px auto 0;
}
.acciones-cancion:not(:has(> :not(.hidden))) { display: none; }

.community-page .player-top, .form-page .player-top {
  position: static;
  border-bottom: 1px solid var(--line);
}

/* ---------- Estilos (paso 1) ---------- */
.styles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.style-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  padding: 22px; text-align: left; color: var(--text);
  transition: transform 0.25s ease, border-color 0.25s ease;
}
.style-card:hover { transform: translateY(-3px); border-color: var(--c); }
.style-name { font-size: 1.05rem; font-weight: 700; margin-bottom: 6px; }
.style-count { font-size: 0.78rem; color: var(--text-dim); }

/* ---------- Duración (paso 2) ---------- */
.duration-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 20px; }
.duration-option {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  padding: 18px; text-align: center; color: var(--text); transition: all 0.2s ease;
}
.duration-option:hover { border-color: var(--accent); }
.duration-option.is-selected { border-color: var(--accent); background: rgba(139, 124, 246, 0.12); }
.duration-option:disabled { opacity: 0.5; cursor: not-allowed; }
.duration-option:disabled:hover { border-color: var(--line); }
/* El candado de las opciones de Premium: SVG del juego propio, alineado
   con el texto de la opción (5-sep-2026). */
.duration-label { display: flex; align-items: center; justify-content: center; gap: 6px; font-weight: 700; font-size: 1.05rem; }
.duration-candado { display: inline-flex; color: var(--text-dim); }
/* El aviso que explica el candado de Premium, donde aparece el candado. */
.premium-aviso {
  margin: 14px 0 16px; font-size: 0.8rem; line-height: 1.5;
  color: var(--text-dim); text-align: center;
}
.premium-aviso a { color: var(--accent); text-decoration: underline; }
.duration-candado .fm-icono { width: 16px; height: 16px; display: block; }
.duration-desc { display: block; color: var(--text-dim); font-size: 0.78rem; margin-top: 3px; }
.duration-free {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  flex-wrap: wrap; margin-bottom: 20px; color: var(--text-dim); font-size: 0.92rem;
}
.duration-free input {
  width: 90px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--text);
  font-size: 1rem; text-align: center;
}
.duration-free input:focus { outline: none; border-color: var(--accent); }
.duration-free input:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------- Reproductor (paso 3) ---------- */
#playerPanel { text-align: center; }
.embed-wrap {
  position: relative;
  width: 100%; max-width: 700px;
  aspect-ratio: 16 / 9;
  margin: 0 auto 18px;
  border-radius: 16px;
  overflow: hidden;
  background: #000;
  box-shadow: var(--shadow);
}
.embed-wrap iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
  transition: opacity 0.4s ease;
}
.music-frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}
/* Dos huecos superpuestos: el activo se ve, el otro prepara en silencio
   la siguiente canción para que el cambio de pista sea instantáneo. */
.music-slot {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; pointer-events: none;
  transition: opacity 0.4s ease;
}
.music-slot.is-active {
  opacity: 1; pointer-events: auto;
}
.music-slot iframe, .music-slot > div {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
.music-frame.is-loading .music-slot.is-active {
  opacity: 0;
}
.embed-loading {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px; color: var(--text-dim);
}
.spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid var(--velo-borde); border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}

.now-info { display: flex; gap: 12px; align-items: center; justify-content: center; flex-wrap: wrap; margin-bottom: 16px; }
.provider-tag {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em;
  border: 1px solid var(--line); padding: 5px 11px; border-radius: 999px; color: var(--text-dim);
}
.now-label { font-weight: 600; }
.track-index { color: var(--text-dim); font-size: 0.82rem; }

/* ---------- Cambiar de plataforma o de estilo sin salir (10-sep-2026) -------
   Ramón: "si estoy en Spotify y quiero cambiar a YouTube debe ser fácil en
   pantalla, o si quiero cambiar de género musical".

   Las dos fichas llevan escrito lo que suena ahora, así que no hacen falta
   rótulos: se lee «Spotify» y «Techno» y se entiende que tocándolo se cambia.
   La flechita de después es lo que dice que se puede tocar; sin ella la de la
   plataforma se leía como una etiqueta más, que es lo que era antes. */
.cambiar-fila { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: center; }
.cambiar-chip {
  font: inherit;
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em;
  border: 1px solid var(--line); padding: 5px 11px; border-radius: 999px;
  color: var(--text-dim); background: transparent;
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%;
}
.cambiar-chip::after {
  content: '';
  width: 6px; height: 6px; flex: none;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.cambiar-chip:hover, .cambiar-chip:focus-visible { color: var(--text); border-color: var(--accent); }
.cambiar-chip-estilo { color: var(--accent-2); border-color: var(--accent-2); }

.cambiar-hoja-cuerpo { max-height: 60vh; overflow-y: auto; }
.cambiar-hoja-cuerpo .favoritos-titulo { margin: 0 0 10px; }
.cambiar-hoja-cuerpo .styles-grid { margin-bottom: 14px; }

/* El aviso de los trozos de 30 segundos. No es una alarma: es un dato y una
   salida. Por eso lleva el color de la app y no el rojo de un error, que aquí
   no lo hay (Spotify hace lo que dice que hace). */
.aviso-trozos {
  max-width: 460px; margin: 12px auto 0;
  border: 1px solid var(--accent); border-radius: 14px;
  padding: 12px 14px; text-align: center;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.aviso-trozos-titulo { margin: 0 0 6px; font-weight: 600; font-size: 0.92rem; }
.aviso-trozos-texto { margin: 0 0 10px; font-size: 0.82rem; line-height: 1.45; color: var(--text-dim); }
.aviso-trozos-btn { display: inline-block; }

.session-progress { max-width: 700px; margin: 0 auto 16px; }
.progress-track { height: 6px; background: var(--line); border-radius: 999px; overflow: hidden; }
.progress-fill { height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width 0.4s linear; }
.progress-time { text-align: center; color: var(--text-dim); font-size: 0.82rem; margin-top: 6px; }

.player-controls { display: flex; align-items: center; justify-content: center; gap: 14px; }
.ctl-btn {
  width: 52px; height: 52px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--text);
  font-size: 1.15rem; display: flex; align-items: center; justify-content: center;
  transition: all 0.22s ease;
}
/* Los mandos ya no son caracteres sino dibujos: 24px dentro del círculo de
   52, y 28 en el botón grande de play/pausa (5-sep-2026). */
.ctl-btn .fm-icono { width: 24px; height: 24px; display: block; }
.ctl-main .fm-icono, .pause-glyph .fm-icono { width: 28px; height: 28px; }
.pause-glyph { display: flex; align-items: center; justify-content: center; }
.ctl-btn:hover { border-color: var(--accent); transform: scale(1.06); }
.ctl-btn.is-active { border-color: var(--accent); color: var(--accent); background: rgba(139, 124, 246, 0.12); }
.ctl-main { width: 66px; height: 66px; background: linear-gradient(135deg, var(--accent), var(--accent-2)); border: none; color: var(--sobre-acento); font-size: 1.3rem; }
.ctl-quiet { color: var(--text-dim); }

.fallback-banner {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: rgba(220, 90, 50, 0.92); color: #fff;
  padding: 12px 22px; border-radius: 999px; font-size: 0.86rem; z-index: 60;
  box-shadow: var(--shadow); max-width: 90%;
}

.center-actions { display: flex; gap: 14px; justify-content: center; margin-top: 22px; flex-wrap: wrap; }

.wake-hint {
  display: flex; align-items: center; gap: 8px; justify-content: center;
  max-width: 460px; margin: 16px auto 0; text-align: center;
  color: var(--text-dim); font-size: 0.78rem; line-height: 1.4;
}
.wake-hint .wake-hint-icon { flex: none; font-size: 1rem; display: flex; }
.wake-hint .wake-hint-icon .fm-icono { width: 16px; height: 16px; display: block; }

.dim-toggle {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; margin: 10px auto 0; padding: 7px 16px;
  border: 1px solid var(--line); border-radius: 999px; background: transparent;
  color: var(--text-dim); font-size: 0.78rem; cursor: pointer;
}
.dim-toggle .fm-icono { width: 17px; height: 17px; flex: none; }
.dim-toggle:hover { border-color: var(--accent); }
.dim-toggle.is-on { border-color: var(--accent); color: var(--accent); background: rgba(139, 124, 246, 0.12); }

/* Capa encima de todo, sin bloquear el dedo (pointer-events:none): tapa
   TODO lo que se ve sin tapar los botones que hay debajo. El wake lock
   sigue igual de activo -- esto no apaga nada de verdad, solo se ve
   negro, como si estuviera apagado.
   13-sep-2026, Ramón: "no solo atenuar: pantalla negra" -- antes dejaba
   pasar un 28% de luz (rgba con 0.72 de opacidad); un negro a medias no
   vale para quien de verdad quiere apagar la pantalla sin apagarla. */
.dim-overlay {
  position: fixed; inset: 0; background: #000;
  pointer-events: none; z-index: 9999;
}
.dim-overlay.hidden { display: none; }

/* ---------- Ruta A→B: modo sin pantalla, silencio programado, "no era
   esto" (5-sep-2026) ---------- */
.duration-mode-tabs { display: flex; gap: 8px; margin-bottom: 16px; }
.silencio-check {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 20px;
  color: var(--text-dim); font-size: 0.88rem; text-align: left; cursor: pointer;
}
.silencio-check input[type="checkbox"] { width: 20px; height: 20px; margin-top: 3px; flex: none; }
#arrivalTimeInput { width: auto; }

/* Se ve el vídeo apagado, no el reproductor: el iframe sigue debajo,
   sonando igual -- esta capa solo lo tapa a la vista. */
.pantalla-off-overlay {
  position: fixed; inset: 0; z-index: 700; background: var(--bg);
  display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px;
  text-align: center; padding: 24px;
}
.pantalla-off-overlay.hidden { display: none; }
.pantalla-off-titulo { color: var(--text-dim); font-size: 1.05rem; font-weight: 600; }
.pantalla-off-sub { color: var(--text-dim); opacity: 0.55; font-size: 0.82rem; }

/* Silencio programado: pantalla negra con un punto que respira, nada más
   -- Ramón, 5-sep-2026: "ninguna app programa el silencio". */
.silencio-overlay {
  position: fixed; inset: 0; z-index: 800; background: #000;
  display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 20px;
}
.silencio-overlay.hidden { display: none; }
.silencio-punto {
  width: 14px; height: 14px; border-radius: 50%; background: var(--accent);
  animation: silencio-respirar 4s ease-in-out infinite;
}
@keyframes silencio-respirar {
  0%, 100% { transform: scale(0.6); opacity: 0.3; }
  50% { transform: scale(1.3); opacity: 1; }
}
.silencio-texto { color: var(--text-dim); font-size: 0.82rem; letter-spacing: 0.02em; }

/* ---------- Préstamo de canción (5-sep-2026) ---------- */
#lendInbox { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
#lendInbox.hidden { display: none; }
.lend-card {
  background: var(--bg-card); border: 1px solid var(--accent); border-radius: 14px;
  padding: 14px 16px;
}
.lend-de { color: var(--accent); font-size: 0.82rem; font-weight: 600; margin: 0 0 4px; }
.lend-titulo { font-weight: 700; margin: 0 0 10px; }

/* ---------- Banner del plan gratis ---------- */
.ad-banner {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  max-width: 900px; margin: 0 auto 14px; padding: 8px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg-card);
  overflow: hidden;
}
/* Ocupa su propia línea encima del anuncio (flex: 0 0 100%), para que se lea
   antes que el mensaje y no le quite sitio a la imagen ni al texto. */
.ad-banner-etiqueta {
  flex: 0 0 100%; margin-bottom: -2px;
  font-size: 0.6rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-dim); opacity: 0.75;
}
.ad-banner-texto { font-size: 0.85rem; color: var(--text-dim); flex: 1 1 auto; }
.ad-banner-img { flex: none; border-radius: 8px; object-fit: contain; }
.ad-banner-video { flex: none; border-radius: 8px; overflow: hidden; }
.ad-banner-video iframe { display: block; border: none; }

.ad-banner-pequeno { padding: 5px 12px; }
.ad-banner-pequeno .ad-banner-img { height: 28px; width: 28px; }
.ad-banner-pequeno .ad-banner-video, .ad-banner-pequeno .ad-banner-video iframe { height: 60px; width: 106px; }

.ad-banner-mediano .ad-banner-img { height: 48px; width: 48px; }
.ad-banner-mediano .ad-banner-video, .ad-banner-mediano .ad-banner-video iframe { height: 100px; width: 178px; }

.ad-banner-grande { padding: 12px 16px; }
.ad-banner-grande .ad-banner-img { height: 80px; width: 80px; }
.ad-banner-grande .ad-banner-video, .ad-banner-grande .ad-banner-video iframe { height: 160px; width: 284px; }

.fm-relevo-aviso {
  background: rgba(220, 90, 50, 0.15); color: #f2a488;
  border: 1px solid rgba(220, 90, 50, 0.35); border-radius: 10px;
  padding: 10px 14px; font-size: 0.85rem; margin-bottom: 14px;
}

/* ---------- Formularios ---------- */
.create-form { display: flex; flex-direction: column; gap: 16px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } }
input[type="color"] { padding: 3px; height: 46px; cursor: pointer; }
.form-block { background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; padding: 16px; }
.form-block-head { margin-bottom: 10px; }
.form-block-head h3 { font-size: 0.95rem; }
.hint { color: var(--text-dim); font-size: 0.78rem; margin-top: 2px; }
.hint-inline { font-weight: 400; color: var(--text-dim); font-size: 0.78rem; }
.link-feedback { margin-top: 10px; }
.fb { font-size: 0.8rem; padding: 4px 0; }
.fb-ok { color: var(--bien); }
.fb-error { color: var(--malo); }

/* ---------- Crear estado: pasos numerados + vista previa (3-sep-2026) ----------
   Antes era un formulario plano (campos sueltos + textarea de enlaces).
   Ahora son 3 pasos separados visualmente, con paleta de color e iconos
   clicables (nada de escribir hex/emoji a mano salvo que se quiera algo
   distinto) y una réplica en vivo de la tarjeta tal y como se verá en el
   menú principal (misma clase .mood-card que usa app.js). */
.create-layout { display: grid; grid-template-columns: 1fr 220px; gap: 24px; align-items: start; }
@media (max-width: 780px) { .create-layout { grid-template-columns: 1fr; } }

.create-steps { gap: 22px; }
.create-step { display: flex; gap: 14px; }
.step-num {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--sobre-acento); font-weight: 700; font-size: 0.85rem;
  display: flex; align-items: center; justify-content: center;
}
.step-body { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.step-title { font-size: 1rem; }

.picker-block { display: flex; flex-direction: column; gap: 8px; }
.picker-label { font-size: 0.82rem; color: var(--text-dim); }
.picker-more { margin-top: 2px; }
.picker-more input[type="color"] { max-width: 120px; }

.swatch-row { display: flex; flex-wrap: wrap; gap: 10px; }
/* La muestra de color sigue viéndose de 34px, pero responde en 44: el
   borde de más es transparente (5-sep-2026). */
.swatch {
  width: 44px; height: 44px; border-radius: 50%; border: 5px solid transparent;
  background-clip: content-box; box-sizing: border-box; padding: 0;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.swatch:hover { transform: scale(1.1); }
.swatch.is-selected { box-shadow: 0 0 0 2px var(--text), inset 0 0 0 1px var(--line); transform: scale(1.08); }

.emoji-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.emoji-btn {
  width: 44px; height: 44px; font-size: 1.15rem; line-height: 1;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.emoji-btn:hover { border-color: var(--accent); }
.emoji-btn.is-selected { border-color: var(--accent); background: rgba(139, 124, 246, 0.18); }

.link-example { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 4px; font-size: 0.78rem; }
.link-example-row { display: flex; gap: 6px; align-items: baseline; word-break: break-all; }
.link-example-row.is-ok { color: var(--bien); }
.link-example-row.is-bad { color: var(--malo); }
.link-example-row em { color: var(--text-dim); font-style: normal; }

.preview-col { position: sticky; top: 16px; display: flex; flex-direction: column; gap: 8px; }
.preview-label { font-size: 0.78rem; color: var(--text-dim); text-align: center; }
.preview-card { min-height: 150px; pointer-events: none; }
.preview-card .mood-card-body { padding: 18px 16px; gap: 6px; }
@media (max-width: 780px) { .preview-col { position: static; max-width: 260px; margin: 0 auto; } }

.quota-box { background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.quota-head { display: flex; justify-content: space-between; font-size: 0.82rem; color: var(--text-dim); margin-bottom: 8px; }
.quota-track { height: 6px; background: var(--line); border-radius: 999px; overflow: hidden; }
.quota-fill { height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width 0.3s ease; }
.quota-note { font-size: 0.8rem; color: var(--text-dim); margin-top: 8px; }
.quota-note a { color: var(--accent); text-decoration: underline; }
.quota-note-limit { color: #f0abfc; }

.custom-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.custom-item {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
}
.custom-icon { font-size: 1.3rem; width: 34px; text-align: center; }
.custom-item-info { flex: 1; display: flex; flex-direction: column; }
.custom-item-info strong { font-size: 0.95rem; }
.custom-item-info span { color: var(--text-dim); font-size: 0.78rem; }
.mini-btn {
  background: transparent; border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 9px; padding: 6px 11px; font-size: 0.78rem; transition: all 0.2s ease;
  min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
}
.mini-btn:hover { border-color: var(--malo); color: var(--malo); }
.subset-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.empty-hint { color: var(--text-dim); font-size: 0.9rem; }
.import-result { color: var(--text-dim); font-size: 0.85rem; margin-top: 8px; }
.file-btn { position: relative; }
.import-result.ok { color: var(--bien); }

/* ---------- Comunidad ---------- */
.community-auth .auth-form { display: flex; flex-direction: column; gap: 14px; max-width: 420px; }
.campo-contrasena { position: relative; }
.campo-contrasena input { padding-right: 42px; }
.ver-contrasena {
  position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  background: none; border: none; font-size: 1.05rem; cursor: pointer;
  width: 44px; height: 44px; padding: 0; opacity: 0.6; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.ver-contrasena:hover { opacity: 1; }
.auth-actions { display: flex; gap: 12px; flex-wrap: wrap; }

.session-head { display: flex; align-items: center; gap: 16px; justify-content: space-between; flex-wrap: wrap; }
.session-user { display: flex; align-items: center; gap: 12px; }
.session-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.avatar {
  width: 46px; height: 46px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--sobre-acento); font-size: 1.1rem; flex-shrink: 0;
}
.avatar.small { width: 34px; height: 34px; font-size: 0.9rem; }
.sub-dim { color: var(--text-dim); font-size: 0.8rem; }

.feed-panel { padding-top: 4px; }
/* flex-wrap (31-ago-2026, segunda vuelta). Primero se probó overflow-x:auto
   (deslizar como una fila de chips), y arreglaba el desbordamiento, pero
   escondía "Por grupo o cantante" y "Mis bibliotecas" sin ninguna pista de
   que seguían ahí -- Ramón: "no seria mejor... para que se sepa que hay mas
   opciones". Con 4 botones exactos, envolver a dos filas las deja TODAS
   visibles sin ningún toque de más, que es justo lo que hace falta cuando
   una de ellas es la biblioteca del cliente. overflow-x:auto se queda puesto
   por si acaso (letras muy grandes, pantalla muy estrecha): con dos filas ya
   no debería hacer falta deslizar nunca, pero si algún día no cupiera ni así,
   no vuelve a romper la página entera. Donde ya cabía en una fila
   (community.html, 2 tabs) esto no cambia nada visible. */
.feed-tabs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 4px 0 20px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; -ms-overflow-style: none;
}
.feed-tabs::-webkit-scrollbar { display: none; }
/* min-height 48px (5-sep-2026, auditoría): estas pastillas medían 34px de
   alto y son la navegación principal del móvil. Google pide 48dp de zona
   de toque y Apple 44pt; con 34 se falla en los dos. */
.tab {
  background: var(--bg-card); border: 1px solid var(--line); color: var(--text-dim);
  padding: 10px 20px; border-radius: 999px; font-size: 0.86rem; font-weight: 500;
  transition: all 0.2s ease;
  flex: none; white-space: nowrap;
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
}
.tab:hover { border-color: var(--accent); color: var(--text); transform: translateY(-1px); }
.tab.is-active {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border-color: transparent; color: var(--sobre-acento); font-weight: 700;
  box-shadow: 0 6px 18px rgba(139, 124, 246, 0.35);
}
.feed-toolbar { margin-bottom: 16px; }
.feed-input { max-width: 340px; }

.feed-list { display: flex; flex-direction: column; gap: 16px; }
.post { background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px; padding: 16px; }
.post-head { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
.post-meta { flex: 1; display: flex; flex-direction: column; }
.post-author { font-weight: 700; font-size: 0.92rem; }
.post-time { color: var(--text-dim); font-size: 0.72rem; }
.post-mood {
  font-size: 0.74rem; color: var(--accent-2);
  border: 1px solid rgba(103, 232, 249, 0.25); padding: 4px 10px; border-radius: 999px;
}
.post-text { margin: 8px 0; font-size: 0.92rem; }
.post-embed { margin: 10px 0; }
.iframe-16-9 { width: 100%; aspect-ratio: 16/9; border: 0; border-radius: 10px; }
.iframe-square { width: 100%; height: 152px; border: 0; border-radius: 10px; }
.post-foot { display: flex; gap: 14px; align-items: center; margin-top: 10px; }
.like-btn {
  background: transparent; border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 999px; padding: 7px 14px; font-size: 0.85rem; transition: all 0.2s ease;
}
.like-btn:hover { border-color: var(--megusta); color: var(--megusta); }
.like-btn.is-liked { border-color: var(--megusta); color: var(--megusta); background: rgba(255,68,119,0.1); }
.mini-link { color: var(--accent); font-size: 0.85rem; }
.mini-link:hover { text-decoration: underline; }

.users-list { display: flex; flex-direction: column; gap: 10px; }
.user-item { display: flex; align-items: center; gap: 12px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.user-info { flex: 1; display: flex; flex-direction: column; }
.user-info strong { font-size: 0.93rem; }
.mini-tag { font-size: 0.72rem; color: var(--text-dim); border: 1px solid var(--line); padding: 4px 10px; border-radius: 999px; }

/* ---------- Modal compartir ---------- */
.modal {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(0, 0, 0, 0.65);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-card {
  position: relative; background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 30px; max-width: 460px; width: 100%; box-shadow: var(--shadow);
  /* Sin esto, una tarjeta más alta que la pantalla (el modal de "Qué es
     Frasly Music", con su lista larga) quedaba centrada y desbordada por
     arriba Y por abajo a la vez, sin ninguna forma de hacer scroll --
     Ramón, con el móvil real: "no se ve la cabecera y no hace scroll". */
  max-height: calc(100vh - 40px); overflow-y: auto;
}
/* 5-sep-2026 (prueba de usuario): la "×" medía 26px. Es la salida de
   CUALQUIER emergente de la app, o sea lo que busca quien se ha perdido, y
   con 26px se falla el dedo. Ahora es un cuadrado de 44px (mínimo de Apple);
   la aspa se ve igual de grande, lo que crece es la zona que responde. */
.modal-close {
  position: absolute; top: 8px; right: 8px; background: transparent; border: none;
  color: var(--text-dim); font-size: 1.6rem; line-height: 1;
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.modal-close:hover, .modal-close:focus-visible { color: var(--text); background: var(--velo-3); }
.modal-title { font-size: 1.25rem; font-weight: 700; }
.modal-sub { color: var(--text-dim); font-size: 0.86rem; margin: 4px 0 18px; }
.share-form { display: flex; flex-direction: column; gap: 14px; }
.share-row { }
.modal-preview { font-size: 0.85rem; color: var(--accent-2); }
.share-unlogged { text-align: center; }

/* ---------- Buscar por grupo o cantante (30-ago-2026) ---------- */
.buscador-artista { margin: 0 0 18px; }
.buscador-campo {
  width: 100%; background: var(--bg-card); color: var(--text);
  border: 1px solid var(--line); border-radius: 14px;
  padding: 13px 16px; font-size: 1rem;
}
.buscador-campo:focus { outline: none; border-color: var(--accent); }
.buscador-nota { color: var(--text-dim); font-size: 0.85rem; margin: 8px 2px 0; }

.disco-card { display: flex; align-items: center; gap: 14px; text-align: left; }
.disco-portada { width: 64px; height: 64px; border-radius: 10px; flex: 0 0 auto; object-fit: cover; }

/* ---------- Elegir la fuente (30-ago-2026) ---------- */
.fuente-opciones { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 12px; }
.fuente-opcion {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 10px; text-align: center; color: var(--text); cursor: pointer;
  transition: all 0.2s ease;
}
.fuente-opcion:hover { border-color: var(--accent); }
.fuente-opcion.is-selected { border-color: var(--accent); background: rgba(139, 124, 246, 0.12); }
.fuente-icono { display: flex; justify-content: center; font-size: 1.3rem; line-height: 1.1; color: var(--accent); }
.fuente-icono .fm-icono { width: 24px; height: 24px; display: block; }
/* El botón de "Mi música" (solo dentro de la app) lo construye
   lib/local-player.js con estilos en línea; esto es solo su dibujo. */
.mi-musica-icono { display: flex; align-items: center; }
.mi-musica-icono .fm-icono { width: 22px; height: 22px; display: block; }
.fuente-nombre { display: block; font-weight: 700; font-size: 0.95rem; margin-top: 4px; }
.fuente-corto { display: block; color: var(--text-dim); font-size: 0.72rem; margin-top: 2px; }

.fuente-aviso {
  color: var(--text-dim); font-size: 0.85rem; line-height: 1.45;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; margin: 0 0 18px;
}
.fuente-aviso-alerta { color: var(--text); border-color: var(--accent); background: rgba(139, 124, 246, 0.14); }

/* Las instrucciones para reflejar la pantalla en la TV (31-ago-2026).
   El aparato que tiene delante va primero y resaltado; los otros debajo,
   porque la misma cuenta se usa en varios sitios. */
.cast-porque { display: block; margin: 6px 0 10px; color: var(--text-dim); }
.cast-como { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.cast-como li { color: var(--text-dim); line-height: 1.45; }
.cast-como li strong { color: var(--text); }
.cast-como li.es-el-tuyo {
  color: var(--text); background: rgba(139, 124, 246, 0.12);
  border-left: 3px solid var(--accent); border-radius: 8px; padding: 9px 11px;
}

/* El aviso de bienvenida (31-ago-2026). Va DENTRO de la página, empujando lo
   de abajo: nada de ventana que tape, que un overlay a pantalla completa ya
   dejó el reproductor bloqueado una vez en esta misma app. */
.bienv {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 14px; padding: 16px 18px; margin: 0 0 18px;
}
.bienv-titulo { font-size: 1.05rem; margin: 0 0 12px; color: var(--text); }
.bienv-lista { list-style: none; margin: 0 0 12px; padding: 0; display: grid; gap: 12px; }
.bienv-lista li { display: flex; gap: 12px; align-items: flex-start; }
.bienv-icono { font-size: 1.25rem; line-height: 1.2; flex: 0 0 auto; color: var(--accent); }
.bienv-icono .fm-icono { width: 22px; height: 22px; display: block; }
/* 5-sep-2026 (prueba de usuario nuevo): este display:block estaba pensado
   para el TÍTULO de cada punto, pero alcanzaba también a los <strong> que
   van dentro del párrafo, y partía la frase en trozos, dejando los puntos
   sueltos al principio de la línea siguiente ("Instalar aplicación" / ". En
   iPhone..." / "Compartir" / "→"). Se ilegible en la primera pantalla que
   ve todo el mundo. Ahora solo es bloque el <strong> que cuelga
   directamente del <div>, o sea el título. */
.bienv-lista li > div > strong { display: block; color: var(--text); font-size: 0.95rem; }
.bienv-lista p strong { color: var(--text); font-weight: 600; }
.bienv-lista p { margin: 3px 0 0; color: var(--text-dim); font-size: 0.85rem; line-height: 1.45; }
.bienv-donde { color: var(--text-dim); font-size: 0.85rem; margin: 0 0 12px; }
.bienv .mini-btn { min-height: 44px; padding: 10px 16px; }

/* ---------- "Qué es Frasly Music" (3-sep-2026) ----------
   Misma tarjeta emergente que el resto de modales, reutiliza .bienv-lista
   para la lista de puntos (mismo aspecto que la de bienvenida.js). */
.intro-card { max-width: 480px; }
.intro-lista { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 14px; }
.intro-lista li { display: flex; gap: 12px; align-items: flex-start; }
.intro-icono { font-size: 1.25rem; line-height: 1.2; flex: 0 0 auto; color: var(--accent); }
.intro-icono .fm-icono { width: 22px; height: 22px; display: block; }
/* Título del emergente con su icono al lado. Alineado ARRIBA, no al centro:
   con un título de tres líneas, centrarlo dejaba el icono flotando en mitad
   de la frase (5-sep-2026). El margen sube el dibujo hasta la altura de la
   primera línea. */
.titulo-con-icono { display: flex; align-items: flex-start; gap: 10px; }
.titulo-con-icono .fm-icono { margin-top: 3px; }
.titulo-con-icono .fm-icono { width: 26px; height: 26px; flex: 0 0 auto; color: var(--accent); }
.intro-lista li > div > strong { display: block; color: var(--text); font-size: 0.95rem; }
.intro-lista p strong { color: var(--text); font-weight: 600; }
.intro-lista p { margin: 3px 0 0; color: var(--text-dim); font-size: 0.85rem; line-height: 1.45; }
/* El emergente de entrada (5-sep-2026): corto, con el enlace al tutorial. */
.aviso-tutorial-card { max-width: 430px; }
.aviso-tutorial-card .modal-sub { margin-bottom: 18px; }
/* Este botón NO va del morado de la casa (5-sep-2026, Ramón: "el fondo de
   este botón debería ser de otro color para que resaltara"). Con el morado
   se confundía con el resto del interfaz, que es morado entero. En ámbar
   destaca sobre el fondo oscuro y sobre todo lo demás, y no choca: es el
   mismo calor que ya tienen Energía y Domingo lento.
   El texto va oscuro, que sobre ámbar es lo único que se lee bien. */
.aviso-tutorial-ir {
  display: block; width: 100%; text-align: center; margin-bottom: 16px;
  background: linear-gradient(135deg, #ffc247, #ff8a3d);
  color: #241504;
  box-shadow: 0 8px 26px rgba(255, 150, 60, 0.28);
}
.aviso-tutorial-ir:hover { filter: brightness(1.06); }

/* El aviso que manda a "Cómo se usa" desde el emergente de entrada. */
.intro-remite {
  margin: 4px 0 16px; padding: 12px 14px;
  background: var(--velo-2); border: 1px solid var(--line); border-radius: 12px;
  color: var(--text-dim); font-size: 0.86rem; line-height: 1.5;
}
.intro-remite a { color: var(--accent); text-decoration: underline; font-weight: 600; }
.intro-acciones { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; }
.intro-acciones .mini-btn { min-height: 44px; padding: 10px 16px; }

/* "Cómo se usa" propio de cada pantalla (13-sep-2026, ver
   lib/aviso-pantalla.js). Misma tarjeta que aviso-tutorial-card; solo
   necesita su propia lista con viñeta. */
.aviso-pantalla-lista { margin: 0 0 6px; padding-left: 20px; color: var(--text-dim); font-size: 0.88rem; line-height: 1.55; }
.aviso-pantalla-lista li { margin-bottom: 6px; }

/* La barra de bibliotecas (31-ago-2026): elegir cuál, y las tres acciones.
   En móvil se apila, que en una fila de 360 px no caben cuatro cosas sin que
   los botones bajen de los 44 px que hacen falta para pulsar con el dedo. */
.biblio-barra {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
  margin-bottom: 14px;
}
.biblio-elegir {
  display: flex; flex-direction: column; gap: 4px;
  color: var(--text-dim); font-size: 0.85rem; flex: 1 1 190px;
}
.biblio-elegir select {
  background: var(--bg-soft); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 12px; font-size: 0.95rem; min-height: 44px; width: 100%;
}
.biblio-acciones { display: flex; gap: 8px; flex-wrap: wrap; }
.biblio-acciones .mini-btn { min-height: 44px; padding: 10px 14px; }
.biblio-ayuda {
  color: var(--text-dim); font-size: 0.82rem; margin: 10px 0 14px;
}

/* El aviso del botón de Transmitir. No tenía NINGÚN estilo (31-ago-2026):
   salía como texto suelto, y desde hoy puede llevar dentro un enlace, que sin
   estilo no se distingue del resto sobre el fondo oscuro. Se le pone el mismo
   traje que a .fuente-aviso, que es el aviso hermano de la pantalla anterior. */
.cast-aviso {
  color: var(--text-dim); font-size: 0.85rem; line-height: 1.45;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; margin: 12px 0 0;
}
.cast-aviso a {
  color: var(--accent); font-weight: 600; text-decoration: underline;
  /* 44 px de alto para que se pueda pulsar con el dedo sin apuntar */
  display: inline-block; padding: 11px 0; min-height: 22px;
}
.cast-aviso a:hover, .cast-aviso a:focus-visible { color: var(--text); }

.fuente-archivos { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 18px; }
.fuente-archivos-botones { display: flex; gap: 10px; flex-wrap: wrap; }
.fuente-archivos-ayuda { color: var(--text-dim); font-size: 0.78rem; margin: 0; }
.fuente-archivos-cuenta { color: var(--text-dim); font-size: 0.85rem; }
.file-btn-vaciar { background: none; border: 1px solid var(--line); color: var(--text-dim);
  font-size: 0.8rem; padding: 6px 12px; border-radius: 8px; cursor: pointer; }
.file-btn-vaciar:hover { border-color: var(--accent); color: var(--text); }
.archivos-audio { width: 100%; }

/* Con "Mi música" no hay vídeo que enseñar: el hueco 16:9 se quedaba de
   rectángulo negro enorme debajo del audio. Aquí el hueco se ajusta al
   reproductor y deja de pintar fondo. */
.embed-wrap.solo-audio {
  aspect-ratio: auto; background: transparent; box-shadow: none;
  display: flex; align-items: center; padding: 8px 0;
}
.embed-wrap.solo-audio .music-frame { display: none; }

.panel-head-sep { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--line); }

/* Mandar lo que suena a Frasly Lab */
.lab-btn {
  display: block; width: 100%; margin: 12px 0 0;
  background: transparent; color: var(--accent-2);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 11px 14px; font-size: 0.9rem; cursor: pointer;
  transition: all 0.2s ease;
}
.lab-btn:hover { border-color: var(--accent-2); background: rgba(103, 232, 249, 0.08); }

/* ---------- Valoración y sugerencias (30-ago-2026) ---------- */
.opinion-estrellas { display: flex; gap: 8px; justify-content: center; margin: 6px 0 20px; }
.opinion-estrellas button {
  min-width: 44px; min-height: 44px;
  background: none; border: 0; padding: 2px; font-size: 44px; line-height: 1;
  cursor: pointer; color: var(--text-dim);
}
.opinion-estrellas button.activa { color: #f5c518; }
.opinion-estado { font-size: 0.85rem; color: var(--text-dim); margin-top: 10px; }
.opinion-estado.ok { color: var(--bien); }

/* ---------- Instalar como app (30-ago-2026) ---------- */
.instalar-pasos { margin: 14px 0; padding-left: 22px; line-height: 1.6; font-size: 0.9rem; color: var(--text); }
.instalar-pasos li { margin-bottom: 6px; }
.instalar-nota { margin: 0 0 14px; padding: 10px 12px; border-radius: 8px;
  background: rgba(139, 124, 246, .12); color: var(--text); font-size: 0.82rem; line-height: 1.5; }
.instalar-no-mostrar { display: flex; align-items: center; gap: 8px; margin-top: 16px;
  font-size: 0.82rem; color: var(--text-dim); cursor: pointer; }

/* ---------- Menú único de opciones (30-ago-2026 / 1-sep-2026): un solo
   icono para todo (opinión, cuenta, transmitir). Antes era un círculo
   flotante fijo en la esquina -- y por mucho hueco que se le reservara,
   Ramón seguía viendo la pantalla "bloqueada" en el móvil, y ese hueco
   reservado dejaba media pantalla vacía sin usar ("esto más ancho, el
   botón de transmitir integrado, no a un lado", con foto). Ahora vive
   DENTRO de la cabecera de cada página, como un botón más: en flujo
   normal, nunca flotando sobre el contenido, así que no puede tapar
   nada en ningún punto del scroll y el contenido usa el ancho entero. */
/* 44px, no 40: es el botón que abre idioma, cuenta, instalar y "qué es
   esto" -- el sitio al que va quien no sabe qué hacer (5-sep-2026). */
.menu-flotante-fab {
  width: 44px; height: 44px; border-radius: 50%; border: none; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: var(--sobre-acento); font-size: 20px; font-weight: 900;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.menu-flotante-fab:hover { filter: brightness(1.08); }
/* Las tres rayas dentro del botón redondo (8-sep-2026). Sin medida propia el
   dibujo sale del tamaño que le dé la letra y queda diminuto o desbordado. */
.menu-flotante-fab .fm-icono { width: 21px; height: 21px; }

/* La fila de mandos de la cabecera: idioma, claro/oscuro y "⋯" (5-sep-2026).
   44px cada uno, que es el mínimo para el dedo, y `flex: none` para que no
   los encoja el título de al lado. Si no caben, la fila entera baja a la
   línea siguiente en vez de aplastar el nombre de la app. */
.cabecera-acciones { display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }
.cabecera-btn {
  width: 44px; height: 44px; flex: none; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--velo-2); color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.cabecera-btn:hover { border-color: var(--accent); color: var(--accent); }
.cabecera-btn .fm-icono { width: 21px; height: 21px; display: block; }
.cabecera-btn-idioma { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.04em; }
.menu-flotante-card { max-width: 320px; }
.menu-flotante-opciones { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.menu-flotante-opcion {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; font: inherit; font-size: 0.95rem; color: var(--text); cursor: pointer;
}
.menu-flotante-opcion:hover { border-color: var(--accent); }
.menu-flotante-icono { font-size: 1.3rem; line-height: 1; color: var(--accent); display: flex; align-items: center; }
.menu-flotante-icono .fm-icono { width: 22px; height: 22px; display: block; }

/* ---------- Animaciones ---------- */
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Scrollbar ---------- */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--velo-borde); border-radius: 5px; }


/* Pie legal (31-ago-2026): el aviso de privacidad solo se veia al registrarse
   y el aviso legal no existia. Discreto, pero en todas las paginas. */
.pie-legal{
  margin: 2.5rem auto 1.2rem; padding: 0 1rem;
  text-align: center; font-size: .78rem; opacity: .6; line-height: 1.9;
}
.pie-legal a{ color: inherit; text-decoration: underline; }
.pie-legal a:hover{ opacity: 1; }
/* Zona de toque de los enlaces legales (5-sep-2026, auditoría): eran de
   16px de alto, imposibles de acertar con el dedo. El subrayado sigue
   midiendo lo mismo; lo que crece es el área que responde. */
.pie-legal a,
.pie-legal-enlaces a{
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 8px;
}

/* ============================================================
   Ajuste compacto (2-sep-2026): se aprieta el conjunto "ocupando
   el menor espacio posible" y se añade el reproductor de archivos
   del dispositivo (música y vídeo) y el filtro de música libre.
============================================================ */

/* ---------- Reproductor de archivos del dispositivo (música y vídeo) ---------- */
.archivos-lista {
  width: 100%; max-height: 220px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 6px;
  border: 1px solid var(--line); border-radius: 12px; padding: 8px;
  background: var(--bg-card);
}
.archivos-fila {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px;
  background: transparent; border: 1px solid transparent; border-radius: 9px;
  color: var(--text); font: inherit; font-size: 0.88rem; text-align: left;
  padding: 6px 10px; cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.archivos-fila:hover { background: var(--velo-1); }
.archivos-fila.is-playing { border-color: var(--accent); background: rgba(139, 124, 246, 0.12); }
.archivos-fila-icono { flex: none; font-size: 1rem; }
.archivos-fila-nombre {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.archivos-fila-quitar { flex: none; font-size: 1.15rem; line-height: 1; color: var(--text-dim); cursor: pointer; }
.archivos-fila-quitar:hover { color: var(--malo); }
.archivos-fila-cola {
  flex: none; width: 26px; height: 26px; line-height: 26px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 7px; font-size: 1.05rem;
  color: var(--accent); background: rgba(139, 124, 246, 0.10);
  cursor: pointer; transition: background 0.2s ease, transform 0.15s ease;
}
.archivos-fila-cola:hover { background: rgba(139, 124, 246, 0.25); transform: scale(1.1); }
.archivos-fila:not(.is-playing) .archivos-fila-cola { margin-right: 4px; }

@keyframes fila-pulse {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 rgba(139, 124, 246, 0.45); }
  50%  { transform: scale(0.97); box-shadow: 0 0 0 6px rgba(139, 124, 246, 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(139, 124, 246, 0); }
}
.archivos-fila.fila-pulse { animation: fila-pulse 0.35s ease; }

/* --- Animación de la carátula al reproducir --- */
@keyframes r-cover-entra {
  0%   { transform: scale(0.9); opacity: 0.6; }
  100% { transform: scale(1); opacity: 1; }
}
.r-cover, .r-cover-placeholder { animation: r-cover-entra 0.4s ease; }

/* --- Cola de reproducción ("A continuación") --- */
.player-cola {
  max-width: 700px; margin: 14px auto 0; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg-card);
}
.player-cola-titulo {
  color: var(--text-dim); font-size: 0.75rem; text-transform: uppercase;
  letter-spacing: 0.06em; margin-bottom: 8px;
}
.player-cola-vacia { color: var(--text-dim); font-size: 0.85rem; margin: 4px 0; }
.player-cola-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.player-cola-item {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 8px; border-radius: 8px; font-size: 0.86rem;
}
.player-cola-item:hover { background: var(--velo-1); }
.player-cola-pos {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(139, 124, 246, 0.12); color: var(--accent);
  font-size: 0.72rem; font-weight: 600;
}
.player-cola-nombre {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.archivos-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  background: #000; border: 0;
}

/* ---------- Barra de progreso del archivo que suena ---------- */
.file-progress { max-width: 700px; margin: 0 auto 12px; }
.file-progress input[type="range"] {
  width: 100%; margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none;
  height: 5px; border-radius: 999px;
  background: var(--line); outline: none; cursor: pointer;
}
.file-progress input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 15px; height: 15px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border: 2px solid var(--bg); box-shadow: 0 0 8px rgba(139, 124, 246, 0.6);
}
.file-progress input[type="range"]::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border: 2px solid var(--bg);
}
.file-progress-time {
  display: flex; justify-content: space-between; margin-top: 5px;
  color: var(--text-dim); font-size: 0.78rem;
}

/* ---------- "Mi música" desde el dispositivo, en la web (17-sep-2026) ----------
   dispositivo.html: migas de pan de las carpetas, botones de velocidad y los
   dos botones sueltos ("Elegir otra carpeta", "Ver carpeta"). El resto
   reutiliza .archivos-lista/.archivos-fila y .player-controls/.ctl-btn, que
   ya existían para otras pantallas. */
.dispositivo-migas {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  max-width: 700px; margin: 0 auto 10px; font-size: 0.85rem;
}
.dispositivo-miga {
  background: none; border: none; color: var(--text-dim); cursor: pointer;
  padding: 4px 2px; font: inherit;
}
.dispositivo-miga:last-child { color: var(--text); font-weight: 600; }
.dispositivo-miga:hover { color: var(--accent); }
.dispositivo-miga-sep { color: var(--text-dim); }

.dispositivo-velocidad {
  max-width: 700px; margin: 14px auto 0;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.dispositivo-velocidad-titulo { color: var(--text-dim); font-size: 0.8rem; }
.dispositivo-velocidad-lista { display: flex; gap: 6px; flex-wrap: wrap; }
.dispositivo-velocidad-btn.is-active {
  border-color: var(--accent); color: var(--accent); background: rgba(139, 124, 246, 0.12);
}
.dispositivo-btn-suelto { display: block; width: 100%; max-width: 700px; margin: 16px auto 0; text-align: center; }


/* --- Carátula de la canción --- */
.r-cover-wrap {
  display: none;
  justify-content: center; align-items: center;
  width: 100%; padding: 10px 0;
}
.r-cover {
  width: 220px; height: 220px; object-fit: cover;
  border-radius: 16px; box-shadow: 0 8px 30px rgba(0,0,0,0.45);
}
.r-cover-placeholder {
  width: 220px; height: 220px;
  display: flex; justify-content: center; align-items: center;
  background: linear-gradient(135deg, #1a1a2e, #16213e);
  border-radius: 16px; font-size: 4.5rem; color: rgba(139,124,246,0.35);
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
}
.embed-wrap.solo-audio .r-cover-wrap {
  display: flex;
}

/* ---------- Densidad del conjunto (menor espacio posible) ----------
   A esto le faltaba el @media que lo encierra (encontrado 3-sep-2026,
   Ramón con una foto real del móvil: la cabecera, las pestañas y las
   tarjetas de sección salían encogidas y desordenadas). Sin él, todas
   estas reglas de "hazlo más compacto para el móvil" se aplicaban
   SIEMPRE, en cualquier tamaño de pantalla, ganándole por orden de
   cascada a los valores de escritorio de más arriba en este mismo
   archivo. Ahora solo entran por debajo de 640px, que es para lo que
   se escribieron. */
@media (max-width: 640px) {
.container { padding: 14px 18px 90px; }
.app-header { padding: 18px 18px 8px; gap: 14px; }
.logo-mark { width: 38px; height: 38px; box-shadow: 0 0 32px rgba(139, 124, 246, 0.4); }
.menu-title { font-size: clamp(1.35rem, 3vw, 1.9rem); }
.menu-subtitle { font-size: 0.85rem; }
.top-link { padding: 7px 13px; font-size: 0.82rem; }
.app-footer { padding: 12px; }

/* DOS COLUMNAS EN EL MÓVIL (5-sep-2026).
   Antes cabía un estado y medio por pantalla: para ver los 20 había que
   pasar seis pantallas de scroll. Con dos columnas se ven seis de golpe,
   que es como enseñan sus rejillas Spotify y Apple Music. Lo que se cae de
   la tarjeta es la descripción larga, no el nombre ni los géneros: el
   nombre y el icono son lo que se busca de un vistazo, y la descripción
   está una sola vez arriba de cada estado cuando entras. */
.moods-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.mood-card { min-height: 0; }
.mood-card-body { padding: 14px 12px; gap: 5px; }
.mood-icon { font-size: 1.3rem; }
.mood-icon .fm-icono { width: 26px; height: 26px; }
.mood-name { font-size: 1rem; line-height: 1.25; }
.mood-desc { display: none; }
/* Los géneros sí se quedan: son la pista de qué suena dentro. Dos líneas
   como mucho, y lo que sobre se corta con puntos suspensivos. */
.mood-styles {
  font-size: 0.66rem; margin-top: 4px; letter-spacing: 0.03em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.badge { top: 8px; right: 8px; font-size: 0.58rem; padding: 3px 7px; }

/* Móviles muy estrechos (320px): una sola columna, que a 150px de ancho no
   cabe un nombre de dos palabras sin partirse en cuatro líneas. */
@media (max-width: 360px) {
  .moods-grid { grid-template-columns: 1fr; }
  .mood-desc { display: block; font-size: 0.8rem; }
}

.feed-tabs { margin-bottom: 12px; gap: 7px; }

/* LOS CUATRO FILTROS, DOS Y DOS (5-sep-2026, Ramón con una foto: "faltaría
   igualar estos 4 botones: todos del mismo tamaño, dos arriba y dos abajo
   llenando todo el ancho").
   Eran una fila que se iba envolviendo sola, así que cada pastilla medía lo
   que medía su texto y quedaban descolocadas: una larga y una corta arriba,
   y otras dos distintas debajo. En cuadrícula de dos columnas las cuatro
   miden exactamente lo mismo y ocupan el ancho entero.
   Solo aquí (#viewTabs): en Comunidad son dos y en Ruta son tres tramos,
   donde una cuadrícula de dos dejaría uno solo en la última fila. */
#viewTabs {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  justify-content: stretch;
}
#viewTabs .tab {
  width: 100%;
  /* Sin nowrap: "Por estado de ánimo" no cabe de una línea en media
     pantalla, y con nowrap se salía de la pastilla. */
  white-space: normal; line-height: 1.25; padding: 8px 10px;
  text-align: center;
}
.tab { padding: 7px 15px; font-size: 0.84rem; min-height: 48px; }
.buscador-artista { margin: 0 0 14px; }
.buscador-campo { padding: 10px 14px; }
.buscador-nota { margin: 6px 2px 0; }

.panel { padding: 18px; margin-bottom: 16px; }
.panel-head { margin-bottom: 12px; }
.panel-title { font-size: 1.15rem; }
.panel-sub { font-size: 0.84rem; margin-top: 3px; }
.panel-head-sep { margin-top: 16px; padding-top: 14px; }
.styles-grid { gap: 10px; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.style-card { padding: 16px; }
.duration-options { gap: 10px; margin-bottom: 14px; }
.duration-option { padding: 14px; }
.duration-free { margin-bottom: 14px; }
.fuente-archivos { gap: 6px; margin-bottom: 14px; }
.fuente-archivos-botones { gap: 8px; }
.fuente-opciones { gap: 8px; margin-bottom: 10px; }
.fuente-opcion { padding: 10px 8px; }
.fuente-aviso { margin: 0 0 14px; }

.player-top { padding: 12px 18px 4px; gap: 12px; }
.player-mood-name { font-size: 0.95rem; }

.embed-wrap { max-width: 640px; margin: 0 auto 12px; }
.now-info { gap: 8px; margin-bottom: 10px; }
.session-progress { margin-bottom: 10px; }
.player-controls { gap: 10px; }
.ctl-btn { width: 46px; height: 46px; font-size: 1.05rem; }
.ctl-btn .fm-icono { width: 22px; height: 22px; }

.bienv { padding: 12px 14px; margin: 0 0 14px; }
.bienv-lista { gap: 10px; }

/* ---------- El paso 3 también en una sola pantalla (10-sep-2026) ----------
   Medido en un móvil de 361x784 contra la web publicada: el desplegable de
   abajo terminaba en el píxel 767 y la barra de abajo empieza en el 725, o
   sea que su cabecera quedaba TAPADA por la barra. Y Ramón había pedido
   justo lo contrario para ese desplegable: "es importante que se lea".

   Lo que NO se ha tocado, a propósito: los botones siguen en 44 px. Es el
   mínimo para acertar con el dedo, y está defendido en media hoja de estilos.
   Un primer intento los bajó a 38 y ni siquiera funcionó: la regla de
   .acciones-cancion .dim-toggle va más abajo en este archivo y ganaba el
   empate. Por eso todo aquí va colgado de #playerPanel, que gana por peso
   y no por posición.

   De dónde sale el sitio (medido, no estimado): la cabecera del desplegable
   pasa de cuatro líneas a tres (83 -> 56 px), y se quita aire entre bloques.
   Resultado: termina en el 712, con 13 px de margen sobre la barra. */
#playerPanel .embed-wrap { margin-bottom: 8px; }
#playerPanel .now-info { margin-bottom: 6px; gap: 6px 8px; }
#playerPanel .session-progress { margin-bottom: 6px; }
#playerPanel .acciones-cancion { margin-top: 6px; }
#playerPanel .info-desplegable { margin-top: 8px; }
#playerPanel .info-desplegable-cabecera { padding: 10px 34px 10px 12px; font-size: 0.82rem; }
} /* fin @media (max-width: 640px) de "Densidad del conjunto" */

/* La × del aviso de los 30 segundos. Quien prefiere seguir en Spotify con
   trozos (o va a entrar en su cuenta ahora) tiene que poder quitárselo de
   delante: el aviso mide casi 200 px y empujaría la pantalla fuera. */
.aviso-trozos { position: relative; }
.aviso-trozos-cerrar {
  position: absolute; top: 2px; right: 2px;
  width: 44px; height: 44px;
  background: none; border: 0; cursor: pointer;
  color: var(--text-dim); font-size: 1.4rem; line-height: 1;
}
.aviso-trozos-cerrar:hover, .aviso-trozos-cerrar:focus-visible { color: var(--text); }
.aviso-trozos-titulo { padding: 0 30px; }

/* ---------- Dentro de la app: las dos hamburguesas en la cabecera (10-sep-2026)
   Ramón: "hay dos hamburguesas: la que lleva el menú completo de las
   pestañas, esa a la izquierda, y la que lleva las instrucciones, esa a la
   derecha", en todas las pantallas. Dentro de la app eso es un botón más de
   44 px en una cabecera que ya iba justa: medido a 361 px, partía la
   cabecera del reproductor en dos filas (60 -> 116 px) y la pantalla de la
   música se salía 46 px por abajo.

   Se aprieta solo lo que hace falta, y solo dentro de la app: la clase la
   pone lib/menu-app.js al colocar el botón, y en el navegador, donde ese
   botón no existe, todo sigue como estaba. La flecha de volver CONSERVA su
   texto, que es lo que Ramón pidió el 5-sep ("se hace difícil encontrar
   cómo volver atrás"); se probó quitárselo y se descartó por eso. El
   subtítulo, si no cabe, se corta con puntos suspensivos en vez de bajar de
   línea y hacer crecer la cabecera.
   Medido: el reproductor vuelve a una sola fila de 60 px y la música cabe. */
@media (max-width: 640px) {
  .con-menu-app .player-top { gap: 6px; }
  .con-menu-app .player-top .back-link { padding: 8px 11px 8px 9px; font-size: 0.84rem; }
  .con-menu-app .cabecera-acciones { gap: 6px; }
  .con-menu-app .player-mood-info { min-width: 0; }
  .con-menu-app .player-mood-name { font-size: 0.9rem; }
  .con-menu-app .player-style-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* ---------- Extra de los controles del player (3-sep-2026) ---------- */
.player-extra {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 10px;
}

/* ---------- Si el móvil pide menos movimiento (7-sep-2026, auditoría) ----------
   Android e iPhone tienen una casilla de accesibilidad, "Reducir movimiento",
   que la gente con mareo o vértigo lleva puesta. La app tenía 34 transiciones
   y animaciones y no la miraba ninguna. Aquí no se quita nada de sitio: solo
   se dejan de animar los cambios, así que quien no tenga esa casilla puesta
   ve exactamente lo mismo que antes.
   El "scroll-behavior" también entra: lo usa la barra de abajo al llevarte a
   la rejilla de estados (lib/nav-inferior.js, scrollIntoView con smooth). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
/* ---------- Seguir escuchando (9-sep-2026) ----------
   El aviso de la portada para volver a la sesión que se quedó a medias
   (lib/seguir-escuchando.js). Ramón: "tengo que poder volver exactamente
   donde lo había dejado".
   Va con el morado de la app, como el botón de "Mi música", pero en versión
   suave: es un ofrecimiento, no la acción principal de la pantalla. */
/* 18-sep-2026, Ramón: "esto es antiestético de cojones" -- en una pantalla
   ancha (escritorio) esta banda no tenía tope de ancho y se estiraba a todo
   el contenedor (1180px), mientras que las fichas de abajo ya van con un
   tope de 700px como el resto de bloques de contenido (.player-cola,
   .file-progress). Mismo tope aquí. */
.seguir-escuchando {
  display: flex;
  align-items: stretch;
  gap: 8px;
  max-width: 700px;
  margin: 0 auto 14px;
}
.seguir-escuchando-btn {
  flex: 1;
  min-width: 0;                 /* que el texto largo se recorte, no desborde */
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(124, 108, 240, 0.55);
  border-radius: 14px;
  background: rgba(124, 108, 240, 0.14);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.seguir-escuchando-icono {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: #7c6cf0;
  color: #fff;
}
.seguir-escuchando-textos { display: flex; flex-direction: column; min-width: 0; }
.seguir-escuchando-titulo { font-weight: 600; font-size: 0.98rem; }
.seguir-escuchando-detalle {
  font-size: 0.82rem;
  color: var(--text-dim);
  /* En un móvil de 320px caben unas 34 letras: "Relajación · Piano de noche ·
     quedan 42 min" no cabe, y sin esto empujaba el aspa fuera de la pantalla. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seguir-escuchando-cerrar {
  flex: none;
  width: 40px;
  border: 1px solid var(--velo-borde);
  border-radius: 14px;
  background: transparent;
  color: var(--text-dim);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

/* ---------- La línea de opciones del reproductor (9-sep-2026) ----------
   Ramón, con una foto de la pantalla: "después la línea de opciones, y ahí
   van juntas las tres cosas que ahora están sueltas o más abajo: Atenuar
   pantalla, Estudiar esta canción en Frasly Lab y Compartir, con los
   iconos", y después "atenuar pantalla arriba también".

   "Atenuar pantalla" y "Estudiar en Frasly Lab" nacieron cada uno como un
   bloque suelto a lo ancho de la pantalla (.dim-toggle con margin:auto,
   .lab-btn con width:100%). Metidos en esta fila, esos dos rasgos la
   partían. Aquí se les quita solo eso: dentro de la fila son una pastilla
   más, igual que Compartir. Fuera de ella siguen exactamente como estaban,
   que es como los usa ruta.html. */
.acciones-cancion .dim-toggle,
.acciones-cancion .lab-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  margin: 0;
  min-height: 44px;
  padding: 9px 16px;
  border-radius: 999px;
  font-size: 0.85rem;
}
.acciones-cancion .lab-btn { color: var(--accent-2); border-color: var(--accent-2); }
.acciones-cancion .lab-btn .fm-icono { width: 17px; height: 17px; flex: none; }
/* El nombre largo de Frasly Lab no puede empujar la fila fuera de la
   pantalla en un móvil estrecho. */
.acciones-cancion .lab-btn span { min-width: 0; }

/* ---------- Lo que se lee, al final y recogido (9-sep-2026) ----------
   Ramón: "abajo pero con un desplegable que llame la atención", "es
   importante que se lea". Va cerrado, pero no como una línea gris que nadie
   toca: lleva el color de la app, su icono y su flecha.

   El <summary> NO lleva display:flex a propósito: en Safari de iPhone eso
   rompe el desplegable y deja de abrirse. El icono y el texto van en línea,
   que se comporta igual de bien en todas partes. */
.info-desplegable {
  margin: 18px auto 0;
  max-width: 620px;
  border: 1px solid var(--accent);
  border-radius: 14px;
  background: rgba(139, 124, 246, 0.10);
  overflow: hidden;
}
.info-desplegable-cabecera {
  padding: 13px 44px 13px 14px;
  color: var(--accent);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.35;
  cursor: pointer;
  position: relative;
  list-style: none;
}
/* La flecha de serie se quita en los dos motores y se pone la nuestra, para
   que sea igual en Android y en iPhone. */
.info-desplegable-cabecera::-webkit-details-marker { display: none; }
.info-desplegable-cabecera::marker { content: ''; }
.info-desplegable-cabecera::after {
  content: '';
  position: absolute;
  right: 18px;
  top: 50%;
  width: 9px; height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.2s ease;
}
.info-desplegable[open] .info-desplegable-cabecera::after {
  transform: translateY(-30%) rotate(-135deg);
}
.info-desplegable-icono { display: inline-block; vertical-align: -4px; margin-right: 8px; }
.info-desplegable-icono .fm-icono { width: 18px; height: 18px; display: block; }
.info-desplegable-cuerpo { padding: 0 14px 14px; }
/* Dentro del desplegable estos dos ya no necesitan su propio marco ni su
   propio centrado: el marco es el del desplegable. */
.info-desplegable-cuerpo .cast-aviso { background: transparent; border: 0; padding: 0; margin: 0; }
.info-desplegable-cuerpo .wake-hint { margin: 12px auto 0; }

/* ---------- Los estados, encima del reproductor (9-sep-2026) ----------
   Ramón: "hay que poder ver los estados sin que deje de sonar la música por
   cambiar de pantalla". Se enseñan aquí, sin salir de la página, porque salir
   es justo lo que cortaba la música. Ver lib/estados-flotante.js.

   La tarjeta es más ancha que un modal normal (460 px se queda en una sola
   columna de estados) y las tarjetas van más pequeñas que en la portada: esto
   es un vistazo por encima de lo que suena, no la pantalla principal. */
.estados-flotante-card { max-width: 720px; padding: 24px 20px; }
.estados-flotante-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.estados-flotante-grid .mood-card { min-height: 0; }
.estados-flotante-grid .mood-card-body { padding: 14px; }
.estados-flotante-grid .mood-name { font-size: 1rem; }
.estados-flotante-grid .mood-desc { font-size: 0.8rem; }
/* La tarjeta no se levanta al pasar por encima: aquí van muchas y juntas, y
   el salto de una sobre las de al lado se ve como un temblor. */
.estados-flotante-grid .mood-card:hover { transform: none; }

/* ---------- Cuando la plataforma no se deja mandar (9-sep-2026) ----------
   Ramón pidió que la app controlara todas. Se puede con YouTube y con Spotify
   (lib/spotify-control.js). Con Apple Music y Deezer no: probado en vivo, uno
   no contesta y el otro avisa pero no obedece.

   Los botones no se quitan, se apagan: quitarlos movería toda la fila y
   parecería otra pantalla. Apagados se ve que están y que ahora no tocan. */
.player-controls.sin-mando { opacity: 0.35; pointer-events: none; }
.sin-mando-aviso {
  max-width: 460px;
  margin: 10px auto 0;
  text-align: center;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--text-dim);
}

/* ---------- El paso 2, en una sola pantalla de móvil (9-sep-2026) ----------
   Ramón, con dos fotos: "no debe hacerse scroll para llegar a reproducir y ver
   todas las opciones. Mira si puede encajar todo en una pantalla de móvil,
   menos el texto de abajo que puede ir en desplegable". Y después: "y subir y
   encajar lo de abajo".

   El párrafo largo ya se recogió en un desplegable (player.html). Lo que queda
   es apretar: mismas piezas, mismos textos, menos aire. Va solo en pantallas
   estrechas: en el ordenador sobra sitio y no hay nada que apretar.

   Las tres duraciones pasan a una sola fila de tres. Antes, con minmax(160px),
   en un móvil de 360 px caben dos por fila y la tercera se iba sola a la
   siguiente, que es lo que empujaba «Empezar» fuera de la pantalla. */
@media (max-width: 640px) {
  #durationPanel { padding: 12px 14px; margin-bottom: 10px; }
  #durationPanel .panel-head { margin-bottom: 8px; }
  #durationPanel .panel-title { font-size: 1.12rem; }
  #durationPanel .panel-sub { font-size: 0.8rem; margin-top: 2px; }
  #durationPanel .panel-head-sep { margin-top: 10px; padding-top: 8px; }

  /* Los subtítulos de los dos pasos se quedan fuera SOLO en el móvil. Son
     explicativos, no imprescindibles ("solo salen las plataformas que tienen
     este estilo", "cada estilo tiene música continua"), y entre los dos se
     llevaban 44 px, que es justo lo que faltaba para que «Empezar» entrara.
     En pantalla ancha siguen ahí, y en el HTML no se ha quitado nada. */
  #durationPanel .panel-sub { display: none; }

  /* Las cuatro plataformas, en horizontal: el dibujo a la izquierda y el
     nombre con su nota a la derecha, en vez de uno encima de otro. La misma
     información en 100 px en vez de 164. Se hace con la rejilla y sin tocar
     el HTML que escribe renderFuentes(). */
  #durationPanel .fuente-opciones { gap: 7px; margin-bottom: 8px; }
  #durationPanel .fuente-opcion {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "icono nombre" "icono corto";
    align-items: center;
    column-gap: 8px;
    padding: 7px 9px;
    border-radius: 12px;
    text-align: left;
  }
  #durationPanel .fuente-icono { grid-area: icono; }
  #durationPanel .fuente-icono .fm-icono { width: 22px; height: 22px; }
  #durationPanel .fuente-nombre { grid-area: nombre; font-size: 0.86rem; margin: 0; }
  #durationPanel .fuente-corto { grid-area: corto; font-size: 0.66rem; margin: 0; line-height: 1.25; }

  #durationPanel .info-desplegable { margin: 0 0 10px; }

  #durationPanel .duration-options {
    grid-template-columns: repeat(3, 1fr);
    gap: 7px;
    margin-bottom: 8px;
  }
  #durationPanel .duration-option { padding: 8px 4px; border-radius: 12px; }
  #durationPanel .duration-label { font-size: 0.88rem; }
  #durationPanel .duration-desc { font-size: 0.68rem; margin-top: 2px; }

  #durationPanel .duration-free { margin-bottom: 8px; font-size: 0.82rem; gap: 8px; }
  #durationPanel .duration-free input { width: 74px; padding: 6px 8px; font-size: 0.9rem; }
  #durationPanel .primary-btn { width: 100%; padding: 12px 16px; }
}

/* La versión fina del desplegable, para el paso 2: el mismo aspecto que en el
   reproductor pero sin tanto aire, que aquí cada línea cuenta. */
.info-desplegable-fino .info-desplegable-cabecera {
  padding: 9px 38px 9px 12px;
  font-size: 0.82rem;
}
.info-desplegable-fino .info-desplegable-cuerpo { padding: 0 12px 12px; }
.info-desplegable-fino .info-desplegable-cuerpo .fuente-aviso {
  background: transparent; border: 0; padding: 0; margin: 0;
}
