/* EF — Sistema de diseño único, extraído literalmente del CSS de las
   landings reales (laestacionflamenca.com/5dias/ y /oferta/): fondo
   casi negro cálido, naranja + naranja claro + dorado, tipografía
   Montserrat (titulares) + Cormorant Garamond itálica dorada (nombres
   de sección/tramo). Nada de blanco puro, gris frío ni azul. */
:root {
  --ef-fondo: #161310;
  --ef-fondo-2: #211b16;
  --ef-naranja: #E1581F;
  --ef-naranja-claro: #F0861F;
  --ef-dorado: #F8B336;
  --ef-crema: #F5EFE6;
  --ef-crema-tenue: #c9bfb2;
  --ef-verde-ok: #2E7D4F;
  --ef-azul-noche: #1F3A5F;
  --ef-tramo-completado: #F6A93D;
  --ef-tramo-pendiente: #818181;
  --ef-guia-rojo: #E5433A;
  --ef-radio: 14px;
  --ef-sombra: 0 10px 30px rgba(0, 0, 0, 0.35);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  overflow-x: hidden; /* 28-ago: red de seguridad -- ningun elemento debe poder abrir scroll horizontal */
  font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-weight: 600;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(225, 88, 31, 0.28) 0%, rgba(225, 88, 31, 0) 55%),
    radial-gradient(90% 60% at 50% 110%, rgba(248, 179, 54, 0.12) 0%, rgba(248, 179, 54, 0) 60%),
    var(--ef-fondo);
  background-attachment: fixed;
  color: var(--ef-crema);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--ef-naranja-claro); }

/* Nombres de sección/tramo: el toque de carácter distintivo de la marca */
h1, h2 {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  color: var(--ef-dorado);
  line-height: 1.15;
  margin: 0 0 4px;
}
h1 { font-size: clamp(2rem, 5vw, 2.6rem); }
/* 27-ago (Seba, móvil): los títulos de sección de la ficha ("Tu progreso",
   "Tu camino, jornada a jornada"...) se veían pequeños al lado de textos
   normales como "Nivel Aprendiz" -- se sube el tamaño general. */
h2 { font-size: clamp(1.55rem, 4vw, 1.85rem); }
h3 {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  color: var(--ef-crema);
  margin: 0 0 4px;
}

.ef-header {
  background: var(--ef-fondo);
  border-bottom: 1px solid rgba(245, 239, 230, 0.08);
  color: var(--ef-crema);
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

.ef-header a { color: var(--ef-crema); text-decoration: none; font-weight: 600; }
.ef-header-logo { display: flex; align-items: center; }
.ef-logo { display: block; height: 36px; width: auto; }
.ef-header nav { display: flex; flex-wrap: wrap; gap: 10px; }
.ef-header nav a {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid #f0a83c;
  border-radius: 20px;
  padding: 8px 16px;
  color: #e8ddc7;
  font-weight: 600;
}
.ef-header nav a:hover { color: var(--ef-naranja-claro); }
.ef-header nav a.activo {
  background: var(--ef-dorado);
  border-color: var(--ef-dorado);
  color: #1a1208;
}
.ef-header .ef-badge-sandbox {
  background: var(--ef-dorado);
  color: var(--ef-fondo);
  font-size: 11px;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  margin-left: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ef-contenedor {
  max-width: 880px;
  margin: 0 auto;
  padding: 28px 20px 60px;
}

/* Hero de logo en /login: bloque centrado antes del formulario */
.ef-login-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 20px auto 30px;
}
.ef-login-hero-logo {
  display: block;
  width: 100%;
  max-width: 340px;
  height: auto;
}
.ef-login-separador {
  width: 90px;
  height: 2px;
  margin-top: 22px;
  background: linear-gradient(90deg, transparent, var(--ef-dorado), transparent);
}

.ef-card {
  background: var(--ef-fondo-2);
  border: 1px solid rgba(245, 239, 230, 0.08);
  border-radius: var(--ef-radio);
  box-shadow: var(--ef-sombra);
  padding: 20px 22px;
  margin-bottom: 18px;
}

/* 31-ago: pantalla de bienvenida tras el pago -- foto de Seba (PNG
   recortado sin fondo) a un lado y bocadillo de comic al otro, en vez
   del mensaje de texto plano anterior. Escritorio: dos columnas, foto
   a la izquierda. Movil: se apila (foto arriba, bocadillo debajo).
   31-ago (2a ronda, Seba: "no quiero ningun recuadro", "el bocadillo
   es blanco, quiero los colores corporativos, que tenga armonia"):
   se quita la .ef-card (caja con fondo/borde/sombra) -- ya NO lleva esa
   clase en el HTML, la foto y el bocadillo flotan directamente sobre el
   fondo de la pagina. En su lugar, un resplandor radial dorado/naranja
   muy sutil detras de la foto (el mismo lenguaje visual que el resto de
   la marca, ver login-guitar y el marco del mapa) le da cuerpo sin caja.
   El bocadillo pasa de blanco liso a un degradado dorado -> naranja
   (los dos colores de marca), con texto oscuro para contraste, igual
   que los botones .ef-btn-dorado. */
.ef-bienvenida-card {
  position: relative;
  max-width: 1320px;
  margin: 40px auto;
  padding: 56px 24px;
}
.ef-bienvenida-card::before {
  content: "";
  position: absolute;
  inset: -40px 0 0 0;
  z-index: 0;
  background:
    radial-gradient(55% 65% at 22% 45%, rgba(248, 179, 54, 0.16) 0%, rgba(248, 179, 54, 0) 65%),
    radial-gradient(45% 55% at 78% 60%, rgba(225, 88, 31, 0.10) 0%, rgba(225, 88, 31, 0) 65%);
  pointer-events: none;
}
.ef-bienvenida-wrap {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 48px;
}
.ef-bienvenida-foto-col {
  flex: 0 0 auto;
}
.ef-bienvenida-foto {
  display: block;
  width: 460px;
  max-width: 100%;
  height: auto;
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, 0.45));
}
.ef-bienvenida-texto-col {
  flex: 1;
  min-width: 0;
  text-align: left;
}
/* 31-ago (Seba, tras comparar con /mapa y /ficha): fuera el bocadillo de
   comic (bloque de color solido + rabito) -- no pega con el resto de la
   app, donde el titular siempre es texto grande en cursiva dorada sobre
   el fondo, sin caja de color detras (igual que <h1> en .ef-card). Se
   sustituye por ese mismo lenguaje: .ef-bienvenida-titulo hace de h1
   (Cormorant Garamond italica dorada) y .ef-bienvenida-progreso (ya
   existia) hace de subtitulo en crema. */
.ef-bienvenida-titulo {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  color: var(--ef-dorado);
  font-size: clamp(2.2rem, 4.6vw, 3.4rem);
  line-height: 1.14;
  margin: 0 0 10px;
}
.ef-bienvenida-progreso {
  font-size: 21px;
  color: var(--ef-crema);
  margin: 0 0 22px;
}
/* 31-ago (Seba): "en movil se queda como esta, en ordenador que se haga
   mas grande" -- los valores base de arriba son los de escritorio; el
   bloque @media (max-width: 640px) de abajo ya pisa foto/margenes con
   sus propios numeros fijos, así que el movil no cambia con esto. */
@media (max-width: 640px) {
  .ef-bienvenida-card {
    margin: 20px auto;
    padding: 22px 18px;
  }
  .ef-bienvenida-card::before {
    inset: -16px 0 0 0;
  }
  .ef-bienvenida-wrap {
    flex-direction: column;
    text-align: center;
  }
  .ef-bienvenida-texto-col {
    text-align: center;
  }
  .ef-bienvenida-foto {
    width: 200px;
    margin: 0 auto;
  }
  /* 31-ago: el movil se queda con el tamano de letra que ya tenia --
     los valores base de arriba se subieron solo para escritorio. */
  .ef-bienvenida-titulo {
    font-size: clamp(1.6rem, 4vw, 2.1rem);
  }
  .ef-bienvenida-progreso {
    font-size: 15px;
  }
}

/* Caja destacada (reto del mes, avisos de sandbox): mismo fondo de
   tarjeta + borde discontinuo dorado, para llamar la atención sin
   salirse de la paleta. */
.ef-card-destacada {
  background: var(--ef-fondo-2);
  border: 1px dashed var(--ef-dorado);
  border-radius: var(--ef-radio);
  padding: 14px 16px;
}

/* 31-ago: galeria de "mapa completado" en /mapa (antes un aviso de texto
   plano) -- una tarjeta por mapa del camino, con su ilustracion e
   insignia "Completado" cuando corresponde. Primer borrador, pensado
   para crecer cuando haya mas de un mapa. */
.ef-mapa-galeria-completado {
  text-align: center;
}
.ef-mapa-galeria-titulo {
  margin: 0 0 14px;
  font-weight: 600;
}
.ef-mapa-galeria-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}
.ef-mapa-galeria-item {
  width: 200px;
  max-width: 100%;
}
.ef-mapa-galeria-imagen-wrap {
  position: relative;
  border-radius: var(--ef-radio);
  overflow: hidden;
  border: 2px solid var(--ef-dorado);
}
.ef-mapa-galeria-item.completado .ef-mapa-galeria-imagen-wrap {
  border-color: var(--ef-naranja);
}
.ef-mapa-galeria-imagen {
  display: block;
  width: 100%;
  height: 130px;
  object-fit: cover;
}
.ef-mapa-galeria-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: var(--ef-naranja);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
}
.ef-mapa-galeria-nombre {
  margin: 8px 0 0;
  font-weight: 600;
}

/* ====== Botones: degradado + glow + hover con elevación, calcados de
   las landings ====== */
.ef-btn {
  display: inline-block;
  background: linear-gradient(90deg, var(--ef-naranja) 0%, var(--ef-naranja-claro) 100%);
  color: #fff;
  border: none;
  border-radius: var(--ef-radio);
  padding: 13px 22px;
  font-family: 'Montserrat', sans-serif;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 10px 30px rgba(225, 88, 31, 0.45), 0 0 0 2px rgba(248, 179, 54, 0.25);
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.ef-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 36px rgba(225, 88, 31, 0.6), 0 0 0 2px rgba(248, 179, 54, 0.4);
}
.ef-btn:active { transform: translateY(0); }

.ef-btn-dorado {
  background: linear-gradient(90deg, var(--ef-dorado) 0%, #ffce6b 100%);
  color: var(--ef-fondo);
  box-shadow: 0 10px 30px rgba(248, 179, 54, 0.4), 0 0 0 2px rgba(248, 179, 54, 0.2);
  animation: ef-pulso-dorado 2.6s ease-in-out infinite;
}
.ef-btn-dorado:hover {
  box-shadow: 0 14px 36px rgba(248, 179, 54, 0.6), 0 0 0 2px rgba(248, 179, 54, 0.35);
  animation-play-state: paused;
}
@keyframes ef-pulso-dorado {
  0%, 100% { box-shadow: 0 10px 30px rgba(248, 179, 54, 0.4), 0 0 0 2px rgba(248, 179, 54, 0.2); }
  50% { box-shadow: 0 10px 38px rgba(248, 179, 54, 0.65), 0 0 0 6px rgba(248, 179, 54, 0.1); }
}
@media (prefers-reduced-motion: reduce) {
  .ef-btn-dorado { animation: none; }
}

/* 31-ago (Seba): el boton "Continuar con el pago" en checkout pasaba
   desapercibido -- centrado y mas grande (escritorio y movil), y con un
   halo rojo/naranja encendido todo el rato (no solo un momento), para
   que se vea siempre donde hay que pulsar. Al elegir un plan tambien
   hace scroll hacia el boton (ver el <script> en checkout_elegir.php). */
.ef-checkout-btn-wrap {
  text-align: center;
  margin-top: 8px;
}
.ef-checkout-btn-continuar {
  font-size: 18px;
  padding: 17px 38px;
}
.ef-checkout-btn-halo {
  animation: ef-checkout-halo-pulso 0.9s ease-in-out infinite;
}
@keyframes ef-checkout-halo-pulso {
  0%, 100% {
    box-shadow: 0 10px 30px rgba(248, 179, 54, 0.4), 0 0 0 2px rgba(248, 179, 54, 0.2);
  }
  50% {
    box-shadow: 0 10px 30px rgba(248, 179, 54, 0.4), 0 0 0 10px rgba(225, 88, 31, 0.55);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ef-checkout-btn-halo { animation: none; }
}

/* Botón "Empezar" de /dia/{n} (índice "Hoy nos toca" + "Antes de
   empezar"): modificador aparte, no se toca .ef-btn-dorado en sí para no
   afectar el resto de pantallas que lo reutilizan (checkout, reto,
   login...). Fondo dorado sólido (sin gradiente) y sin el pulso animado
   de .ef-btn-dorado, con un glow estático propio. */
.ef-btn-empezar-dia {
  display: block;
  width: 100%;
  text-align: center;
  padding: 16px 22px;
  background: var(--ef-dorado);
  box-shadow: 0 0 24px 4px rgba(246, 169, 61, 0.45);
  animation: none;
  /* 31-ago (Seba): texto mas grande para dar mas potencia al "¡¡Vamos
     al lio!!" -- .ef-btn base se queda en 15px, este boton concreto
     sube el tamaño sin tocar el resto de botones que reutilizan .ef-btn. */
  font-size: 21px;
  letter-spacing: 0.3px;
}
.ef-btn-empezar-dia:hover {
  background: var(--ef-dorado);
  box-shadow: 0 0 30px 6px rgba(246, 169, 61, 0.6);
}

.ef-btn-secundario {
  background: transparent;
  color: var(--ef-dorado);
  border: 1px solid var(--ef-dorado);
  box-shadow: none;
}
.ef-btn-secundario:hover {
  background: var(--ef-dorado);
  color: var(--ef-fondo);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(248, 179, 54, 0.35);
}

input[type="text"], input[type="email"], input[type="password"], input[type="search"], textarea {
  padding: 12px 14px;
  background: var(--ef-crema);
  color: var(--ef-fondo);
  border: 2px solid transparent;
  border-radius: 10px;
  font-size: 15px;
  font-family: 'Montserrat', sans-serif;
}
.ef-form input[type="text"], .ef-form input[type="email"], .ef-form input[type="password"], .ef-form textarea {
  width: 100%;
  margin-bottom: 12px;
}

/* 29-ago: toggle de mostrar/ocultar contraseña en /registro -- evita
   pedir la contraseña dos veces (desaconsejado hoy en dia por las guias
   de UX de registro), un solo campo con un botón de texto encima. */
.ef-password-wrap {
  position: relative;
}
.ef-password-wrap input[type="password"], .ef-password-wrap input[type="text"] {
  padding-right: 76px;
}
.ef-password-toggle {
  position: absolute;
  right: 10px;
  top: 0;
  bottom: 12px;
  display: flex;
  align-items: center;
  background: none;
  border: none;
  color: var(--ef-naranja);
  font-size: 13px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  cursor: pointer;
  padding: 0 4px;
}
.ef-password-toggle:hover {
  text-decoration: underline;
}
input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="search"]:focus, textarea:focus {
  outline: none;
  border-color: var(--ef-dorado);
}

/* Controles nativos (radios/checkboxes): recolorearlos a la marca sin
   tener que reconstruirlos a mano. */
input[type="radio"], input[type="checkbox"] {
  accent-color: var(--ef-naranja);
}

/* Checkbox "Es mi vídeo del Reto de este mes" (27-ago, Comunidad). */
.ef-check-linea {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ef-crema-tenue);
  margin: 6px 0 12px;
  cursor: pointer;
}
.ef-check-linea input[type="checkbox"] { margin: 0; }

/* Tarjeta de puntos/nivel en /ficha (27-ago, Comunidad v1) -- deliberadamente
   sobria, sin insignias ni barras de "juego": el público objetivo (40-70
   años) no debe sentir que esto es infantil. Solo el propio alumno la ve. */
