:root {
  --primary: #0A417A;
  --primary-dark: #0A417A;
  --accent: #2085EC;
  --accent-dark: #0A417A;
  --accent-light: #72B4EB;
  --accent-bg: #F0F5FC;
  --purple: #8464A0;
  --secondary: #CEA9BC;
  --secondary-bg: #F8EEF3;
  --bg: #f5f6fb;
  --card-bg: #ffffff;
  --text: #323232;
  --muted: #6b7280;
  --success: #16a34a;
  --danger: #dc2626;
  --border: #e5e7eb;
  --font-display: 'Baloo 2', -apple-system, BlinkMacSystemFont, sans-serif;
}

* { box-sizing: border-box; }

/* Sin esto, Safari/iOS pinta un recuadro gris translucido encima de
   cualquier boton/enlace al tocarlo (el "tap highlight" por defecto) --
   sobre un fondo ya de color (los nuevos degradados morado/rosa/verde/
   coral) eso deslava el texto y lo hace dificil de leer justo en el
   momento de tocarlo (reportado por el usuario con una captura real de
   iPhone, 2026-09-16). Los botones que ya tenian su propio ":active"
   (escala 0.98, etc.) siguen dando feedback al tacto igual que antes --
   esto solo quita el recuadro gris feo encima. */
button, a, label { -webkit-tap-highlight-color: transparent; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  padding-bottom: 2rem;
}

.app-header {
  position: relative;
  background: linear-gradient(135deg, var(--accent), var(--primary));
  color: white;
  padding: 2rem 1.25rem 1.5rem;
  text-align: center;
}

.lang-select-wrapper {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.4);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lang-select-flag {
  font-size: 1.3rem;
  line-height: 1;
  pointer-events: none;
}
.lang-select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: none;
  padding: 0;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}
.lang-select option {
  color: var(--text);
  font-size: 1rem;
  text-indent: 0;
}

.app-logo { display: block; margin: 0 auto 0.4rem; cursor: pointer; }
.app-logo-ring { transform-origin: 32px 32px; }
.app-logo-ring.spin { animation: omira-logo-spin 900ms ease-in-out; }
@keyframes omira-logo-spin { to { transform: rotate(720deg); } }
@media (prefers-reduced-motion: reduce) {
  .app-logo-ring.spin { animation: none; }
}

/* Transicion sutil al cambiar de pantalla (2026-09-18, boceto aprobado por el
   usuario). Las 8 vistas de nivel superior (#view-home, #app-content, etc.)
   comparten esta clase; switchView() solo alterna la clase "hidden"
   (display:none) entre ellas, nunca las anima directamente -- no hace falta:
   al quitar display:none la animacion se reinicia sola cada vez que una
   vista vuelve a mostrarse, es el comportamiento normal del navegador. */
.view-panel { animation: view-fade-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1); }
@keyframes view-fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .view-panel { animation: none; }
}
.app-header h1 { margin: 0; font-size: 1.85rem; font-family: var(--font-display); font-weight: 700; letter-spacing: 0.01em; }
.app-header p { margin: 0; opacity: 0.9; font-size: 0.95rem; }
.card h2 { font-family: var(--font-display); font-weight: 700; }

.user-bar {
  margin-top: 0.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
  opacity: 0.95;
}
.user-bar button {
  background: rgba(255,255,255,0.15);
  color: white;
  border: 1px solid rgba(255,255,255,0.4);
  border-radius: 8px;
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
  cursor: pointer;
}

/* Iconos fijos, sin deslizar (2026-09-17, "opcion B" del boceto -- pedido
   explicito del usuario tras probar las pastillas deslizables). Las 7
   caben siempre en una sola linea (flex:1 en cada boton reparte el ancho
   entero); el texto solo aparece en la pestana activa, para no obligar a
   memorizar iconos sin agobiar el espacio el resto del tiempo. */
.registered-nav {
  position: relative;
  background: var(--card-bg);
  display: flex;
  justify-content: space-between;
  gap: 0.2rem;
  padding: 0.6rem 0.5rem;
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
/* Indicador deslizante (2026-09-18, boceto aprobado): en vez de que la
   tinta de la pestana activa aparezca/desaparezca de golpe en cada boton,
   un unico indicador flotante se desliza de una posicion a otra y cambia
   de color por el camino -- switchView() en app.js calcula su posicion
   (indice de la pestana activa entre las 7) y su color. Vive DETRAS de los
   botones (z-index 0 contra el 1 de .nav-btn), asi que estos siguen
   pudiendo pulsarse con normalidad encima. */
.nav-indicator {
  position: absolute;
  top: 0.6rem;
  bottom: 0.6rem;
  left: 0.5rem;
  width: calc((100% - 1rem) / 7);
  border-radius: 12px;
  z-index: 0;
  /* Tinta por defecto = la de "Generar test", la pestana activa en el HTML
     de partida -- evita un instante sin color antes de que switchView() se
     ejecute la primera vez. */
  background: #EAF2FC;
  transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1), background-color 320ms ease;
}
.nav-btn {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  background: none;
  color: var(--muted);
  border: none;
  border-radius: 12px;
  padding: 0.4rem 0.15rem;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1.1;
  cursor: pointer;
  font-family: inherit;
  z-index: 1;
  /* Rebote tactil (2026-09-18, boceto aprobado): :active encoge rapido: al
     soltar, esta transicion (con curva "back") lo trae de vuelta con un
     ligero rebote en vez de pararse en seco. El color tambien se cruza
     suave con la transicion del indicador que se desliza por detras. */
  transition: transform 380ms cubic-bezier(0.34, 1.56, 0.64, 1), color 260ms ease;
}
.nav-btn:active { transform: scale(0.86); transition: transform 90ms ease-out; }
.nav-btn svg { width: 18px; height: 18px; flex: none; }
/* :not() excluye la insignia de repasos pendientes -- solo la etiqueta de
   texto se oculta hasta que la pestana esta activa, la insignia tiene que
   verse siempre. */
.nav-btn span:not(.nav-badge) { display: none; white-space: nowrap; }
.nav-btn.active span:not(.nav-badge) { display: block; }
/* Color de la pestana activa (2026-09-15, ampliado 2026-09-17): antes
   siempre el mismo rosa fijo sin importar la seccion -- ahora toma el color
   propio de la pantalla en la que estas (mismo par usado en las cabeceras
   de configuracion), asi la barra tambien ayuda a ubicarte. En la opcion B
   el fondo activo es una tinta suave (--gtint), no un degradado solido --
   el icono ya lleva ese mismo tono en reposo (ver mas abajo), aqui solo se
   oscurece un poco (--g2) para marcar cual esta activa. */
#nav-test-btn.active,
#nav-profile-btn.active { color: #0A417A; }
#nav-review-btn.active { color: #5b4370; }
#nav-study-plan-btn.active { color: #1f4f46; }
#nav-documents-btn.active { color: #6c3853; }
#nav-stats-btn.active { color: #8f2f35; }
#nav-plans-btn.active { color: #8a5f12; }

/* Icono con el color propio de su seccion, incluso en reposo (2026-09-16,
   pedido por el usuario: "incluso si le das un tono de color a la linea
   del dibujo... mejor"). Solo cuando NO esta activa -- la pestana activa ya
   fija su propio color mas oscuro arriba, heredado por el icono via
   currentColor. */
#nav-test-btn:not(.active) svg,
#nav-profile-btn:not(.active) svg { color: #2085EC; }
#nav-review-btn:not(.active) svg { color: #8464A0; }
#nav-study-plan-btn:not(.active) svg { color: #2F7A6B; }
#nav-documents-btn:not(.active) svg { color: #A6567F; }
#nav-stats-btn:not(.active) svg { color: #E1585F; }
#nav-plans-btn:not(.active) svg { color: #D99A2B; }

/* Insignias (numero de repasos pendientes, "Nuevo" de Plan de estudio):
   antes vivian en linea junto al texto, pero en la opcion B el texto se
   oculta salvo en la pestana activa -- pasan a una insignia suelta sobre
   la esquina del icono, visible siempre. */
.nav-badge {
  position: absolute;
  top: 0.1rem;
  right: 0.35rem;
  background: var(--purple);
  color: white;
  border-radius: 999px;
  min-width: 14px;
  padding: 0 0.25rem;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1.4;
}
/* Casillas del home a color (2026-09-15, pedido por el usuario tras ver el
   boceto: extiende a esta pantalla el mismo lenguaje de color por tipo ya
   usado en las pantallas de eleccion/configuracion -- una tinta suave por
   funcion en vez del azul/morado plano de antes. Los ids/clases que ya lee
   el JS (.home-tile, .badge, .lock-hint, .locked) se mantienen igual, solo
   cambia el aspecto visual). */
/* Fondo con textura sutil (2026-09-18, boceto aprobado): 3 manchas grandes,
   muy difuminadas y de opacidad muy baja, moviendose despacio detras de
   las casillas -- nada que distraiga, solo que Home no se sienta tan plano
   y blanco. #view-home necesita position:relative para que esto quede
   detras de su contenido (orden de documento normal, sin z-index). */