.ef-puntos-nivel { font-size: 17px; font-weight: 600; color: var(--ef-dorado); margin: 4px 0 4px; }
.ef-puntos-numero { color: var(--ef-crema); font-weight: 400; }
.ef-puntos-siguiente { font-size: 13px; color: var(--ef-crema-tenue); margin: 0; }

/* Mapa de niveles en "Tu progreso" (27-ago v3, Seba): misterio parcial --
   el nivel actual y el siguiente muestran nombre + puntos; los que quedan
   más lejos se pintan como "?" (PuntosService::nivel() ya no manda su
   nombre ni sus puntos para esos), para generar curiosidad sin caer en
   una estética de barra de videojuego. v3: icono + color/glow por estado,
   y en móvil la fila se desliza en lugar de apretujarse. */
.ef-nivel-camino {
  display: flex;
  gap: 10px;
  margin: 16px 0 4px;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
}
@media (min-width: 560px) {
  .ef-nivel-camino { -webkit-mask-image: none; mask-image: none; }
}
/* 28-ago v7 (Seba, movil real): un elemento con mask-image pasa a ser el
   contenedor de posicion de cualquier position:fixed que tenga dentro en
   vez de la pantalla entera (asi lo trata Safari) -- por eso el popover
   del camino de niveles salia mal colocado en movil. Mientras haya un
   popover abierto dentro de esta fila, calendario-popover.js le quita la
   mascara con esta clase, y el popover (position:fixed) vuelve a
   centrarse en toda la pantalla como es debido. */
.ef-nivel-camino.ef-mascara-pausada { -webkit-mask-image: none; mask-image: none; }
.ef-nivel-paso-detalle {
  flex: 0 0 100px;
  scroll-snap-align: start;
  position: relative;
}
@media (min-width: 560px) {
  .ef-nivel-camino { overflow-x: visible; }
  .ef-nivel-paso-detalle { flex: 1 1 0; }
}
.ef-nivel-paso {
  display: block;
  width: 100%;
  text-align: center;
  border: 1px solid rgba(245, 239, 230, 0.14);
  border-top: 3px solid rgba(245, 239, 230, 0.14);
  border-radius: 10px;
  padding: 12px 6px 10px;
  background: rgba(245, 239, 230, 0.03);
  cursor: pointer;
  list-style: none;
}
.ef-nivel-paso::-webkit-details-marker { display: none; }
.ef-nivel-paso:focus { outline: none; }
.ef-nivel-paso:focus-visible { outline: 2px solid var(--ef-dorado); outline-offset: 2px; }
/* 28-ago v4 (Seba: "olvidate de iconografia, deja solo el propio anillo,
   vamos a probarlo") -- ya no hay SVGs de icono por nivel; el anillo de
   progreso (relleno segun % conseguido hacia el siguiente nivel, solo en
   el paso "actual") es el unico elemento visual dentro de cada paso. */
.ef-nivel-paso-icono {
  display: block;
  position: relative;
  width: 34px;
  height: 34px;
  margin: 0 auto 6px;
}
.ef-anillo-fondo { fill: none; stroke: rgba(245, 239, 230, 0.14); stroke-width: 3; }
.ef-anillo-relleno {
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  transition: stroke-dashoffset 0.4s ease;
}
.ef-nivel-paso-interrogante {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  color: var(--ef-crema-tenue);
  opacity: 0.55;
}
.ef-nivel-paso-nombre { display: block; font-size: 12.5px; font-weight: 600; color: var(--ef-crema-tenue); }
.ef-nivel-paso-pts { display: block; font-size: 11px; color: var(--ef-crema-tenue); opacity: 0.7; margin-top: 2px; }

/* 28-ago noche v2 (Seba: "cuando se supera un nivel se pone blanco, sin
   vida -- quiero un color vivo que marque que ya esta hecho") -- pasa de
   crema plano a un tono naranja calido con fondo tenue del mismo color,
   bien distinto del dorado pulsante del nivel actual y del gris apagado
   de los niveles ocultos. */
.ef-nivel-paso.alcanzado {
  border-top-color: var(--ef-guia-rojo);
  border-color: rgba(229, 67, 58, 0.4);
  background: rgba(229, 67, 58, 0.12);
  color: var(--ef-guia-rojo);
}
.ef-nivel-paso.alcanzado .ef-nivel-paso-nombre { color: var(--ef-crema); font-weight: 700; }
.ef-nivel-paso.alcanzado .ef-nivel-paso-pts { color: var(--ef-guia-rojo); opacity: 1; font-weight: 800; }
.ef-nivel-paso.alcanzado .ef-nivel-paso-icono svg { display: none; }
/* 29-ago v2 (Seba: "entre la r de aprendiz hay como una barra") -- el
   arreglo anterior rompio el centrado: al quitar el position:absolute
   del circulo (::before) pero dejarlo en el check (::after), flexbox
   los coloco UNO AL LADO DEL OTRO en vez de superpuestos -- de ahi la
   barra. Se vuelve a la tecnica de superponer ambos con position:
   absolute + translate(-50%,-50%) sobre el mismo punto central, que es
   la unica forma fiable de apilarlos exactamente uno encima del otro. */
.ef-nivel-paso-check { position: absolute; inset: 0; }
.ef-nivel-paso-check::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--ef-guia-rojo);
  box-shadow: 0 0 0 2px rgba(229, 67, 58, 0.35);
}
.ef-nivel-paso-check::after {
  content: '\2713';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
  font-weight: 900;
  color: var(--ef-crema);
  line-height: 1;
}

.ef-nivel-paso.actual {
  border-color: var(--ef-dorado);
  border-top-color: var(--ef-dorado);
  border-width: 2px;
  background: rgba(248, 179, 54, 0.2);
  color: var(--ef-dorado);
  animation: ef-nivel-actual-pulso 1.8s ease-in-out infinite;
}
.ef-nivel-paso.actual .ef-nivel-paso-nombre { color: var(--ef-crema); font-size: 13.5px; }
.ef-nivel-paso.actual .ef-nivel-paso-pts { color: var(--ef-dorado); opacity: 1; font-weight: 800; }
/* 28-ago v5 (Seba: "que se ilumine y se apague, mas llamativo") -- el paso
   actual del camino de niveles late en vez de quedarse con un glow fijo,
   para que llame la atencion sin caer en flashes bruscos de videojuego. */
/* 28-ago v7 (Seba: "quiero que destaque todavia mas, que brille mas") --
   se sube la intensidad del pulso, mismo esquema de color, sin cambiar el
   ritmo (1.8s) que ya estaba bien. */
/* 28-ago noche v2 (Seba: "el de iniciado tambien esta un poco muerto,
   dale un poco mas de vida") -- se anade un leve pulso de escala al glow
   que ya existia, mismo ritmo (1.8s), para que se note mas "en accion"
   sin llegar a ser brusco. */
@keyframes ef-nivel-actual-pulso {
  0%, 100% { box-shadow: 0 0 10px rgba(248, 179, 54, 0.35); transform: scale(1); }
  50% { box-shadow: 0 0 28px rgba(248, 179, 54, 0.9); transform: scale(1.025); }
}
@media (prefers-reduced-motion: reduce) {
  .ef-nivel-paso.actual { animation: none; box-shadow: 0 0 18px rgba(248, 179, 54, 0.4); }
}

.ef-nivel-paso.siguiente { border-top-color: rgba(248, 179, 54, 0.45); color: rgba(248, 179, 54, 0.6); }

.ef-nivel-paso.oculto { border-style: dashed; color: var(--ef-crema-tenue); }
.ef-nivel-paso.oculto .ef-anillo-fondo { opacity: 0.4; }
.ef-nivel-paso.oculto .ef-nivel-paso-nombre { color: var(--ef-crema-tenue); opacity: 0.55; font-size: 16px; }
.ef-nivel-paso.oculto .ef-nivel-paso-pts { visibility: hidden; }

/* Popover del nivel al hacer click (28-ago v4) -- mismo mecanismo/estilo
   que el popover de jornada (.ef-calendario-casilla-popover, ver arriba y
   calendario-popover.js), con un anillo mas grande y el texto de
   "sorpresa" para el nivel actual y el siguiente. */
.ef-nivel-paso-detalle[open] > .ef-calendario-casilla-popover { display: block; }
.ef-nivel-popover-anillo { display: block; position: relative; margin: 0 auto 10px; width: 72px; height: 72px; }
.ef-nivel-popover-anillo svg { overflow: visible; }
.ef-nivel-popover-anillo-texto { fill: var(--ef-crema); font-size: 8px; font-weight: 700; }
.ef-nivel-popover-texto { font-size: 13.5px; color: var(--ef-crema); font-weight: 600; margin: 4px 0 0; }
.ef-nivel-popover-sorpresa { color: var(--ef-dorado); font-weight: 700; font-size: 14px; }
/* 28-ago noche v2 (Seba: "que sea alegre, viva, que transmita felicidad" +
   "quita lo de los puntos, no hace falta") -- el popover de un nivel ya
   superado deja de repetir el umbral en puntos y pasa a un mensaje corto
   y celebratorio; el anillo y el texto tambien pasan de crema a naranja
   vivo en este estado, igual que el paso pequeno del camino. */
.ef-nivel-popover-conseguido { color: var(--ef-guia-rojo); font-size: 16px; font-weight: 800; }
/* 29-ago v2 (Seba: "que sea la misma caja que la del carril, no dos
   disenos distintos") -- el popover de un nivel conseguido deja el
   anillo SVG hueco + titulo en cursiva (que solo esta ahi por heredar el
   mismo popover que usan los demas estados) y pasa a reutilizar el
   mismo icono (circulo solido + check por CSS) y tipografia de nombre
   que ya usa la cajita pequena del carril -- un unico lenguaje visual
   para "conseguido" en toda la app, ahora en rojo. */
.ef-nivel-popover--alcanzado .ef-nivel-popover-anillo { position: relative; }
.ef-nivel-popover--alcanzado .ef-nivel-popover-anillo svg { display: none; }
.ef-nivel-popover--alcanzado .ef-nivel-popover-anillo::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--ef-guia-rojo);
  box-shadow: 0 0 0 3px rgba(229, 67, 58, 0.35);
}
.ef-nivel-popover--alcanzado .ef-nivel-popover-anillo::after {
  content: '\2713';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 28px;
  font-weight: 900;
  color: var(--ef-crema);
  line-height: 1;
}
.ef-nivel-popover--alcanzado .ef-calendario-tooltip-titulo {
  font-family: inherit;
  font-style: normal;
  font-weight: 700;
  font-size: 17px;
  color: var(--ef-crema);
}
.ef-nivel-popover--alcanzado { border-color: var(--ef-guia-rojo); }
/* 28-ago v6 (Seba: "lo veo muy soso, muy aburrido") -- el popover del
   camino de niveles pasa de fondo plano a un degradado calido con mas
   glow dorado alrededor, mismo esquema de color, solo mas vivo. */
.ef-calendario-casilla-popover.ef-nivel-popover {
  background: linear-gradient(165deg, #2e2007 0%, #241a08 70%);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6), 0 0 26px rgba(248, 179, 54, 0.3);
}
/* 29-ago (Seba: "aparece en amarillo cuando pulso Aprendiz, deberia ser
   siempre el mismo color") -- este popover heredaba el borde/resplandor
   DORADO de la regla de arriba (pensada para el nivel actual) y nunca se
   habia sobreescrito a naranja para "alcanzado" -- de ahi el cambio de
   color al abrir. Misma especificidad que la regla de arriba (2 clases
   cada una), asi que tiene que ir DESPUES en el archivo para ganar. */
.ef-nivel-popover--alcanzado.ef-nivel-popover {
  background: linear-gradient(165deg, #2e0f07 0%, #241008 70%);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6), 0 0 26px rgba(229, 67, 58, 0.35);
}
.ef-nivel-popover--alcanzado .ef-calendario-tooltip-titulo { color: var(--ef-crema); }

/* Aviso de mitad de semana (28-ago, Seba) -- solo para alumnos en prueba
   gratuita, ver FichaController::ficha()/avisoBonusPrueba. */
.ef-aviso-bonus-prueba {
  margin: 14px 0 4px;
  padding: 10px 14px;
  border: 1px solid rgba(248, 179, 54, 0.4);
  border-radius: 8px;
  background: rgba(248, 179, 54, 0.08);
  font-size: 13px;
  color: var(--ef-crema);
}
.ef-aviso-bonus-prueba p { margin: 0; }
.ef-aviso-bonus-prueba.conseguido {
  border-color: var(--ef-dorado);
  background: rgba(248, 179, 54, 0.16);
  font-weight: 600;
  color: var(--ef-dorado);
}

.ef-error { color: #e05a5a; font-size: 14px; margin-bottom: 10px; }
/* 31-ago (Seba, la noche antes del lanzamiento): "Tu semana de prueba
   ha terminado" en /checkout se veia demasiado pequeno -- se separa de
   .ef-error generico (que sigue igual para el resto del sitio) para
   poder subirle el tamano solo aqui, sin afectar a ningun otro mensaje
   de error de la web. */
.ef-aviso-prueba-caducada-checkout {
  color: #e05a5a;
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.4rem, 5vw, 1.9rem);
  line-height: 1.25;
  margin-top: 22px;
  margin-bottom: 16px;
}

/* 31-ago: ahora "Killo, ya has visto..." es el <h1> de la pagina (ver
   checkout_elegir.php) en vez de un texto aparte -- esta clase ya solo
   envuelve los dos parrafos de debajo. Mas margen abajo que antes: Seba
   pidio explicitamente mas aire hasta las tarjetas de precio. */
.ef-checkout-texto-prueba-caducada {
  font-size: 17px;
  line-height: 1.5;
  margin-bottom: 56px;
}
@media (max-width: 640px) {
  /* 31-ago: en movil 56px se veia como un hueco enorme antes de las
     tarjetas de precio (Seba, con captura) -- se queda a la mitad solo
     en movil, en escritorio no se toca. */
  .ef-checkout-texto-prueba-caducada {
    margin-bottom: 28px;
  }
}
.ef-checkout-texto-rojo {
  color: #e05a5a;
}
.ef-checkout-elige-un-plan-naranja {
  color: var(--ef-naranja-claro);
  font-weight: 700;
}

.ef-nota-todo {
  background: rgba(248, 179, 54, 0.08);
  border: 1px dashed var(--ef-dorado);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--ef-crema-tenue);
  margin: 10px 0;
}

/* Avisos neutros: no son errores, así que no usan rojo (§6.3) */
.ef-aviso-neutro {
  color: var(--ef-crema-tenue);
  font-size: 14px;
  margin-bottom: 10px;
}

/* Mapa visual del tramo: vía SVG + tren + hitos */
.ef-mapa-visual {
  position: relative;
  width: 100%;
  aspect-ratio: 1536 / 1024;
  margin-top: 12px;
}
.ef-mapa-visual .ef-mapa-bg {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: var(--ef-radio);
}
.ef-mapa-visual .ef-mapa-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
/* tren.png trae bastante margen transparente alrededor de la locomotora,
   así que el ancho real necesita ser mayor que la locomotora "visible".
   El punto de anclaje (48.6%, 63.3%) es el centro de la base de las ruedas
   dentro de tren.png (medido sobre el canal alfa: bbox x 328-1144 / y hasta
   648 de 1513x1024) — así la locomotora apoya justo sobre la vía en vez de
   flotar, tanto en el origen como en cualquier punto del recorrido.
   El mismo punto se usa como transform-origin: mapa-visual.js aplica
   translate() + rotate() en ese orden, así que la rotación pivota sobre
   las ruedas (que no se mueven) y no sobre el centro de la imagen. El
   transform completo lo pone JS inline (necesita el ángulo calculado). */
.ef-mapa-visual .ef-mapa-tren-wrap {
  position: absolute;
  width: 17%;
  transform-origin: 48.6% 63.3%;
  pointer-events: none;
}
.ef-mapa-visual .ef-mapa-tren-wrap .ef-mapa-tren {
  display: block;
  width: 100%;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.35));
}

/* Humo de la chimenea: posición relativa a la locomotora dentro de tren.png */
.ef-mapa-tren-wrap .ef-humo {
  position: absolute;
  top: 30%;
  left: 65%;
  width: 9%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
  animation: ef-humo-subir 3s ease-out infinite;
}
.ef-mapa-tren-wrap .ef-humo-2 { left: 69%; animation-delay: 1s; }
.ef-mapa-tren-wrap .ef-humo-3 { left: 61%; animation-delay: 2s; }

@keyframes ef-humo-subir {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  20%  { opacity: 0.7; }
  100% { opacity: 0; transform: translate(-50%, -220%) scale(1.5); }
}

@media (prefers-reduced-motion: reduce) {
  .ef-mapa-tren-wrap .ef-humo { display: none; }
}

/* Anillo pulsante detrás de la locomotora del mapa grande — la destaca
   como "el jugador" frente a los hitos, que quedan estáticos. */
.ef-tren-glow {
  fill: none;
  stroke: var(--ef-dorado);
  stroke-width: 2.5;
  opacity: 0.7;
  animation: ef-pulso-anillo 1.8s ease-in-out infinite;
}
@keyframes ef-pulso-anillo {
  0%, 100% { r: 16; opacity: 0.7; }
  50% { r: 22; opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .ef-tren-glow { animation: none; }
}

/* CTA principal de /mapa (hand-off "mejoras visuales"): el elemento con
   más peso visual de toda la pantalla — más grande que cualquier otro
   botón y con un halo en capas dorado→naranja que "respira" (nunca
   parpadea). Modificador aparte (no se toca .ef-btn-dorado en sí) para
   no afectar el resto de pantallas que reutilizan ese mismo botón
   (checkout, reto, login, intro-bordón...). */
.ef-btn-hero {
  padding: 20px 40px;
  font-size: 19px;
  margin-top: 6px;
  animation-name: ef-pulso-hero;
  animation-duration: 2.5s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
.ef-btn-hero:hover { animation-play-state: paused; }
@keyframes ef-pulso-hero {
  0%, 100% {
    box-shadow:
      0 0 22px 4px rgba(248, 179, 54, 0.45),
      0 0 46px 10px rgba(225, 88, 31, 0.3),
      0 10px 30px rgba(248, 179, 54, 0.4),
      0 0 0 2px rgba(248, 179, 54, 0.2);
  }
  50% {
    box-shadow:
      0 0 34px 8px rgba(248, 179, 54, 0.7),
      0 0 68px 18px rgba(225, 88, 31, 0.45),
      0 10px 38px rgba(248, 179, 54, 0.6),
      0 0 0 6px rgba(248, 179, 54, 0.12);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ef-btn-hero { animation: none; }
}
@media (max-width: 600px) {
  .ef-btn-hero {
    padding: 16px 20px;
    font-size: clamp(1rem, 4vw, 1.4rem);
    line-height: 1.3;
  }
}

/* Marco de azulejos del mapa (paisaje.png trae el marco pintado) — glow
   externo sutil, como si el propio mapa emitiera luz cálida desde dentro
   del marco, sin llegar a competir con el CTA principal. */
.ef-mapa-visual {
  border-radius: var(--ef-radio);
  box-shadow:
    0 0 40px 4px rgba(248, 179, 54, 0.18),
    0 0 80px 12px rgba(225, 88, 31, 0.14);
}

/* Tarjeta "Tu camino": fondo con degradado sutil que conecta con los
   tonos cálidos del mapa de abajo, en vez de una caja plana suelta. */
.ef-card-camino {
  background:
    radial-gradient(ellipse 70% 60% at 100% 100%, rgba(248, 179, 54, 0.14) 0%, transparent 70%),
    var(--ef-fondo-2);
}

/* Barra lineal de progreso del tramo (mapa) — ticks en 0/25/50/75/100% que
   pasan de crema a dorado al ser superados, y una locomotora en miniatura
   (icono propio, no emoji) en el borde del relleno. */
/* Título de la sección de mapa: más peso que un h2 normal, con un
   kicker "Mapa" en mayúsculas para dar jerarquía sin perder el
   tratamiento itálico dorado de marca. */
.ef-mapa-titulo {
  font-size: clamp(1.8rem, 4.6vw, 2.3rem);
  margin: 0 0 4px;
}
.ef-mapa-titulo-kicker {
  font-family: 'Montserrat', sans-serif;
  font-style: normal;
  font-weight: 800;
  font-size: 0.5em;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ef-crema-tenue);
  vertical-align: middle;
}

.ef-reto-mes-opciones {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 10px;
}

/* Panel del reto del mes: bloque independiente centrado, del ancho de su
   contenido — no debe estirarse hasta el borde de la página como el
   resto de .ef-card. */
.ef-reto-mes-panel {
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
}

.ef-progreso-lineal { margin-top: 18px; }
/* 4 tramos independientes en fila: el tramo activo (donde va el tren) se
   ve más grueso que los otros tres, en vez de una única barra continua. */
.ef-progreso-lineal-track {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 32px 4px 14px;
}
.ef-progreso-lineal-segmento {
  position: relative;
  flex: 1 1 0;
  height: 6px;
  border-radius: 999px;
  background: var(--ef-tramo-pendiente);
  transition: height 0.3s ease;
}
.ef-progreso-lineal-segmento-relleno {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0%;
  border-radius: 999px;
  background: var(--ef-tramo-completado);
  transition: width 0.6s ease;
}
.ef-progreso-lineal-segmento.activo {
  height: 16px;
  box-shadow: 0 0 10px rgba(246, 169, 61, 0.35);
}
/* Marcadores de la barra (handoff 16-ago P5): líneas verticales en vez de
   puntos — dos gruesas/largas en inicio y fin, tres cortas en los hitos
   intermedios (25/50/75%). Blancas mientras no se alcanzan, doradas al
   superarse; la lógica de estado no cambia, solo el marcador visual. */
.ef-progreso-lineal-marcador {
  flex: 0 0 auto;
  width: 2px;
  height: 12px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.55);
  transition: background-color 0.3s ease;
}
.ef-progreso-lineal-marcador-extremo {
  width: 3px;
  height: 20px;
}
.ef-progreso-lineal-marcador.superado {
  background: var(--ef-tramo-completado);
  box-shadow: 0 0 6px rgba(246, 169, 61, 0.7);
}
.ef-progreso-lineal-tren {
  position: absolute;
  bottom: 100%;
  margin-bottom: -9px;
  left: 0;
  color: var(--ef-dorado);
  transform: translateX(-50%);
  pointer-events: none;
  transition: left 0.6s ease;
  /* Glow bajo la locomotora (hand-off "mejoras visuales"): marca
     visualmente hasta dónde llega el progreso dentro del tramo activo. */
  filter: drop-shadow(0 0 5px rgba(248, 179, 54, 0.8)) drop-shadow(0 0 10px rgba(225, 88, 31, 0.5));
  animation: ef-tren-lineal-marcha 1.6s ease-in-out infinite;
}
.ef-progreso-lineal-tren svg { display: block; }
/* Rediseño 17-ago: pequeño balanceo vertical + humo con color de acento
   naranja — mismo lenguaje visual que el humo de la locomotora grande del
   mapa (.ef-humo), a escala reducida para este icono de línea. */
@keyframes ef-tren-lineal-marcha {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(-1.5px); }
}
.ef-tren-lineal-humo {
  stroke: var(--ef-naranja-claro);
  opacity: 0;
  animation: ef-tren-lineal-humo-subir 2.4s ease-out infinite;
}
.ef-tren-lineal-humo-2 { animation-delay: 1.1s; }
@keyframes ef-tren-lineal-humo-subir {
  0% { opacity: 0; transform: translateY(2px) scale(0.7); }
  25% { opacity: 0.85; }
  100% { opacity: 0; transform: translateY(-4px) scale(1.3); }
}
@media (prefers-reduced-motion: reduce) {
  .ef-progreso-lineal-tren { animation: none; }
  .ef-tren-lineal-humo { animation: none; opacity: 0.6; }
}
.ef-progreso-lineal-texto {
  font-size: 13px;
  font-weight: 700;
  color: var(--ef-dorado);
  margin: 0 0 16px;
}

/* Barra de vídeos del día — única barra de la pantalla del reproductor:
   un .ef-dia-segmento por clip (contenedor que JS rellena, ver
   reproductor.js). Mismo tamaño/presencia que tenía la barra de bloques
   que sustituye. */
.ef-barra-dia-fondo {
  background: rgba(245, 239, 230, 0.1);
  border-radius: 999px;
  overflow: hidden;
  display: flex;
  gap: 3px;
  padding: 3px;
  margin-bottom: 20px;
}
.ef-dia-segmento {
  flex: 1;
  height: 16px;
  background: rgba(245, 239, 230, 0.1);
  border-radius: 999px;
  overflow: hidden;
}
.ef-dia-segmento-relleno {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--ef-naranja), var(--ef-dorado));
  border-radius: 999px;
  transition: width 0.15s linear;
}

/* Reproductor: fondo casi negro para que el vídeo sea el protagonista,
   con el mismo glow radial naranja tenue que el resto de la marca. */
.ef-reproductor {
  background:
    radial-gradient(140% 100% at 50% 0%, rgba(225, 88, 31, 0.16) 0%, rgba(225, 88, 31, 0) 55%),
    var(--ef-fondo-2);
  border: 1px solid rgba(245, 239, 230, 0.08);
  border-radius: var(--ef-radio);
  padding: 20px;
  color: var(--ef-crema);
}
.ef-reproductor-nombre {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 4.6vw, 36px);
  color: var(--ef-dorado);
  line-height: 1.15;
  margin: 0 0 14px;
}
/* Separador dorado bajo el título de /dia/{n} (índice + reproductor).
   #F6A93D específico (no var(--ef-dorado), que es un dorado distinto,
   #F8B336) — mismo tono que el color de campo ACORDES. */
.ef-reproductor-nombre::after {
  content: '';
  display: block;
  width: 64px;
  height: 2px;
  background: #F6A93D;
  margin-top: 12px;
}
/* Eyebrow de categoría/subcategoría (p.ej. "ACORDES — A y Dm") encima de un
   encabezado grande — mismo color por campo que ya usa CampoVisualService
   en "Hoy nos toca" (.ef-indice-campo-titulo). Compartida entre el
   reproductor de días y la Biblioteca. Solo el prefijo va en mayúsculas
   (ver .ef-campo-eyebrow-prefijo) — el resto conserva su capitalización
   porque puede llevar notación con significado (p.ej. "Dm" vs "D"). */
.ef-campo-eyebrow {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.3;
  color: var(--campo-color, var(--ef-crema-tenue));
  margin: 14px 0 2px;
}
.ef-campo-eyebrow-prefijo { text-transform: uppercase; }
.ef-clip-titulo {
  font-family: 'Montserrat', sans-serif;
  font-size: 22px;
  font-weight: 800;
  line-height: 1.35;
  margin: 4px 0 12px;
  color: var(--ef-crema);
}
.ef-video-envoltorio {
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  aspect-ratio: 16/9;
  margin-bottom: 14px;
  position: relative;
}
.ef-video-envoltorio iframe, .ef-video-envoltorio video {
  width: 100%; height: 100%; border: 0; display: block;
}
/* 27-ago: capa de "toca para pausar" -- empieza inactiva (pointer-events
   none) para no bloquear el primer toque que arranca el video; en cuanto
   reproductor.js recibe el evento 'play' de Bunny se activa, y se
   desactiva otra vez con 'pause' -- ver conectarPlayerBunny(). */
.ef-video-tap-pausa {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
/* 26-ago (Seba: mismo fallo que el aviso de prueba v1 — vivía dentro de
   .ef-video-envoltorio, recuadro de altura fija 16:9 con overflow:hidden;
   en el segundo día el contenido no cabía y el botón "Saltar pausa"
   quedaba fuera, bloqueando el avance). Ahora es un overlay real a
   pantalla completa, independiente del tamaño del vídeo. */
.ef-pausa-overlay {
  position: fixed; inset: 0;
  z-index: 998;
  /* 28-ago (Seba: mas atractivo, colores mas corporativos -- sin tocar el
     circulo que respira, el numero de segundos ni el audio). 28-ago v2:
     Seba dijo que la primera version (con naranja) le daba ansiedad --
     se quita el naranja del todo, se deja solo una veladura de dorado muy
     suave y baja opacidad, para que sea calmado, no urgente. */
  background:
    radial-gradient(85% 60% at 50% 100%, rgba(248, 179, 54, 0.09) 0%, rgba(248, 179, 54, 0) 65%),
    rgba(22, 19, 16, 0.97);
  color: var(--ef-crema);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 22px;
  padding: 24px;
  overflow-y: auto;
}
.ef-pausa-overlay.activa { display: flex; }

/* Círculo de "respira": expansión/contracción lenta, estilo Apple Fitness+ / Headspace */
.ef-respira-circulo {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 28-ago: degradado suave de dorado -- la animacion de "respirar"
     (escala/opacidad) no se toca, sigue exactamente igual. 28-ago v2:
     Seba dijo que la primera version (dorado+naranja, mucho glow) le daba
     ansiedad -- se deja solo dorado, mas suave, con mucho menos resplandor,
     para que se sienta calmado en vez de urgente. */
  background: radial-gradient(circle, rgba(248, 179, 54, 0.22) 0%, rgba(248, 179, 54, 0.05) 60%, transparent 100%);
  border: 2px solid rgba(248, 179, 54, 0.55);
  box-shadow: 0 0 18px 2px rgba(248, 179, 54, 0.12);
  animation: ef-respirar 3s ease-in-out infinite;
}
@keyframes ef-respirar {
  0%, 100% { transform: scale(0.85); opacity: 0.8; }
  50% { transform: scale(1.15); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .ef-respira-circulo { animation: none; }
}

.ef-pausa-overlay .ef-pausa-numero { font-family: 'Montserrat', sans-serif; font-size: 56px; font-weight: 900; color: var(--ef-dorado); }
.ef-pausa-overlay .ef-pausa-texto { font-size: 19px; font-weight: 300; letter-spacing: 0.02em; opacity: 0.95; color: var(--ef-dorado); }
/* Consejo bajo "respira" (hand-off 21-ago): el botón "Saltar pausa" se
   queda, pero con un motivo breve al lado en vez de dejarlo mudo. */
.ef-pausa-overlay .ef-pausa-consejo { font-size: 14px; font-weight: 300; opacity: 0.65; max-width: 320px; text-align: center; margin: 6px 0 2px; }

/* 27-ago (Seba: en escritorio se veía "supersuper" apretado, mucha
   información junta, sin armonía) -- se limita el ancho de lectura (igual
   que un párrafo de libro, no todo el ancho de la pantalla) y se da un
   ritmo vertical uniforme a cada bloque (mensaje, aviso de prueba, gracia,
   tope, recompensas, botones, presentación), en vez de que cada uno traiga
   su propio margen suelto. El contenido de los botones y de la tarjeta
   "Grábate y preséntate" no cambia, solo el aire alrededor. */
.ef-cierre-dia {
  text-align: center;
  padding: 24px 0 10px;
  max-width: 480px;
  margin: 0 auto;
}
.ef-cierre-dia h2 { font-size: 26px; margin: 0 0 16px; }
.ef-cierre-dia > p { margin: 0 0 18px; line-height: 1.55; }
.ef-cierre-dia > .ef-card-destacada { margin: 22px 0; }
.ef-cierre-botones { display: flex; gap: 10px; justify-content: center; margin-top: 26px; flex-wrap: wrap; }
/* 26-ago v2 (Seba): "Recuerda" destacado en dorado dentro de su frase. */
.ef-cierre-recuerda { color: var(--ef-dorado); font-weight: 700; }

/* 26-ago v2 (rehecho — Seba: la v1 vivía dentro de .ef-video-envoltorio, un
   recuadro de altura fija 16:9, y en móvil el texto no cabía: el botón
   quedaba fuera de la pantalla visible y la persona se quedaba bloqueada
   sin poder avanzar. Ahora es un overlay real a pantalla completa,
   independiente del tamaño del vídeo, con scroll de seguridad. */
.ef-nudge-prueba-overlay {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: rgba(22, 19, 16, 0.97);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 24px;
  overflow-y: auto;
  text-align: center;
}
.ef-nudge-prueba-overlay.activa { display: flex; }

/* 28-ago noche v2 (Seba: "pop-up de celebracion al llegar a Iniciado, con
   cohete, alegre, un solo boton de compartir") -- mismo mecanismo que
   .ef-nudge-prueba-overlay (overlay fijo a pantalla completa, .activa lo
   muestra), pero SIN el boton "mas tarde": se cierra tocando fuera de la
   tarjeta (ver script en ficha.php) o pulsando "Compartir en la
   comunidad". Solo se pinta la primera vez que el alumno cruza a
   Iniciado -- ver FichaController/GamificacionService::evaluarBonusNivelIniciado. */
.ef-nivel-iniciado-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background:
    radial-gradient(70% 55% at 50% 15%, rgba(248, 179, 54, 0.28) 0%, rgba(248, 179, 54, 0) 60%),
    radial-gradient(60% 45% at 50% 100%, rgba(225, 88, 31, 0.14) 0%, rgba(225, 88, 31, 0) 65%),
    rgba(22, 19, 16, 0.97);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 24px;
  overflow-y: auto;
  text-align: center;
}
.ef-nivel-iniciado-overlay.activa { display: flex; }
.ef-nivel-iniciado-card {
  max-width: 360px;
  padding: 32px 24px 26px;
  border-color: var(--ef-dorado);
  box-shadow: 0 0 44px rgba(248, 179, 54, 0.28);
}
.ef-nivel-iniciado-titulo { margin: 0 0 6px; font-size: 27px; color: var(--ef-dorado); }
.ef-nivel-iniciado-texto { font-size: 15px; color: var(--ef-crema); margin: 0 0 14px; line-height: 1.5; }
.ef-nivel-iniciado-regalo { font-size: 14.5px; color: var(--ef-naranja-claro); font-weight: 600; margin: 0 0 20px; line-height: 1.5; }
/* 29-ago (Seba): que el regalo de dias resalte de verdad -- mas grande, en dorado (distinto del naranja del resto de la frase), con un leve resplandor. */
.ef-nivel-iniciado-regalo-destacado { display: inline-block; margin: 6px 0; font-size: 21px; font-weight: 900; color: var(--ef-dorado); text-shadow: 0 0 16px rgba(248, 179, 54, 0.45); }
.ef-nivel-iniciado-card form { margin: 0; }
.ef-nivel-iniciado-card .ef-btn { width: 100%; }
.ef-nudge-prueba-card {
  max-width: 340px;
  padding: 24px 22px;
}
.ef-nudge-prueba-kicker {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ef-dorado);
  margin: 0 0 8px;
}
/* 26-ago v3 (Seba): quería el titular también con un poco de color, no
   solo el kicker — se deja en un naranja distinto del dorado del kicker,
   para conservar la jerarquía (etiqueta vs. dato). */