#view-home { position: relative; overflow: hidden; }
.home-bg-texture { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.home-bg-blob { position: absolute; border-radius: 50%; filter: blur(40px); }
.home-bg-blob-1 { width: 260px; height: 260px; top: -60px; left: -80px; background: #2085EC; opacity: 0.07; animation: home-bg-drift-1 22s ease-in-out infinite alternate; }
.home-bg-blob-2 { width: 220px; height: 220px; top: 220px; right: -90px; background: #E1585F; opacity: 0.06; animation: home-bg-drift-2 26s ease-in-out infinite alternate; }
.home-bg-blob-3 { width: 200px; height: 200px; bottom: -70px; left: 40px; background: #D99A2B; opacity: 0.06; animation: home-bg-drift-3 19s ease-in-out infinite alternate; }
@keyframes home-bg-drift-1 { from { transform: translate(0,0); } to { transform: translate(30px, 40px); } }
@keyframes home-bg-drift-2 { from { transform: translate(0,0); } to { transform: translate(-25px, -30px); } }
@keyframes home-bg-drift-3 { from { transform: translate(0,0); } to { transform: translate(20px, -35px); } }
@media (prefers-reduced-motion: reduce) {
  .home-bg-blob { animation: none; }
}

/* 2026-09-18: mismo fondo con textura de Home, extendido al resto de vistas
   principales -- mismas posiciones/tamanos/animaciones (reutilizadas tal
   cual via las clases genericas .view-bg-blob-N), pero cada pantalla tinta
   sus 3 manchas con SU PROPIO color de seccion (el mismo que ya usa el icono
   de esa pestana en reposo), en vez de reutilizar los 3 colores de Home. Con
   un unico tono por pantalla no hay 3 colores distintos que combinar, asi
   que las 3 manchas del mismo color se diferencian solo por opacidad. */
.view-bg-texture { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.view-bg-blob { position: absolute; border-radius: 50%; filter: blur(40px); }
.view-bg-blob-1 { width: 260px; height: 260px; top: -60px; left: -80px; opacity: 0.07; animation: home-bg-drift-1 22s ease-in-out infinite alternate; }
.view-bg-blob-2 { width: 220px; height: 220px; top: 220px; right: -90px; opacity: 0.05; animation: home-bg-drift-2 26s ease-in-out infinite alternate; }
.view-bg-blob-3 { width: 200px; height: 200px; bottom: -70px; left: 40px; opacity: 0.06; animation: home-bg-drift-3 19s ease-in-out infinite alternate; }
@media (prefers-reduced-motion: reduce) {
  .view-bg-blob { animation: none; }
}
#app-content, #view-documents, #view-study-plan, #view-stats, #view-plans, #view-profile, #view-review {
  position: relative;
  /* Bug real (2026-09-21): "overflow: hidden" aqui era para recortar los
     .view-bg-blob decorativos que sobresalen a proposito (ver sus top/left/
     right/bottom negativos mas abajo), pero de paso recortaba CUALQUIER
     contenido real mas alto que la vista (p.ej. el menu "Repetir/Eliminar"
     de un borrador cerca del final de una lista larga) de forma invisible Y
     sin poder hacer scroll para alcanzarlo -- un elemento en position:absolute
     que se sale de un antecesor con overflow:hidden queda fuera del area
     con scroll, no solo fuera de la vista. overflow-x basta para el recorte
     horizontal que de verdad hace falta (los blobs con left/right negativos);
     el eje vertical se deja libre.
  */
  overflow-x: hidden;
}
#view-documents .view-bg-blob { background: #A6567F; }
#view-study-plan .view-bg-blob { background: #2F7A6B; }
#view-stats .view-bg-blob { background: #E1585F; }
#view-plans .view-bg-blob { background: #D99A2B; }
#view-profile .view-bg-blob { background: #2085EC; }
#view-review .view-bg-blob { background: #8464A0; }
#app-content .view-bg-blob { background: #2085EC; }

.home-tiles {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.7rem;
  max-width: 420px;
  margin: 1.5rem auto 0;
  padding: 0 1rem;
}
.home-tile {
  position: relative;
  overflow: hidden;
  background: var(--accent-bg);
  color: var(--accent);
  border: none;
  border-radius: 16px;
  padding: 1.25rem 0.6rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  cursor: pointer;
}
.home-tile:active { transform: scale(0.98); }
.home-tile-deco { position: absolute; border-radius: 50%; background: #fff; opacity: 0.35; width: 56px; height: 56px; top: -16px; right: -12px; }
.home-tile-icon-wrap {
  width: 44px; height: 44px; border-radius: 50%; background: rgba(255,255,255,0.6);
  display: flex; align-items: center; justify-content: center; position: relative; z-index: 1;
}
.home-tile-icon-wrap svg { width: 20px; height: 20px; }
.home-tile span { font-size: 0.88rem; font-weight: 700; position: relative; z-index: 1; }

.home-tile-test        { background: #EAF2FC; color: #0A417A; }
.home-tile-studyplan   { background: #E9F2F0; color: #1f4f46; }
.home-tile-review      { background: #F1EDF6; color: #5b4370; }
.home-tile-documents   { background: #F6ECF1; color: #6c3853; }
.home-tile-stats       { background: #FBEBEC; color: #8f2f35; }
.home-tile-plans       { background: #FBF1DE; color: #8a5f12; }
.home-tile-test .home-tile-icon-wrap        { color: #2085EC; }
.home-tile-studyplan .home-tile-icon-wrap   { color: #2F7A6B; }
.home-tile-review .home-tile-icon-wrap      { color: #8464A0; }
.home-tile-documents .home-tile-icon-wrap   { color: #A6567F; }
.home-tile-stats .home-tile-icon-wrap       { color: #E1585F; }
.home-tile-plans .home-tile-icon-wrap       { color: #D99A2B; }

.home-tile .badge {
  position: relative;
  z-index: 1;
  align-self: flex-end;
  margin: -0.3rem -0.1rem 0.05rem auto;
  background: #fff;
  color: inherit;
  font-size: 0.62rem;
  font-weight: 700;
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.home-tile .lock-hint { display: none; position: relative; z-index: 1; }
.home-tile.locked { opacity: 0.6; }
.home-tile.locked .lock-hint {
  display: block;
  font-size: 0.65rem;
  font-weight: 600;
  color: inherit;
  opacity: 0.75;
  margin-top: -0.3rem;
}
/* Banner "hoy toca" (2026-09-15): pasa de un recuadro tintado plano a un
   degradado con puntos decorativos, mismo idioma que las cabeceras de
   configuracion -- es lo primero que se ve al abrir la app, conviene que
   destaque de verdad. */
.home-study-plan-banner {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 420px;
  background: linear-gradient(135deg, var(--accent), var(--primary));
  border: none;
  border-radius: 16px;
  padding: 0.9rem 1rem;
  margin: 1.1rem auto 0;
  cursor: pointer;
}
.home-study-plan-banner-deco { position: absolute; border-radius: 50%; background: #fff; opacity: 0.14; width: 60px; height: 60px; top: -20px; right: -14px; }
.home-study-plan-banner-icon {
  width: 34px;
  height: 34px;
  min-width: 34px;
  border-radius: 50%;
  background: rgba(255,255,255,0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
}
.home-study-plan-banner-icon svg { width: 17px; height: 17px; }
.home-study-plan-banner-text { min-width: 0; position: relative; z-index: 1; }
.home-study-plan-banner-label {
  font-size: 0.65rem;
  color: #fff;
  opacity: 0.85;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin: 0 0 2px;
}
.home-study-plan-banner-title {
  font-size: 0.8rem;
  font-weight: 600;
  color: #fff;
  margin: 0;
}

.days-per-week-picker {
  display: flex;
  gap: 0.4rem;
}
/* Mismo motivo de siempre con .hint (ver la regla general mas abajo en este
   archivo): #study-plan-days-hint sigue a esta fila de botones, no a un
   campo, asi que el margen negativo de .hint lo montaba encima de los
   botones de dias -- reportado por el usuario con una captura real de
   movil. */
#study-plan-days-hint { margin-top: 0.5rem; }
/* Mismo motivo otra vez: sigue a una fila de checkbox, no a un campo --
   comprobado con getBoundingClientRect() (no solo con una captura), daba un
   solape real de -1.6px, poco a simple vista pero real y dependiente del
   tamano de letra/zoom real del dispositivo. */
#study-plan-notify-hint { margin-top: 0.3rem; }
.day-count-btn {
  flex: 1;
  aspect-ratio: 1;
  border-radius: 10px;
  border: none;
  background: var(--accent-bg);
  color: var(--primary);
  font-weight: 700;
  cursor: pointer;
}
.day-count-btn.active { background: var(--accent); color: white; }
.study-plan-content-types {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

.study-plan-card {
  background: var(--card-bg);
  border: 1px solid var(--accent-light);
  border-radius: 14px;
  padding: 1rem;
  margin-bottom: 0.8rem;
  cursor: pointer;
}
.study-plan-card-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}
.study-plan-card-title-group { display: inline-flex; align-items: center; gap: 0.35rem; min-width: 0; }
.study-plan-card-title { font-weight: 700; color: var(--primary); }
/* Icono "hoy toca estudiar" (2026-09-13, pedido por el usuario) -- mismo
   ambar de aviso que el resto de la app, visible de un vistazo en la lista
   sin tener que abrir cada plan. */
.study-plan-card-due-icon { display: inline-flex; flex: none; color: #d97706; }
.study-plan-card-date {
  background: var(--accent-bg);
  color: var(--primary);
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
}
.study-plan-card-bar {
  height: 6px;
  background: var(--accent-bg);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 0.4rem;
}
.study-plan-card-bar-fill { height: 100%; background: var(--accent); }
.study-plan-card-progress { font-size: 0.75rem; color: var(--muted); margin: 0; }

.study-plan-session-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0.7rem 0.5rem;
  border-radius: 12px;
  cursor: pointer;
}
.study-plan-session-row.study-plan-session-today {
  background: var(--accent-bg);
  border: 1px solid var(--accent-light);
}
.study-plan-session-row.study-plan-session-done { opacity: 0.6; cursor: default; }
/* Las sesiones ya hechas tambien se pueden reabrir para repetirlas
   (2026-09-03, pedido explicito del usuario) -- se sobreescribe el
   "cursor: default" y se sube un poco la opacidad para que no lea como
   deshabilitada, sin perder la distincion visual frente a la de hoy. */
.study-plan-session-row.study-plan-session-done.study-plan-session-clickable { opacity: 0.85; cursor: pointer; }
.study-plan-future-summary { text-align: center; padding: 0.5rem; }
.study-plan-session-icon {
  width: 30px;
  height: 30px;
  min-width: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-bg);
  color: var(--accent);
}
.study-plan-session-icon svg { width: 15px; height: 15px; }
.study-plan-session-done .study-plan-session-icon { background: var(--accent); color: #fff; }
.study-plan-session-icon-flashcards { color: var(--purple); }
.study-plan-session-icon-summary { color: #A6567F; }
.study-plan-session-icon-podcast { color: #2F7A6B; }
.study-plan-session-info { min-width: 0; }
.study-plan-session-type { font-size: 0.85rem; font-weight: 600; color: var(--primary); margin: 0; }
.study-plan-session-done .study-plan-session-type { text-decoration: line-through; }
.study-plan-session-date { font-size: 0.72rem; color: var(--muted); margin: 0; }

/* Calendario del plan de estudio (2026-09-04) -- solo indica QUE dias hay
   actividad, sin tachar el tipo de sesion en los dias futuros. */
.study-plan-calendar-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin: 0.4rem 0 0.8rem;
}
.study-plan-calendar-nav-btn {
  background: var(--accent-bg);
  border: none;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  cursor: pointer;
}
.study-plan-calendar-nav-btn:disabled { opacity: 0.35; cursor: default; }
.study-plan-calendar-month-label { font-weight: 600; color: var(--primary); min-width: 9rem; text-align: center; text-transform: capitalize; }
.study-plan-calendar-weekdays, .study-plan-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.study-plan-calendar-weekdays { margin-bottom: 4px; }
.study-plan-calendar-weekday { text-align: center; font-size: 0.7rem; color: var(--muted); font-weight: 600; }
.study-plan-calendar-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  font-size: 0.85rem;
  color: var(--primary);
  position: relative;
}
.study-plan-calendar-day-empty { visibility: hidden; }
.study-plan-calendar-day-today { box-shadow: inset 0 0 0 1.5px var(--accent); }
.study-plan-calendar-day-done {
  background: var(--accent);
  color: #fff;
  text-decoration: line-through;
  cursor: pointer;
  opacity: 0.85;
}
.study-plan-calendar-day-active {
  background: var(--accent-bg);
  border: 1px solid var(--accent-light);
  font-weight: 700;
  cursor: pointer;
}
/* Dia futuro con sesion programada: se ve que hay actividad (puntito), pero
   NO es pulsable -- no adelantar al usuario que le toca ese dia (pedido
   explicito del usuario). */
.study-plan-calendar-day-future { color: var(--muted); cursor: default; }
.study-plan-calendar-day-future::after {
  content: '';
  position: absolute;
  bottom: 5px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent-light);
}
.study-plan-calendar-day-none { color: var(--muted); cursor: default; }

/* Cabecera: el avatar pasa a ser el acceso a Mi perfil (2026-09-01, sustituye
   a la antigua casilla grande de la home). */
.header-avatar-btn { border: none; padding: 0; cursor: pointer; }

/* Recorte circular del avatar (2026-09-01, pedido explicito del usuario: el
   paso tipico de arrastrar/hacer zoom a una foto antes de dejarla como foto
   de perfil). Mismo patron de overlay a pantalla completa que ya usa el
   onboarding (position:fixed + fondo oscuro + tarjeta centrada). */
.avatar-crop-overlay {
  position: fixed;
  inset: 0;
  z-index: 600;
  background: rgba(10, 65, 122, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.avatar-crop-overlay.hidden { display: none; }
.avatar-crop-card {
  width: 100%;
  max-width: 360px;
  background: var(--card-bg);
  border-radius: 20px;
  padding: 1.25rem;
  text-align: center;
}
.avatar-crop-card h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.avatar-crop-stage {
  position: relative;
  width: 260px;
  height: 260px;
  margin: 0 auto;
  overflow: hidden;
  border-radius: 16px;
  background: #000;
  touch-action: none;
  cursor: grab;
}
.avatar-crop-stage:active { cursor: grabbing; }
#avatar-crop-img {
  position: absolute;
  top: 0;
  left: 0;
  max-width: none;
  transform-origin: top left;
  user-select: none;
  -webkit-user-drag: none;
}
.avatar-crop-mask {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}
.avatar-crop-zoom-row {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  margin: 1rem 0;
}
.avatar-crop-zoom-row input[type="range"] { flex: 1; }

/* Mi perfil, rediseño compacto (2026-09-01, pedido explicito del usuario:
   "quiero reducir la visual con botones, hacerla mas compacta e intuitiva").
   Reutiliza los mismos campos/IDs de siempre, solo cambia como se presentan:
   una lista de filas en vez de varias tarjetas grandes con titulo y texto. */
/* Cabecera-perfil (2026-09-15): el avatar pasa a superponerse sobre un
   degradado, como una mini portada -- .profile-avatar-row sube con margen
   negativo para quedar a caballo sobre .profile-hero (el mismo truco que un
   banner de perfil normal). El input de apodo sigue siendo el mismo campo
   real, solo centrado y con la tipografia de titulo. */
.profile-hero { position: relative; z-index: 0; overflow: hidden; height: 74px; background: linear-gradient(135deg, var(--g1), var(--g2)); }
/* Bug real (2026-09-13, visto y descrito directamente por el usuario: "la
   banda azul esta en una capa superior a la foto"): el avatar sube con
   margen negativo para superponerse sobre .profile-hero, pero sin una
   posicion+z-index explicitos quedaba pintado ANTES que la banda en algun
   contexto de apilamiento real (aunque vaya despues en el HTML), asi que la
   banda tapaba la parte de arriba de la foto -- exactamente el "corte por
   la banda superior" que se llevaba reportando todo este tiempo, y que
   nunca fue un problema de la foto en si (por eso ningun arreglo de
   orientacion/recorte lo solucionaba). */
.profile-identity-card .profile-avatar-row { position: relative; z-index: 1; justify-content: center; margin: -34px 0 0.7rem; }
.profile-avatar-row #profile-avatar { border: 3px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.18); }
.profile-avatar-row #profile-avatar {
  background-size: cover;
  background-position: center;
}
.profile-identity-card .profile-identity-info { text-align: center; padding: 0 1.25rem; margin-bottom: 1rem; }
.profile-identity-card .profile-nickname-input { text-align: center; font-family: var(--font-display); }
.profile-identity-card .profile-remove-avatar-btn { margin: 0 auto; }
.profile-identity-info { flex: 1; min-width: 0; }
.profile-nickname-input {
  width: 100%;
  border: none;
  background: transparent;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--primary);
  padding: 0;
  margin-bottom: 0.2rem;
}
.profile-nickname-input:focus { outline: none; border-bottom: 1px solid var(--accent); }
.profile-identity-info .hint { margin: 0; }
.profile-remove-avatar-btn {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.2rem 0;
  cursor: pointer;
}

.settings-list {
  background: var(--card-bg);
  border: 1px solid var(--border, #eee);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 1rem;
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid #f0f1f5;
  width: 100%;
  background: none;
  border-left: none;
  border-right: none;
  border-top: none;
  text-align: left;
  cursor: default;
}
.settings-list .settings-row:last-child { border-bottom: none; }
.settings-row label,
.settings-row > span { font-size: 0.88rem; font-weight: 600; color: var(--text); }
.settings-row select { width: auto; max-width: 55%; padding: 0.4rem; font-size: 0.85rem; }
.settings-row-stacked { flex-direction: column; align-items: stretch; }
.settings-row-stacked .birth-date-selects { margin-top: 0.5rem; }
.settings-row-toggle { cursor: pointer; }
.settings-row-toggle input[type="checkbox"] { width: 20px; height: 20px; flex-shrink: 0; }
.settings-row-link {
  color: var(--accent);
  font-weight: 600;
  cursor: pointer;
}
.settings-row-link::after { content: '\203A'; color: var(--muted); }
.settings-row-label-block { min-width: 0; }
.settings-row-label-block .hint { margin: 0.2rem 0 0; font-size: 0.72rem; }
.settings-row-action {
  background: none;
  border: none;
  color: var(--accent);
  font-weight: 700;
  font-size: 0.8rem;
  cursor: pointer;
  flex-shrink: 0;
}

/* Ajustes en rejilla (2026-09-15, pedido por el usuario tras ver el boceto:
   "mas pequenos/compactos/visuales" en vez de las filas apiladas de antes)
   -- mismo lenguaje que las tarjetas de "que quieres generar" del home,
   solo mas pequenas al ser acciones secundarias. El checkbox real de
   Recordatorio sigue existiendo (oculto), su estado on/off se ve con una
   insignia via :has(), mismo truco ya usado en los chips de tipo de
   pregunta -- cero JS nuevo. */
.settings-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.6rem; margin-bottom: 1rem; }
.settings-tile {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.45rem;
  background: var(--gtint); border: none; border-radius: 14px; padding: 0.85rem 0.4rem;
  text-align: center; font-family: inherit; color: var(--text); text-decoration: none; cursor: pointer;
}
.settings-tile input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.settings-tile-icon { width: 36px; height: 36px; border-radius: 50%; background: #fff; color: var(--g2); display: flex; align-items: center; justify-content: center; }
.settings-tile span.stitle { font-weight: 700; font-size: 0.74rem; line-height: 1.15; }
.settings-tile-badge { display: none; position: absolute; top: 0.5rem; right: 0.5rem; width: 16px; height: 16px; border-radius: 50%; background: var(--g1); color: #fff; align-items: center; justify-content: center; }
.settings-tile:has(input:checked) .settings-tile-badge { display: flex; }

.profile-danger-card { text-align: center; }
.danger-link-btn {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 0.8rem;
  text-decoration: underline;
  cursor: pointer;
}

.study-choice-options {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}
.stats-summary {
  display: flex;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.stat-tile {
  flex: 1;
  background: var(--gtint, var(--accent-bg));
  border-radius: 12px;
  padding: 1rem;
  text-align: center;
}
.stat-number {
  display: block;
  font-size: 1.6rem;
  font-weight: 700;
  font-family: var(--font-display);
  color: var(--g2, var(--primary-dark));
}
.stat-label {
  display: block;
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 0.2rem;
}
.stat-tile-hero {
  background: var(--accent);
}
.stat-tile-hero .stat-number,
.stat-tile-hero .stat-label {
  color: white;
}

.reinforce-badge {
  background: var(--accent-bg);
  border: 1px solid var(--primary);
  border-radius: 10px;
  padding: 0.5rem 0.75rem;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.reinforce-badge button {
  background: transparent;
  border: none;
  font-size: 1.1rem;
  cursor: pointer;
  color: var(--primary-dark);
}

.topic-row {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}
.topic-row-main {
  display: flex;
  justify-content: space-between;
  width: 100%;
}
.reinforce-btn {
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: 8px;
  padding: 0.3rem 0.6rem;
  font-size: 0.8rem;
  cursor: pointer;
}
.document-picker {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.mode-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.mode-btn {
  flex: 1;
  min-width: 45%;
  padding: 0.6rem;
  border-radius: 10px;
  border: none;
  background: var(--accent-bg);
  color: var(--primary);
  font-weight: 600;
  cursor: pointer;
}
.mode-btn.active {
  background: var(--accent);
  color: white;
}
/* Fallo real encontrado 2026-09-16 (captura de iPhone del usuario: "no se
   aprecia el texto" en "Configurar flashcards"): este bloque entero era de
   ANTES del rediseno de anoche, cuando #generate-btn/#configure-content-btn/
   #configure-podcast-btn/etc. eran botones de contorno (.secondary-btn) y
   estas reglas por id+data-mode les pintaban el texto/fondo del color del
   tipo activo. Anoche esos botones pasaron a .fc-primary-pill-block (relleno
   solido, texto blanco) y .fc-link-btn-block, que ya toman su color de
   --g1/--g2 del .fc-color-card ambiente -- pero estas reglas viejas, al ir
   por id, seguian ganando en especificidad y pisaban el color nuevo: el
   texto blanco de "Configurar flashcards" se volvia var(--purple), el mismo
   tono que el fondo, practicamente invisible. Eliminadas por completo, ya
   no aportan nada y solo estorban. */

.flashcard {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 2rem 1.25rem;
  text-align: center;
  min-height: 160px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  background: var(--accent-bg);
}
.flashcard-topic {
  font-size: 0.8rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.flashcard-text {
  font-size: 1.05rem;
  font-weight: 600;
}
.flashcard-back {
  color: var(--primary-dark);
  font-weight: 500;
}
.flashcard-nav {
  display: flex;
  gap: 0.6rem;
  margin-top: 0.9rem;
}
.flashcard-nav button {
  flex: 1;
}

/* Cuadro de flashcards centrado y superpuesto (2026-09-10). Nombres de clase
   nuevos a proposito (fc-*) -- .flashcard/.flashcard-topic/.flashcard-text/
   .flashcard-back de arriba los sigue usando tal cual la pantalla de Repasar
   (#review-card y companeros en index.html), no se tocan. */
.flashcards-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(10,65,122,0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.2rem;
}
.flashcards-overlay-card {
  width: 100%;
  max-width: 380px;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--card-bg);
  border-radius: 22px;
  box-shadow: 0 24px 48px rgba(10,65,122,0.35);
  margin: auto;
}
.flashcards-overlay-head {
  position: relative;
  overflow: hidden;
  border-radius: 22px 22px 0 0;
  padding: 1.3rem 1.3rem 1.1rem;
  background: linear-gradient(160deg, var(--purple), #5b4370);
  text-align: center;
  color: #fff;
}
.fc-deco { position: absolute; border-radius: 50%; opacity: 0.14; background: #fff; }
.fc-deco-1 { width: 110px; height: 110px; top: -35px; right: -28px; }
.fc-deco-2 { width: 65px; height: 65px; bottom: -18px; left: -18px; }
.fc-head-icon {
  width: 44px; height: 44px; border-radius: 50%; margin: 0 auto 0.5rem;
  background: rgba(255,255,255,0.22); display: flex; align-items: center; justify-content: center;
  position: relative; z-index: 1;
}
.fc-head-counter { font-family: var(--font-display); font-weight: 700; font-size: 1rem; position: relative; z-index: 1; }
.fc-head-track {
  width: 100%; max-width: 200px; height: 4px; border-radius: 4px; background: rgba(255,255,255,0.28);
  margin: 0.6rem auto 0; position: relative; z-index: 1; overflow: hidden;
}
.fc-head-fill { height: 100%; background: #fff; border-radius: 4px; transition: width 0.25s ease; }

.flashcards-overlay-body { padding: 1.3rem 1.2rem 1.2rem; }

.fc-viewer { display: flex; align-items: center; gap: 0.5rem; }
.fc-arrow-btn {
  flex: none; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border); background: #fff;
  display: flex; align-items: center; justify-content: center; color: var(--purple); cursor: pointer; padding: 0;
}
.fc-arrow-btn:disabled { opacity: 0.3; cursor: default; }

.fc-flip-scene { flex: 1; position: relative; perspective: 1000px; min-height: 190px; max-height: min(320px, 42vh); cursor: pointer; }
.fc-flip-card {
  position: relative; width: 100%; height: 100%; min-height: 190px;
  transition: transform 0.5s cubic-bezier(0.4,0.2,0.2,1); transform-style: preserve-3d;
}
.fc-flip-card.fc-is-flipped { transform: rotateY(180deg); }
/* Bug real reportado por el usuario (2026-09-11, captura de un contrato de
   alquiler con una respuesta larga): el texto se salia por fuera de la
   tarjeta porque esta caja tenia una altura fija sin scroll propio. Ahora
   el texto largo se desplaza DENTRO de su propia cara en vez de invadir el
   resto del cuadro. */
/* Bug real (2026-09-12): con justify-content:center, un texto largo que
   necesitaba scroll aparecia centrado en el MEDIO en vez de empezar por el
   principio -- el usuario tenia que darse cuenta de que podia subir el
   scroll. Truco real de flexbox (compatible en todos los navegadores, no
   una propiedad nueva): el contenido vive en un .fc-flip-face-inner con
   margin:auto -- se centra solo cuando sobra espacio, y en cuanto el
   contenido es mas alto que la cara, el margen se colapsa a 0 y el texto
   empieza justo arriba, visible desde el primer momento. */
.fc-flip-face {
  position: absolute; inset: 0; backface-visibility: hidden; border-radius: 16px; border: 1px solid var(--border);
  display: flex; flex-direction: column; text-align: center; padding: 1.1rem;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.fc-flip-face-inner { display: flex; flex-direction: column; align-items: center; gap: 0.6rem; margin: auto 0; width: 100%; }
.fc-flip-front { background: var(--accent-bg); }
.fc-flip-back { background: #F3EEF7; transform: rotateY(180deg); }
.fc-flip-topic { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.fc-flip-text { font-size: 1.02rem; font-weight: 600; line-height: 1.35; }
.fc-flip-hint { font-size: 0.72rem; color: var(--muted); }

.fc-edit-fab {
  position: absolute; top: 0.5rem; right: 0.5rem; z-index: 2; width: 28px; height: 28px; border-radius: 50%;
  background: #fff; border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; color: var(--muted); cursor: pointer; padding: 0;
}

.fc-editor { padding-top: 0.2rem; }

.fc-action-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-top: 1.1rem; }
/* Imprimir/Guardar (2026-09-11): "Descargar" se fundio dentro del cuadro de
   Imprimir (ver #fc-print-dialog-backdrop), asi que la fila real solo tiene
   2 acciones -- 2 columnas en vez de 3. */
.fc-action-row-2 { grid-template-columns: repeat(2, 1fr); }
.fc-action-row-1 { grid-template-columns: minmax(120px, 200px); justify-content: center; }
.fc-action-btn {
  display: flex; flex-direction: column; align-items: center; gap: 0.3rem; padding: 0.6rem 0.3rem;
  border-radius: 12px; border: 1px solid var(--border); background: #fafbff; color: var(--text); font-size: 0.72rem; font-weight: 600; cursor: pointer;
}
.fc-action-btn svg { color: var(--purple); }

/* Cuadros de "Imprimir" y "Guardar" (2026-09-11). z-index por encima de
   .result-modal-backdrop (50) a proposito: desde el 2026-09-11 el cuadro
   de resultado ya NO se cierra al pulsar "Guardar" (para poder guardar Y
   generar refuerzo sin perder ninguna de las dos), asi que el dialogo de
   guardar tiene que quedar POR ENCIMA de el, no debajo. */
.fc-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgba(10,65,122,0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.2rem;
}
.fc-dialog {
  width: 100%;
  max-width: 340px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--card-bg);
  border-radius: 20px;
  box-shadow: 0 20px 40px rgba(10,65,122,0.3);
  padding: 1.4rem 1.3rem;
}
.fc-dialog h3 {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text);
  text-align: center;
}
.fc-print-option {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
  width: 100%;
  text-align: left;
  background: #F8F7FC;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1rem;
  cursor: pointer;
  margin-bottom: 0.75rem;
}
.fc-print-option:last-of-type { margin-bottom: 0; }
.fc-print-option-icon {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--purple);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fc-print-option-title { display: block; font-weight: 700; font-size: 0.92rem; color: var(--text); margin-bottom: 0.25rem; }
.fc-print-option-desc { display: block; font-size: 0.78rem; color: var(--muted); line-height: 1.4; }
.fc-dialog-cancel {
  display: block;
  width: 100%;
  text-align: center;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  margin-top: 0.9rem;
  cursor: pointer;
  padding: 0.4rem;
}

.fc-footer-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-top: 1.2rem; }
.fc-link-btn { flex: none; background: none; border: none; color: var(--muted); font-size: 0.85rem; font-weight: 600; cursor: pointer; padding: 0.4rem; }
.fc-primary-pill {
  flex: none; background: var(--purple); color: #fff; border: none; border-radius: 999px; padding: 0.65rem 1.3rem;
  font-size: 0.88rem; font-weight: 700; cursor: pointer; margin-left: auto;
}
.fc-restart-link { display: block; width: 100%; text-align: center; margin-top: 0.4rem; }

/* Variantes de color (2026-09-12): el mismo patron de botones de
   flashcards (morado) reutilizado en resumen (rosa) y podcast (verde) --
   mismos acentos por tipo de contenido que ya se usan en el resto de la
   app (selector de modo, iconos de refuerzo...). */
.fc-action-btn-pink svg { color: #A6567F; }
.fc-action-btn-teal svg { color: #2F7A6B; }
.fc-action-btn-blue svg { color: var(--accent); }
.fc-action-btn-amber svg { color: #D99A2B; }
.fc-primary-pill-pink { background: #A6567F; }
.fc-primary-pill-teal { background: #2F7A6B; }
.fc-primary-pill-blue { background: var(--accent); }
.fc-primary-pill-amber { background: #D99A2B; }

/* "Leccion con pictogramas" (2026-09-18): navegacion bloque a bloque, mismo
   patron general que las flashcards pero con imagenes en vez de flip-card. */
.picto-counter { text-align: center; font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; color: #8a4f14; }
.picto-progress-track { width: 100%; max-width: 220px; height: 4px; border-radius: 4px; background: #F1E3C8; margin: 0.5rem auto 1rem; overflow: hidden; }
.picto-progress-fill { height: 100%; background: #D99A2B; border-radius: 4px; transition: width 0.25s ease; }
.picto-topic { text-align: center; font-weight: 700; color: #8a4f14; margin: 0 0 0.6rem; }
.picto-images-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.9rem; margin-bottom: 0.9rem; }
.picto-image-card { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; width: 100px; }
.picto-image-card img { width: 84px; height: 84px; object-fit: contain; background: #fff; border-radius: 14px; padding: 0.4rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.picto-image-card span { font-size: 0.78rem; font-weight: 600; color: var(--text); text-align: center; }
.picto-text { line-height: 1.55; color: var(--text); margin-bottom: 1rem; }
#picto-audio-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; }
#picto-audio { width: 100%; }

/* Banner tintado (2026-09-12) -- sustituye titulos de texto plano que ya no
   describian bien lo que hay debajo (ver #step-quiz-result: ya no se llama
   "Resultado", ese mensaje ya lo dio el cuadro central al corregir). */
.fc-inline-banner {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  border-radius: 12px; padding: 0.7rem 1rem; font-weight: 700; font-size: 0.9rem; margin-bottom: 1rem;
}
.fc-inline-banner-blue { background: var(--accent-bg); color: var(--accent-dark); }
.fc-inline-banner-blue svg { color: var(--accent); flex: none; }

/* Sistema de "cuadro de color" (2026-09-13, pedido por el usuario tras ver
   bocetos: "tantisimo blanco de fondo... jugar con los colores de los
   cuadros"). #fc-color-card lleva un data-mode que fija --g1/--g2/--gtint
   para TODO lo que hay dentro (cabecera, pastillas, chips, banner, boton
   "Generar") -- un solo sitio que cambiar por pantalla en vez de repetir el
   selector data-mode en cada componente. Mismos 2 tonos por tipo que ya usa
   el resto de la app (flashcards/resultado/etc.), ninguno nuevo. */
/* padding:0 (2026-09-15, fallo real encontrado al revisar esta pantalla de
   nuevo): .fc-color-card convive con la clase generica .card, que ya trae
   padding:1.25rem -- sin este reset, ese padding metia un margen blanco de
   20px alrededor de la cabecera de color, apenas visible pero real (medido
   con getBoundingClientRect, no solo a ojo), impidiendo que el degradado
   llegara a las esquinas redondeadas de verdad. .fc-color-head/.fc-color-body
   ya traen su propio padding, asi que el de .card sobraba por completo. */
.fc-color-card { background: var(--card-bg); border-radius: 16px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.08); padding: 0; }
.fc-color-card[data-mode="test"]       { --g1: #2085EC; --g2: #0A417A; --gtint: #EAF2FC; }
.fc-color-card[data-mode="flashcards"] { --g1: #8464A0; --g2: #5b4370; --gtint: #F1EDF6; }
.fc-color-card[data-mode="summary"]    { --g1: #A6567F; --g2: #6c3853; --gtint: #F6ECF1; }
.fc-color-card[data-mode="audio"]      { --g1: #2F7A6B; --g2: #1f4f46; --gtint: #E9F2F0; }
.fc-color-card[data-mode="tutor"]      { --g1: #2085EC; --g2: #0A417A; --gtint: #EAF2FC; }
/* Bug real (2026-09-18): faltaba esta regla para "picto" -- sin --g1/--g2
   definidos, el gradiente de fondo de .fc-primary-pill-block (el boton
   "Configurar leccion con pictogramas") quedaba invalido y se pintaba
   transparente con texto blanco: el boton existia y funcionaba, pero era
   invisible sobre fondo blanco. Un usuario real lo reporto como "el boton
   Pictogramas no hace nada" cuando en realidad el boton siguiente, ya
   desbloqueado, era el que no se veia. */
.fc-color-card[data-mode="picto"]      { --g1: #D99A2B; --g2: #8a4f14; --gtint: #FBF0E3; }
/* Extension del mismo sistema (2026-09-15) a pantallas que no son de
   generacion de contenido -- mismos tonos ya usados arriba salvo "stats",
   coral nuevo (no habia ningun tono rojizo todavia en la app). */
.fc-color-card[data-mode="profile"]    { --g1: #2085EC; --g2: #0A417A; --gtint: #EAF2FC; }
.fc-color-card[data-mode="documents"]  { --g1: #A6567F; --g2: #6c3853; --gtint: #F6ECF1; }
.fc-color-card[data-mode="review"]     { --g1: #8464A0; --g2: #5b4370; --gtint: #F1EDF6; }
.fc-color-card[data-mode="studyplan"]  { --g1: #2F7A6B; --g2: #1f4f46; --gtint: #E9F2F0; }
.fc-color-card[data-mode="stats"]      { --g1: #E1585F; --g2: #8f2f35; --gtint: #FBEBEC; }
.fc-color-card[data-mode="plans"]      { --g1: #D99A2B; --g2: #8a5f12; --gtint: #FBF1DE; }

.fc-color-head { position: relative; overflow: hidden; padding: 1.15rem 1.25rem 1.3rem; background: linear-gradient(135deg, var(--g1), var(--g2)); color: #fff; text-align: center; }
/* Icono redondo opcional encima del titulo (2026-09-15) -- usado en
   pantallas sin selector de tipo debajo (Plan de estudio), para que la
   cabecera no se quede vacia de contenido propio. */
.fc-head-icon { width: 46px; height: 46px; border-radius: 50%; background: rgba(255,255,255,0.2); display: flex; align-items: center; justify-content: center; margin: 0 auto 0.6rem; position: relative; z-index: 1; }
.fc-color-head h2 { margin: 0; font-size: 1.05rem; font-family: var(--font-display); font-weight: 700; position: relative; z-index: 1; }
.fc-head-deco { position: absolute; border-radius: 50%; background: #fff; opacity: 0.12; }
.fc-head-deco-1 { width: 90px; height: 90px; top: -30px; right: -20px; }
.fc-head-deco-2 { width: 50px; height: 50px; bottom: -18px; left: 30%; }
.fc-color-body { padding: 1.25rem; }
.fc-color-body .field-label { font-weight: 700; font-size: 0.85rem; margin: 0 0 0.6rem; color: var(--text); }

/* Fila de eleccion (2026-09-15): icono en circulo + titulo + flecha, mismo
   idioma visual que .text-summary-chip -- sustituye los botones planos de
   "Subir nuevo documento"/"Borradores"/"Repasa ahora"/etc. Cuando vive
   suelta (no dentro de un .fc-color-card) necesita su propio data-mode para
   fijar --g1/--g2/--gtint; dentro de un .fc-color-card los hereda solos. */
.fc-choice-row {
  display: flex; align-items: center; gap: 0.85rem; width: 100%;
  background: #fff; border: 1.5px solid var(--border); border-radius: 14px;
  padding: 0.85rem 0.95rem; text-align: left; margin-bottom: 0.9rem; font-family: inherit; cursor: pointer;
  /* Mismo rebote tactil que .nav-btn (2026-09-18, boceto aprobado) -- ver el
     comentario de ahi para el porque de la curva "back". */
  transition: transform 380ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.fc-choice-row:active { transform: scale(0.97); transition: transform 90ms ease-out; }
.fc-choice-icon { width: 42px; height: 42px; border-radius: 12px; background: var(--gtint); color: var(--g2); display: flex; align-items: center; justify-content: center; flex: none; }
.fc-choice-title { flex: 1; font-weight: 700; font-size: 0.92rem; color: var(--text); }
.fc-choice-sub { font-size: 0.78rem; color: var(--muted); }
.fc-choice-chevron { color: var(--muted); flex: none; }
.fc-choice-row[data-mode="documents"] { --g1: #A6567F; --g2: #6c3853; --gtint: #F6ECF1; }
.fc-choice-row[data-mode="review"]    { --g1: #8464A0; --g2: #5b4370; --gtint: #F1EDF6; }
.fc-choice-row[data-mode="stats"]     { --g1: #E1585F; --g2: #8f2f35; --gtint: #FBEBEC; }

/* Los <select> reales de num-preguntas/tarjetas, nivel de detalle,
   dificultad y precision del podcast se quedan en el DOM y siguen siendo
   la unica fuente de verdad (buildPillGroupFromSelect() en app.js lee y
   escribe su .value) -- solo se ocultan visualmente, las pastillas los
   sustituyen en pantalla. */
.fc-hidden-select { display: none; }

/* Tarjetas de "que quieres generar" (2026-09-13): sustituyen los botones de
   texto plano de .mode-toggle/.mode-btn. Cada tarjeta lleva su PROPIO color
   fijo (no el del data-mode del padre, que aqui no aplica -- conviven las 5
   a la vez) via variables puestas inline en el HTML; la seleccionada
   (.active, la misma clase que ya pone setMode() en app.js) pasa a
   degradado. */
.mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; margin-bottom: 1.1rem; }
.mode-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  padding: 1.1rem 0.6rem; border-radius: 16px; border: none; cursor: pointer;
  background: var(--tint); color: var(--dark); font-family: inherit;
}
.mode-card-icon {
  width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.7); color: var(--accentc); position: relative; z-index: 1;
}
.mode-card span { font-weight: 700; font-size: 0.88rem; position: relative; z-index: 1; }
.mode-card-tutor { grid-column: 1 / -1; flex-direction: row; justify-content: center; padding: 0.85rem; }
.mode-card.active { background: linear-gradient(160deg, var(--g1), var(--g2)); color: #fff; box-shadow: 0 10px 22px rgba(10,65,122,0.22); }
.mode-card.active .mode-card-icon { background: rgba(255,255,255,0.22); color: #fff; box-shadow: 0 0 0 8px rgba(255,255,255,0.12); }
.mode-deco { position: absolute; border-radius: 50%; background: #fff; opacity: 0.14; }
.mode-deco-1 { width: 60px; height: 60px; top: -18px; right: -14px; }
.mode-deco-2 { width: 34px; height: 34px; bottom: -10px; left: -8px; }

/* Pastillas para menus que antes eran <select> nativos (numero de
   preguntas/tarjetas, nivel de detalle, precision del podcast). El <select>
   real sigue existiendo (oculto) como unica fuente de verdad -- las
   pastillas solo lo reflejan/actualizan, ver buildPillGroupFromSelect() en
   app.js. */
.pill-scroll { display: flex; gap: 0.5rem; overflow-x: auto; margin: 0 -1.25rem 1.1rem; padding: 0.15rem 1.25rem 0.3rem; }
.pill-choice { flex: none; padding: 0.55rem 1rem; border-radius: 999px; border: 1.5px solid var(--border); background: #fff; font-weight: 700; font-size: 0.9rem; color: var(--text); cursor: pointer; font-family: inherit; }
.pill-choice.is-active { background: linear-gradient(135deg, var(--g1), var(--g2)); border-color: transparent; color: #fff; box-shadow: 0 4px 10px rgba(10,65,122,0.22); }

/* Chips para los checkboxes de "tipos de pregunta" -- el checkbox real
   sigue ahi (position:absolute, invisible), :has(input:checked) es lo que
   pinta el chip activo, sin JS nuevo para esto. */
.chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.1rem; }
.type-chip-label { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.85rem; border-radius: 999px; border: 1.5px solid var(--border); background: #fff; font-weight: 600; font-size: 0.85rem; color: var(--muted); cursor: pointer; }
.type-chip-label input { position: absolute; opacity: 0; width: 0; height: 0; }
.type-chip-label .chip-check { display: none; color: var(--g1); flex: none; }
.type-chip-label:has(input:checked) { background: var(--gtint); border-color: var(--g1); color: var(--g2); }
.type-chip-label:has(input:checked) .chip-check { display: inline-flex; }

.diff-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-bottom: 1.1rem; }
.diff-pill { padding: 0.7rem 0.4rem; border-radius: 12px; border: 1.5px solid var(--border); background: #fff; font-weight: 700; font-size: 0.85rem; text-align: center; color: var(--muted); cursor: pointer; font-family: inherit; }
.diff-pill.is-active { background: linear-gradient(135deg, var(--g1), var(--g2)); border-color: transparent; color: #fff; box-shadow: 0 4px 10px rgba(10,65,122,0.22); }

.fc-color-banner { display: flex; align-items: center; justify-content: center; gap: 0.5rem; background: var(--gtint); color: var(--g2); border-radius: 12px; padding: 0.7rem 1rem; font-weight: 700; font-size: 0.85rem; margin-bottom: 1.1rem; text-align: center; }
.fc-color-banner svg { color: var(--g1); flex: none; }

.fc-primary-pill-block {
  display: block; width: 100%; text-align: center; color: #fff; border: none; border-radius: 999px; padding: 0.85rem; font-size: 0.95rem; font-weight: 700;
  background: linear-gradient(135deg, var(--g1), var(--g2));
  /* Sombra teñida del color propio de cada pantalla (2026-09-16) en vez de
     un azul fijo que desentonaba en morado/rosa/verde/coral -- color-mix
     necesita Safari 16.2+, ya asumido por :has() en otro sitio de este
     mismo archivo; la declaracion de arriba sirve de respaldo si el
     navegador no entiende color-mix (la ignora entera y se queda con esta). */
  box-shadow: 0 8px 16px rgba(10,65,122,0.22);
  box-shadow: 0 8px 16px color-mix(in srgb, var(--g2) 28%, transparent);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.fc-primary-pill-block:active { transform: scale(0.98); }
.fc-link-btn-block { display: block; width: 100%; text-align: center; background: none; border: none; color: var(--muted); font-size: 0.9rem; font-weight: 600; padding: 0.6rem; margin-top: 0.5rem; cursor: pointer; -webkit-tap-highlight-color: transparent; }

.audio-segment-image-wrap {
  width: 100%;
  max-width: 240px;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  /* Bug real reportado por un tester (2026-09-05), sobre todo visible en
     movil: sin esto, un bloque de ancho maximo fijo dentro de un contenedor
     mas ancho (la tarjeta de #step-audio) se queda pegado a la izquierda en
     vez de centrado. Unico uso actual: la portada del podcast. */
  margin: 0 auto;
}
.audio-segment-image { width: 100%; height: 100%; object-fit: cover; }
.hint.audio-segment-image-error { margin: 0; padding: 0.5rem; color: var(--danger); }

#podcast-box { margin-top: 1rem; }
#podcast-audio { width: 100%; margin-bottom: 0.6rem; }
/* Mismo motivo de siempre con .hint (ver mas abajo): este .hint sigue al
   reproductor <audio>, no a un campo, asi que el margen negativo de .hint lo
   montaria encima de los controles nativos. Se previene desde ya. */
#podcast-duration-hint { margin-top: 0.5rem; }
/* Ya no es un enlace de ancho completo (2026-09-12, ver .fc-action-btn) --
   solo hace falta quitarle el subrayado de <a>, el layout lo pone la clase. */
#podcast-download-link { text-decoration: none; }
#podcast-config-progress { display: block; margin: 0.6rem auto; text-align: center; }
#podcast-legacy-box { text-align: left; }
#podcast-legacy-box .flashcard-topic { margin-top: 0.8rem; font-weight: 600; }

.topic-row, .recent-row {
  display: flex;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

/* Carrusel horizontal de resumen (2026-09-10): sustituye los bloques
   apilados de antes -- ver renderSummary() en app.js. */
.summary-carousel {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  margin: 0 -1.25rem;
  padding: 0.15rem 1.25rem 0.6rem;
  scrollbar-width: none;
}
.summary-carousel::-webkit-scrollbar { display: none; }
.summary-point {
  flex: 0 0 76%;
  scroll-snap-align: center;
  border-radius: 16px;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 4px 14px rgba(10,65,122,0.08);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.summary-point-topic {
  background: linear-gradient(135deg, #A6567F, #6c3853);
  color: #fff;
  padding: 0.8rem 1rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.summary-point-text {
  padding: 1rem;
  font-size: 0.95rem;
  line-height: 1.45;
  flex: 1;
}
/* Un punto sin topic (raro, pero renderSummary lo contempla) se queda sin
   banda de color -- que el texto no se pegue al borde superior. */
.summary-point-text:first-child { padding-top: 1rem; }

.summary-swipe-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  color: var(--muted);
  font-size: 0.78rem;
  margin: 0 0 0.9rem;
}
.summary-dots { display: flex; justify-content: center; gap: 6px; margin: -0.4rem 0 0.9rem; }
.summary-dot {
  width: 6px; height: 6px; border-radius: 3px; background: var(--border); cursor: pointer;
  transition: width 0.2s ease, background 0.2s ease; padding: 0; border: none;
}
.summary-dot.is-active { width: 18px; background: #A6567F; }


input[type="email"], input[type="password"], input[type="text"] {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  font-size: 1rem;
  font-family: inherit;
}

.password-wrap { position: relative; }
.password-wrap input { padding-right: 5rem; }
.password-toggle {
  position: absolute;
  right: 0.4rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 0.4rem 0.6rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--primary);
  cursor: pointer;
}

.container {
  max-width: 640px;
  margin: 0 auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.card {
  background: var(--card-bg);
  border-radius: 16px;
  padding: 1.25rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

.card h2 { margin-top: 0; font-size: 1.1rem; }
.hint { color: var(--muted); font-size: 0.9rem; margin-top: -0.5rem; }
/* Result/status messages reuse .hint for its muted small text, but they sit below a
   button rather than an input field, so the negative pull-up from .hint overlaps the
   button instead of hugging a field — override it back to normal spacing here. */
.hint.save-message { margin-top: 0.5rem; }
/* Same root cause as above: #review-back-btn is directly followed by .hint content
   (review-empty, or review-counter inside review-session) with no heading in between
   to absorb the negative margin-top, so the "Volver" button overlapped the review
   question/counter beneath it. */
#review-back-btn { margin-bottom: 1rem; }
/* Same root cause again: the "Política de privacidad" link sits right after the
   "Cancelar" button on the login/signup screen, with nothing to absorb .hint's
   negative margin-top, so the link overlapped the button above it. */
#auth-privacy-link { margin-top: 1rem; }
/* Mismo motivo otra vez: el nuevo texto "Solo por registrarte recibiras:"
   de la tarjeta Invitado/Registrados va justo debajo de .plan-price, sin
   ningun titulo entre medias que absorba el margen negativo de .hint. */
.hint.plan-free-intro { margin-top: 0.3rem; }
/* Mismo motivo de siempre: este .hint sigue al boton "Imprimir para el aula",
   no a un campo. */
#print-flashcards-classroom-hint { margin-top: 0.4rem; }
/* Mismo motivo de siempre (2026-09-05, bug real reportado con captura por el
   usuario): la explicacion de Borradores va justo debajo del boton
   "Borradores", no de un campo -- sin esto se solapaba con el boton. */
#drafts-section > .hint:first-child { margin-top: 0.6rem; }
/* 2026-08-30: los resumenes de configuracion bajo "Configurar podcast" /
   "Configurar test" (que sufrian este mismo problema, .hint pegado a un
   boton en vez de a un campo) se quitaron del todo a peticion del usuario
   (mostraban el ajuste del ultimo modo configurado, no el actual -- mas
   confuso que util). Se deja esta regla general: ningun .hint deberia
   solaparse con otro .hint inmediatamente anterior. */
.hint + .hint { margin-top: 0.4rem; }
/* 2026-08-30: el usuario reporto 3 veces seguidas que este texto concreto
   seguia solapandose, y las capturas de escritorio no lo mostraban -- medido
   de verdad con getBoundingClientRect() (no solo mirando una captura) y
   confirmado: el margen negativo de .hint SI hacia que su caja se solapara
   -8px con la caja del <select> de arriba, aunque a resoluciones/tipos de
   letra normales el padding interno del select absorbia visualmente ese
   solape (por eso no se veia en las capturas de prueba). En un movil real
   con el texto mas grande (accesibilidad) deja de haber margen de sobra y el
   solape se vuelve visible de verdad. Unico sitio de toda la app donde un
   .hint sigue justo a un <select> sin nada mas entre medias -- arreglo
   puntual, no una regla general. */
#podcast-precision-hint { margin-top: 0.5rem; }

.hidden { display: none !important; }

.document-review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0.75rem 0;
}
.pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  width: auto;
  background: transparent;
  color: var(--primary);
  border: 1px solid var(--accent-light);
  border-radius: 999px;
  padding: 0.5rem 0.9rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  margin-top: 0;
}
.pill-btn-muted {
  border-color: var(--border);
  color: var(--muted);
}
.content-type-chip {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  background: var(--accent-bg);
  color: var(--accent-dark);
  border-radius: 14px;
  padding: 0.7rem 0.85rem;
  margin-bottom: 0.9rem;
}
.content-type-chip-icon { display: flex; flex: none; margin-top: 0.15rem; }
.content-type-chip-icon svg { width: 18px; height: 18px; }
.content-type-chip-text { flex: 1; display: flex; flex-direction: column; gap: 0.15rem; }
.content-type-chip-label { font-size: 0.85rem; font-weight: 700; }
.content-type-chip-sub { font-size: 0.78rem; font-weight: 500; opacity: 0.85; }
.content-type-chip-toggle {
  background: none;
  border: none;
  color: inherit;
  text-decoration: underline;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
  flex: none;
  align-self: flex-start;
}

.add-photo-preview {
  margin: 0.75rem 0;
  padding: 0.85rem;
  border: 1.5px solid var(--border);
  border-radius: 14px;
  background: #fff;
  text-align: center;
}
.add-photo-preview img {
  max-width: 100%;
  max-height: 240px;
  border-radius: 10px;
  display: block;
  margin: 0 auto 0.6rem;
}
.add-photo-preview .hint { margin: 0 0 0.6rem; }

/* Nivel 1 de deteccion de fotos (2026-09-13): aviso de "1 pagina por foto"
   con un poco mas de presencia que un .hint normal, sin llegar a ser un
   error -- mismos tokens de color que .content-type-chip. */
.photo-guidance-hint {
  background: var(--accent-bg);
  color: var(--accent-dark);
  border-radius: 10px;
  padding: 0.55rem 0.75rem;
  font-size: 0.8rem;
  font-weight: 500;
  margin-top: 0.5rem;
}
.add-photo-preview .photo-guidance-hint { margin: 0 0 0.6rem; text-align: left; }
.add-photo-preview-actions {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.btn-with-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.text-summary-chip {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  background: var(--accent-bg);
  border: none;
  border-radius: 14px;
  padding: 0.75rem 0.9rem;
  margin-bottom: 1rem;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}
.text-summary-chip-icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--primary);
}
.text-summary-chip-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.text-summary-chip-title {
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--text);
}
.text-summary-chip-hint {
  font-size: 0.78rem;
  color: var(--muted);
}
.text-summary-chip-chevron {
  flex-shrink: 0;
  color: var(--muted);
}
.format-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}
.format-chip {
  background: var(--accent-bg);
  color: var(--primary);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  font-size: 0.75rem;
  font-weight: 600;
}
.format-chip-premium {
  background: var(--secondary-bg);
  color: var(--purple);
}

.file-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 1px solid var(--border);
  background: var(--card-bg);
  border-radius: 16px;
  padding: 1.5rem 1rem;
  color: var(--primary-dark);
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}

.file-drop:active { background: var(--accent-bg); }

.file-drop-icon { width: 60px; height: 56px; overflow: visible; }
.fdi-back { fill: var(--secondary-bg); stroke: var(--secondary); stroke-width: 1.5; }
.fdi-page { fill: #ffffff; stroke: var(--primary); stroke-width: 2; stroke-linejoin: round; }
.fdi-fold { fill: var(--bg); stroke: var(--primary); stroke-width: 1.5; stroke-linejoin: round; }
.fdi-line { stroke: var(--muted); stroke-width: 2.5; stroke-linecap: round; }
.fdi-badge { fill: var(--purple); }
.fdi-plus { stroke: white; stroke-width: 2.5; stroke-linecap: round; }

textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem;
  font-size: 0.95rem;
  font-family: inherit;
  resize: vertical;
}

.field { margin-bottom: 1rem; }
.field label { display: block; font-weight: 600; margin-bottom: 0.4rem; }

.birth-date-selects { display: flex; gap: 0.5rem; }
.birth-date-selects select { flex: 1; min-width: 0; }

select {
  width: 100%;
  padding: 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  font-size: 1rem;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  margin-bottom: 0.4rem;
}
.checkbox input { width: 18px; height: 18px; }

.primary-btn {
  width: 100%;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 10px;
  padding: 0.9rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
}
.primary-btn:active { background: var(--accent-dark); }

.danger-btn {
  width: 100%;
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: 10px;
  padding: 0.8rem;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  margin-top: 0.5rem;
}
.danger-btn:active { background: rgba(220,38,38,0.08); }

.secondary-btn {
  width: 100%;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 0.8rem;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  margin-top: 0.75rem;
}

/* 2026-08-30, pedido por el usuario: la pantalla de resultado del test tenia
   8 botones seguidos con el mismo peso visual (todos .secondary-btn), sin
   ninguna jerarquia -- "demasiados botones". "Reportar error de correccion"
   es la accion menos frecuente de todas (un caso excepcional, no parte del
   flujo normal), asi que se rebaja a un enlace de texto discreto en vez de
   un boton mas, para que no compita visualmente con Guardar/Configurar/
   Estudiar/Crear otro. */
.link-btn {
  display: block;
  width: 100%;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  text-decoration: underline;
  padding: 0.5rem;
  margin-top: 0.75rem;
  cursor: pointer;
  text-align: center;
}
.link-btn:active { color: var(--accent); }

.progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  margin-top: 1rem;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.omira-spinner-rotor {
  transform-origin: 32px 32px;
  animation: omira-spin 1.4s linear infinite;
}

@keyframes omira-spin { to { transform: rotate(360deg); } }

.omira-progress-ring {
  transform-origin: 32px 32px;
  transform: rotate(-90deg);
  transition: stroke-dashoffset 0.25s linear;
  filter: drop-shadow(0 1.5px 2px rgba(10,65,122,0.3));
}

@media (prefers-reduced-motion: reduce) {
  .omira-spinner-rotor { animation: none; }
  .omira-progress-ring { transition: none; }
}

.error {
  color: var(--danger);
  font-size: 0.9rem;
  margin-top: 0.75rem;
}

.question-block {
  margin-bottom: 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.question-block:last-child { border-bottom: none; }
.question-text { font-weight: 600; margin-bottom: 0.6rem; }

.option {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 0.5rem;
  cursor: pointer;
}
.option input { width: 18px; height: 18px; }
.option.correct { border-color: var(--success); background: rgba(22,163,74,0.08); }
.option.incorrect { border-color: var(--danger); background: rgba(220,38,38,0.08); }

.explanation {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 0.4rem;
}

.result {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 10px;
  background: var(--accent-bg);
  font-weight: 600;
  text-align: center;
}

.promo-box {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 10px;
  background: var(--secondary-bg);
  border: 1px dashed var(--secondary);
  text-align: center;
}
.promo-box p { margin-top: 0; font-size: 0.9rem; }

/* Mensaje contextual de por que se ha llevado al usuario al registro
   (2026-09-04, pedido explicito: el texto muted de siempre "no es visible,
   mala eleccion de color") -- se rellena con el mismo degradado rosa/rose ya
   usado para la tarjeta de Master en Planes, para que quede claro que viene
   de ahi. Solo se activa cuando openAuthPanel() recibe un mensaje
   personalizado (ver app.js); el mensaje generico de bienvenida se queda
   como texto discreto de siempre. */
.hint.auth-hint-highlight {
  margin-top: 0.6rem;
  padding: 0.8rem 1rem;
  border-radius: 10px;
  background: linear-gradient(160deg, #B9789B, #A6567F);
  color: #ffffff;
  font-weight: 600;
  text-align: center;
  box-shadow: 0 4px 14px rgba(166,86,127,0.3);
}

#save-document-box {
  margin-top: 1rem;
}

/* Tarjeta de lista con chip de tipo + fecha + menu de opciones (kebab), usada en
   "Mis documentos guardados" y en "Test, flashcards y resumenes guardados".
   Bocetada primero como Artifact antes de implementarla. */
.list-card {
  position: relative;
  background: var(--card-bg);
  border-radius: 16px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  padding: 1.1rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 0.75rem;
}
/* La tarjeta entera se tinta con un tono muy claro del color de su tipo (en vez
   de quedarse en blanco puro) — el mismo color que ya usaba solo el chip. */
.list-card.list-card-document, .list-card.list-card-test { background: var(--accent-bg); }
.list-card.list-card-flashcards { background: #F1EDF6; }
.list-card.list-card-summary { background: var(--secondary-bg); }
.list-card.list-card-audio { background: #EAF3F1; }
.list-card-main {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.list-card-main label.checkbox { margin-bottom: 0; flex-shrink: 0; }
.list-card-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.list-card-name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.list-card-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}
.list-card-chip {
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
/* Ahora que la tarjeta entera lleva el tono claro, el chip pasa a ser solido
   (con texto blanco) para que siga destacando sobre ese fondo. */
.list-card-chip.chip-document, .list-card-chip.chip-test { background: var(--primary); color: #ffffff; }
.list-card-chip.chip-flashcards { background: var(--purple); color: #ffffff; }
.list-card-chip.chip-summary { background: #A6567F; color: #ffffff; }
.list-card-chip.chip-audio { background: #2F7A6B; color: #ffffff; }
.list-card-date { font-size: 0.78rem; color: var(--muted); }
.list-card-kebab {
  all: unset;
  cursor: pointer;
  padding: 6px;
  border-radius: 8px;
  display: flex;
  flex-shrink: 0;
}
/* Fondo neutro semitransparente (no un color fijo) para que se note el estado
   "abierto" encima de cualquiera de los tintes de tarjeta de arriba. */
.list-card-kebab.open { background: rgba(10, 65, 122, 0.1); }
.list-card-kebab svg circle { fill: var(--muted); }
.list-card-kebab.open svg circle { fill: var(--primary); }
.list-card-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 1.1rem;
  background: var(--card-bg);
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(10,65,122,0.18);
  padding: 6px;
  min-width: 170px;
  z-index: 10;
}
/* Bug real (2026-09-21, reportado por el usuario con una captura real: el
   menu de "Repetir/Eliminar" del ultimo borrador de la lista salia cortado
   por el borde de la pantalla, sin forma de hacer scroll para verlo entero)
   -- el menu siempre se abria hacia abajo sin comprobar si habia sitio.
   Cuando no cabe por debajo, list-card-kebab.js le anade esta clase para que
   se abra hacia arriba en su lugar. */
.list-card-menu.list-card-menu-up {
  top: auto;
  bottom: calc(100% + 6px);
}
.list-card-menu button {
  all: unset;
  box-sizing: border-box;
  display: block;
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
}
.list-card-menu button:hover { background: var(--accent-bg); }
.list-card-menu button.accent { color: var(--accent); }
.list-card-menu button.danger { color: var(--danger); }

.plans-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}
.plans-grid .plan-card { margin-bottom: 0; min-width: 0; }

/* Las 4 tarjetas de plan se apilan en una sola columna y se comportan como
   un acordeon (solo el titulo visible, el resto se despliega al pulsar) para
   que la pantalla de Planes no obligue a hacer tanto scroll. Una sola
   columna evita ademas que una tarjeta desplegada y otra plegada queden mal
   emparejadas en la misma fila de una rejilla de 2 columnas. */
.plans-grid-accordion { grid-template-columns: 1fr; gap: 0.6rem; }
/* 2026-09-08: mismo motivo de siempre -- .hint tira -0.5rem hacia arriba para
   pegarse a un campo de formulario, pero este aviso (Terminos/Privacidad)
   viene despues de la rejilla de tarjetas de plan, no de un campo, asi que
   se solapaba con la tarjeta Master expandida. Reportado por un tester real
   en Android. */
#plans-subscription-disclosure { margin-top: 0.9rem; }
.plan-card h3.plan-card-toggle-heading { margin: 0; }
.plan-card-toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.plan-card-toggle .plan-card-icon { margin-bottom: 0; flex-shrink: 0; }
.plan-card-toggle span:not(.plan-card-icon-wrap) { flex: 1; font-weight: 700; font-size: 1rem; }
.plan-card-chevron { flex-shrink: 0; color: var(--muted); transition: transform 0.2s ease; }
.plan-card-toggle[aria-expanded="true"] .plan-card-chevron { transform: rotate(180deg); }
.plan-card-body {
  margin-top: 0.7rem;
  overflow: hidden;
  max-height: 600px;
  opacity: 1;
  transition: max-height 0.32s ease, opacity 0.25s ease, margin-top 0.32s ease;
}
/* 2026-09-18: acordeon de Planes con transicion real -- antes .hidden
   (display:none) alternaba de golpe sin animacion. max-height con un techo
   generoso (ninguna tarjeta pasa de 600px de contenido) en vez del truco de
   grid-template-rows: 0fr/1fr, para no tener que envolver el contenido de
   las 4 tarjetas en un div extra solo para esto. */
.plan-card-body.plan-card-collapsed {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .plan-card-body { transition: none; }
}
.plan-card-highlight .plan-card-chevron,
.plan-card-premium-plus .plan-card-chevron { color: rgba(255,255,255,0.85); }

.plan-card {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 1rem;
  margin-bottom: 1rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.plan-card h3 { margin: 0 0 0.3rem; font-size: 1rem; }
.plan-card ul { margin: 0.5rem 0; padding-left: 1.2rem; font-size: 0.9rem; }
.plan-card li { margin-bottom: 0.25rem; }
.master-trial-terms { margin: 0.8rem 0; padding-left: 1.2rem; font-size: 0.9rem; color: var(--muted); }
.master-trial-terms li { margin-bottom: 0.3rem; }
#master-trial-confirm-btn { margin-top: 0.4rem; }
#master-trial-cancel-btn { margin-top: 0.5rem; }
/* Icono en circulo (2026-09-17, "otra estetica" pedida por el usuario --
   la pantalla de Planes desentonaba del resto) -- mismo lenguaje que las
   tarjetas de "que quieres generar" y las filas de eleccion, en vez del
   icono suelto de antes. En las 2 tarjetas planas (Invitado/Registrados)
   toma la tinta ambar heredada de .fc-color-card[data-mode="plans"]; en
   las de degradado (Pro/Master/colegios) pasa a blanco translucido, igual
   que ya hacen los iconos sobre fondos de color en el resto de la app. */
.plan-card-icon-wrap {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--gtint); color: var(--g2);
}
.plan-card-highlight .plan-card-icon-wrap,
.plan-card-premium-plus .plan-card-icon-wrap,
.schools-promo-box .plan-card-icon-wrap { background: rgba(255,255,255,0.2); }
.plan-card-icon { display: block; margin-bottom: 0; }
/* Envoltorio solo para los puntos decorativos (2026-09-17): las tarjetas
   Pro/Master llevan la insignia "Popular" asomando por encima del borde
   superior (top negativo, a proposito) -- si el overflow:hidden fuera
   directo en la tarjeta, esa insignia se recortaria. Aislarlo en un
   envoltorio propio dentro de la tarjeta deja la insignia intacta. */
.plan-card-deco-clip { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
.plan-price {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--primary);
  margin: 0.2rem 0;
}

/* Cada nivel de plan lleva su propio color, en vez de un borde gris igual
   para todos — bocetado primero como Artifact antes de implementarlo. */
.plan-card-registered {
  border: none;
  background: var(--accent-bg);
}
.plan-card-registered h3, .plan-card-registered .plan-price { color: var(--primary); }
.plan-card-registered li { color: var(--primary); }

.plan-card-highlight {
  border: none;
  background: linear-gradient(160deg, var(--purple), #6B4F86);
  color: #ffffff;
  position: relative;
  box-shadow: 0 4px 14px rgba(132,100,160,0.35);
}
.plan-card-highlight h3, .plan-card-highlight .plan-price { color: #ffffff; }
.plan-card-highlight li { color: rgba(255,255,255,0.92); }
.plan-card-highlight .hint { color: rgba(255,255,255,0.8); }
.plan-card-highlight .primary-btn { background: #ffffff; color: #6B4F86; }
.plan-badge {
  position: absolute;
  top: -0.6rem;
  right: 0.8rem;
  background: #F4B840;
  color: #4A3200;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
}

.plan-card-premium-plus {
  position: relative;
  border: none;
  background: linear-gradient(160deg, #B9789B, #A6567F);
  color: #ffffff;
  box-shadow: 0 4px 14px rgba(166,86,127,0.3);
}
.plan-card-premium-plus h3, .plan-card-premium-plus .plan-price { color: #ffffff; }
.plan-card-premium-plus li { color: rgba(255,255,255,0.92); }
.plan-card-premium-plus .hint { color: rgba(255,255,255,0.8); }
.plan-card-premium-plus .primary-btn { background: #ffffff; color: #A6567F; }
/* El boton de la prueba de Master (2026-09-04, segundo aviso del usuario:
   "sigue sin verse bien"): .secondary-btn por defecto es azul (var(--accent))
   sobre fondo transparente -- azul sobre el degradado rosa de esta tarjeta
   es un contraste pobre, casi ilegible. Se sobreescribe a blanco (borde y
   texto), un "boton fantasma" que lee bien sobre el rosa sin competir con el
   blanco solido de "Hazte Master". */
.plan-card-premium-plus #master-trial-offer-btn {
  background: rgba(255,255,255,0.12);
  color: #ffffff;
  border-color: #ffffff;
}

.schools-promo-box {
  position: relative;
  margin-top: 1rem;
  padding: 1.1rem;
  border-radius: 12px;
  background: linear-gradient(160deg, var(--accent), var(--primary));
  color: #ffffff;
  text-align: center;
  box-shadow: 0 4px 14px rgba(10,65,122,0.3);
}
.schools-promo-box .plan-card-icon { margin: 0 auto 0.4rem; }
.schools-promo-box h3 { margin: 0 0 0.4rem; font-size: 1rem; color: #ffffff; }
.schools-promo-box p { margin: 0 0 0.9rem; font-size: 0.9rem; color: rgba(255,255,255,0.9); }
.schools-promo-box .primary-btn { background: #ffffff; color: var(--primary); width: auto; padding: 0.7rem 1.4rem; margin: 0 auto; }

/* Paquetes de creditos, "opcion C" (2026-09-18): selector de pastillas +
   una sola tarjeta resumen, en vez de las 3 cajas apiladas de antes. Fuera
   de .fc-color-card (esta seccion no lleva cabecera de degradado propia,
   a proposito -- ya hay bastante ambar en la cabecera de Planes justo
   encima), asi que los tonos ambar van literales en vez de heredados. */
.size-pills { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.size-pill {
  flex: 1; min-width: 0; padding: 0.6rem 0.3rem; border-radius: 12px; border: 1.5px solid var(--border);
  background: #fff; text-align: center; font-weight: 700; font-size: 0.8rem; color: var(--muted); font-family: inherit; cursor: pointer;
}
.size-pill.is-active { background: linear-gradient(135deg, #D99A2B, #8a5f12); border-color: transparent; color: #fff; box-shadow: 0 4px 10px rgba(138,95,18,0.25); }
.size-pill span { display: block; }
.size-pill .sp-credits { font-size: 0.68rem; font-weight: 600; margin-top: 0.1rem; opacity: 0.85; }

.summary-box { display: flex; align-items: center; gap: 0.9rem; background: #FBF1DE; border-radius: 14px; padding: 1rem; margin-bottom: 1rem; }
.summary-icon { width: 46px; height: 46px; border-radius: 50%; background: #fff; color: #8a5f12; display: flex; align-items: center; justify-content: center; flex: none; }
.summary-info { flex: 1; }
.summary-credits { font-weight: 700; font-size: 1.05rem; font-family: var(--font-display); color: #8a5f12; }
.summary-price { font-weight: 700; font-size: 1.05rem; flex: none; color: var(--text); }

.buy-pill-block {
  display: block; width: 100%; text-align: center; color: #fff; border: none; border-radius: 999px; padding: 0.85rem; font-size: 0.95rem; font-weight: 700;
  background: linear-gradient(135deg, #D99A2B, #8a5f12); box-shadow: 0 8px 16px rgba(138,95,18,0.22); cursor: pointer;
}

.home-button {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255,255,255,0.15);
  color: white;
  border: 1px solid rgba(255,255,255,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 2;
}
.home-button:active { background: rgba(255,255,255,0.28); }

.update-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  background: var(--primary);
  color: white;
  text-align: center;
}
.update-banner button {
  background: white;
  color: var(--primary);
  border: none;
  border-radius: 8px;
  padding: 0.4rem 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.avatar-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: white;
  font-weight: 700;
  flex-shrink: 0;
}
.avatar-circle-small { width: 28px; height: 28px; font-size: 0.85rem; }
.avatar-circle-large { width: 64px; height: 64px; font-size: 1.6rem; }

.profile-avatar-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.review-stats { margin-bottom: 1rem; }

.review-streak-block {
  display: flex;
  align-items: center;
  gap: 14px;
  border-radius: 14px;
  padding: 1.1rem;
  margin-bottom: 12px;
  background: #e5e7eb;
  color: #6b7280;
  transition: background 0.2s ease;
  position: relative;
  overflow: visible;
}
/* 2026-09-18: celebracion al SUBIR la racha (no en cada visita a Repasar,
   solo cuando el numero realmente aumenta respecto a la ultima vez que se
   vio -- ver applyStreakTier/loadReviewStats). Mismas 3 chispas y el mismo
   "pop" ya usados en el modal de resultado del test, reaplicados aqui. */
.review-streak-block.streak-celebrate { animation: result-modal-pop 0.4s cubic-bezier(0.34,1.56,0.64,1); }
.review-streak-block .streak-spark-1 { top: 20%; left: 15%; }
.review-streak-block .streak-spark-2 { top: 20%; left: 15%; }
.review-streak-block .streak-spark-3 { top: 20%; left: 15%; }
.review-streak-block.streak-celebrate .streak-spark-1 { animation: spark1 0.7s ease-out; }
.review-streak-block.streak-celebrate .streak-spark-2 { animation: spark2 0.75s ease-out 0.03s backwards; }
.review-streak-block.streak-celebrate .streak-spark-3 { animation: spark3 0.65s ease-out 0.06s backwards; }
@media (prefers-reduced-motion: reduce) {
  .review-streak-block.streak-celebrate { animation: none; }
  .review-streak-block.streak-celebrate .streak-spark-1,
  .review-streak-block.streak-celebrate .streak-spark-2,
  .review-streak-block.streak-celebrate .streak-spark-3 { animation: none; }
}
.review-streak-icon { flex-shrink: 0; }
.review-streak-number { font-family: var(--font-display); font-weight: 700; font-size: 1.9rem; line-height: 1; }
.review-streak-tier-label { font-size: 0.8rem; font-weight: 600; opacity: 0.9; }

.review-substats { display: flex; gap: 10px; margin-bottom: 16px; }
.review-substat {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--accent-bg);
  border-radius: 10px;
  padding: 0.6rem 0.7rem;
}
.review-substat-pink { background: var(--secondary-bg); }
.review-substat-number { display: block; font-weight: 700; font-size: 0.95rem; color: var(--primary); }
.review-substat-pink .review-substat-number { color: #A6567F; }
.review-substat-label { display: block; font-size: 0.68rem; color: var(--muted); }

.review-week-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 8px;
  gap: 8px;
}
.review-week-header label { font-size: 0.78rem; font-weight: 600; color: var(--muted); }
.review-week-header span { font-size: 0.78rem; font-weight: 700; color: #B8790E; text-align: right; }

.review-heatmap {
  display: flex;
  gap: 6px;
}
.review-heatmap-day {
  flex: 1;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}
.review-heatmap-day-label { font-size: 0.65rem; color: var(--muted); margin-bottom: 3px; }
.review-heatmap-cell {
  height: 30px;
  border-radius: 7px;
  background: var(--border);
}
.review-heatmap-day.selected .review-heatmap-cell { outline: 2px solid #B8790E; outline-offset: -2px; }

.review-heatmap-legend {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: flex-end;
  margin-top: 10px;
  font-size: 0.68rem;
  color: #9CA3AF;
}
.review-legend-swatch { width: 12px; height: 12px; border-radius: 3px; }
.review-legend-0 { background: var(--border); }
.review-legend-1 { background: #FBD97E; }
.review-legend-2 { background: #F4B840; }
.review-legend-3 { background: #B8790E; }

.recent-row-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--card-bg);
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text);
  cursor: pointer;
}
.recent-row-btn:active { background: var(--accent-bg); }

.result-detail-question {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 0.5rem;
}
.result-detail-question-icon { flex-shrink: 0; margin-top: 0.1rem; }
.result-detail-question-text { font-size: 0.9rem; }
.result-detail-question-topic { display: block; font-size: 0.72rem; color: var(--muted); margin-top: 0.15rem; }

.chat-tutor-messages {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-height: 340px;
  overflow-y: auto;
  padding: 0.25rem;
  margin-bottom: 0.75rem;
}
.chat-tutor-msg {
  max-width: 85%;
  padding: 0.6rem 0.85rem;
  border-radius: 14px;
  font-size: 0.9rem;
  line-height: 1.4;
  white-space: pre-wrap;
}
.chat-tutor-msg-user {
  align-self: flex-end;
  background: var(--purple);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.chat-tutor-msg-tutor {
  align-self: flex-start;
  background: #F1EDF6;
  color: var(--text);
  border-bottom-left-radius: 4px;
}
.chat-tutor-msg-loading { opacity: 0.6; font-style: italic; }
.chat-tutor-input-row { display: flex; gap: 0.5rem; }
.chat-tutor-input-row input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.7rem 0.85rem;
  font-size: 0.95rem;
  font-family: inherit;
}
.chat-tutor-input-row button { width: auto; flex-shrink: 0; margin-top: 0; padding: 0.7rem 1.1rem; }

/* Onboarding (2026-09-01) -- pantalla completa solo la primera vez que se
   abre la app en este dispositivo. Reutiliza el mismo azul de cabecera
   (--primary) y los colores reales de cada modo, no colores inventados. */
.onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.onboarding-overlay.hidden { display: none; }
.onboarding-card {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  height: min(600px, 100vh - 2rem);
}
.onboarding-viewport {
  position: relative;
  flex: 1;
  overflow: hidden;
  border-radius: 18px;
}
.onboarding-track {
  display: flex;
  width: 800%;
  height: 100%;
  transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.onboarding-slide {
  width: calc(100% / 8);
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.75rem;
  text-align: center;
  color: #fff;
  box-sizing: border-box;
}
.onboarding-slide h2 { font-size: 1.3rem; font-weight: 500; margin: 0 0 0.6rem; color: #fff; }
.onboarding-slide p { font-size: 0.95rem; line-height: 1.6; color: rgba(255, 255, 255, 0.78); margin: 0 0 0.4rem; }
.onboarding-logo-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; margin-bottom: 1.6rem; }
.onboarding-wordmark { font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; letter-spacing: 0.02em; }
.onboarding-lang-btn {
  position: absolute;
  top: 1rem;
  left: 1rem;
  background: rgba(255, 255, 255, 0.12);
  border: none;
  border-radius: 20px;
  color: #fff;
  font-size: 0.85rem;
  padding: 0.4rem 0.7rem;
  cursor: pointer;
}
.onboarding-icon { width: 52px; height: 52px; color: var(--accent-light); margin-bottom: 1.2rem; }
.onboarding-highlight { color: #fff !important; font-weight: 500; }
.onboarding-subtitle { font-size: 0.85rem !important; margin: 0 0 1.1rem !important; }
.onboarding-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; width: 100%; }
.onboarding-grid-item {
  border-radius: 12px;
  padding: 0.9rem 0.6rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
.onboarding-grid-item svg { width: 22px; height: 22px; }
.onboarding-grid-item span { font-size: 0.8rem; }
.onboarding-grid-item-wide { grid-column: span 2; }
.onboarding-c-blue { background: rgba(32, 133, 236, 0.22); color: var(--accent-light); }
.onboarding-c-purple { background: rgba(132, 100, 160, 0.32); color: #C6AEDA; }
.onboarding-c-pink { background: rgba(166, 86, 127, 0.32); color: #E3A6C1; }
.onboarding-c-teal { background: rgba(47, 122, 107, 0.34); color: #7FD3C1; }
.onboarding-c-gold { background: rgba(217, 154, 43, 0.30); color: #F0C878; }
/* Diapositivas de diferenciadores con captura real (2026-09-24, rediseño de
   la onboarding: refuerzo por errores, repeticion espaciada y pictogramas
   pasan a tener su propia diapositiva con la funcion funcionando de verdad,
   en vez de un icono generico -- misma leccion ya aplicada en la presentacion
   a colegios: lo que convence de verdad es ver la funcion en accion). */
.onboarding-eyebrow { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: #F0C878; margin-bottom: 0.4rem; }
.onboarding-shotcard { background: #fff; border-radius: 16px; overflow: hidden; box-shadow: 0 16px 34px -14px rgba(0,0,0,.45); width: 100%; max-height: 46vh; margin-top: 0.4rem; }
.onboarding-shotcard img { width: 100%; display: block; object-fit: cover; object-position: top; max-height: 46vh; }
.onboarding-feature-list { display: flex; flex-direction: column; gap: 0.7rem; width: 100%; }
.onboarding-feature-row {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 0.9rem;
  display: flex;
  gap: 0.8rem;
  align-items: center;
  text-align: left;
}
.onboarding-feature-row svg { width: 24px; height: 24px; color: var(--accent-light); flex-shrink: 0; }
.onboarding-feature-row strong { display: block; font-size: 0.9rem; font-weight: 500; color: #fff; }
.onboarding-feature-row span { display: block; font-size: 0.78rem; color: rgba(255, 255, 255, 0.7); margin-top: 0.15rem; line-height: 1.4; }
.onboarding-steps { display: flex; flex-direction: column; gap: 1rem; width: 100%; text-align: left; }
.onboarding-step-row { display: flex; gap: 0.75rem; align-items: flex-start; font-size: 0.9rem; line-height: 1.5; }
.onboarding-step-num {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  flex-shrink: 0;
}
.onboarding-skip-btn {
  position: absolute;
  top: 1rem;
  right: 1rem;
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.8rem;
  cursor: pointer;
  padding: 0.4rem;
}
.onboarding-footer { padding: 1.1rem 0.25rem 0; display: flex; flex-direction: column; gap: 0.9rem; }
.onboarding-dots { display: flex; justify-content: center; gap: 7px; }
.onboarding-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  transition: all 0.3s;
  display: inline-block;
}
.onboarding-dots span.active { background: #fff; width: 18px; border-radius: 3px; }
.onboarding-nav-row { display: flex; gap: 0.6rem; }
.onboarding-back-btn {
  width: 50px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.1);
  border: none;
  border-radius: 10px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: opacity 0.2s;
}
.onboarding-back-btn:disabled { opacity: 0.35; pointer-events: none; }
.onboarding-next-btn {
  flex: 1;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 0.85rem;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
}

/* Cuadro de resultado centrado (2026-09-09) -- disenado con el usuario como
   maqueta ("Opcion C") antes de construirse, ver la memoria del proyecto
   (testgen-app-study-plan-design). Primer modal centrado real de toda la
   app; se penso desde el principio como componente reutilizable para las 4
   pantallas de resultado, no solo para el test. */
.result-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 65, 122, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.2rem;
  z-index: 50;
}
.result-modal {
  width: 100%;
  max-width: 340px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--card-bg);
  border-radius: 22px;
  box-shadow: 0 24px 48px rgba(10,65,122,0.35);
}
.result-modal-header {
  padding: 1.7rem 1.3rem 1.9rem;
  position: relative;
  overflow: hidden;
  border-radius: 22px 22px 0 0;
  text-align: center;
}
.result-modal-deco-dot { position: absolute; border-radius: 50%; opacity: 0.14; background: #fff; }
.result-modal-deco-dot-1 { width: 120px; height: 120px; top: -40px; right: -30px; }
.result-modal-deco-dot-2 { width: 70px; height: 70px; bottom: -20px; left: -20px; }
.result-modal-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  margin: 0 auto 0.8rem;
  background: rgba(255,255,255,0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  animation: result-modal-pop 0.4s cubic-bezier(0.34,1.56,0.64,1);
}
@keyframes result-modal-pop { from { transform: scale(0.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .result-modal-icon { animation: none; } }
.result-modal-icon-wrap { position: relative; width: 64px; height: 64px; margin: 0 auto 0.8rem; }
.result-modal-icon-wrap .result-modal-icon { margin: 0; }
/* Chispitas de celebracion (2026-09-18, boceto aprobado): solo salen cuando
   openResultModal() marca el envoltorio como ".celebrate" (tier "good", el
   unico realmente celebratorio de los 3 del test) -- se restablecen solas
   cada vez que el cuadro se abre, igual que el "pop" del icono de arriba
   (display:none -> visible reinicia la animacion sin ningun truco de JS). */
.spark { position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; border-radius: 50%; background: #fff; opacity: 0; }
.result-modal-icon-wrap.celebrate .spark-1 { animation: spark1 0.7s ease-out; }
.result-modal-icon-wrap.celebrate .spark-2 { animation: spark2 0.75s ease-out 0.03s backwards; }
.result-modal-icon-wrap.celebrate .spark-3 { animation: spark3 0.65s ease-out 0.06s backwards; }
@keyframes spark1 { 0% { transform: translate(-50%,-50%) scale(0.4); opacity: 1; } 100% { transform: translate(-160%,-260%) scale(0); opacity: 0; } }
@keyframes spark2 { 0% { transform: translate(-50%,-50%) scale(0.4); opacity: 1; } 100% { transform: translate(180%,-220%) scale(0); opacity: 0; } }
@keyframes spark3 { 0% { transform: translate(-50%,-50%) scale(0.4); opacity: 1; } 100% { transform: translate(10%,-320%) scale(0); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .result-modal-icon-wrap.celebrate .spark-1,
  .result-modal-icon-wrap.celebrate .spark-2,
  .result-modal-icon-wrap.celebrate .spark-3 { animation: none; }
}
.result-modal-headline {
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: #fff;
  margin: 0 0 0.3rem;
  position: relative;
  z-index: 1;
}
.result-modal-sub {
  font-size: 0.86rem;
  color: rgba(255,255,255,0.92);
  margin: 0;
  line-height: 1.4;
  position: relative;
  z-index: 1;
}
.result-modal-brand {
  position: relative;
  z-index: 2;
  width: fit-content;
  margin: -16px auto 0;
  background: #fff;
  border-radius: 999px;
  padding: 0.32rem 0.95rem;
  box-shadow: 0 4px 10px rgba(10,65,122,0.18);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.result-modal-body { padding: 1.9rem 1.3rem 1.4rem; }
.result-modal-btn {
  width: 100%;
  border: none;
  border-radius: 12px;
  padding: 0.85rem;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
}
.result-modal-btn-primary {
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.result-modal-btn-ghost { background: var(--accent-bg); color: var(--accent-dark); margin-top: 0.6rem; }
.result-modal-btn-plan {
  background: #2F7A6B;
  color: #fff;
  margin-top: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.result-modal-btn-text {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  text-decoration: underline;
  margin-top: 0.9rem;
  display: block;
  width: 100%;
  text-align: center;
  padding: 0;
  cursor: pointer;
}
.result-modal-dropdown-wrap { position: relative; }
.result-modal-dropdown-menu {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(10,65,122,0.22);
  border: 1px solid var(--border);
  overflow: hidden;
  z-index: 5;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.result-modal-dropdown-menu.result-modal-dropdown-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.result-modal-dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0.7rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.result-modal-dropdown-item:hover { background: #f7f9fd; }
.result-modal-dropdown-item svg { width: 19px; height: 19px; flex-shrink: 0; }
.result-modal-dropdown-item + .result-modal-dropdown-item { border-top: 1px solid var(--border); }
#result-modal-chevron { transition: transform 0.22s ease; }
#result-modal-chevron.result-modal-chevron-open { transform: rotate(180deg); }

/* Aviso discreto (2026-09-19): confirma que un material lento de generar
   (podcast, resumen narrado) ya esta listo, para quien se quedo mirando el
   anillo girar en vez de cambiar de pantalla -- ver showToast() en app.js.
   Deliberadamente discreto: una franja pequeña abajo, no un modal. */
.toast-notice {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(12px);
  max-width: min(420px, calc(100vw - 32px));
  background: var(--ink, #1E2A3A);
  color: #fff;
  font-size: 0.88rem;
  font-weight: 600;
  padding: 0.75rem 1.2rem;
  border-radius: 30px;
  box-shadow: 0 12px 30px -8px rgba(0, 0, 0, 0.4);
  z-index: 700;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  text-align: center;
}
.toast-notice.hidden { display: none; }
.toast-notice.toast-notice-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Compartir con la clase (2026-10-13) */
.shared-banner {
  margin: 0 0 0.8rem;
  padding: 0.7rem 0.9rem;
  border-radius: 12px;
  background: #F8F7FC;
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.9rem;
  text-align: center;
}
.share-name { text-align: center; margin: 0 0 0.8rem; }
.share-qr { width: 190px; height: 190px; margin: 0 auto 0.8rem; }
.share-qr svg { width: 100%; height: 100%; display: block; }
.share-link-input { width: 100%; box-sizing: border-box; margin-bottom: 0.6rem; font-size: 0.85rem; }
.share-download { display: block; text-align: center; text-decoration: none; box-sizing: border-box; margin: 0.5rem 0; }
.share-stats { margin: 0.8rem 0 0.4rem; font-size: 0.92rem; }
.share-stats p { margin: 0.2rem 0; }
.share-stop { color: #B3261E; }