.ef-nudge-prueba-card h3 { font-size: 20px; margin: 0 0 8px; color: var(--ef-naranja-claro); }
.ef-nudge-prueba-card p { color: var(--ef-crema-tenue); line-height: 1.5; margin: 0; }
/* 27-ago v4 (Seba, tras varias vueltas): fuera el titulo "se inaugura la
   web nueva" y su emoji -- va directo a la frase de perdida + la lista.
   Fuera tambien la X roja (leia como error/algo roto) -- guion simple en
   dorado delante de cada linea, igual que el resto de la paleta. Se quita
   "gratis" al final de las dos primeras lineas (redundante, ya se cuenta
   como perdida). Y el bug real de las lineas "bailando": .ef-bono-lanzamiento
   vive dentro de .ef-nudge-prueba-overlay, que tiene text-align:center --
   al envolver una linea larga, el segundo renglon quedaba centrado en vez
   de alineado bajo el primero. text-align:left explicito aqui lo arregla
   en los dos sitios (aviso y checkout), venga de donde venga el heredado.
   Es un <div>, no un <p>, para no chocar con la regla .ef-nudge-prueba-card
   p de más arriba -- así no hacen falta !important como en la v1. */
.ef-bono-lanzamiento {
  margin: 14px 0;
  padding: 14px 16px;
  border: 1px dashed var(--ef-dorado);
  border-radius: var(--ef-radio);
  background: rgba(248, 179, 54, 0.08);
  text-align: left;
}
.ef-bono-lanzamiento-intro {
  font-size: 13.5px;
  color: var(--ef-crema);
  line-height: 1.45;
  margin: 0 0 10px;
}
.ef-bono-lanzamiento-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  text-align: left;
}
.ef-bono-lanzamiento-lista li {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ef-crema);
  line-height: 1.4;
  padding-left: 18px;
  position: relative;
  text-align: left;
}
.ef-bono-lanzamiento-lista li::before {
  content: "–";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--ef-dorado);
  font-weight: 700;
}
/* 31-ago (Seba): en checkout el bono se veia con letra mucho mas
   pequena que el titulo Killo... y el parrafo de debajo -- se sube
   solo aqui (no en reproductor.php, que usa la misma clase base
   .ef-bono-lanzamiento y se queda como estaba) al mismo tamano que ese
   parrafo (17px), igual en movil que en escritorio. */
.ef-checkout-bono-lanzamiento .ef-bono-lanzamiento-intro,
.ef-checkout-bono-lanzamiento .ef-bono-lanzamiento-lista li {
  font-size: 17px;
}
.ef-nudge-prueba-overlay .ef-btn:disabled { opacity: 0.5; cursor: default; animation: none; }
.ef-nudge-prueba-botones {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Aviso de conversión al cerrar cada día, graduado por día de prueba
   (1-4 discreto, 5-6 urgente, 7 el más directo) — ver construirAvisoPrueba()
   en reproductor.js. Mismo kicker dorado que el aviso de arriba, para que
   se lea como el mismo mensaje en todos los sitios donde aparece. */
.ef-aviso-prueba { text-align: center; margin: 16px 0; }
.ef-aviso-prueba p { margin: 0; }
.ef-aviso-prueba-kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ef-dorado);
  margin: 0 0 6px;
}
/* 27-ago v4 (Seba: "esto es lo que tiene que destacar absolutamente y no
   destaca" -- el aviso de prueba gratuita/hazte-alumno se perdía entre las
   demás tarjetas de puntitos del cierre de día, con el mismo peso visual
   que un aviso de recompensa o el prompt de subir vídeo). Deja de ser un
   borde de puntos discreto y pasa a ser lo más llamativo de la pantalla:
   fondo con degradado cálido sólido, borde sólido con resplandor, texto y
   botón más grandes. Las 3 variantes comparten esta base y solo suben de
   intensidad según se acerca el día 7. */
.ef-aviso-prueba.ef-card-destacada {
  border-style: solid;
  border-width: 2px;
  border-color: rgba(248, 179, 54, 0.55);
  background: linear-gradient(160deg, rgba(248, 179, 54, 0.18) 0%, var(--ef-fondo-2) 65%);
  box-shadow: 0 0 32px 4px rgba(248, 179, 54, 0.28);
  padding: 22px 20px;
}
.ef-aviso-prueba-sutil {
  text-align: center;
  color: var(--ef-crema);
  font-size: 16px;
  font-weight: 700;
}
.ef-aviso-prueba-sutil p { margin: 0 0 14px; }
.ef-aviso-prueba-sutil .ef-btn { font-size: 16px; padding: 13px 26px; }
.ef-aviso-prueba-urgente.ef-card-destacada {
  border-color: rgba(240, 134, 31, 0.7);
  background: linear-gradient(160deg, rgba(240, 134, 31, 0.22) 0%, var(--ef-fondo-2) 65%);
  box-shadow: 0 0 36px 5px rgba(240, 134, 31, 0.32);
}
.ef-aviso-prueba-ultimo.ef-card-destacada {
  border-color: var(--ef-naranja-claro);
  background: linear-gradient(160deg, rgba(225, 88, 31, 0.26) 0%, var(--ef-fondo-2) 65%);
  box-shadow: 0 0 40px 6px rgba(225, 88, 31, 0.4);
}
.ef-aviso-prueba-ultimo p strong { color: var(--ef-naranja-claro); }

/* Pantalla "Antes de empezar" (§0.4/§0.8) */
.ef-intro-bordon h1 { margin-bottom: 24px; }
/* Sangría de primera línea al estilo libro clásico + primera letra en dorado
   de marca — hand-off Seba 26-ago (v2): el calderón suelto en el margen no
   convencía ("descuadrado"); esto lo sustituye por una sangría de verdad
   (~6-7 espacios) más la inicial resaltada, pegada a la propia palabra. */
.ef-intro-bordon p {
  margin: 0 0 2em;
  line-height: 1.7;
  text-indent: 2.2em;
}
.ef-intro-bordon p::first-letter {
  color: var(--ef-dorado);
  font-weight: 700;
  font-size: 1.3em;
}
.ef-intro-bordon ul { margin: -8px 0 1.5em; padding-left: 40px; line-height: 1.7; }
.ef-intro-bordon .ef-btn { margin-top: 18px; }

/* Índice del día ("Hoy nos toca", §9) */
.ef-indice-titulo { font-size: 22px; font-weight: 500; }
.ef-bienvenida-bordon {
  margin-bottom: 40px; /* separación extra antes de "Hoy nos toca" */
}
.ef-bienvenida-bordon p {
  margin-bottom: 28px;
  line-height: 1.7;
}
.ef-indice-lista { padding-left: 22px; line-height: 1.9; }

/* "Hoy nos toca": vídeos del día agrupados por campo, cada uno con su
   color propio (kicker + borde izquierdo) — nunca todo en una sola línea. */
.ef-indice-campos { display: flex; flex-direction: column; gap: 16px; margin: 18px 0; }
.ef-indice-campo {
  border-left: 3px solid var(--campo-color, var(--ef-crema-tenue));
  padding-left: 14px;
}
.ef-indice-campo-titulo {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--campo-color, var(--ef-crema-tenue));
  margin-bottom: 6px;
}
/* Mayúsculas solo en el prefijo (ACORDES/TÉCNICA/PALO...) — el detalle tras
   " — " se imprime tal cual en el HTML (fuera de este span) para no perder
   notación con significado como "Dm" (menor) vs "D" (mayor). */
.ef-indice-campo-prefijo { text-transform: uppercase; }
.ef-indice-campo-lista { list-style: disc; padding-left: 20px; margin: 0; line-height: 1.8; }

/* Recurso descargable del día: tarjeta bajo el reproductor de vídeo +
   modal propio para "Ver PDF" en escritorio. En móvil (<768px) el PDF se
   abre directo en pestaña nueva — más fiable que un iframe en un modal
   dentro de Safari iOS. Ver recurso-dia.js. */
.ef-recurso-dia {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  margin: 18px 0;
  padding: 14px 18px;
  border: 1px solid rgba(248, 179, 54, 0.25);
  border-radius: var(--ef-radio);
  background: rgba(248, 179, 54, 0.06);
}
.ef-recurso-dia-info { display: flex; align-items: center; gap: 12px; }
.ef-recurso-dia-icono { color: var(--ef-dorado); flex-shrink: 0; }
.ef-recurso-dia-kicker {
  display: block;
  font-family: 'Montserrat', sans-serif;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ef-crema-tenue);
}
.ef-recurso-dia-nombre { display: block; margin-top: 2px; }
.ef-recurso-dia-acciones { display: flex; gap: 10px; flex-wrap: wrap; }

/* Modal nativo <dialog> (Escape + capa superior sin reflow ya vienen
   incluidos gratis; el cierre por click fuera se hace a mano en JS). */
.ef-recurso-modal {
  border: 1px solid rgba(248, 179, 54, 0.3);
  border-radius: var(--ef-radio);
  padding: 0;
  background: var(--ef-fondo-2);
  color: var(--ef-crema);
  width: min(820px, 92vw);
  height: min(85vh, 900px);
  box-shadow: var(--ef-sombra);
}
.ef-recurso-modal::backdrop { background: rgba(22, 19, 16, 0.78); }
.ef-recurso-modal-panel { display: flex; flex-direction: column; width: 100%; height: 100%; }
.ef-recurso-modal-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(245, 239, 230, 0.1);
  flex-shrink: 0;
}
.ef-recurso-modal-cerrar {
  background: none;
  border: 1px solid var(--ef-dorado);
  color: var(--ef-dorado);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}
.ef-recurso-modal-cerrar:hover { background: var(--ef-dorado); color: var(--ef-fondo); }
/* Scroll interno propio del PDF (nunca de la página: el <dialog> vive en
   la capa superior y no participa del flujo normal del documento). */
.ef-recurso-modal iframe { flex: 1; width: 100%; border: 0; display: block; background: #fff; }

/* Modal de vídeo (§9.3 Comunidad / ficha "Mis vídeos", hand-off 21-ago):
   el primer intento (20-ago) agrandaba el <dialog> pero mantenía el vídeo
   con su proporción 16:9 fija — como el ancho ya llegaba casi a pantalla
   completa, el alto (calculado a partir del ancho) apenas crecía. Casi no
   se notaba. Aquí se quita esa proporción fija SOLO para este modal: el
   vídeo pasa a rellenar TODO el alto disponible del modal (el reproductor
   de Bunny ya se encarga de no deformar la imagen si sobra espacio arriba
   o abajo).
   A propósito esto NO usa el botón de pantalla completa nativo del
   reproductor de Bunny (confirmado con la documentación de Bunny: no se
   puede quitar el aviso del sistema operativo que aparece con la pantalla
   completa nativa, y ese aviso es justo lo que tapaba los controles e
   impedía pausar/retroceder/salir). Al ser un agrandado nuestro (CSS, sin
   pantalla completa nativa del navegador), ese aviso nunca aparece y los
   controles del reproductor están siempre accesibles. */
#ef-video-modal {
  width: min(1000px, 96vw);
  height: min(92vh, 720px);
}
#ef-video-modal .ef-video-envoltorio {
  aspect-ratio: auto;
  flex: 1;
  min-height: 0;
}

@media (max-width: 700px) {
  #ef-video-modal {
    width: 100vw;
    height: 100vh;
    max-width: 100vw;
    max-height: 100vh;
    border-radius: 0;
  }
  #ef-video-modal .ef-video-envoltorio {
    margin: 0 !important;
    border-radius: 0;
  }
  #ef-video-modal .ef-recurso-modal-cabecera {
    padding: 10px 14px;
  }
}

/* Calendario de la ficha (§P1 hand-off 27-jul): cuadrícula "camino
   recorrido" del Bordón (clicable en lo completado, repaso) + vista
   semanal/mensual sobre progreso_dias. Nunca rojo — gris = pendiente,
   dorado/ocre = completado. Pieza de más impacto visual de la ficha. */
.ef-calendario-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}
/* 27-ago (Seba): "Tu camino, jornada a jornada" es más largo que el resto
   de títulos de sección -- con el h2 general más grande de arriba se
   partía en dos líneas en móvil. Clamp propio, más agresivo en vw y con
   un mínimo menor, para que quepa siempre en una sola línea (más pequeño
   que el resto si hace falta, nunca partido). */
.ef-calendario-cabecera h2 { margin: 0; font-size: clamp(1.25rem, 4.6vw, 1.7rem); white-space: nowrap; }
.ef-calendario-tabs { display: flex; gap: 6px; }
.ef-calendario-tab {
  background: transparent;
  border: 1px solid rgba(245, 239, 230, 0.25);
  color: var(--ef-crema-tenue);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.ef-calendario-tab:hover { border-color: var(--ef-dorado); color: var(--ef-crema); }
.ef-calendario-tab.activa {
  background: linear-gradient(90deg, var(--ef-naranja), var(--ef-dorado));
  border-color: transparent;
  color: #241a08;
}
.ef-calendario-nota { font-size: 14px; color: var(--ef-crema-tenue); margin: 6px 0 14px; }
/* 27-ago (Seba: quien llega aquí desde "Por hoy, ya está bien" -> "Repasar
   lo que ya has visto" no tenía forma de saber que ESTO es donde se repasa
   -- la frase se perdía en texto pequeño y apagado). Se resalta en dorado
   la parte que de verdad importa ("toca un día para repasarlo"), sin tocar
   el resto de la nota. */
.ef-calendario-nota-destacada { color: var(--ef-dorado); font-weight: 700; }

.ef-calendario-dias {
  display: grid;
  /* Handoff 16-ago P2: cuadrícula 8×8 real de los 64 días (sustituye el
     encaje de ancho con Vista mensual de la ronda 2 — ese acoplamiento de
     tamaños queda descartado a propósito). Cada casilla es 1:1 vía
     aspect-ratio propio, así que 8 columnas ya bastan para un cuadrado sin
     fijar filas/aspect-ratio en el contenedor. */
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
  margin-top: 18px;
}
.ef-calendario-casilla {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  background: rgba(245, 239, 230, 0.1);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  text-decoration: none;
  font-size: 11px;
  color: var(--ef-crema-tenue);
}
@media (max-width: 600px) {
  .ef-calendario-dias { grid-template-columns: repeat(4, 1fr); gap: 8px; }
  .ef-calendario-casilla { font-size: 13px; }
}
.ef-calendario-casilla-num { line-height: 1; }
.ef-calendario-casilla.completado {
  background: linear-gradient(180deg, #ffdb96 0%, var(--ef-dorado) 55%, #d99a2b 100%);
  box-shadow: 0 0 6px rgba(248, 179, 54, 0.4);
  cursor: pointer;
  color: #241a08;
  font-weight: 700;
}
/* 28-ago (Seba, móvil): la jornada completada ahora es un <details> propio
   (ver ficha.php) en vez de un enlace directo -- el glow al pasar el ratón
   se mantiene en escritorio y, además, se repite al abrir en cualquier
   dispositivo (: hover Y [open] cubren ratón y toque por igual). */
.ef-calendario-casilla-detalle { position: relative; }
.ef-calendario-casilla-detalle > summary { list-style: none; cursor: pointer; }
.ef-calendario-casilla-detalle > summary::-webkit-details-marker { display: none; }
.ef-calendario-casilla-detalle > summary:hover,
.ef-calendario-casilla-detalle[open] > summary {
  transform: scale(1.18);
  box-shadow: 0 0 12px rgba(248, 179, 54, 0.75);
  z-index: 6;
  position: relative;
}
.ef-calendario-casilla-popover {
  display: none;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 999;
  background: #241a08;
  border: 1px solid var(--ef-dorado);
  border-radius: 8px;
  padding: 14px 16px;
  min-width: 200px;
  max-width: min(280px, calc(100vw - 32px));
  /* 28-ago v7 (Seba, movil real: el recuadro se veia cortado por arriba,
     solo se leia la ultima linea) -- 100vh en movil cuenta el alto total
     de la pantalla, no el hueco que de verdad queda libre con la barra de
     direcciones visible, asi que el recuadro podia salir mas alto de lo
     que en realidad cabia y quedar centrado fuera de la parte visible.
     100dvh (alto "dinamico") sí sigue el hueco real; el navegador que no
     lo entienda simplemente ignora esa segunda linea y se queda con la
     primera (calc con vh), asi que es un arreglo seguro en cualquier caso. */
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  text-align: center;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
}
/* Fondo oscurecido, solo visual, mientras hay un popover de jornada
   abierto (ver calendario-popover.js) -- pointer-events:none para no
   bloquear el clic directo a otra casilla: pasar de una jornada abierta
   a otra debe funcionar con un solo toque, sin cerrar primero. */
.ef-popover-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 6, 0.6);
  z-index: 998;
  pointer-events: none;
}
.ef-popover-backdrop.visible { display: block; }
/* Clips agrupados por campo dentro del popover de la jornada (28-ago
   ronda 3, Seba): mismas clases .ef-indice-campo* que "Hoy nos toca", con
   el mismo color por categoria via CampoVisualService::color() -- para
   que sea EXACTAMENTE el mismo codigo de colores en los dos sitios.
   Aqui solo se compactan tipografia/gap para caber en un popover
   pequeño, y se fuerza texto a la izquierda (el popover por defecto
   centra el contenido). */
.ef-popover-campos { text-align: left; margin: 10px 0; gap: 10px; }
.ef-popover-campos .ef-indice-campo-titulo { font-size: 11px; margin-bottom: 3px; }
.ef-popover-campos .ef-indice-campo-lista { font-size: 12px; line-height: 1.5; padding-left: 16px; }
/* "+ Reto del mes" dentro del popover -- sustituye a la insignia "RM"
   flotante sobre la casilla (28-ago ronda 3, Seba: quedaba demasiado
   grande, sobre todo en Vista mensual). Mismo dorado, como texto en
   linea en vez de una insignia superpuesta sobre la cuadricula. */
.ef-popover-reto {
  display: inline-block;
  background: var(--ef-dorado);
  color: #1a1208;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 2px 7px;
  border-radius: 5px;
  vertical-align: middle;
  margin-left: 4px;
}
.ef-calendario-casilla-detalle[open] > .ef-calendario-casilla-popover { display: block; }
.ef-calendario-casilla-popover.ef-popover-flotante,
.ef-mes-casilla-lista.ef-popover-flotante {
  top: 0;
  left: 0;
  transform: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.ef-calendario-casilla-popover .ef-calendario-tooltip-clips { text-align: left; }

/* Tooltip propio del calendario (hand-off 28-jul, punto 10) — compartido
   entre Camino recorrido y Vista mensual, posicionado por JS junto a la
   casilla con la que se interactúa (ver calendario-tooltip.js). */
.ef-calendario-tooltip {
  position: fixed;
  z-index: 50;
  background: var(--ef-fondo-2);
  border: 1px solid var(--ef-dorado);
  border-radius: 8px;
  padding: 10px 12px;
  max-width: 240px;
  box-shadow: var(--ef-sombra);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.ef-calendario-tooltip.visible { opacity: 1; }
.ef-calendario-tooltip-titulo {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  color: var(--ef-dorado);
  font-size: 18px;
  line-height: 1.15;
}
.ef-calendario-tooltip-fecha { font-size: 12px; color: var(--ef-crema-tenue); margin: 2px 0 6px; }
.ef-calendario-tooltip-clips { margin: 0; padding-left: 16px; font-size: 12px; color: var(--ef-crema); }
.ef-calendario-tooltip-clips li { margin: 2px 0; }
/* Vista mensual, jornadas apiladas bajo "Has practicado:" (27-ago v3,
   Seba): una por línea en vez de un único renglón horizontal, en un tono
   más claro para que llamen más la atención que la etiqueta. */
.ef-calendario-tooltip-jornadas { margin-top: -2px; margin-bottom: 4px; }
.ef-calendario-tooltip-jornada { font-size: 13px; font-weight: 600; color: var(--ef-crema); line-height: 1.5; }

/* Vista mensual — calendario normal L-M-X-J-V-S-D sobre progreso_dias. */
.ef-calendario-mes-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-bottom: 12px;
  font-size: 15px;
}
.ef-calendario-mes-nav .ef-btn { padding: 4px 12px; font-size: 15px; line-height: 1; }
.ef-btn-deshabilitado { opacity: 0.25; pointer-events: none; }
.ef-mes-semana-cabecera,
.ef-mes-semana {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.ef-mes-semana-cabecera {
  margin-bottom: 6px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ef-crema-tenue);
  text-transform: uppercase;
}
.ef-mes-semana { margin-bottom: 6px; }
.ef-mes-casilla {
  aspect-ratio: 1;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: var(--ef-crema-tenue);
  background: rgba(245, 239, 230, 0.06);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  text-decoration: none;
}
.ef-mes-casilla.fuera-mes { opacity: 0.25; }
.ef-mes-casilla.practicado {
  background: linear-gradient(180deg, #ffdb96 0%, var(--ef-dorado) 55%, #d99a2b 100%);
  color: #241a08;
  font-weight: 700;
  box-shadow: 0 0 6px rgba(248, 179, 54, 0.4);
  cursor: pointer;
}
a.ef-mes-casilla.practicado:hover,
.ef-mes-casilla-detalle > summary.ef-mes-casilla.practicado:hover,
.ef-mes-casilla-detalle[open] > summary.ef-mes-casilla.practicado {
  transform: scale(1.1);
  box-shadow: 0 0 12px rgba(248, 179, 54, 0.75);
  z-index: 6;
  position: relative;
}
/* 27-ago: fechas con mas de una jornada practicada (cabe con el tope
   diario) -- <details> nativo en vez de un enlace directo a una sola, ver
   ficha.php. El summary reutiliza el mismo estilo dorado de la casilla
   normal; el desplegable es un cajetin oscuro con un enlace por jornada. */
.ef-mes-casilla-detalle { position: relative; }
.ef-mes-casilla-detalle > summary { list-style: none; }
.ef-mes-casilla-detalle > summary::-webkit-details-marker { display: none; }
.ef-mes-casilla-detalle[open] > summary {
  box-shadow: 0 0 12px rgba(248, 179, 54, 0.75);
  z-index: 6;
  position: relative;
}
.ef-mes-casilla-lista {
  display: none;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 999;
  background: #241a08;
  border: 1px solid var(--ef-dorado);
  border-radius: 8px;
  padding: 10px;
  flex-direction: column;
  gap: 4px;
  min-width: 160px;
  max-width: min(280px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
}
.ef-mes-casilla-detalle[open] > .ef-mes-casilla-lista { display: flex; }
/* 28-ago ronda 5 (Seba: "la jerarquia visual... choca mucho una con otra"
   -- un dia con una sola jornada usaba boton "Repetir esta jornada" y un
   dia con varias usaba una lista de texto con guion, dos lenguajes
   visuales sin relacion. Ahora es el MISMO componente en los dos casos:
   una fila de chips dorados (mismo degradado que las casillas
   practicadas del calendario), uno por jornada -- con una sola jornada
   se ve un chip solo, con varias se ve una fila que envuelve. Sin boton
   aparte: el propio chip es el enlace que repite. */
.ef-mes-casilla-lista > .ef-calendario-tooltip-titulo {
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(248, 179, 54, 0.25);
}
.ef-popover-jornadas-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}
.ef-popover-jornada-chip {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  color: #241a08;
  background: linear-gradient(180deg, #ffdb96 0%, var(--ef-dorado) 55%, #d99a2b 100%);
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.ef-popover-jornada-chip:hover,
.ef-popover-jornada-chip:focus-visible {
  transform: translateY(-1px) scale(1.05);
  box-shadow: 0 4px 12px rgba(248, 179, 54, 0.5);
}
.ef-mes-casilla-lista-individual { align-items: center; text-align: center; }

/* Galería de "Mis vídeos" (§P2 hand-off) — cuadrícula de miniaturas en vez
   de listado de texto. Arquitectura de subida sin cambios (§8.2): directa
   a Bunny, esto solo cambia cómo se muestran los ya registrados. */
.ef-galeria-videos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
  margin-top: 12px;
}
.ef-galeria-tarjeta {
  background: rgba(245, 239, 230, 0.05);
  border: 1px solid rgba(245, 239, 230, 0.12);
  border-radius: 10px;
  overflow: hidden;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.ef-galeria-tarjeta:hover { transform: translateY(-2px); border-color: var(--ef-dorado); }
.ef-galeria-miniatura {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--ef-fondo);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ef-galeria-miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ef-galeria-miniatura-icono { font-size: 28px; opacity: 0.5; }
.ef-galeria-miniatura { cursor: pointer; }
.ef-galeria-miniatura:focus-visible { outline: 2px solid var(--ef-dorado); outline-offset: 2px; }
/* 28-ago v3: .ef-galeria-miniatura fuerza display:flex, que por
   especificidad de origen (autor vs. user-agent) gana al [hidden] nativo
   del navegador -- sin esto, poster.hidden=true en JS no ocultaria nada. */
.ef-video-inline-poster[hidden] { display: none; }
/* Botón "play" superpuesto (hand-off 20-ago P1): confirma con un vistazo
   que la tarjeta se puede reproducir, no solo mirar. */
.ef-galeria-play-icono {
  position: absolute;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(22, 19, 16, 0.55);
  border: 1px solid rgba(248, 179, 54, 0.7);
  color: var(--ef-crema);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding-left: 3px; /* óptico: centra el triángulo ▶, que pesa a la izquierda */
  transition: background 0.15s ease, border-color 0.15s ease;
}
.ef-galeria-miniatura:hover .ef-galeria-play-icono,
.ef-galeria-miniatura:focus-visible .ef-galeria-play-icono {
  background: var(--ef-dorado);
  color: var(--ef-fondo);
  border-color: var(--ef-dorado);
}
.ef-galeria-privacidad {
  position: absolute;
  top: 6px;
  right: 6px;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 6px;
  padding: 3px 6px;
  font-size: 11px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  color: var(--ef-crema);
  white-space: nowrap;
}
.ef-galeria-info {
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ef-galeria-info strong { font-size: 13px; }
.ef-galeria-info span { font-size: 11px; color: var(--ef-crema-tenue); }
.ef-galeria-compartido { color: var(--ef-dorado) !important; }
.ef-galeria-compartir-form { margin-top: 2px; }
.ef-galeria-compartir-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  color: var(--ef-dorado);
  font-size: 11px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  cursor: pointer;
}
.ef-galeria-compartir-btn:hover { color: var(--ef-naranja-claro); }
/* 28-ago (Seba: boton de borrar en "Mis videos") -- mismo tratamiento que
   Compartir (texto+icono sin fondo), pero en un tono apagado en reposo
   para no competir visualmente, y solo se pone rojo de aviso al pasar el
   raton/tocar, para que borrar nunca sea el boton mas llamativo de la
   tarjeta. */
.ef-galeria-borrar-form { margin-top: 2px; }
.ef-galeria-borrar-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  color: var(--ef-crema-tenue);
  font-size: 11px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  cursor: pointer;
}
.ef-galeria-borrar-btn:hover { color: #e0554a; }

/* Subida real de vídeo del alumno (§8.2, ficha.php + subida-video.js) */
.ef-form input[type="file"] {
  width: 100%;
  margin-bottom: 12px;
  color: var(--ef-crema-tenue);
  font-size: 13px;
  font-family: 'Montserrat', sans-serif;
}
.ef-subida-progreso { margin: 10px 0 2px; }
.ef-subida-barra-fondo {
  background: rgba(245, 239, 230, 0.12);
  border-radius: 999px;
  height: 8px;
  overflow: hidden;
}
.ef-subida-barra {
  background: linear-gradient(90deg, var(--ef-naranja) 0%, var(--ef-dorado) 100%);
  height: 100%;
  width: 0%;
  transition: width 0.2s ease;
}
.ef-subida-progreso span {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: var(--ef-crema-tenue);
}
.ef-subida-estado {
  font-size: 13px;
  color: var(--ef-crema-tenue);
  margin: 6px 0 0;
}

/* Tu progreso — racha + sellos fusionados en una sola tarjeta (hand-off 28-jul). */
.ef-progreso-fila {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 10px 0;
}
.ef-progreso-fila-secundaria { margin: 4px 0; }
.ef-progreso-icono { color: var(--ef-dorado); flex-shrink: 0; margin-top: 2px; }
.ef-progreso-texto { display: flex; flex-direction: column; gap: 2px; }
.ef-progreso-subtitulo { font-size: 14px; color: var(--ef-crema-tenue); }
.ef-progreso-separador {
  border: none;
  border-top: 1px solid rgba(248, 179, 54, 0.5);
  margin: 26px 0 18px;
}
.ef-progreso-sellos-titulo { font-size: 15px; margin: 0 0 8px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ef-crema-tenue); }
.ef-sellos-lista { margin: 0; padding-left: 20px; }
.ef-sellos-lista li { margin: 4px 0; }

/* Jerarquía Medalla/Trofeo/Diploma (ronda 17-ago): mismo criterio de
   colores en los tres — bronce/plata/oro dentro de la familia
   naranja→dorado de marca, nunca gris — pero formas de icono distintas
   (no la misma medalla escalada), jerarquía de tamaño creciente:
   medalla (semanal, pequeña) < trofeo (mensual) < diploma (mapa
   completo, la más grande y distintiva). Primera versión razonable del
   trazo — el pulido fino queda para una ronda posterior. */
.ef-nivel-bronce { color: var(--ef-naranja); }
.ef-nivel-plata { color: var(--ef-naranja-claro); }
.ef-nivel-oro { color: var(--ef-dorado); }

.ef-sello-con-icono {
  display: flex;
  align-items: center;
  gap: 10px;
  list-style: none;
  margin-left: -20px;
}
.ef-icono-trofeo, .ef-icono-diploma {
  flex-shrink: 0;
  display: inline-flex;
}
.ef-icono-diploma { color: var(--ef-dorado); }

/* Medalla semanal, al final de cada fila de "Vista mensual". */
.ef-mes-semana-fila {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.ef-mes-semana-fila .ef-mes-semana { flex: 1; margin-bottom: 0; }
.ef-mes-semana-medalla {
  flex: 0 0 auto;
  width: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Indicador provisional del mes en curso, junto a la cabecera de Vista mensual. */
.ef-mes-nivel-provisional {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(248, 179, 54, 0.1);
  border: 1px solid currentColor;
}

/* Logros — sección de trofeos permanentes en la ficha (hand-off 27-jul). */
.ef-logros-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.ef-logro-tarjeta {
  background: rgba(248, 179, 54, 0.08);
  border: 1px solid rgba(248, 179, 54, 0.3);
  border-radius: 10px;
  padding: 16px 10px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ef-logro-icono { font-size: 32px; }
.ef-logro-tarjeta strong { font-size: 13px; }
.ef-logro-tarjeta span { font-size: 11px; color: var(--ef-crema-tenue); }
/* 31-ago (Seba): la tarjeta pasa a ser un <button> real (antes un div) --
   reset de los estilos por defecto del navegador para que se vea IGUAL
   que antes, mas un hover claro de que es clicable. */
.ef-logro-tarjeta {
  font-family: 'Montserrat', sans-serif;
  color: inherit;
  cursor: pointer;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.ef-logro-tarjeta:hover,
.ef-logro-tarjeta:focus-visible {
  border-color: var(--ef-dorado);
  transform: translateY(-2px);
}

/* 31-ago (Seba: "cuando le des al trofeo, que salte un banner grande con
   lo mismo pero mas grande y ponga Conseguido: fecha"): mismo lenguaje
   visual que .ef-nivel-iniciado-overlay (celebracion de nivel), overlay
   propio y mas simple -- sin audio ni formulario, solo mostrar y cerrar
   tocando fuera. */
.ef-logro-detalle-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background:
    radial-gradient(70% 55% at 50% 15%, rgba(248, 179, 54, 0.28) 0%, rgba(248, 179, 54, 0) 60%),
    rgba(22, 19, 16, 0.97);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  text-align: center;
}
.ef-logro-detalle-overlay.activa { display: flex; }
.ef-logro-detalle-card {
  max-width: 360px;
  padding: 36px 28px 30px;
  border-color: var(--ef-dorado);
  box-shadow: 0 0 44px rgba(248, 179, 54, 0.28);
}
.ef-logro-detalle-icono { font-size: 56px; margin-bottom: 10px; }
.ef-logro-detalle-titulo { margin: 0 0 10px; font-size: 24px; color: var(--ef-dorado); line-height: 1.3; }
.ef-logro-detalle-fecha { margin: 0; font-size: 15px; color: var(--ef-crema-tenue); }

/* Trofeo de mapa completado (hand-off 27-jul) — celebración distinta a
   los sellos normales. Respeta prefers-reduced-motion (§6.2, mismo
   principio que la pausa "respira"). */
.ef-trofeo-celebracion {
  text-align: center;
  padding: 24px 16px;
}
.ef-trofeo-icono {
  font-size: 48px;
  line-height: 1;
  margin-bottom: 8px;
  animation: ef-trofeo-aparece 0.6s ease-out, ef-trofeo-brillo 2s ease-in-out 0.6s infinite;
}
@keyframes ef-trofeo-aparece {
  0% { transform: scale(0.3) rotate(-15deg); opacity: 0; }
  70% { transform: scale(1.15) rotate(5deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
@keyframes ef-trofeo-brillo {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(248, 179, 54, 0.4)); }
  50% { filter: drop-shadow(0 0 18px rgba(248, 179, 54, 0.9)); }
}
@media (prefers-reduced-motion: reduce) {
  .ef-trofeo-icono { animation: none; }
}

/* Icono "RM" — marca de participación en el reto del mes, superpuesta
   sobre el día normal. Solo participación, nunca evaluación (§ hand-off).
   26-ago (Seba, testing Pepecruceno): a 8px/sin brillo pasaba desapercibido
   del todo en la casilla — se sube tamaño/padding y se le da el mismo
   tratamiento de brillo dorado que ya usan los trofeos (ef-trofeo-brillo),
   para que destaque igual de claro en Camino recorrido y en Vista mensual. */
.ef-calendario-casilla { position: relative; }
.ef-mes-casilla { position: relative; }
.ef-calendario-rm,
.ef-mes-casilla .ef-calendario-rm {
  position: absolute;
  top: -7px;
  right: -7px;
  background: var(--ef-dorado);
  color: #1a1208;
  border: 1.5px solid var(--ef-fondo);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 5px;
  letter-spacing: 0.02em;
  box-shadow: 0 0 6px rgba(248, 179, 54, 0.9), 0 0 2px rgba(0, 0, 0, 0.6);
  animation: ef-trofeo-brillo 2.4s ease-in-out infinite;
  z-index: 2;
}
@media (prefers-reduced-motion: reduce) {
  .ef-calendario-rm, .ef-mes-casilla .ef-calendario-rm { animation: none; }
}
.ef-calendario-leyenda-rm { font-size: 12px; color: var(--ef-crema-tenue); margin: 16px 0 0; }

/* 27-ago (Seba: "/ficha se siente superapelotonado, me entra agobio") —
   más aire entre tarjetas SOLO en /ficha, sin tocar el resto del sitio. */
.pagina-ficha .ef-card { padding: 24px 26px; margin-bottom: 26px; }


/* Cabecera de /ficha (26-ago, Seba): email/plan/estado apilados en vez de
   una sola línea con puntos, y el estado de acceso real (prueba con día
   1..7, caducada, o alumno activo) como badge de color en vez del ENUM
   crudo de estado_suscripcion — ver FichaController::etiquetaEstadoAcceso(). */
.ef-ficha-meta { margin-top: 6px; }
/* 27-ago (Seba: email + "Plan Base" se veían "feos" en dos líneas del
   mismo peso que el nombre) -- se funden en una sola línea discreta
   (tamaño menor, tono apagado), dejando el protagonismo al badge de
   estado justo debajo. 27-ago v2: en movil esa linea se quedaba corta y
   partía "Plan" y "Base" en dos renglones distintos -- se une con
   &nbsp; en ficha.php para que "Plan Base" salte entero a la siguiente
   línea si no cabe, nunca partido por la mitad. */
.ef-ficha-meta-linea { margin: 4px 0; color: var(--ef-crema-tenue); font-size: 14px; letter-spacing: 0.01em; }
/* Chip de estado, no bloque sólido (26-ago v2, Seba: el relleno naranja con
   letras negras rompía la estética oscura/elegante del resto de la ficha).
   Fondo translúcido + borde fino + punto de color, con 3 tonos según el
   estado real (ver FichaController::etiquetaEstadoAcceso). */
.ef-ficha-estado-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 8px 0 0;
  padding: 5px 14px;
  font-weight: 700;
  font-size: 13px;
  border-radius: 999px;
  letter-spacing: 0.01em;
  background: rgba(248, 179, 54, 0.1);
  border: 1px solid rgba(248, 179, 54, 0.35);
  color: var(--ef-dorado);
}
.ef-ficha-estado-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.ef-ficha-estado-badge--ok {
  background: rgba(46, 125, 79, 0.14);
  border-color: rgba(46, 125, 79, 0.4);
  color: #4fbf83;
}
.ef-ficha-estado-badge--alerta {
  background: rgba(225, 88, 31, 0.14);
  border-color: rgba(225, 88, 31, 0.4);
  color: var(--ef-naranja-claro);
}

/* 27-ago (Seba: "Vas por: Mapa Bordón" + "Bordón: X de Y días completados"
   repetía "Bordón" dos veces y quedaba como dos frases sueltas). Ahora es
   un único bloque: la frase de arriba nombra el mapa una sola vez, y
   debajo una barra de progreso fina sustituye a la segunda frase -- los
   números (X de Y, Z% recorrido) quedan como nota pequeña bajo la barra. */
.ef-ficha-ruta { margin: 14px 0 18px; }
.ef-ficha-ruta-titulo { margin: 0 0 10px; font-size: 16px; }
.ef-ficha-progreso-barra {
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
.ef-ficha-progreso-relleno {
  height: 100%;
  border-radius: 999px;
  background: var(--ef-dorado);
}
.ef-ficha-progreso-texto { margin: 8px 0 0; font-size: 13px; color: var(--ef-crema-tenue); }

/* Biblioteca: índice (título+desc, buscador, 3 tarjetas) — pegado tal
   cual del diseño dado, con sus propios colores fijos (no las variables
   --ef-*).
   29-ago (Seba: "todo mucho mas fino, como una cara alargada" -- esta
   caja tenia su PROPIO max-width:900px + padding horizontal de 24px,
   metido DENTRO de .ef-contenedor (max-width:880px, ya con sus propios
   20px de cada lado) -- el padding se sumaba dos veces y estrechaba tanto
   la cajita de "Estacion Cero" como las 3 tarjetas de abajo frente al
   ancho real que usan Reto del mes/Directos/Comunidad. Se quita el
   padding horizontal propio del todo: ahora hereda el mismo ancho que
   cualquier .ef-card del resto del sitio. */
.biblioteca{ padding: 0 0 40px; }
/* 28-ago: h1 de Estacion Cero unificado con el resto de titulos de
   seccion (Directos, Comunidad, Reto del mes, Tu camino...) -- hereda
   la regla global h1 (Cormorant Garamond, dorado, mismo tamano). */
.biblioteca .desc{ font-size:16px; color:var(--ef-crema); max-width:560px; line-height:1.5; margin-bottom:24px; }
.biblioteca .search-wrap{ position:relative; margin-bottom:40px; }
.biblioteca .search{
  width:100%; padding:14px 16px; border-radius:9px; border:1px solid rgba(255,255,255,0.08);
  background:#f3ede4; font-size:14px; color:#2b241d; margin-bottom:0;
}
/* Resultados del buscador (ampliado — categorías, secciones y vídeos): */
.biblioteca .search-resultados{
  position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:20;
  background:#f3ede4; border-radius:9px; border:1px solid rgba(255,255,255,0.08);
  box-shadow:0 12px 28px rgba(0,0,0,0.35); max-height:360px; overflow-y:auto;
}
.biblioteca .search-resultados a{
  display:flex; flex-direction:column; gap:2px; padding:10px 16px;
  text-decoration:none; border-bottom:1px solid rgba(43,36,29,0.08);
}
.biblioteca .search-resultados a:last-child{ border-bottom:none; }
.biblioteca .search-resultados a:hover{ background:rgba(246,169,61,0.16); }
.biblioteca .search-resultados .tipo{
  font-family:'Montserrat',sans-serif; font-size:10px; font-weight:800;
  letter-spacing:0.06em; text-transform:uppercase; color:#C65C18;
}
.biblioteca .search-resultados .texto{ font-size:14px; color:#2b241d; font-weight:600; }
.biblioteca .search-resultados .sub{ font-size:12px; color:#6b6258; }
.biblioteca .search-resultados .vacio{ padding:14px 16px; font-size:13px; color:#6b6258; }
.biblioteca .cards{ display:grid; grid-template-columns:repeat(3, 1fr); gap:20px; }
.biblioteca .card{
  background:rgba(79,72,64,0.18);
  border:1px solid var(--card-accent, rgba(246,169,61,0.28));
  border-radius:16px; padding:28px 20px 24px; text-align:center;
  text-decoration:none; display:flex; flex-direction:column; align-items:center;
  transition:transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.biblioteca .card:hover{
  transform:translateY(-6px) scale(1.03);
  box-shadow:0 0 24px rgba(204, 154, 82, 0.35);
}
/* Retos anteriores: glow en su color rosa/granate, no el dorado de las otras dos */
.biblioteca .c3:hover{ box-shadow:0 0 24px rgba(184, 66, 92, 0.35); }
.biblioteca .icon-wrap{ width:64px; height:64px; margin:0 auto 16px; display:flex; align-items:center; justify-content:center; }
.biblioteca .card h2{
  font-family:Georgia,serif; font-style:italic; font-weight:600;
  font-size:20px; color:#f3ede4; margin:0 0 10px;
}
.biblioteca .divider{ width:56px; height:10px; margin:0 auto 12px; position:relative; }
.biblioteca .divider::before, .biblioteca .divider::after{
  content:""; position:absolute; left:0; right:0; height:1px; background:var(--card-accent);
}
.biblioteca .divider::before{ top:2px; opacity:.9; }
.biblioteca .divider::after{ top:6px; opacity:.5; }
.biblioteca .card p{ font-size:12.5px; color:#9a9890; line-height:1.5; margin:0; }
.biblioteca .c1{ --card-accent:#F6A93D; }
.biblioteca .c2{ --card-accent:#C65C18; }
.biblioteca .c3{ --card-accent:#C10230; }

@media (max-width: 600px) {
  /* Móvil (hand-off 20-ago, confirmado con Seba): 3 tarjetas apiladas en
     2+1 quedaba desigual y muy alto. Una columna, ancho completo, una
     debajo de otra — scroll normal de la página, sin deslizar de lado. */
  .biblioteca .cards{
    display:grid;
    grid-template-columns:1fr;
    gap:16px;
  }
  .biblioteca .card{ min-height:0; justify-content:center; }
}

/* Biblioteca: índice de categorías dentro de un grupo */
.ef-bib-categorias-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); gap: 12px; }
.ef-bib-categoria-card {
  display: block;
  border: 1px solid rgba(245, 239, 230, 0.12);
  border-radius: 10px;
  padding: 16px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.ef-bib-categoria-card:hover { border-color: var(--ef-dorado); transform: translateY(-2px); }

/* Biblioteca: vídeos dentro de una categoría */
.ef-breadcrumb { font-size: 13px; color: var(--ef-crema-tenue); margin: 0 0 14px; }
.ef-breadcrumb a { color: var(--ef-crema-tenue); }
/* Encabezado de subcategoría dentro de una categoría de Biblioteca (p.ej.
   "Fundamentos"/"Compás"/"Tonalidades"/"Cante" en Sevillanas) — kicker
   neutro, no ligado a los colores de campo (esto no es un "campo" de
   CampoVisualService, es una subdivisión propia de la Biblioteca). */
.ef-bib-subcategoria {
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ef-dorado);
  margin: 28px 0 4px;
  padding-top: 14px;
  border-top: 2px solid rgba(248, 179, 54, 0.2);
}
.ef-bib-subcategoria:first-child { margin-top: 8px; padding-top: 0; border-top: none; }
/* Agrupación por nombre base (Explicación→Explicación de la práctica→
   Práctica, sin asumir parejas fijas de 2): sin separación dentro del
   propio grupo (Explicación y Práctica van juntas) — la línea blanca va
   DESPUÉS de cada pareja completa, antes de la siguiente (handoff
   16-ago P8: antes separaba mal, dentro de la pareja). Mismo criterio
   de grosor que la línea amarilla de subcategoría. */
.ef-bib-grupo-base + .ef-bib-grupo-base {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 2px solid rgba(245, 239, 230, 0.18);
}
.ef-bib-item { padding: 14px 0; transition: background-color 1.6s ease; }
/* Resultado del buscador de Estación Cero: resalta temporalmente la fila de
   vídeo o el encabezado de sección al llegar desde /biblioteca (?resaltar=). */
.ef-resaltado-temporal { background-color: rgba(246, 169, 61, 0.22); border-radius: 8px; }
.ef-bib-subcategoria { transition: background-color 1.6s ease; }
.ef-bib-item-toggle {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: var(--ef-crema);
  font-family: 'Montserrat', sans-serif;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  padding: 6px 0;
}
.ef-bib-item-icono { color: var(--ef-dorado); display: inline-block; width: 1.2em; }
.ef-bib-item-player { margin-top: 10px; }
.ef-bib-item-player[hidden] { display: none; }

/* Comunidad */
/* Vídeo en el muro (hand-off 20-ago P2): misma miniatura clicable que "Mis
   vídeos" de la ficha, pero acotada en anchura — aquí no está en cuadrícula.
   28-ago (Seba: se veia "cuadrado" y descentrado en movil): width:100% +
   box-sizing explicito, por si el navegador estaba calculando el ancho
   contando el borde/padding del propio recuadro (aspect-ratio 16/9 de
   .ef-galeria-miniatura ya estaba bien, el problema era el contenedor). */
.ef-comunidad-video { width: 100%; max-width: 100%; margin: 0 0 10px; box-sizing: border-box; }
.ef-comentario { font-size: 14px; margin: 4px 0; padding-left: 10px; border-left: 2px solid rgba(245, 239, 230, 0.15); }
/* Formulario de comentario (§9.3): "min-width: 0" es lo que de verdad
   arregla el desbordamiento en móvil — un input dentro de un flex no se
   encoge nunca por debajo de su ancho de contenido si no se lo decimos
   explícitamente, así que sin esto se sale del contenedor en pantallas
   estrechas por mucho "flex:1" que tenga. */
.ef-comentario-form {
  margin-top: 8px;
  display: flex;
  gap: 6px;
  max-width: 100%;
}
.ef-comentario-form input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid transparent;
}
.ef-comentario-form button { padding: 6px 14px; font-size: 13px; flex-shrink: 0; }

/* Comunidad — un único muro (27-ago v3, Seba: las cápsulas separadas
   sentían como "puertas" que elegir; se simplifica a una sola columna
   de arriba a abajo). Franja de avisos arriba (solo el más reciente,
   con desplegable nativo <details> para los anteriores -- sin JS), y
   debajo, sin cortes, el muro de vídeos en una sola columna, en
   escritorio y en móvil (28-ago v4, Seba: el grid de 2 columnas se veía
   "álbum de foto"; una columna deja el vídeo bastante más ancho, ya que
   ocupa el ancho completo de la tarjeta en vez de la mitad). */
/* 28-ago v5 (Seba, tajante: el video de Comunidad se veia mas ancho y
   desproporcionado que el de Directos -- este max-width de 1080px era la
   causa; con el fuera, .ef-contenedor se queda en su valor por defecto de
   880px en las dos paginas, asi que el video mide EXACTAMENTE lo mismo en
   ambas). Antes: .pagina-comunidad .ef-contenedor { max-width: 1080px; } */

.ef-aviso-franja {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  background: linear-gradient(90deg, rgba(248, 179, 54, 0.10), rgba(248, 179, 54, 0.02));
  border: 1px solid rgba(248, 179, 54, 0.35);
  border-left: 4px solid var(--ef-dorado);
  border-radius: 10px;
  padding: 16px 20px;
  margin-bottom: 20px;
}
.ef-aviso-franja-icono { color: var(--ef-dorado); flex-shrink: 0; margin-top: 2px; }
.ef-aviso-franja-texto { font-size: 15px; margin: 0 0 4px; }
.ef-aviso-franja-meta { font-size: 12px; color: var(--ef-crema-tenue); }
.ef-aviso-franja-detalle { margin-top: 8px; }
.ef-aviso-franja-detalle summary { font-size: 12px; color: var(--ef-dorado); cursor: pointer; }
.ef-aviso-franja-detalle > div { margin-top: 8px; }

.ef-form-aviso-detalle { margin-bottom: 20px; }
.ef-form-aviso-detalle summary { font-size: 13px; color: var(--ef-crema-tenue); cursor: pointer; }
.ef-form-aviso { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; max-width: 460px; }
.ef-form-aviso textarea { resize: vertical; min-height: 60px; }
.ef-aviso-item { border-bottom: 1px solid rgba(245, 239, 230, 0.1); padding: 10px 0; }
.ef-aviso-item:last-child { border-bottom: none; }
.ef-aviso-texto { margin: 0 0 4px; font-size: 14px; }
.ef-aviso-meta { font-size: 12px; color: var(--ef-crema-tenue); }

.ef-muro-grid { display: grid; grid-template-columns: 1fr; gap: 18px; }
/* 28-ago v2 (Seba, tajante: quiere el vídeo tan ancho como el de la
   jornada -- reproductor.php solo tiene el margen de .ef-contenedor (20px)
   por delante, pero aquí el vídeo iba dentro de .ef-muro-tarjeta y sumaba
   su propio padding (18px) encima. Se rompe el padding de la tarjeta SOLO
   para el vídeo, en vez de tocar el padding general de la tarjeta -- así
   el vídeo queda al mismo nivel que el borde de .ef-contenedor, igual que
   en la jornada). Mismo criterio en .pagina-directos más abajo. */
@media (max-width: 700px) {
  .ef-muro-tarjeta .ef-video-envoltorio,
  .ef-muro-tarjeta .ef-video-inline-poster,
  .ef-muro-tarjeta .ef-muro-logro-media {
    margin-left: -18px;
    margin-right: -18px;
    border-radius: 0;
  }
}
.ef-muro-tarjeta {
  background: var(--ef-fondo-2);
  border: 1px solid rgba(245, 239, 230, 0.10);
  border-radius: 12px;
  padding: 16px 18px;
  overflow: hidden; /* 28-ago: igual que .ef-reto-nivel -- sin esto, el
    sangrado de -18px del video en movil no se recortaba al borde de la
    tarjeta y desbordaba la pantalla, tapando el boton Comentar. */
}
.ef-muro-tarjeta-cabecera {
  font-size: 14px;
  margin-bottom: 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  min-width: 0; /* mismo motivo que .ef-comentario-form: un hijo dentro de
    flex no se encoge por debajo de su contenido si no se lo decimos, y en
    movil eso empujaba toda la tarjeta (video incluido) fuera de la
    pantalla en vez de partir el texto en varias lineas. */
}
.ef-muro-autor { color: var(--ef-crema); text-decoration: none; }
.ef-muro-autor:hover strong { color: var(--ef-dorado); }
/* 28-ago (Seba: nombre / titulo del video / fecha, cada uno con su color
   para distinguirlos de un vistazo -- nombre en crema (ya lo tenia),
   titulo en dorado (el mismo acento que ya se usa para "lo importante" en
   toda la web), fecha en el tono apagado de siempre, la mas discreta de
   las tres por ser el dato menos util). */
.ef-muro-video-titulo { color: var(--ef-dorado); font-weight: 600; }
.ef-muro-fecha { color: var(--ef-crema-tenue); font-size: 12px; }
.ef-muro-tarjeta-texto { margin: 0 0 10px; font-size: 14px; }

/* 28-ago (Seba, pop-up "Iniciado"): tarjeta de LOGRO en el muro -- misma
   jerarquia visual que un video (destacada, arriba de la tarjeta), pero sin
   video ni el regalo de dias (eso solo lo ve quien ya lo tiene). */
.ef-muro-tarjeta--logro {
  border-color: var(--ef-dorado);
  box-shadow: 0 0 24px rgba(248, 179, 54, 0.14);
}
/* 29-ago (Seba): la caja del logro tiene que medir EXACTAMENTE lo mismo
   que la de un video (misma relacion 16:9, mismo ancho de borde a borde
   en movil -- ver la regla @media de arriba, .ef-muro-logro-media se sumo
   ahi tambien) -- antes era un bloque de texto suelto, mas bajo que un
   video. Colores corporativos (dorado/naranja) en vez de la version
   apagada anterior. */
.ef-muro-logro-media {
  position: relative;
  aspect-ratio: 16 / 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  text-align: center;
  padding: 12px;
  box-sizing: border-box;
  background: radial-gradient(ellipse at center, rgba(229, 67, 58, 0.22) 0%, rgba(22, 19, 16, 0.97) 72%);
  border: 1px solid rgba(229, 67, 58, 0.35);
}
/* 29-ago v3 (Seba, tras probar 2 rondas de maquetas: "que se vea claro
   que es Estación Flamenca" + "que llame la atención, que le pique la
   curiosidad a quien lo vea") -- rediseño completo, concepto "medalla":
   el logo va SIEMPRE nítido y en su propio rincón (nunca de fondo ni
   traslúcido -- eso fue justo lo que Seba rechazó de la primera ronda de
   maquetas), y la insignia roja (círculo + check) es ahora lo primero que
   se ve, la misma que ya usa el paso "alcanzado" de Tu progreso en
   /ficha -- mismo lenguaje visual de "conseguido" en toda la web. */
.ef-muro-logro-logo { position: absolute; top: 12px; left: 14px; height: 20px; z-index: 2; }
.ef-muro-logro-badge {
  position: relative;
  z-index: 2;
  display: block;
  width: 84px;
  height: 84px;
  margin: 0 auto 4px;
  border-radius: 50%;
  background: var(--ef-guia-rojo);
  box-shadow: 0 0 0 4px rgba(229, 67, 58, 0.3), 0 0 30px rgba(229, 67, 58, 0.5);
}
.ef-muro-logro-badge::after {
  content: '\2713';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 38px;
  font-weight: 900;
  color: var(--ef-crema);
  line-height: 1;
}
.ef-muro-logro-nivel-label { position: relative; z-index: 2; margin: 8px 0 0; font-size: clamp(13px, 3.2vw, 15px); font-weight: 700; color: var(--ef-crema-tenue); text-transform: uppercase; letter-spacing: 0.08em; }
.ef-muro-logro-nivel-nombre { position: relative; z-index: 2; margin: 2px 0 0; font-size: clamp(32px, 9vw, 46px); font-weight: 900; color: var(--ef-crema); line-height: 1.05; }
.ef-muro-logro-regalo-obtenido { position: relative; z-index: 2; margin: 12px 0 0; font-size: clamp(13px, 3.4vw, 15px); font-weight: 700; color: var(--ef-dorado); letter-spacing: 0.02em; line-height: 1.4; }
.ef-muro-logro-regalo-destacado { font-size: 1.35em; font-weight: 900; color: var(--ef-crema); }

.ef-muro-vacio { text-align: center; padding: 44px 20px; color: var(--ef-crema-tenue); }
.ef-muro-vacio svg { color: var(--ef-dorado); opacity: 0.75; margin-bottom: 12px; }
.ef-muro-vacio p { margin: 0; font-size: 14px; }

/* Reto — paleta de marca real (Blueprint v1.3 §6.2), mismos colores fijos
   que ya usa el índice de Biblioteca (bloque .biblioteca más abajo):
   burdeos #C10230, naranja quemado #C65C18, ocre #E59145, dorado #F6A93D,
   amarillo pálido #FCE67F, marrón/carbón #4F4840, gris neutro #818181. */
.ef-reto-nivel {
  position: relative;
  border: 1px solid rgba(246, 169, 61, 0.25);
  border-radius: var(--ef-radio);
  background: rgba(79, 72, 64, 0.18);
  padding: 20px 20px 18px;
  margin-bottom: 12px;
  overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.ef-reto-nivel::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--nivel-acento, #E59145);
}
.ef-reto-nivel.nivel-basico { --nivel-acento: #E59145; }
.ef-reto-nivel.nivel-intermedio { --nivel-acento: #C65C18; }
/* 28-ago v2 (Seba: mismo criterio de ancho que el muro de Comunidad, ver
   comentario junto a .ef-muro-grid -- SOLO en /directos, .ef-reto-nivel
   padding es 20px a los lados. Con scope a .pagina-directos porque
   .ef-reto-nivel es la misma clase que usa Reto mensual, que no se toca). */
@media (max-width: 700px) {
  .pagina-directos .ef-reto-nivel .ef-video-envoltorio,
  .pagina-directos .ef-reto-nivel .ef-video-inline-poster {
    margin-left: -20px;
    margin-right: -20px;
    border-radius: 0;
  }
}
.ef-reto-nivel:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3); }
.ef-reto-nivel-cabecera { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.ef-reto-kicker {
  display: inline-block;
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4F4840;
  background: var(--nivel-acento, #E59145);
  padding: 6px 16px;
  border-radius: 999px;
}
.ef-reto-badge-ok { font-size: 16px; font-weight: 700; color: var(--ef-verde-ok); white-space: nowrap; }
/* Título de la pieza del reto (27-ago, Seba: "Farseta Bulería"/"Farseta Taranta") — junto al kicker de nivel. */
.ef-reto-titulo { font-family: 'Montserrat', sans-serif; font-weight: 700; font-size: 17px; color: var(--ef-crema); }
.ef-reto-nivel p { color: var(--ef-crema); margin: 0; font-size: 18px; line-height: 1.5; }
/* Pista de "se completa solo" cuando aún no se ha visto entero (26-ago v2) */
.ef-reto-pista { font-size: 16px; font-style: italic; color: var(--ef-crema-tenue); margin: 10px 0 0; }
/* "Ya practicado" (reto del mes): dorado real + tinte de fondo, hito alcanzado */
.ef-reto-nivel.completado { border-color: #F6A93D; background: rgba(246, 169, 61, 0.12); }
.ef-reto-nivel.completado::before { background: #F6A93D; }
.ef-reto-nivel.completado .ef-reto-kicker { background: #F6A93D; }
.ef-reto-nivel-vacio { visibility: hidden; }
/* Subnota bajo "¿Serás capaz de tocarlo?" cuando hay dos niveles (27-ago) */
.ef-reto-subnota { font-size: 14px; color: var(--ef-crema-tenue); margin: 6px 0 0; }
/* Enlace a Retos anteriores, siempre visible debajo de los niveles (27-ago) */
.ef-reto-anteriores-link { text-align: center; }
.ef-reto-anteriores-link p { margin: 0 0 12px; }
/* Cierre inline al terminar el vídeo de Práctica de un nivel (27-ago v5) —
   mismo tono que .ef-cierre-dia, pero dentro de la tarjeta del vídeo. */
.ef-reto-cierre-practica { text-align: center; padding: 14px 4px 4px; }
.ef-reto-cierre-practica p { color: var(--ef-crema); font-size: 16px; margin: 0; }
/* Cierre al completar un reto del mes (26-ago v2) */
.ef-reto-cierre-botones { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }

/* Retos anteriores (Biblioteca): fila por mes — etiqueta lateral en burdeos
   + básico/intermedio uno junto al otro, misma altura. */
.ef-retos-mes-fila { display: flex; align-items: stretch; gap: 16px; margin-bottom: 22px; }
.ef-retos-mes-etiqueta {
  flex: 0 0 78px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: linear-gradient(165deg, #C10230, #820221);
  border-radius: var(--ef-radio);
  padding: 12px 6px;
  text-align: center;
  box-shadow: 0 6px 16px rgba(193, 2, 48, 0.3);
}
.ef-retos-mes-mes {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 600;
  font-size: 1.3rem;
  color: #FCE67F;
  line-height: 1.1;
}
.ef-retos-mes-anio {
  font-family: 'Montserrat', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: rgba(252, 230, 127, 0.75);
}
.ef-retos-mes-niveles {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.ef-retos-mes-niveles .ef-reto-nivel { margin-bottom: 0; }
@media (max-width: 600px) {
  .ef-retos-mes-fila { flex-direction: column; gap: 10px; }
  .ef-retos-mes-etiqueta { flex-direction: row; flex-basis: auto; gap: 8px; padding: 8px 14px; }
  .ef-retos-mes-niveles { grid-template-columns: 1fr; }
}

/* Landing pública (/): puerta de entrada minimalista, sin cabecera/nav
   interna — logo + titular corto + tarjeta de acceso, mismo fondo con
   glow radial y misma tarjeta/CTA que el resto de la plataforma. */
.ef-landing {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 20px;
  padding: 40px 20px;
}
.ef-landing-logo { display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto; }
.ef-landing-tagline {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.3rem, 4vw, 1.6rem);
  color: var(--ef-dorado);
  max-width: 420px;
  margin: 0;
}
.ef-landing-card { width: 100%; max-width: 380px; text-align: left; }

/* Ficha: avatar simple (iniciales sobre color de marca) — sin foto real
   ni creador de avatar tipo Duolingo, cubre el mismo valor de identidad
   visual con una fracción del esfuerzo. */
.ef-ficha-cabecera { display: flex; align-items: center; gap: 16px; margin-bottom: 10px; }
.ef-avatar {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #1F3A5F;
  border: 2px solid var(--ef-dorado);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Montserrat', sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: var(--ef-dorado);
}
.ef-ficha-cabecera h1 { margin-bottom: 2px; }

/* Guía paso a paso para subir el vídeo de presentación — activada solo
   con ?guia=presentacion (ver guia-presentacion.js). Tarjeta explicativa
   + recuadro rojo que se va moviendo, campo a campo, hasta "Subir vídeo". */
.ef-guia-presentacion {
  background: var(--ef-fondo);
  border: 1px solid var(--ef-naranja-claro);
  border-radius: var(--ef-radio);
  padding: 14px 16px;
  margin: 0 0 14px;
}
.ef-guia-titulo {
  margin: 0 0 10px;
  font-size: 16px;
  font-weight: 800;
  color: var(--ef-naranja-claro);
}
.ef-guia-lista {
  margin: 0;
  padding-left: 22px;
  font-size: 14px;
  color: var(--ef-crema-tenue);
}
.ef-guia-lista li { margin-bottom: 8px; transition: all 0.2s ease; }
.ef-guia-lista li:last-child { margin-bottom: 0; }
/* 26-ago (Seba: quiere que el paso activo destaque MUCHO más, no una
   diferencia casi imperceptible) — más grande, en rojo de guía, en
   negrita, y con un pulso propio de opacidad para que llame la atención
   igual que el recuadro del campo. */
.ef-guia-lista li.ef-guia-paso-activo {
  color: var(--ef-guia-rojo);
  font-weight: 800;
  font-size: 18px;
  animation: ef-guia-paso-pulso 1.3s ease-in-out infinite;
}
@keyframes ef-guia-paso-pulso {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
/* 26-ago: recuadro rojo del campo activo, más grande y con un pulso de
   sombra más marcado (antes casi no se notaba) — outline más grueso y
   un ligero "respiro" de escala además del resplandor. */
.ef-guia-resaltado {
  outline: 5px solid var(--ef-guia-rojo) !important;
  outline-offset: 3px;
  border-radius: 8px;
  animation: ef-guia-pulso 1.2s ease-in-out infinite;
}
@keyframes ef-guia-pulso {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229, 67, 58, 0.6); transform: scale(1); }
  50% { box-shadow: 0 0 0 12px rgba(229, 67, 58, 0); transform: scale(1.03); }
}

/* 30-ago (rediseno grande, Seba: "esto tiene que ser bien bonito,
   armonico con el resto de la academia" -- lo compara directamente con la
   tarjeta de "!Jornada X completada!"): el aviso de instalar la app
   (Android e iPhone comparten ya el mismo diseno) deja de ser una caja
   rectangular con borde dorado -- pasa a ser una tarjeta grande, mismo
   lenguaje visual que .ef-card (fondo --ef-fondo-2, sombra) y el mismo
   titulo cursivo dorado que usan los h1/h2 de toda la web -- ocupa al
   menos la mitad de la pantalla, con el icono de la guitarra grande y un
   resplandor naranja que palpita para invitar al toque. Solo el boton
   "cerrar" queda fuera de la tarjeta, arriba a la derecha. */
/* 31-ago (Seba: podia darle a Play al video con el aviso todavia
   abierto encima) -- fondo fijo a pantalla completa, DEBAJO del propio
   aviso (z-index justo por debajo), que no hace nada al tocarlo salvo
   bloquear el toque -- asi ninguna pantalla de detras (video, botones)
   recibe ningun click mientras el aviso este en pantalla. No se cierra
   solo al tocarlo a proposito: Seba pidio que solo se pueda cerrar
   pulsando instalar o la X, nunca tocando fuera. */
.ef-pwa-banner-v2-fondo {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: rgba(22, 19, 16, 0.55);
}
.ef-pwa-banner-v2 {
  position: fixed;
  left: 0;
  right: 0;
  /* 30-ago (noche, otra vez -- Seba: "que quede mas hacia abajo, en el
     primer tercio de la pantalla, no pegado del todo arriba"): antes
     top:0 dejaba el rectangulo pegado al borde superior de la pantalla,
     sin nada de aire por encima. Ahora baja el mismo hueco que ya tenia
     por debajo (el padding inferior del cajetin, 24px) para que quede
     igual de espacio arriba del icono que el que hay entre el titulo y
     el borde de abajo -- ancho, izquierda y derecha, intactos. */
  top: calc(env(safe-area-inset-top, 0px) + 24px);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  animation: ef-pwa-banner-v2-entra 0.35s ease-out;
}
@keyframes ef-pwa-banner-v2-entra {
  from { transform: translateY(-16px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.ef-pwa-banner-v2-cerrar {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(245, 239, 230, 0.25);
  border-radius: 50%;
  color: var(--ef-crema-tenue);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.ef-pwa-banner-v2-cerrar:hover { color: var(--ef-crema); }
.ef-pwa-banner-v2-cajetin {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  /* 30-ago (mas tarde, mas -- Seba: "recorta el banner, hay mucho hueco
     vacio arriba y abajo"): antes min-height:50vh forzaba la tarjeta a
     ocupar media pantalla siempre, sobrara texto o no -- se quita del
     todo y la altura pasa a ser la que pida el propio contenido (icono +
     titulo + padding), nunca mas grande de lo necesario. Solo cambia el
     RECORTE -- letras, color, icono y el resto de la tarjeta (fondo,
     resplandor, halo del icono, animaciones) intactos, tal y como pidio. */
  padding: 26px 24px 24px;
  border: none;
  /* 30-ago (noche): antes solo se redondeaban las esquinas de abajo
     porque el rectangulo estaba pegado al borde superior de la pantalla
     (no se veian esquinas arriba). Ahora que baja un poco y queda
     separado del borde, se redondean las cuatro esquinas para que se
     vea como una tarjeta flotante completa, no a medias. */
  border-radius: 28px;
  /* 30-ago (mas tarde, mas): en el navegador NO-Safari de iPhone este
     mismo cajetin es un <a> (enlace, no <button>) para poder llevar al
     alumno a Safari de un solo toque -- sin esto se veria el titulo
     subrayado y de otro color, como un enlace suelto en vez de parte de
     la tarjeta. */
  text-decoration: none;
  color: inherit;
  background:
    radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--ef-naranja) 35%, transparent) 0%, transparent 60%),
    var(--ef-fondo-2);
  box-shadow: var(--ef-sombra);
  cursor: pointer;
  overflow: hidden;
  animation: ef-pwa-banner-v2-pulso 2.4s ease-in-out infinite;
}
.ef-pwa-banner-v2-cajetin:hover { filter: brightness(1.06); }
.ef-pwa-banner-v2-icono-halo {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 92px;
  height: 92px;
  border-radius: 20px;
  animation: ef-pwa-banner-v2-halo-icono 1.8s ease-in-out infinite;
}
.ef-pwa-banner-v2-icono {
  position: relative;
  z-index: 1;
  width: 92px;
  height: 92px;
  border-radius: 20px;
}
.ef-pwa-banner-v2-titulo {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 500;
  color: var(--ef-dorado);
  font-size: clamp(1.9rem, 8vw, 2.7rem);
  line-height: 1.2;
  text-align: center;
  margin: 0;
}
.ef-pwa-banner-v2-instruccion {
  margin: 0;
  max-width: 320px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ef-crema);
  text-align: center;
}
.ef-pwa-banner-v2-instruccion strong { color: var(--ef-dorado); }
.ef-pwa-banner-v2-glifo {
  display: inline-flex;
  vertical-align: -4px;
  color: var(--ef-naranja-claro);
}
@keyframes ef-pwa-banner-v2-pulso {
  0%, 100% { box-shadow: var(--ef-sombra), 0 0 0 0 color-mix(in srgb, var(--ef-naranja) 45%, transparent); }
  50% { box-shadow: var(--ef-sombra), 0 0 0 16px color-mix(in srgb, var(--ef-naranja) 0%, transparent); }
}
@keyframes ef-pwa-banner-v2-halo-icono {
  0%, 100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--ef-dorado) 75%, transparent);
  }
  50% {
    box-shadow: 0 0 22px 8px color-mix(in srgb, var(--ef-dorado) 80%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ef-pwa-banner-v2-cajetin,
  .ef-pwa-banner-v2-icono-halo { animation: none; }
}

/* 30-ago (Seba, dictado): banner-globo para quien aterriza en /mapa sin
   haber completado ninguna jornada todavía ("una amiga empezó a explorar
   la web del tirón" y no tenía claro por dónde arrancar) — llamativo, con
   flecha roja, señalando directamente a "Empezar mi camino". Se pinta
   SOLO server-side (gateado en mapa.php por $yaEmpezoElCamino), así que no
   hace falta localStorage ni lógica de cierre: en cuanto completa su
   primera jornada, deja de verse solo. El botón en sí reutiliza
   .ef-guia-resaltado (ya existente, guía de subir vídeo de presentación)
   para el contorno rojo pulsante que pidió Seba ("rodeado por una línea
   roja, señalado"). */
.ef-cta-primeriza-globo {
  position: relative;
  display: table;
  margin: 4px auto 22px;
  padding: 14px 20px;
  border-radius: var(--ef-radio);
  background: linear-gradient(135deg, color-mix(in srgb, var(--ef-guia-rojo) 22%, var(--ef-fondo-2)) 0%, var(--ef-fondo-2) 70%);
  border: 2px solid var(--ef-guia-rojo);
  color: var(--ef-crema);
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 16px;
  text-align: center;
  line-height: 1.35;
  animation: ef-cta-primeriza-pulso 1.6s ease-in-out infinite;
}
.ef-cta-primeriza-flecha {
  position: absolute;
  left: 50%;
  bottom: -14px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 14px solid transparent;
  border-right: 14px solid transparent;
  border-top: 16px solid var(--ef-guia-rojo);
  animation: ef-cta-primeriza-flecha-rebote 1.2s ease-in-out infinite;
}
@keyframes ef-cta-primeriza-pulso {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ef-guia-rojo) 55%, transparent); }
  50% { box-shadow: 0 0 0 10px color-mix(in srgb, var(--ef-guia-rojo) 0%, transparent); }
}
@keyframes ef-cta-primeriza-flecha-rebote {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(5px); }
}
@media (prefers-reduced-motion: reduce) {
  .ef-cta-primeriza-globo,
  .ef-cta-primeriza-flecha { animation: none; }
}
/* 31-ago (Seba): el boton "Empezar mi camino" quedaba centrado bajo la
   flecha en movil (donde el globo es casi todo el ancho de pantalla),
   pero en ordenador la flecha (centrada en el globo, ya centrado en su
   propio ancho desde el cambio de arriba) no coincidia con el boton
   (que antes se quedaba pegado a la izquierda). Selector de hermano
   directo -- el boton solo esta justo despues del globo en este estado
   concreto (primera visita), asi que no afecta a ef-btn-hero en el
   resto de pantallas que lo reutilizan. */
.ef-cta-primeriza-globo + .ef-btn-hero {
  display: table;
  margin-left: auto;
  margin-right: auto;
}

/* 30-ago (mas tarde): "bajate la app" como hipervínculo real dentro del
   parrafo de movil/ordenador -- mas grande, en naranja corporativo,
   subrayado, para que destaque claramente como algo pulsable dentro del
   texto normal. */
.ef-intro-bordon-bajar-app {
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  text-decoration: none;
}
/* 31-ago (Seba): en ordenador se veia raro como hipervinculo suelto
   dentro del parrafo -- ahi que no destaque, texto normal, sin color
   propio ni subrayado. En movil se queda como estaba arriba (confirmado
   que ahi si funciona bien como aviso pulsable) -- mismo corte de 600px
   que ya usa el resto de la hoja (.ef-btn-hero, etc.) para movil. */
@media (max-width: 600px) {
  .ef-intro-bordon-bajar-app {
    font-size: 1.15em;
    font-weight: 800;
    color: var(--ef-naranja-claro);
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  .ef-intro-bordon-bajar-app:hover { color: var(--ef-dorado); }
}

/* 30-ago: linea de contacto por incidencias tecnicas, en Mi ficha, justo
   debajo de "Gestionar mi suscripcion"/"Salir". */
/* 31-ago (Seba): se veia demasiado pequeña, sobre todo en ordenador --
   sube el tamaño en ambos (movil y ordenador). */
.ef-ficha-contacto-incidencia {
  margin: 14px 0 0;
  font-size: 16px;
  color: var(--ef-crema-tenue);
  text-align: center;
}
.ef-ficha-contacto-incidencia a { color: var(--ef-naranja-claro); }

/* 1-sep (Seba, resumen mensual mas atractivo): tarjetas de estadistica en
   grid (mismo espiritu que Duolingo/Strava), en vez de filas de
   icono+texto plano. Reutiliza .ef-card-destacada para las sugerencias
   (Reto/Comunidad) en vez de inventar un componente nuevo. */
.ef-resumen-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 12px;
  margin: 18px 0;
}
.ef-resumen-stat {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 16px 14px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.ef-resumen-stat-icono { color: var(--ef-dorado); margin-bottom: 2px; }
.ef-resumen-stat-num { font-size: 22px; color: var(--ef-crema); }
.ef-resumen-stat-label { font-size: 12px; color: var(--ef-crema-tenue); line-height: 1.3; }

.ef-resumen-camino { margin: 22px 0 18px; }
.ef-resumen-camino-texto { margin: 0 0 10px; font-size: 15px; }

.ef-resumen-comparacion {
  font-size: 14px;
  color: var(--ef-crema-tenue);
  margin: 0 0 18px;
}

.ef-resumen-sugerencias {
  display: grid;
  gap: 12px;
  margin: 18px 0;
}
a.ef-resumen-sugerencia {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease;
}
a.ef-resumen-sugerencia:hover { border-color: var(--ef-dorado); }
a.ef-resumen-sugerencia p { margin: 6px 0 0; color: var(--ef-crema-tenue); font-size: 14px; }
