/* ==========================================================================
   Bit AI School — sistema de diseño v4: «violeta eléctrico sobre blanco puro»

   Dirección de arte (especificación de Alan, agosto 2026). La regla que no se
   rompe: EL COLOR NO DECORA, MARCA PROGRESO. Cada color tiene un solo trabajo.

     violeta #6C2BF7   marca, acción, elemento activo, progreso completado
     lima    #DBFF6B   acierto y solo acierto (nunca como color de texto)
     fucsia  #FF2D87   celebración (solo en texto de 24 px o mayor)
     coral   #FF5A5A   fallo, sin dramatismo (solo fondo claro + coral tinta)
     blanco + lila     el escenario donde ocurre todo lo anterior

   Prohibido en todo el producto: crema, beige, hueso, arena, marrón,
   terracota, mostaza, ocre, verde salvia, azul genérico, gris azulado de
   marca, degradados decorativos de fondo, sombras difuminadas bajo tarjetas,
   sombras sólidas desplazadas, bordes negros gruesos, radios pequeños y
   mayúsculas completas. scripts/design-test.mjs lo comprueba en cada pasada.

   Índice:
     1. Fuente
     2. Tokens
     3. Base y accesibilidad
     4. Layout
     5. Tipografía
     6. Botones
     7. Componentes
     8. Chrome (cabecera, pie, migas)
     9. Portada, catálogo y Pro
    10. Mi camino
    11. Reproductor de lección
    12. Marcador de logros
    13. Estados de carga y error
    14. Movimiento
    15. Móvil
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/a/f1/fonts/inter-latin-variable.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/a/f1/fonts/inter-latin-ext-variable.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ======================================================================
   2. TOKENS
   ====================================================================== */

:root {
  /* -- marca ---------------------------------------------------------- */
  --violet: #6C2BF7;
  --violet-hover: #7B3FF8;
  --violet-deep: #4A15C4;
  --lila: #F7F5FF;          /* lila LIENZO: fondo neutro de superficie y nada
                               más. No es el color de las tarjetas de
                               contenido, ni el de los contadores de logro,
                               ni el de los botones. */
  --lila-idle: #E3DCFA;     /* lila inactivo: vacíos, separadores, off */
  --lila-dim: #F1EFF7;      /* gris lila: solo el fondo de una bloqueada */

  /* -- estado --------------------------------------------------------- */
  --lime: #DBFF6B;          /* acierto. NUNCA como color de texto */
  --lime-ink: #2C4400;
  --fuchsia: #FF2D87;       /* celebración. Solo en texto de 24 px o mayor */
  --fuchsia-bg: #FFE7F1;    /* su tinte: fondo de racha y de experiencia */
  --fuchsia-ink: #8A0E45;   /* fucsia legible por debajo de 24 px */
  --coral: #FF5A5A;         /* fallo. NUNCA como texto sobre blanco */
  --coral-bg: #FFECEC;
  --coral-ink: #8A1A1A;

  /* -- etiqueta de lección de pago (vive dentro de la tarjeta) --------- */
  --paid: #FFC400;
  --paid-ink: #4A3200;

  /* -- neutros -------------------------------------------------------- */
  --white: #FFFFFF;
  --ink: #100D1C;           /* 19,1:1 sobre blanco */
  --ink-soft: #6B6880;      /* 5,4:1 — texto secundario */
  /* Texto flojo LEGIBLE: 4,90:1 sobre blanco y 4,54:1 sobre el lila lienzo.
     El valor anterior se quedaba en 2,80 y 2,59 y no llegaba ni al
     mínimo de texto grande. Sobre el lila INACTIVO (--lila-idle) no cumple:
     ahí va --ink-soft o más oscuro. */
  --ink-faint: #726D8D;     /* metadatos no esenciales y deshabilitado */

  /* -- escala tipográfica (escritorio, con variante móvil en §15) ------ */
  --fs-hero: clamp(34px, 1.5rem + 4.2vw, 56px);
  --fs-h2: clamp(26px, 1.3rem + 1.9vw, 34px);
  --fs-h3: 20px;
  --fs-body: 16px;
  --fs-sm: 14px;
  --fs-meta: 12px;
  --lh-hero: 1.15;
  --lh-title: 1.25;
  --lh-body: 1.6;

  /* -- espaciado ------------------------------------------------------ */
  --sp-1: .25rem;  --sp-2: .5rem;   --sp-3: .75rem;  --sp-4: 1rem;
  --sp-5: 1.25rem; --sp-6: 1.5rem;  --sp-8: 2rem;    --sp-10: 2.5rem;
  --sp-12: 3rem;   --sp-16: 4rem;   --sp-20: 5rem;

  /* -- forma: nada de radios tímidos ---------------------------------- */
  --r-card: 20px;
  --r-field: 14px;
  --r-pill: 999px;

  /* -- movimiento elástico -------------------------------------------- */
  --dur-fast: 150ms;
  --dur: 260ms;
  --dur-slow: 480ms;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);

  /* -- layout --------------------------------------------------------- */
  --wrap: 68rem;
  --wrap-narrow: 48rem;
  --prose: 42.5rem;         /* ~680 px de columna de lectura */
  --column: 42.5rem;
  --header-h: 4.25rem;
  --font: 'Inter', 'Segoe UI Variable Display', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* Identidad de la lección: la fija cada tarjeta y el reproductor con
     estilo en línea. Los cinco colores de lección NO se escriben en esta
     hoja: entran por aquí y solo dentro de una tarjeta.
       --lc  saturado   --lt  tinte de fondo   --ls  desaturado claro */
  --lc: #6C2BF7;
  --lt: #F7F5FF;
  --ls: #E3DCFA;
}

/* ======================================================================
   3. BASE Y ACCESIBILIDAD
   ====================================================================== */

*, *::before, *::after { box-sizing: border-box; }
/* `scroll-padding-top` deja hueco para la cabecera fija: al saltar a un ancla
   («#unidad-2», la colección) el título aterriza DEBAJO de la barra y no
   detrás de ella.

   El recorte horizontal se queda SOLO en el body (más abajo) y no se declara
   aquí a propósito: en cuanto la raíz deja de ser `visible`, el desbordamiento
   del body ya no se propaga al viewport y el body pasa a ser su propio
   contenedor de desplazamiento — con lo que la cabecera y la barra de
   progreso, que son `position: sticky`, dejarían de anclarse. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--sp-4));
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  color: var(--ink);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  line-height: var(--lh-title);
  letter-spacing: -.01em;
}
h1 { font-size: var(--fs-hero); line-height: var(--lh-hero); letter-spacing: -.022em; }
h2 { font-size: var(--fs-h2); letter-spacing: -.018em; }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h3); }
p { margin: 0; }
ul, ol { margin: 0; padding-left: 1.35rem; }
a { color: inherit; text-decoration: none; }
button, a { touch-action: manipulation; }
img, svg, video, canvas { max-width: 100%; height: auto; display: block; }
/* Ninguna palabra suelta (una dirección, un identificador) puede ensanchar la
   página en un móvil de 360 px. `break-word` y no `anywhere`: parte solo la
   palabra que no cabe, sin encoger el ancho mínimo del resto (que es lo que
   partía «Catálogo» en dos dentro de las migas). */
h1, h2, h3, h4, p, li, dd, dt, td, th, figcaption, summary, label { overflow-wrap: break-word; }
hr { border: 0; border-top: 1px solid var(--lila-idle); margin: var(--sp-8) 0; }
small { font-size: var(--fs-sm); }
b, strong { font-weight: 600; }
button { font: inherit; color: inherit; }
code, pre { font-family: var(--mono); font-size: .92em; }
::selection { background: var(--lila-idle); color: var(--ink); }

/* Anillo de foco violeta, grueso y obligatorio en todo lo interactivo. */
:focus-visible {
  outline: 3px solid var(--violet);
  outline-offset: 3px;
  border-radius: var(--r-field);
}
a:focus-visible, button:focus-visible, .btn:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
summary:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--violet);
  outline-offset: 3px;
  box-shadow: 0 0 0 7px rgba(108, 43, 247, .22);
}

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

.skip-link {
  position: absolute; left: var(--sp-4); top: -5rem; z-index: 100;
  background: var(--violet); color: var(--white);
  padding: var(--sp-3) var(--sp-5); border-radius: var(--r-pill);
  font-size: var(--fs-sm); font-weight: 600;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--sp-4); }

/* ======================================================================
   4. LAYOUT
   ====================================================================== */

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--sp-5); }
.wrap-narrow { max-width: var(--wrap-narrow); }
.wrap-prose { max-width: var(--prose); }
@media (min-width: 640px) { .wrap { padding-inline: var(--sp-6); } }

.section { padding-block: var(--sp-12); }
.section-lg { padding-block: var(--sp-16); }
@media (min-width: 640px) {
  .section { padding-block: var(--sp-16); }
  .section-lg { padding-block: var(--sp-20); }
}
/* La jerarquía se construye alternando blanco y lila lienzo, nunca con
   sombras ni bordes ni degradados. */
.section-alt, .section-muted, .section-tint { background: var(--lila); }
.section-alt .card, .section-muted .card, .section-tint .card { background: var(--white); }

.center { text-align: center; }
.stack { display: flex; flex-direction: column; }
.stack-2 { gap: var(--sp-2); } .stack-3 { gap: var(--sp-3); } .stack-4 { gap: var(--sp-4); }
.stack-5 { gap: var(--sp-5); } .stack-6 { gap: var(--sp-6); } .stack-8 { gap: var(--sp-8); }
.stack-12 { gap: var(--sp-12); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.row-center { justify-content: center; }
.grid { display: grid; gap: var(--sp-5); }
.grid-2, .grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: 1fr 1fr; }
@media (min-width: 640px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) {
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

.mt-2 { margin-top: var(--sp-2); } .mt-3 { margin-top: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); } .mt-6 { margin-top: var(--sp-6); }
.mt-8 { margin-top: var(--sp-8); } .mt-10 { margin-top: var(--sp-10); }
.mt-12 { margin-top: var(--sp-12); }
.mb-6 { margin-bottom: var(--sp-6); } .mb-10 { margin-bottom: var(--sp-10); }

.page { min-height: 100dvh; display: flex; flex-direction: column; background: var(--white); }
.page > main { flex: 1 0 auto; }

/* ======================================================================
   5. TIPOGRAFÍA
   Una sola familia geométrica redondeada y solo dos pesos: 400 y 600.
   Todo en formato frase; ninguna regla pone mayúsculas.
   ====================================================================== */

.lead { font-size: var(--fs-h3); color: var(--ink-soft); line-height: var(--lh-body); }
.muted { color: var(--ink-soft); }
.small { font-size: var(--fs-sm); }
.xs { font-size: var(--fs-meta); }
.xs.muted, .small.muted { color: var(--ink-soft); }
.meta { font-size: var(--fs-meta); color: var(--ink-faint); }
.strong { font-weight: 600; }
.eyebrow {
  display: inline-block; font-size: var(--fs-sm); font-weight: 600;
  color: var(--violet-deep); letter-spacing: 0;
}
.balance { text-wrap: balance; }
.measure { max-width: var(--prose); }
.measure-center { max-width: var(--prose); margin-inline: auto; }

/* Único sitio del producto donde se colorean palabras sueltas: el titular
   de portada, con una palabra violeta, una fucsia y una en tinta. */
.hl-violet { color: var(--violet); }
.hl-fuchsia { color: var(--fuchsia); }
.hl-ink { color: var(--ink); }

.prose { font-size: var(--fs-body); line-height: var(--lh-body); max-width: var(--prose); }
.prose p + p, .prose p + ul, .prose ul + p, .prose p + h2, .prose ul + h2, .prose p + h3, .prose ul + h3 { margin-top: var(--sp-4); }
.prose h2 + p, .prose h3 + p { margin-top: var(--sp-2); }
/* Las secciones de un texto legal son h2 (van justo bajo el h1 de la página),
   pero se leen al tamaño de un h3: la jerarquía es semántica, no un salto de
   34 px en mitad de un documento largo. */
.prose h2 { font-size: var(--fs-h3); letter-spacing: -.01em; }
/* El respaldo sin JavaScript del reproductor: sus secciones son h2 (van bajo
   el h1 de la lección) pero se leen al tamaño de un h3, como siempre. Solo
   existe cuando el navegador no ejecuta JavaScript. */
noscript h2 { font-size: var(--fs-h3); letter-spacing: -.01em; }
noscript .crumbs ol { display: flex; flex-wrap: wrap; gap: var(--sp-2); padding: 0; margin: 0 0 var(--sp-4); }
noscript .crumbs li { list-style: none; font-size: var(--fs-meta); color: var(--ink-soft); }
.prose li + li { margin-top: var(--sp-2); }
.prose strong { font-weight: 600; }

/* ======================================================================
   6. BOTONES
   Píldoras completas. Al pasar el cursor suben; al pulsarlos se hunden y
   encogen un 2 %. Un único botón violeta sólido grande por pantalla.
   ====================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 52px; padding: 13px 26px;
  border: 0; border-radius: var(--r-pill);
  background: var(--violet); color: var(--white);
  font-family: inherit; font-size: var(--fs-body); font-weight: 600; line-height: 1.2;
  cursor: pointer; text-decoration: none; white-space: normal; text-align: center; position: relative;
  transition: transform var(--dur-fast) var(--ease-back),
              background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
  -webkit-tap-highlight-color: transparent; user-select: none;
}
.btn:hover:not(:disabled) { transform: translateY(-2px); background: var(--violet-hover); }
.btn:active:not(:disabled) { transform: translateY(1px) scale(.98); background: var(--violet-deep); }
.btn:disabled, .btn[disabled] {
  /* Sobre el lila inactivo el gris flojo no llega a 4,5:1: aquí va el
     secundario, que sí. */
  background: var(--lila-idle); color: var(--ink-soft); cursor: not-allowed; transform: none;
}

.btn-primary { background: var(--violet); color: var(--white); }
.btn-primary:hover:not(:disabled) { background: var(--violet-hover); }
.btn-primary:active:not(:disabled) { background: var(--violet-deep); }

/* Secundario: píldora lila con texto violeta profundo, sin borde. */
.btn-secondary, .btn-outline, .btn--ghost {
  background: var(--lila); color: var(--violet-deep);
}
.btn-secondary:hover:not(:disabled), .btn-outline:hover:not(:disabled), .btn--ghost:hover:not(:disabled) {
  background: var(--lila-idle); color: var(--violet-deep);
}
.btn-secondary:active:not(:disabled), .btn-outline:active:not(:disabled), .btn--ghost:active:not(:disabled) {
  background: var(--lila-idle);
}

/* Terciario: solo texto violeta, subrayado únicamente al pasar el cursor. */
.btn-ghost, .btn-text {
  background: transparent; color: var(--violet-deep); padding-inline: var(--sp-3);
}
.btn-ghost:hover:not(:disabled), .btn-text:hover:not(:disabled) {
  background: transparent; text-decoration: underline; text-underline-offset: 4px;
}
.btn-ghost:active:not(:disabled), .btn-text:active:not(:disabled) { background: transparent; }

/* Acción destructiva: coral fondo + coral tinta, nunca coral como texto suelto. */
.btn-danger { background: var(--coral-bg); color: var(--coral-ink); }
.btn-danger:hover:not(:disabled) { background: var(--coral-bg); color: var(--coral-ink); }

/* Alias heredados del sistema anterior: todo se resuelve en la paleta nueva. */
.btn--good, .btn--hint { background: var(--violet); color: var(--white); }
.btn--bad { background: var(--lila); color: var(--violet-deep); }

.btn-sm, .btn--sm { min-height: 44px; padding: 10px 20px; font-size: var(--fs-sm); }
.btn-lg { min-height: 60px; padding: 17px 34px; font-size: var(--fs-h3); }
.btn-block, .btn--block { width: 100%; }
@media (max-width: 639px) { .btn-stack { width: 100%; } }

/* Cargando: el botón conserva su tamaño y cambia el texto por tres puntos. */
.btn.is-loading { color: transparent; pointer-events: none; }
.btn.is-loading::after {
  content: '•••'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--white); font-size: 22px; letter-spacing: .16em;
  animation: dots 1s infinite ease-in-out;
}
.btn-secondary.is-loading::after, .btn-outline.is-loading::after,
.btn-ghost.is-loading::after, .btn-danger.is-loading::after { color: var(--violet-deep); }
@keyframes dots { 0% { opacity: .35 } 50% { opacity: 1 } 100% { opacity: .35 } }

.link {
  color: var(--violet-deep); font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 2px;
}
.link:hover { color: var(--violet); }
.link-muted { color: var(--ink-soft); }

/* ======================================================================
   7. COMPONENTES
   ====================================================================== */

/* -- etiquetas y badges: píldoras pequeñas ---------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  border-radius: var(--r-pill); padding: .35rem .85rem;
  font-size: var(--fs-sm); font-weight: 600; line-height: 1.35; white-space: nowrap;
  background: var(--lila); color: var(--violet-deep);
}
.badge-primary { background: var(--violet); color: var(--white); }
.badge-secondary, .badge-soft, .badge-outline, .badge-accent { background: var(--lila); color: var(--violet-deep); }
/* variante de logro: lima con verde tinta */
.badge-success, .badge-win { background: var(--lime); color: var(--lime-ink); }
/* de pago: amarillo con tinta oscura, el mismo par que la etiqueta de la
   rejilla. Nunca acompañado de un candado. */
.badge-paid { background: var(--paid); color: var(--paid-ink); }

/* -- tarjetas: sin sombra y sin borde --------------------------------- */
.card {
  background: var(--lila); border: 0; border-radius: var(--r-card);
  padding: var(--sp-6) var(--sp-5);
}
@media (min-width: 640px) { .card { padding: var(--sp-6); } }
.card-flat, .card--flat, .card-muted { background: var(--lila); }
.card-tint { background: var(--lila); }
.card-white { background: var(--white); }
.card-link { display: block; transition: transform var(--dur-fast) var(--ease-back); }
.card-link:hover { transform: translateY(-3px); }
.card-link:active { transform: translateY(1px) scale(.98); }
.card-title { font-size: var(--fs-h3); font-weight: 600; line-height: var(--lh-title); }
.card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); }

.panel { border-radius: var(--r-card); background: var(--lila); overflow: hidden; }
.panel > * + * { border-top: 1px solid var(--lila-idle); }
.panel-row {
  padding: var(--sp-4) var(--sp-5); display: flex; align-items: center;
  justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
}

.callout {
  background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-5); font-size: var(--fs-body);
}
.callout-accent { background: var(--lila); }
.callout-title { font-weight: 600; margin-bottom: var(--sp-1); }

/* -- cifras ------------------------------------------------------------ */
.stat { text-align: center; }
.stat-n { font-size: 34px; font-weight: 600; line-height: 1.1; color: var(--violet); font-variant-numeric: tabular-nums; }
.stat-l { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-1); }

/* -- formularios ------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.label { font-size: var(--fs-sm); font-weight: 600; }
.input, .select, .textarea {
  width: 100%; font-family: inherit; font-size: var(--fs-body); font-weight: 400; color: var(--ink);
  background: var(--white); border: 2px solid var(--lila-idle); border-radius: var(--r-field);
  padding: var(--sp-3) var(--sp-4); min-height: 52px;
  transition: border-color var(--dur-fast) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-faint); opacity: 1; }
.input:user-invalid, .select:user-invalid, .textarea:user-invalid { border-color: var(--coral); }
.textarea { min-height: 7rem; resize: vertical; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--violet); }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible { border-color: var(--violet); }
.input[aria-invalid='true'] { border-color: var(--coral); }
.hint { font-size: var(--fs-sm); color: var(--ink-soft); }
.check { display: flex; align-items: flex-start; gap: var(--sp-3); font-size: var(--fs-sm); line-height: 1.5; min-height: 44px; }
.check input { margin-top: .3rem; width: 1.35rem; height: 1.35rem; flex: none; accent-color: var(--violet); }
.hp { position: absolute; left: -9999px; opacity: 0; height: 0; width: 0; }

.alert { border-radius: var(--r-field); padding: var(--sp-4); font-size: var(--fs-sm); }
.alert-error { background: var(--coral-bg); color: var(--coral-ink); border-left: 6px solid var(--coral); }
.alert-ok { background: var(--lime); color: var(--lime-ink); font-weight: 600; }
.alert-info { background: var(--lila); color: var(--violet-deep); }
.alert[hidden] { display: none; }

.auth-shell { display: grid; place-items: center; padding-block: var(--sp-10) var(--sp-16); }
.auth-card { width: 100%; max-width: 27rem; }

/* -- barra de progreso continua (cuenta, catálogo) --------------------- */
.bar { height: 12px; border-radius: var(--r-pill); background: var(--lila-idle); overflow: hidden; }
.bar > i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--violet); transition: width var(--dur-slow) var(--ease); }

/* -- píldoras informativas --------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  background: var(--lila); border-radius: var(--r-pill);
  padding: 8px 16px; font-weight: 600; font-size: var(--fs-sm); white-space: nowrap;
  color: var(--violet-deep); min-height: 40px;
}
.pill .ic { width: 18px; height: 18px; display: block; }

/* -- contadores de logro: racha y experiencia --------------------------
   Son celebración pura, así que van en fucsia sobre su propio tinte, nunca
   en lila. La cifra es de 26 px (por encima del mínimo de 24 px que exige
   el fucsia como texto) y salta cuando sube. */
.pill--xp, .pill--streak {
  background: var(--fuchsia-bg); color: var(--fuchsia-ink);
  padding: 6px 18px 6px 14px; min-height: 52px; gap: var(--sp-3);
}
.pill--xp .ic, .pill--streak .ic { width: 22px; height: 22px; color: var(--fuchsia); }
.pill--xp .n, .pill--streak .n {
  font-size: 26px; font-weight: 600; line-height: 1.05; color: var(--fuchsia);
  font-variant-numeric: tabular-nums; display: block;
}
.pill--xp .k, .pill--streak .k {
  font-size: var(--fs-meta); font-weight: 400; color: var(--fuchsia-ink);
  line-height: 1.1; display: block;
}
.pill .nwrap { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }

/* Las dos píldoras de logro van SIEMPRE en una fila de dos columnas iguales:
   mismo ancho, mismo alto y misma línea de base. Apiladas y con anchos
   distintos parecían dos elementos sueltos sin relación entre sí. */
.statrow { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: var(--sp-3); }
.statrow .pill { width: 100%; min-width: 0; justify-content: flex-start; white-space: normal; }
.statrow .pill .k { overflow-wrap: anywhere; }
/* la cifra salta cuando sube; nunca cambia sin más */
@keyframes countPop {
  0% { transform: scale(1) } 35% { transform: scale(1.28) }
  70% { transform: scale(.94) } 100% { transform: scale(1) }
}
.is-up { animation: countPop 620ms var(--ease-back); }

/* ======================================================================
   8. CHROME
   Fondo blanco, sin borde inferior y sin sombra. El enlace de la sección
   actual va en violeta con un punto violeta debajo.
   ====================================================================== */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, .94); border-bottom: 1px solid var(--lila-idle);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}
.site-header .bar {
  min-height: var(--header-h); display: flex; align-items: center;
  justify-content: space-between; gap: var(--sp-4); padding-block: var(--sp-2);
  height: auto; border-radius: 0; background: none; overflow: visible;
}
.brand { display: inline-flex; align-items: center; gap: .65rem; color: var(--ink); min-height: 44px; }
.brand-symbol { width: 3rem; height: 3rem; flex: none; display: block; }
.brand-symbol img { width: 100%; height: 100%; display: block; object-fit: contain; }
.brand-wordmark { display: inline-flex; align-items: baseline; gap: .3rem; min-width: 0; font-size: 1.05rem; letter-spacing: -.025em; white-space: nowrap; }
.brand-wordmark b { font-weight: 600; }
.brand-wordmark span { color: var(--ink-soft); font-weight: 400; }
.nav { display: flex; align-items: center; gap: var(--sp-2); }
.nav a.nav-link {
  position: relative; font-size: var(--fs-sm); font-weight: 400; color: var(--ink-soft);
  padding: var(--sp-3); border-radius: var(--r-pill); min-height: 44px;
  display: inline-flex; align-items: center;
  transition: color var(--dur-fast) var(--ease);
}
.nav a.nav-link:hover { color: var(--ink); }
.nav a.nav-link[aria-current='page'] { color: var(--violet); font-weight: 600; }
.nav a.nav-link[aria-current='page']::after {
  content: ''; position: absolute; left: 50%; bottom: 4px; width: 6px; height: 6px;
  margin-left: -3px; border-radius: 50%; background: var(--violet);
}
/* T3.7 · La cabecera tiene UN solo elemento violeta, y es el botón. El enlace
   de entrar iba en violeta justo al lado del botón violeta: dos violetas
   seguidos que se restaban fuerza. Aquí va en el color de texto normal y solo
   se tiñe al pasar el cursor. */
.nav-login { color: var(--ink); font-weight: 400; }
.nav-login:hover:not(:disabled) { color: var(--violet-deep); }

.nav-desktop { display: none; }
@media (min-width: 900px) { .nav-desktop { display: flex; } }
.menu-toggle { display: inline-flex; }
@media (min-width: 900px) { .menu-toggle { display: none; } }
/* T4.1 · En móvil la acción principal está EN LA BARRA, no dentro del
   desplegable. En un producto que se presenta como hecho para el móvil, pedir
   que se abra un menú para empezar es perder la conversión en la primera
   pantalla. Es el botón pequeño, así que no compite con el principal del
   bloque que se esté mirando. */
.nav-cta { display: inline-flex; flex: 0 0 auto; }
@media (min-width: 900px) { .nav-cta { display: none; } }
.mobile-nav { display: none; background: var(--lila); }
.mobile-nav.open { display: block; }
.mobile-nav .wrap { padding-block: var(--sp-4) var(--sp-5); }
.mobile-nav a {
  display: flex; align-items: center; padding: var(--sp-3) var(--sp-2);
  font-size: var(--fs-body); min-height: 48px; color: var(--ink-soft);
}
.mobile-nav a:hover { color: var(--ink); }
.mobile-nav a[aria-current='page'] { color: var(--violet-deep); font-weight: 600; }
.mobile-nav .row { margin-top: var(--sp-3); }

.crumbs { font-size: var(--fs-meta); color: var(--ink-faint); padding-block: var(--sp-4) var(--sp-1); }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.crumbs li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.crumbs li + li::before { content: '·'; color: var(--lila-idle); }
.crumbs [aria-current='page'] { color: var(--ink-soft); }

.site-footer { background: var(--lila); margin-top: auto; }
.site-footer .cols { display: grid; gap: var(--sp-8); padding-block: var(--sp-12); grid-template-columns: 1fr; }
@media (min-width: 640px) { .site-footer .cols { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .site-footer .cols { grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; } }
.site-footer h2 { font-size: var(--fs-sm); color: var(--ink-soft); margin-bottom: var(--sp-3); font-weight: 600; }
.site-footer li { list-style: none; }
.site-footer ul { padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.site-footer a { font-size: var(--fs-sm); color: var(--ink-soft); display: inline-flex; align-items: center; min-height: 32px; }
.site-footer a:hover { color: var(--violet-deep); text-decoration: underline; text-underline-offset: 3px; }
/* La línea de abajo llevaba el copyright y el lema pegados, sin nada entre
   ellos, y se leía como una frase rota. Ahora hay un separador de verdad
   —punto medio, decorativo para un lector de pantalla— y en móvil desaparece
   porque la línea apila. */
.footer-bottom {
  border-top: 1px solid var(--lila-idle); padding-block: var(--sp-5);
  font-size: var(--fs-meta); color: var(--ink-faint);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
}
.footer-bottom .fb-sep { color: var(--lila-idle); }
@media (max-width: 479px) {
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: var(--sp-1); }
  .footer-bottom .fb-sep { display: none; }
}

/* ======================================================================
   9. PORTADA, CATÁLOGO Y PRO
   ====================================================================== */

.hero { display: grid; gap: var(--sp-8); align-items: center; }
@media (min-width: 900px) { .hero { grid-template-columns: 1.05fr .95fr; gap: var(--sp-10); } }
.hero-copy h1 { max-width: 15ch; }
.hero-copy .lead { max-width: 32rem; }
/* T4.4 · Bit se presenta DESPUÉS del titular, del apoyo y del botón. Antes iba
   encima del h1: la información menos importante del bloque en la posición más
   importante, y en móvil además duplicaba la mascota del logo cien píxeles más
   arriba. */
.hero-bit { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-5); }
.hero-bit .mascot { width: 56px; height: 56px; flex: 0 0 auto; }
.hero-bit .hb-t { font-size: var(--fs-sm); color: var(--ink-soft); max-width: 22rem; min-width: 0; }
.complete-offer {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  max-width: 32rem; padding: var(--sp-3) var(--sp-4);
  background: var(--lila); border-radius: var(--r-card);
  font-size: var(--fs-sm); color: var(--violet-deep);
}
.complete-offer .btn { flex: 0 0 auto; }
.read-mode { display: block; max-width: 11rem; line-height: 1.25; }
.legal-consent {
  padding: var(--sp-4); background: var(--lila); border-radius: var(--r-field);
}
/* El consentimiento de contenido digital es OBLIGATORIO pero no es venta: va
   pegado al botón de pagar y en letra pequeña, sin mezclarse con las promesas
   de arriba. La casilla conserva su área táctil. */
.check-legal { font-size: var(--fs-meta); line-height: 1.45; color: var(--ink-soft); }
@media (max-width: 520px) {
  .complete-offer { align-items: stretch; flex-direction: column; }
  .complete-offer .btn { width: 100%; }
}

.shotfig { margin: 0; }
/* La captura va dentro de un <picture> (AVIF / WebP / PNG). El envoltorio no
   pinta nada: se comporta como el <img> que envuelve. */
.shotpic { display: block; }
.shotfig img.shot { display: block; width: 100%; height: auto; border-radius: var(--r-card); background: var(--white); }
.shotfig figcaption { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-3); line-height: var(--lh-body); }
.shotfig.is-crop img.shot { max-height: 30rem; object-fit: cover; object-position: top center; }

/* T3.2 · Dos capturas EN PARALELO tienen que medir lo mismo. Las originales
   tienen proporciones distintas (1179×1500 y 1012×1395), así que sus pies
   caían a alturas diferentes —casi 150 px de desfase— y la diferencia se leía
   como un error de montaje. Aquí las dos imágenes comparten proporción y
   recorte, de modo que los pies arrancan en la misma línea de base. */
.shot-pair { display: grid; gap: var(--sp-8); align-items: start; }
@media (min-width: 760px) { .shot-pair { grid-template-columns: 1fr 1fr; gap: var(--sp-8); } }
.shot-pair .shotfig { display: grid; grid-template-rows: auto 1fr; }
.shot-pair .shotfig img.shot,
.shot-pair .shotfig.is-crop img.shot {
  aspect-ratio: 4 / 5; height: auto; max-height: none;
  object-fit: cover; object-position: top center;
}

.promise-grid { display: grid; gap: var(--sp-8); align-items: stretch; }
@media (min-width: 900px) { .promise-grid { grid-template-columns: 1.1fr .9fr; gap: var(--sp-10); } }
/* T3.1 · La columna corta (los cuatro logros) dejaba unos 300 px de vacío
   debajo y la sección se leía descolgada hacia la derecha. Ese hueco lo ocupa
   ahora el botón principal de mitad de página, que antes iba suelto y centrado
   más abajo: la columna se cierra y el llamamiento gana el sitio que le
   corresponde, al final de la lista de lo que se aprende. */
.promise-col { display: flex; flex-direction: column; gap: var(--sp-8); min-width: 0; }
.promise-col .promises { flex: 0 0 auto; }
.promise-col .promise-cta { margin-top: auto; }
@media (max-width: 899px) { .promise-col .promise-cta .btn { width: 100%; } }

.promises { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.promises li { display: flex; gap: var(--sp-3); align-items: flex-start; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--ink-soft); }
/* El texto de un logro puede encogerse; el icono no. Sin esto, en pantalla
   estrecha la línea larga empuja hacia fuera en vez de partirse. */
.promises li > *:not(.ic) { min-width: 0; overflow-wrap: anywhere; }
.promises li strong { color: var(--ink); font-weight: 600; }
/* T3.9 · El icono que marca cada logro es lo que da la lista por buena, así
   que se ve: violeta sólido sobre chip lila (no gris claro), un punto más
   grande y con peso. */
.promises .ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; margin-top: 1px;
  display: grid; place-items: center; background: var(--lila); color: var(--violet);
  font-weight: 600; font-size: var(--fs-body); line-height: 1;
}
.section-alt .promises .ic { background: var(--white); }
.promises-tight li { font-size: var(--fs-sm); gap: var(--sp-3); }
.promises-tight .ic { width: 25px; height: 25px; font-size: var(--fs-sm); }
.price-list .ic { font-size: var(--fs-body); }

.faq { display: flex; flex-direction: column; gap: var(--sp-3); }
.faq-item { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); }
.section-alt .faq-item { background: var(--white); }
.faq-item summary { cursor: pointer; font-weight: 600; font-size: var(--fs-body); line-height: var(--lh-title); min-height: 44px; display: flex; align-items: center; }
.faq-item p { font-size: var(--fs-sm); color: var(--ink-soft); line-height: var(--lh-body); margin-top: var(--sp-3); }

.module-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.lesson-list { display: grid; gap: var(--sp-3); }
.lesson-row {
  display: flex; align-items: center; gap: var(--sp-4);
  border: 0; border-radius: var(--r-card); background: var(--lila);
  padding: var(--sp-4) var(--sp-5); min-height: 76px;
  transition: transform var(--dur-fast) var(--ease-back), background var(--dur-fast) var(--ease);
}
a.lesson-row:hover { transform: translateY(-2px); background: var(--lila-idle); }
a.lesson-row:active { transform: translateY(1px) scale(.98); }
/* El número lleva la identidad de color de la lección: chip del tinte con
   tinta encima (nunca texto blanco sobre un tono claro) y un anillo del
   color saturado. */
.lesson-n {
  flex: none; width: 46px; height: 46px; border-radius: var(--r-pill); display: grid; place-items: center;
  font-size: var(--fs-sm); font-weight: 600; background: var(--lt); color: var(--ink);
  box-shadow: inset 0 0 0 3px var(--lc);
  font-variant-numeric: tabular-nums;
}
/* Lo que aún no existe se apaga; lo de pago conserva su color, porque la
   lección está ahí y lo único que falta es el plan. */
.lesson-row.is-planned .lesson-n, .lesson-row.is-locked .lesson-n {
  /* Sobre el lila inactivo ni el gris flojo ni el secundario llegan a 4,5:1
     (3,70 y 4,06): un número que hay que leer va en tinta principal. */
  background: var(--lila-idle); color: var(--ink); box-shadow: none;
}
.lesson-main { flex: 1 1 auto; min-width: 0; }
.lesson-title { font-weight: 600; font-size: var(--fs-body); line-height: var(--lh-title); }
.lesson-sub { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: 3px; overflow-wrap: anywhere; }
.lesson-meta { flex: none; display: flex; align-items: center; gap: var(--sp-2); }
@media (max-width: 480px) {
  .lesson-row { flex-wrap: wrap; }
  .lesson-meta { width: 100%; padding-left: calc(46px + var(--sp-4)); }
}

.gate, .gate-hero { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-6); }
@media (min-width: 640px) { .gate { padding: var(--sp-10); } }

.price-card { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-6); display: grid; gap: var(--sp-4); }
/* T1.5 · A un metro de la pantalla se lee la CIFRA, no la palabra impuesto.
   La mención del IVA iba al mismo tamaño de titular que el importe y se comía
   la mitad del espacio visual. Ahora es texto pequeño al lado de la cifra, y
   la píldora de «pago único» se apoya en la misma línea de base que el
   número en vez de flotar a media altura. */
.price-main { display: flex; align-items: baseline; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; }
/* Ninguna de las tres piezas se parte: la cifra («39 €») cortada en dos
   líneas era lo peor que podía pasarle a este bloque. */
.price-n { font-size: clamp(38px, 2rem + 3vw, 56px); font-weight: 600; line-height: 1; color: var(--violet); letter-spacing: -.03em; white-space: nowrap; }
.price-vat { font-size: var(--fs-sm); color: var(--ink-soft); line-height: 1; white-space: nowrap; }
.price-tag { font-size: var(--fs-sm); font-weight: 600; color: var(--violet-deep); background: var(--white); border-radius: var(--r-pill); padding: .3rem .9rem; line-height: 1; white-space: nowrap; }
/* T1.1 · El bloque de precio es donde se decide la compra, así que termina en
   UN botón principal sólido de ancho generoso. Debajo, en texto pequeño, la
   salida gratuita: nunca al lado ni con el mismo peso. */
.price-act { display: grid; gap: var(--sp-3); justify-items: stretch; }
.price-act .btn-primary { width: 100%; }
.price-alt { font-size: var(--fs-sm); color: var(--ink-soft); text-align: center; margin: 0; }
.price-alt .link { font-weight: 600; }
.price-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-2); font-size: var(--fs-sm); }

/* -- con qué comparar el precio -------------------------------------------
   Va DEBAJO de la tarjeta de precio y ENCIMA del botón, que es el orden en el
   que se hace la pregunta. No compite con la tarjeta: fondo blanco con filete
   lila, texto normal y ninguna cifra a tamaño de titular, porque la única
   cifra grande de la pantalla tiene que seguir siendo el precio real. */
.price-compare {
  background: var(--white); border: 2px solid var(--lila-idle);
  border-radius: var(--r-card); padding: var(--sp-5);
}
.price-compare-t { font-size: var(--fs-sm); font-weight: 600; color: var(--ink); }
.price-compare-b { font-size: var(--fs-sm); color: var(--ink-soft); line-height: var(--lh-body); margin-top: var(--sp-2); }
.price-list li { display: flex; gap: var(--sp-2); align-items: flex-start; }
.price-list .ic { color: var(--violet); font-weight: 600; flex: none; }

/* El ancla de lanzamiento: la cifra que se paga en violeta (es la acción) y la
   cifra futura tachada en gris de apoyo. NO es un descuento y no se pinta como
   tal: nada de rojo, nada de insignia de porcentaje. La etiqueta que la
   acompaña dice siempre «después / later / ensuite». Ver src/pricing.js. */
.price-anchor { display: inline-flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; margin: 0; }
.price-anchor .pa-now { font-size: var(--fs-h3); font-weight: 600; color: var(--violet); letter-spacing: -.02em; line-height: 1; }
/* La palabra («después», «later», «ensuite») va SIEMPRE con la cifra y NO va
   tachada: es lo que impide leer el tachado como una rebaja pasada. */
.pa-later { color: var(--ink-soft); white-space: nowrap; }
.pa-was { text-decoration: line-through; text-decoration-thickness: 1px; }
.price-main .pa-later { font-size: var(--fs-h3); }
.price-anchor .pa-flag,
.pa-flag { font-size: var(--fs-meta); font-weight: 600; color: var(--violet-deep); background: var(--lila); border-radius: var(--r-pill); padding: .25rem .75rem; }
.price-card .pa-flag { background: var(--white); }

/* Código de compra: se lee en voz alta y se copia a mano, así que va en
   monoespaciada, holgado y sobre el lienzo lila. No es un botón ni una marca:
   ni violeta sólido ni color de lección. */
.refcode {
  font-family: var(--mono); font-size: var(--fs-sm); font-weight: 600;
  color: var(--violet-deep); background: var(--lila); border-radius: var(--r-field);
  padding: .7rem .9rem; letter-spacing: .04em; word-break: break-all; margin: 0;
}

/* -- tabla del panel interno ------------------------------------------- */
.table-wrap { overflow-x: auto; border-radius: var(--r-card); background: var(--lila); }
table.data { border-collapse: collapse; width: 100%; font-size: var(--fs-sm); }
table.data th, table.data td { text-align: left; padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--lila-idle); white-space: nowrap; }
table.data th { font-size: var(--fs-meta); color: var(--ink-soft); font-weight: 600; }
table.data tr:last-child td { border-bottom: 0; }
table.data td.num { text-align: right; font-variant-numeric: tabular-nums; }
.funnel-row { display: grid; grid-template-columns: 12rem 1fr 4rem; gap: var(--sp-3); align-items: center; font-size: var(--fs-sm); }
@media (max-width: 639px) { .funnel-row { grid-template-columns: 8rem 1fr 3rem; } }

/* ======================================================================
   10. MI CAMINO — el color como progreso

   Cada lección tiene un color propio de una paleta de CINCO que rota por
   posición dentro de la unidad (1ª índigo, 2ª cian, 3ª turquesa, 4ª mango,
   5ª sol). Mientras está pendiente ese color solo asoma en la franja
   superior y en el icono; al completarla, la tarjeta se pinta entera con su
   tinte y se queda así para siempre. Después de cinco o seis lecciones la
   pantalla es un mapa de color que ha ganado el alumno.

   Los cinco colores NO se escriben en esta hoja: llegan por --lc (saturado),
   --lt (tinte) y --ls (desaturado claro) en el estilo de cada tarjeta, así
   que por construcción no pueden aparecer en un botón, en un aviso ni en la
   navegación.
   ====================================================================== */

.path-shell { max-width: 64rem; margin: 0 auto; padding: 0 0 var(--sp-16); }
/* La acción va PRIMERA también en el documento, así que el orden visual y el
   orden de tabulación coinciden: nadie ve un botón arriba y llega a él el
   último. En el móvil la columna sigue el documento tal cual. */
/* En MÓVIL el orden es: acción, lista de lecciones y, al final, el progreso.
   Antes el saludo de Bit y el bloque de contadores se metían entre la acción y
   el contenido, así que lo primero que veía quien vuelve no era dónde
   continuar. En escritorio la rejilla de abajo ya los pone en columnas y el
   `order` no interviene. */
.path-layout { display: flex; flex-direction: column; }
/* En móvil el carril no existe como caja: sus dos hijos son hijos directos del
   flex y conservan su orden (acción, lista, progreso). */
.path-rail { display: contents; }
.path-next { order: 1; }
.path-main { order: 2; }
.path-side { display: block; order: 3; }
@media (min-width: 1000px) {
  .path-layout {
    display: grid; grid-template-columns: 19rem minmax(0, 1fr);
    column-gap: var(--sp-8); row-gap: var(--sp-5); align-items: start;
  }
  /* T3.4 · En escritorio la columna izquierda ACOMPAÑA al desplazamiento. La
     lista de lecciones mide varios miles de píxeles y esa columna se quedaba
     en blanco desde la unidad 2 en adelante. Ahora la acción de continuar y el
     resumen de avance van en el mismo carril pegajoso: al llegar a la unidad 4
     siguen a la vista, que es exactamente para lo que sirven. */
  .path-rail {
    display: flex; flex-direction: column; gap: var(--sp-3);
    grid-column: 1; grid-row: 1; align-self: start;
    position: sticky; top: calc(var(--header-h) + var(--sp-4));
    max-height: calc(100dvh - var(--header-h) - var(--sp-8));
    overflow-y: auto; overscroll-behavior: contain;
    padding-right: 2px; scrollbar-width: thin;
  }
  .path-next { margin: 0; }
  .path-next .btn { width: 100%; }
  .path-side { margin: 0; }
  .path-main { grid-column: 2; grid-row: 1; min-width: 0; }
  .path-main .unit:first-child { margin-top: 0; }
}

/* -- El titular de «Mi camino» -----------------------------------------
   La promesa de la casa, en una línea y a todo el ancho, encima de la
   acción. Un escalón por debajo del titular de portada (34 px como máximo)
   para que no compita con él: esta no es una página de venta. */
.path-title {
  font-size: var(--fs-h2); letter-spacing: -.018em;
  margin: var(--sp-6) 0 0; max-width: 22ch;
}
@media (max-width: 599px) { .path-title { margin-top: var(--sp-4); } }
.path-sub { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-2); }

/* -- La acción, lo primero de la página --------------------------------
   Una sola cosa que hacer: la lección que toca (o la primera, si es la
   primera visita) con su botón. Es el único botón violeta de la pantalla. */
.path-next {
  background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-5); margin: var(--sp-5) 0 0;
  display: flex; gap: var(--sp-4); align-items: center;
  justify-content: space-between; flex-wrap: wrap;
}
.pnext-copy { min-width: 0; flex: 1 1 15rem; }
/* Sobre lila lienzo el gris de metadatos se queda en 2,6:1, así que aquí el
   antetítulo va en violeta profundo (9,1:1) y nunca en --ink-faint. */
.pnext-kicker { font-size: var(--fs-meta); font-weight: 600; color: var(--violet-deep); }
.pnext-title { font-size: var(--fs-h3); color: var(--ink); margin-top: var(--sp-1); line-height: var(--lh-title); }
.pnext-meta { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-1); }
.path-next .btn { flex: 0 0 auto; white-space: normal; }
@media (max-width: 599px) { .path-next .btn { width: 100%; } }

.path-hero {
  background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-5); margin: var(--sp-5) 0 var(--sp-2);
  display: flex; gap: var(--sp-4); align-items: center;
}
.path-hero .mascot { flex: 0 0 auto; width: 76px; height: 76px; }
.path-hero h2 { font-size: var(--fs-h3); margin-bottom: var(--sp-1); }
.path-hero p { font-size: var(--fs-sm); color: var(--ink-soft); }
@media (min-width: 1000px) {
  .path-side .path-hero { flex-direction: column; text-align: center; margin-top: 0; }
  .path-side .path-hero .mascot { width: 104px; height: 104px; }
}

/* -- B7. La colección ---------------------------------------------------
   Las veinte lecciones como cuadraditos de color, en una sola pantalla y
   sin desplazamiento. Cierra la página: primero se hace el camino, y aquí
   abajo se ve lo que se lleva pintado. */
.omap { margin: var(--sp-10) 0 var(--sp-6); padding-top: var(--sp-8); border-top: 1px solid var(--lila-idle); }
.omap-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.omap-headings { min-width: 0; flex: 1 1 18rem; }
.omap-head h2 { font-size: var(--fs-h3); }
.omap-note { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-1); max-width: 34rem; }
.omap-count { font-size: var(--fs-sm); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
/* Cuadraditos pequeños de verdad: la rejilla entera cabe en un bloque de
   340 px, así que las veinte lecciones se leen de un vistazo y la imagen se
   puede compartir tal cual. */
.omap-grid { display: flex; flex-direction: column; gap: 8px; margin-top: var(--sp-4); max-width: 340px; }
.omap-row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.ocell {
  position: relative; aspect-ratio: 1 / 1; border-radius: 10px; display: block;
  background: var(--lila-idle); transition: transform var(--dur-fast) var(--ease-back);
}
a.ocell:hover { transform: translateY(-2px); }
.ocell.o-done { background: var(--lc); }
.ocell.o-open { background: var(--ls); }
.ocell.o-paid { background: var(--ls); }
.ocell.o-paid::after {
  content: ''; position: absolute; right: 4px; top: 4px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--paid);
}
/* Igual que la tarjeta bloqueada: el cuadradito insinúa su color, no se apaga
   del todo. Sin esto media colección era un bloque gris. */
.ocell.o-locked { background: var(--ls); opacity: .42; }
.ocell.o-next { background: var(--white); box-shadow: inset 0 0 0 3px var(--violet); }
.omap-key { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-3); font-size: var(--fs-meta); color: var(--ink-soft); }
.omap-key span { display: inline-flex; align-items: center; gap: 7px; }
.omap-key i { width: 14px; height: 14px; border-radius: 8px; display: block; }
.omap-key .k-done { background: var(--violet); }
.omap-key .k-open { background: var(--white); box-shadow: inset 0 0 0 3px var(--violet); }
.omap-key .k-rest { background: var(--lila-idle); }
/* El cuarto estado, que antes no se explicaba: cuadradito con color suave y
   punto amarillo. Es exactamente el dibujo de `.ocell.o-paid`. */
.omap-key .k-paid { background: var(--lila-idle); position: relative; }
.omap-key .k-paid::after {
  content: ''; position: absolute; right: 1px; top: 1px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--paid);
}

/* La cabecera fija no puede tapar el título al que se salta. */
.omap, .unit, [id^='unidad-'], .path-next { scroll-margin-top: calc(var(--header-h) + var(--sp-4)); }

/* -- B6. Cabecera de unidad --------------------------------------------
   Nombre, descripción y, a la derecha, cuántas lecciones lleva de cuántas
   con una barra de tramos. Al cerrarse entera, marca lima y tinte suave. */
.unit { margin-top: var(--sp-10); }
.unit-head {
  padding: 0 0 var(--sp-4); display: flex; gap: var(--sp-4);
  align-items: flex-start; justify-content: space-between; flex-wrap: wrap;
}
.unit-head .kicker { font-size: var(--fs-meta); color: var(--ink-faint); }
.unit-head h2 { font-size: var(--fs-h3); color: var(--ink); margin-top: var(--sp-1); display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.unit-head p { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-1); max-width: 34rem; }
/* T2.4 · La condición de las de pago, una sola vez por unidad y en UNA LÍNEA.
   Es la frase que evita el malentendido sobre el pago, así que se lee: tamaño
   de texto pequeño (no de metadato), tinta principal y un punto amarillo que
   la ata a la etiqueta de las tarjetas. Antes ocupaba dos líneas en el gris
   que no cumplía contraste y nadie la leía. */
.unit-head .unit-paid {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--ink); margin-top: var(--sp-3);
  line-height: var(--lh-title);
}
.unit-head .unit-paid::before {
  content: ''; flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%;
  background: var(--paid);
}
.unit-main { min-width: 0; flex: 1 1 18rem; }
.unit-score { flex: 0 0 auto; display: flex; flex-direction: column; gap: var(--sp-2); align-items: flex-end; min-width: 8.5rem; }
.unit-count { font-size: var(--fs-sm); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
/* T2.5 · Con cero lecciones hechas la barra tiene que VERSE y tienen que
   contarse los cinco tramos: el hueco pendiente es lo que motiva. Los tramos
   vacíos llevan cuerpo (un punto más de tono) y contorno tenue; el tramo hecho
   se pinta de violeta y pierde el contorno. */
.ubar { display: flex; gap: 4px; align-items: center; width: 8.5rem; }
.ubar i {
  flex: 1 1 0; height: 10px; border-radius: var(--r-pill); display: block;
  background: var(--lila-idle);
  box-shadow: inset 0 0 0 1px rgba(16, 13, 28, .16);
  transition: background var(--dur) var(--ease);
}
.ubar i.is-done { background: var(--violet); box-shadow: none; }
.unit-flag {
  display: inline-flex; align-items: center; gap: 5px; border-radius: var(--r-pill);
  padding: 3px 11px; font-size: var(--fs-meta); font-weight: 600;
  background: var(--lime); color: var(--lime-ink);
}
.unit-head.is-complete {
  background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-4);
}

/* -- B3. Anatomía de la tarjeta -----------------------------------------
   Franja de color arriba, icono en chip, numeración, título, descripción y
   acción solo en la disponible. Radio grande, sin borde salvo en la
   disponible, sin sombra en ningún estado. */
/* T3.3 · `grid-auto-rows: 1fr` iguala TODAS las filas de una unidad, así que
   las cinco tarjetas miden lo mismo. Con alturas automáticas la fila de tres y
   la de dos salían distintas y la disposición 3+2 se leía como una rejilla
   rota en vez de como una decisión. */
.trail { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: var(--sp-3); }
@media (min-width: 760px) { .trail { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.lcard {
  position: relative; overflow: hidden; display: flex; flex-direction: column; gap: var(--sp-2);
  min-height: 168px; padding: calc(var(--sp-4) + 8px) var(--sp-4) var(--sp-4);
  border: 0; border-radius: var(--r-card);
  background: var(--white); color: var(--ink); text-align: left;
  font-family: inherit; font-size: var(--fs-sm); cursor: default;
  transition: transform var(--dur-fast) var(--ease-back), background var(--dur) var(--ease);
}
/* la franja de color: lo que pinta la rejilla sin tocar la legibilidad */
.lcard-strip { position: absolute; left: 0; right: 0; top: 0; height: 8px; background: var(--ls); display: block; }
.lcard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2); }
.lcard-ic {
  width: 38px; height: 38px; flex: 0 0 auto; display: grid; place-items: center;
  border-radius: var(--r-pill); background: var(--lt); color: var(--lc);
}
.lcard-ic svg { width: 21px; height: 21px; }
.lcard-n { font-size: var(--fs-meta); color: var(--ink-soft); }
.lcard-title { font-size: var(--fs-sm); font-weight: 600; line-height: var(--lh-title); color: var(--ink); }
.lcard-title, .lcard-sub, .lcard-note { overflow-wrap: anywhere; hyphens: auto; }
.lcard-sub { font-size: var(--fs-meta); color: var(--ink-soft); line-height: 1.4; }
.lcard-note { font-size: var(--fs-meta); color: var(--ink-soft); line-height: 1.35; margin-top: auto; }
.lcard-tag {
  display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  border-radius: var(--r-pill); padding: 4px 11px; font-size: var(--fs-meta); font-weight: 600;
  background: var(--lila); color: var(--violet-deep);
}
/* la acción: solo la lleva la lección disponible, y es píldora violeta */
.lcard-go {
  margin-top: auto; align-self: stretch; text-align: center;
  background: var(--violet); color: var(--white); border-radius: var(--r-pill);
  padding: 11px 18px; font-size: var(--fs-sm); font-weight: 600; min-height: 44px;
  display: flex; align-items: center; justify-content: center;
}

a.lcard, button.lcard { cursor: pointer; }
a.lcard:hover, button.lcard:hover { transform: translateY(-3px); }
a.lcard:active, button.lcard:active { transform: translateY(1px) scale(.98); }

/* -- B4. Los cinco estados ---------------------------------------------- */

/* 1. COMPLETADA — la que el alumno colecciona, y la más bonita de las cinco:
      fondo del tinte, franja saturada, icono a color sobre chip blanco y
      etiqueta lima con la marca de verificación. */
.lcard.is-done { background: var(--lt); }
.lcard.is-done .lcard-strip { background: var(--lc); }
.lcard.is-done .lcard-ic { background: var(--white); color: var(--lc); }
.lcard.is-done .lcard-tag { background: var(--lime); color: var(--lime-ink); }
.lcard.is-done .lcard-title { color: var(--ink); }
.lcard.is-done .lcard-sub, .lcard.is-done .lcard-n { color: var(--ink-soft); }

/* 2. DISPONIBLE — la siguiente que toca. Blanca, contorno violeta grueso con
      pulso lento y la ÚNICA con botón. Solo puede haber una. */
.lcard.is-next { background: var(--white); box-shadow: inset 0 0 0 3px var(--violet); }
.lcard.is-next .lcard-strip { background: var(--lc); }
.lcard.is-next .lcard-ic { background: var(--lt); color: var(--lc); }
.lcard.is-next::after {
  content: ''; position: absolute; inset: 0; border-radius: var(--r-card);
  animation: slowPulse 2.6s var(--ease) infinite; pointer-events: none;
}
@keyframes slowPulse {
  0% { box-shadow: 0 0 0 0 rgba(108, 43, 247, .38) }
  70% { box-shadow: 0 0 0 14px rgba(108, 43, 247, 0) }
  100% { box-shadow: 0 0 0 0 rgba(108, 43, 247, 0) }
}

/* 3. PENDIENTE PERO ACCESIBLE — lila lienzo, franja desaturada que insinúa
      el color que va a ganar, icono a color. Sin botón y sin etiqueta. */
.lcard.is-open { background: var(--lila); }
.lcard.is-open .lcard-strip { background: var(--ls); }
.lcard.is-open .lcard-ic { background: var(--lt); color: var(--lc); }

/* 4. DE PAGO — idéntica a la pendiente más una etiqueta amarilla. SIN
      candado: la lección se puede abrir, lo que hace falta es el plan. */
.lcard.is-paid { background: var(--lila); }
.lcard.is-paid .lcard-strip { background: var(--ls); }
.lcard.is-paid .lcard-ic { background: var(--lt); color: var(--lc); }
/* T1.8 · MISMA familia de color, mucho menos peso. La etiqueta amarilla
   sólida era el elemento con más fuerza de toda la pantalla y lo primero que
   comunicaba el camino era que hay cosas que cuestan dinero. Ahora es el
   amarillo en versión clara con su tinta oscura y un punto sólido delante:
   se lee igual, pero por debajo de las franjas de color de las lecciones. */
.lcard.is-paid .lcard-tag {
  background: color-mix(in srgb, var(--paid) 20%, var(--white));
  color: var(--paid-ink); font-weight: 600;
}
.lcard.is-paid .lcard-tag::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--paid); flex: 0 0 auto;
}

/* 5. BLOQUEADA — gris lila, sin color propio, candado gris y, debajo, la
      condición para abrirla. Se ve siempre: esconderla motiva menos. */
/* T2.2 · La franja NO es gris: es el color que la lección va a ganar, en una
   versión muy clara. La página promete que cada lección tiene su color, y una
   tarjeta completamente gris rompía esa promesa justo donde hay que motivar.
   El resto de la tarjeta sigue apagado, así que una completada se distingue de
   una bloqueada sin leer una palabra. */
.lcard.is-locked { background: var(--lila-dim); }
.lcard.is-locked .lcard-strip { background: var(--ls); opacity: .42; }
.lcard.is-locked .lcard-ic { background: var(--lila-idle); color: var(--ink-soft); }
.lcard.is-locked .lcard-title, .lcard.is-locked .lcard-n,
.lcard.is-locked .lcard-sub, .lcard.is-locked .lcard-note { color: var(--ink-soft); }

/* -- B5. El momento de completar ----------------------------------------
   Al volver al camino, la tarjeta recién terminada se rellena de su color
   con un barrido de izquierda a derecha, la etiqueta lima entra con un
   rebote y la siguiente empieza su pulso. */
@keyframes sweepAway { from { transform: scaleX(1) } to { transform: scaleX(0) } }
.lcard.is-sweep > .lcard-strip,
.lcard.is-sweep > .lcard-top,
.lcard.is-sweep > .lcard-n,
.lcard.is-sweep > .lcard-title,
.lcard.is-sweep > .lcard-sub { position: relative; z-index: 1; }
.lcard.is-sweep::before {
  content: ''; position: absolute; inset: 0; z-index: 0; background: var(--lila);
  transform-origin: right; animation: sweepAway 520ms var(--ease) forwards;
}
@keyframes tagPop {
  0% { transform: scale(.4); opacity: 0 }
  60% { transform: scale(1.18); opacity: 1 }
  100% { transform: scale(1); opacity: 1 }
}
.lcard.is-sweep .lcard-tag { animation: tagPop 460ms var(--ease-back) 420ms both; }

.plain-path { list-style: none; padding: 0; margin: var(--sp-4) 0 0; display: grid; gap: var(--sp-3); }
.plain-path li { background: var(--lila); border-radius: var(--r-field); padding: var(--sp-3) var(--sp-4); }
.plain-path .t { font-weight: 600; }
.plain-path .s { font-size: var(--fs-sm); color: var(--ink-soft); }

/* leyenda del camino */
.trail-key { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-5); font-size: var(--fs-meta); color: var(--ink-soft); }
.trail-key span { display: inline-flex; align-items: center; gap: 7px; }
.trail-key i { width: 14px; height: 14px; border-radius: var(--r-pill); display: block; }
.trail-key .k-done { background: var(--lime); }
.trail-key .k-open { background: var(--white); box-shadow: inset 0 0 0 3px var(--violet); }
.trail-key .k-paid { background: var(--paid); }
.trail-key .k-locked { background: var(--lila-idle); }

/* ======================================================================
   11. REPRODUCTOR DE LECCIÓN
   ====================================================================== */

.player-page { background: var(--white); min-height: 100dvh; }
.pshell { max-width: var(--column); margin: 0 auto; padding: 0 var(--sp-5) var(--sp-16); position: relative; }
.screen { display: none; }
.screen.is-on { display: block; }

/* barra de progreso anclada arriba y visible toda la lección */
.lhead {
  position: sticky; top: 0; z-index: 20; background: var(--white);
  padding: calc(var(--sp-3) + env(safe-area-inset-top)) 0 var(--sp-4); display: flex; align-items: center; gap: var(--sp-3);
  border-bottom: 1px solid var(--lila-idle);
}
.iconbtn {
  width: 44px; height: 44px; flex: 0 0 auto; border: 0; background: transparent; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--ink-soft);
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease-back);
}
.iconbtn:hover { background: var(--lila); color: var(--ink); }
.iconbtn:active { transform: translateY(1px) scale(.98); }
.iconbtn svg { width: 24px; height: 24px; }
.lesson-brand { width: 30px; height: 30px; flex: 0 0 auto; display: block; }
.lesson-brand img { width: 100%; height: 100%; display: block; }

/* tramos discretos: uno por paso */
.pbar { flex: 1; display: flex; gap: 4px; align-items: center; min-height: 14px; }
.pbar i { flex: 1 1 0; height: 8px; border-radius: var(--r-pill); background: var(--lila-idle); display: block; transition: background var(--dur) var(--ease); }
.pbar i.is-done { background: var(--violet); }
.pbar i.is-now { background: var(--violet); animation: breathe 2.2s ease-in-out infinite; }
@keyframes breathe { 0%, 100% { opacity: 1; transform: scaleY(1) } 50% { opacity: .72; transform: scaleY(1.6) } }

.scard { background: var(--white); border-radius: var(--r-card); padding: var(--sp-6) 0 0; }
.step-kicker { font-size: var(--fs-meta); color: var(--ink-faint); }
/* El contador de la cabecera. Cifras de ancho fijo para que no baile al pasar
   de 9/10 a 10/10, y nunca compite con la barra: es del gris más discreto. */
.pcount { flex: 0 0 auto; font-size: var(--fs-meta); color: var(--ink-faint);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Lo que cuesta esto entero, dicho ANTES de la primera respuesta y solo ahí. */
.step-promise { font-size: var(--fs-meta); color: var(--ink-soft); margin-top: var(--sp-1); }
.q { font-size: var(--fs-h2); font-weight: 600; line-height: var(--lh-title); margin: var(--sp-3) 0 var(--sp-2); letter-spacing: -.015em; }
.qlead { font-size: var(--fs-body); color: var(--ink-soft); line-height: var(--lh-body); }

/* -- opciones de respuesta --------------------------------------------- */
.opts { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-6); }
.opt {
  display: flex; align-items: center; gap: var(--sp-4); width: 100%; text-align: left;
  min-height: 64px; padding: var(--sp-4); cursor: pointer; position: relative;
  background: var(--white); border: 2px solid var(--lila-idle); border-radius: var(--r-field);
  font-family: inherit; font-size: var(--fs-body); font-weight: 400; line-height: 1.4; color: var(--ink);
  transition: transform var(--dur-fast) var(--ease-back), background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.opt:hover:not(:disabled) { background: var(--lila); border-color: var(--lila); }
.opt:active:not(:disabled) { transform: translateY(1px) scale(.98); }
/* El texto de la opción tiene que poder encogerse: sin `min-width:0` un
   elemento flexible se planta en su ancho natural y desborda la pantalla. */
.opt > span:not(.key) { min-width: 0; overflow-wrap: anywhere; }
.opt .key {
  width: 32px; height: 32px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--lila);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm);
  font-weight: 600; color: var(--violet-deep);
}
.opt.is-sel { background: var(--lila); border-color: var(--violet); }
.opt.is-sel .key { background: var(--violet); color: var(--white); }
/* acierto: lima + verde tinta + semibold + marca de verificación */
.opt.is-ok { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); font-weight: 600; }
.opt.is-ok .key { background: var(--lime-ink); color: var(--white); }
.opt.is-ok::after { content: '✓'; margin-left: auto; font-weight: 600; color: var(--lime-ink); font-size: var(--fs-h3); }
/* fallo: coral fondo + coral tinta + filo lateral, sin dramatismo */
.opt.is-no { background: var(--coral-bg); border-color: var(--coral-bg); color: var(--coral-ink); border-left: 6px solid var(--coral); }
.opt.is-no .key { background: var(--coral); color: var(--white); }
.opt:disabled { cursor: default; }

.tf { display: flex; gap: var(--sp-3); margin-top: var(--sp-6); }
.tf .btn { flex: 1; }

/* -- montar el proceso por toques --------------------------------------- *
   La cadena que se va construyendo arriba (piezas ya colocadas, en lima) y
   las candidatas debajo, que son botones `.opt` normales: mismo tamaño de
   toque y mismo lenguaje visual que el resto de ejercicios. Sin flechas y
   sin arrastrar. */
.chain { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-6); list-style: none; padding: 0; }
.chain:empty { margin-top: 0; }
.chain-item {
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--lime); border: 2px solid var(--lime); border-radius: var(--r-field);
  color: var(--lime-ink); font-weight: 600;
  padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); line-height: 1.4; min-height: 64px;
  animation: chain-in var(--dur-fast) var(--ease-back) both;
}
.chain-num {
  width: 32px; height: 32px; flex: 0 0 auto; border-radius: var(--r-pill);
  background: var(--lime-ink); color: var(--white);
  display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: var(--fs-sm);
}
.chain-txt { flex: 1; min-width: 0; overflow-wrap: anywhere; }
@keyframes chain-in { from { opacity: 0; transform: translateY(-8px) scale(.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .chain-item { animation: none; } }

/* -- emparejar ---------------------------------------------------------- */
.match { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); margin-top: var(--sp-6); }
.mcol { display: flex; flex-direction: column; gap: var(--sp-2); }
.mcol h4 { font-size: var(--fs-meta); color: var(--ink-faint); font-weight: 400; }
.mitem {
  min-height: 64px; padding: var(--sp-3); text-align: left; cursor: pointer;
  background: var(--white); border: 2px solid var(--lila-idle); border-radius: var(--r-field);
  font-family: inherit; font-size: var(--fs-sm); line-height: 1.4; color: var(--ink);
  transition: transform var(--dur-fast) var(--ease-back), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.mitem:hover:not(.is-ok) { background: var(--lila); border-color: var(--lila); }
.mitem:active:not(:disabled) { transform: translateY(1px) scale(.98); }
.mitem.is-sel { background: var(--lila); border-color: var(--violet); }
.mitem.is-ok { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); font-weight: 600; cursor: default; }
.mitem.is-no { background: var(--coral-bg); border-color: var(--coral-bg); color: var(--coral-ink); border-left: 6px solid var(--coral); }

/* -- constructor de instrucciones --------------------------------------- */
.slot { margin-top: var(--sp-6); }
.slot-label { display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.slot-label .n { font-size: var(--fs-body); font-weight: 600; }
.slot-label .h { font-size: var(--fs-sm); color: var(--ink-soft); }
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.chip {
  min-height: 44px; padding: 11px 18px; border-radius: var(--r-pill); cursor: pointer;
  background: var(--lila); border: 0; color: var(--violet-deep);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 600;
  transition: transform var(--dur-fast) var(--ease-back), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.chip:hover:not(.is-on) { background: var(--lila-idle); }
.chip:active { transform: translateY(1px) scale(.98); }
.chip.is-on { background: var(--violet); color: var(--white); }
.promptbox {
  margin-top: var(--sp-6); background: var(--lila); border-radius: var(--r-field);
  padding: var(--sp-5); font-size: var(--fs-body); line-height: var(--lh-body); min-height: 84px;
  overflow-wrap: anywhere;
}
.promptbox .seg { background: var(--white); border-radius: 8px; padding: 2px 6px; color: var(--violet-deep); font-weight: 600; animation: pop var(--dur) var(--ease-back); }
@keyframes pop { from { transform: scale(.88); opacity: 0 } to { transform: none; opacity: 1 } }
.outbox { margin-top: var(--sp-4); border-radius: var(--r-field); overflow: hidden; background: var(--lila); }
.outbox .oh { padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); font-weight: 600; color: var(--ink-soft); }
.outbox .ob { padding: var(--sp-4); font-size: var(--fs-sm); line-height: var(--lh-body); background: var(--white); overflow-wrap: anywhere; }
.outbox.is-weak .oh { color: var(--ink-faint); }
.outbox.is-strong { background: var(--violet); }
.outbox.is-strong .oh { color: var(--white); }

/* -- narración grabada ---------------------------------------------------
   Jerarquía de tres niveles: «Continuar» es la acción principal de la
   pantalla y es la única píldora violeta sólida; «Escuchar» es la acción de
   este bloque y lleva contorno violeta; «Desde el inicio» y «Velocidad» son
   ajustes y son visiblemente más discretos. */
.player { margin-top: var(--sp-6); }
.player-row { display: flex; gap: var(--sp-3); align-items: center; margin-top: var(--sp-4); }
.btn-listen {
  flex: 1 1 auto; background: var(--white); color: var(--violet-deep);
  box-shadow: inset 0 0 0 3px var(--violet); min-height: 56px; font-size: var(--fs-body);
}
.btn-listen:hover:not(:disabled) { background: var(--lila); color: var(--violet-deep); }
.btn-listen:active:not(:disabled) { background: var(--lila-idle); color: var(--violet-deep); }
.btn-listen.is-loading::after { color: var(--violet-deep); }

/* los ajustes: texto pequeño, sin relleno y sin peso visual */
.aset { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); margin-top: var(--sp-3); }
.aset-btn {
  border: 0; background: transparent; padding: 0 2px; min-height: 44px; cursor: pointer;
  font-family: inherit; font-size: var(--fs-sm); font-weight: 400; color: var(--ink-soft);
  display: inline-flex; align-items: center; gap: 6px;
}
.aset-btn:hover { color: var(--violet-deep); text-decoration: underline; text-underline-offset: 4px; }
.speed { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; max-width: 100%; font-weight: 400; font-size: var(--fs-sm); color: var(--ink-soft); }
/* El desplegable es un control táctil como los demás: 44 px de alto de
   verdad y un ancho que no se estira más allá de sus opciones. */
.speed select {
  border: 0; background: transparent; font: inherit; font-weight: 600;
  min-height: 44px; padding: 0 6px; width: auto; max-width: 9rem;
  cursor: pointer; color: var(--violet-deep);
}

/* la parte reproducida en violeta sólido sobre la pista lila inactiva */
.abar { height: 12px; background: var(--lila-idle); border-radius: var(--r-pill); overflow: hidden; margin-top: var(--sp-5); }
.abar i { display: block; height: 100%; width: 0; background: var(--violet); border-radius: var(--r-pill); transition: width .18s linear; }
.ameta { display: flex; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-2); font-size: var(--fs-meta); color: var(--ink-faint); }
.ameta .el { color: var(--violet-deep); font-weight: 600; font-variant-numeric: tabular-nums; }
.ameta .tt { font-variant-numeric: tabular-nums; }
.caption { margin-top: var(--sp-4); background: var(--white); border: 2px solid var(--lila-idle); border-radius: var(--r-field); padding: var(--sp-4); min-height: 110px; display: flex; flex-direction: column; justify-content: center; }
.caption .lb { font-size: var(--fs-meta); color: var(--ink-faint); }
.caption .tx { font-size: var(--fs-body); line-height: 1.5; margin-top: var(--sp-1); overflow-wrap: anywhere; }
.transcript { margin-top: var(--sp-4); padding-top: var(--sp-3); }
.transcript summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); color: var(--violet-deep); min-height: 44px; display: flex; align-items: center; }
.transcript ol { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.transcript li { padding: var(--sp-3); border-radius: var(--r-field); font-size: var(--fs-sm); line-height: var(--lh-body); background: var(--lila); }
.transcript li.is-now { background: var(--lila-idle); font-weight: 600; }
.note { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-4); }

/* -- tarjeta de lectura --------------------------------------------------- */
.readcard { margin-top: var(--sp-6); border-radius: var(--r-card); background: var(--lila); overflow: hidden; }
.read-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); font-size: var(--fs-meta); color: var(--ink-soft); }
.read-meta .tag { font-size: var(--fs-meta); font-weight: 600; background: var(--violet); color: var(--white); border-radius: var(--r-pill); padding: 4px 12px; }
.read-body { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-4); }
.rline { position: relative; padding-left: 2.6rem; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--ink); }
.rline .rn {
  position: absolute; left: 0; top: .15rem; width: 1.8rem; height: 1.8rem; border-radius: var(--r-pill);
  background: var(--white); color: var(--violet-deep); display: grid; place-items: center;
  font-size: var(--fs-meta); font-weight: 600;
}
.rline:first-child { font-weight: 600; }

/* -- diagrama / recorrido -------------------------------------------------- */
.dg-phases { display: flex; gap: 6px; margin-top: var(--sp-5); }
.dg-phase { flex: 1; text-align: center; font-size: var(--fs-meta); padding: var(--sp-2) 4px; border-radius: var(--r-pill); background: var(--lila-idle); color: var(--ink-soft); transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.dg-phase.on { background: var(--violet); color: var(--white); font-weight: 600; }
.dg-phase.done { background: var(--lila); color: var(--violet-deep); }
.dg-ctx { margin-top: var(--sp-5); background: var(--lila); border-radius: var(--r-field); padding: var(--sp-4); font-size: var(--fs-body); line-height: var(--lh-title); }
.dg-ctx .lb { font-size: var(--fs-meta); color: var(--ink-faint); display: block; margin-bottom: 5px; }
.cands { margin-top: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-2); }
.cand { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2); border-radius: var(--r-field); transition: background var(--dur) var(--ease); }
.cand .w { width: 88px; flex: 0 0 auto; font-weight: 600; font-size: var(--fs-sm); }
.cand .bar2 { flex: 1; height: 12px; background: var(--lila-idle); border-radius: var(--r-pill); overflow: hidden; }
.cand .bar2 i { display: block; height: 100%; width: 0; background: var(--lila-idle); border-radius: var(--r-pill); transition: width var(--dur-slow) var(--ease); }
.cand .p { width: 48px; text-align: right; font-size: var(--fs-sm); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.cand.win { background: var(--lila); }
.cand.win .bar2 i { background: var(--violet); }
.cand.win .p { color: var(--violet-deep); font-weight: 600; }
.dg-sentence { margin-top: var(--sp-5); background: var(--lila); border-radius: var(--r-field); padding: var(--sp-4); font-size: var(--fs-h3); line-height: 1.45; }
.dg-sentence .new { background: var(--violet); color: var(--white); border-radius: 8px; padding: 1px 7px; animation: pop var(--dur) var(--ease-back); }
.dg-bullets { list-style: none; padding: 0; margin: var(--sp-5) 0 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.dg-bullets li { position: relative; padding: var(--sp-3) var(--sp-4) var(--sp-3) 2.6rem; background: var(--lila); border-radius: var(--r-field); font-size: var(--fs-sm); line-height: var(--lh-body); }
.dg-bullets li::before { content: ''; position: absolute; left: var(--sp-4); top: 1.35rem; width: 9px; height: 9px; border-radius: 50%; background: var(--violet); }
.dg-note { margin-top: var(--sp-4); font-size: var(--fs-sm); color: var(--ink-soft); }

/* -- ideas clave ----------------------------------------------------------- */
.insight-list { list-style: none; padding: 0; margin: var(--sp-6) 0 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.insight-list li { display: flex; gap: var(--sp-3); background: var(--lila); border-radius: var(--r-field); padding: var(--sp-4); font-size: var(--fs-sm); line-height: var(--lh-body); }
.insight-list .ic { flex: 0 0 auto; width: 26px; height: 26px; border-radius: var(--r-pill); display: grid; place-items: center; font-weight: 600; font-size: var(--fs-sm); background: var(--white); color: var(--violet-deep); }
.insight-list li.yes .ic { background: var(--lime); color: var(--lime-ink); }
.insight-list li.no { border-left: 6px solid var(--coral); }
.insight-list li.no .ic { background: var(--coral-bg); color: var(--coral-ink); }

/* -- bloque de retroalimentación -------------------------------------------
   Acierto: violeta sólido con texto blanco y la mascota a la izquierda.
   Fallo: lila lienzo con filo coral fino a la izquierda. Fallar duele poco. */
.fb {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: var(--violet); color: var(--white);
  padding: var(--sp-5) var(--sp-4) calc(var(--sp-5) + env(safe-area-inset-bottom));
  transform: translateY(110%); transition: transform var(--dur-slow) var(--ease-back);
  border-radius: var(--r-card) var(--r-card) 0 0;
}
.fb.is-up { transform: none; }
.fb.no { background: var(--lila); color: var(--ink); border-left: 6px solid var(--coral); }
.fb-in { max-width: var(--column); margin: 0 auto; display: flex; gap: var(--sp-4); align-items: flex-start; }
.fb-mascot { width: 56px; height: 56px; flex: 0 0 auto; }
.fb-body { flex: 1; min-width: 0; }
.fb-t { font-size: var(--fs-h3); font-weight: 600; color: var(--white); display: flex; align-items: center; gap: var(--sp-2); }
.fb.no .fb-t { color: var(--coral-ink); }
.fb-w { font-size: var(--fs-sm); margin-top: 4px; line-height: var(--lh-body); color: var(--white); }
.fb.no .fb-w { color: var(--ink-soft); }
.fb .btn { margin-top: var(--sp-4); width: 100%; background: var(--white); color: var(--violet-deep); }
.fb .btn:hover:not(:disabled) { background: var(--lila); color: var(--violet-deep); }
.fb .btn:active:not(:disabled) { background: var(--lila-idle); color: var(--violet-deep); }
.fb.no .btn { background: var(--violet); color: var(--white); }
.fb.no .btn:hover:not(:disabled) { background: var(--violet-hover); color: var(--white); }

.dock { margin-top: var(--sp-8); }
.spacer { height: var(--sp-6); }

/* -- celebración ------------------------------------------------------------ */
.final { text-align: center; padding-top: var(--sp-4); }
.final .mascot { width: 128px; height: 128px; margin: 0 auto; }
.final h1,
.final h2 { font-size: var(--fs-h2); margin-top: var(--sp-5); color: var(--fuchsia); }
.final .sub { font-size: var(--fs-body); color: var(--ink-soft); margin-top: var(--sp-2); }
.stats { display: flex; gap: var(--sp-3); margin-top: var(--sp-8); }
.stat-card { flex: 1; background: var(--lila); border-radius: var(--r-card); padding: var(--sp-4) var(--sp-2); }
.stat-card .k { font-size: var(--fs-meta); color: var(--ink-soft); }
.stat-card .v { font-size: 32px; font-weight: 600; line-height: 1.1; margin-top: var(--sp-1); font-variant-numeric: tabular-nums; color: var(--violet); }
.stat-card.streak .v { color: var(--fuchsia); }
.recap { list-style: none; padding: 0; margin: var(--sp-8) 0 0; display: flex; flex-direction: column; gap: var(--sp-2); text-align: left; }
.recap li { display: flex; gap: var(--sp-3); background: var(--lila); border-radius: var(--r-field); padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); line-height: var(--lh-body); }
.recap .ic { color: var(--violet); font-weight: 600; flex: 0 0 auto; }
/* El lienzo de confeti es un elemento REEMPLAZADO: si no se le da tamaño en
   CSS, `position:fixed; inset:0` no manda y el navegador usa su tamaño
   intrínseco, que es el del mapa de bits (`innerWidth × devicePixelRatio`).
   En un móvil de 360 px con densidad 3-4 eso son 1080-1440 px de ancho y la
   página entera se ensancha en cuanto se celebra algo. Con ancho y alto
   explícitos el lienzo mide siempre la pantalla. */
#confetti { position: fixed; inset: 0; width: 100%; height: 100%; max-width: 100%; pointer-events: none; z-index: 60; }

.mascot-wrap { display: flex; justify-content: center; margin-top: var(--sp-5); }
.mascot-sm { width: 88px; height: 88px; }
.saving { font-size: var(--fs-meta); color: var(--ink-faint); text-align: center; margin-top: var(--sp-3); min-height: 18px; }
.saving.warn { color: var(--coral-ink); }

/* ======================================================================
   12. MARCADOR DE LOGROS
   ====================================================================== */

.markcard { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-5); text-align: left; }
.markcard-lg { padding: var(--sp-6); max-width: 54rem; }
.markcard-head { display: flex; gap: var(--sp-4); align-items: center; }
.markcard-bit { width: 60px; height: 60px; flex: 0 0 auto; }
.markcard-bit svg { width: 100%; height: 100%; }
.markcard-t { font-size: var(--fs-h3); font-weight: 600; line-height: var(--lh-title); }
.markcard-s { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-1); line-height: var(--lh-body); }
.markcard-s strong { color: var(--ink); font-weight: 600; }

.marks { display: grid; grid-template-columns: 1fr; gap: var(--sp-3); margin-top: var(--sp-5); }
@media (min-width: 520px) { .marks { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .marks { grid-template-columns: 1fr 1fr 1fr; } }
.mark { display: flex; align-items: center; gap: var(--sp-3); background: var(--white); border-radius: var(--r-card); padding: var(--sp-4); }
.mark-ic { width: 40px; height: 40px; flex: 0 0 auto; border-radius: var(--r-pill); display: grid; place-items: center; background: var(--lila); color: var(--violet-deep); }
.mark-ic svg { width: 22px; height: 22px; }
.mark-body { display: flex; flex-direction: column; min-width: 0; }
.mark-v { font-size: 30px; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--violet); }
.mark-k { font-size: var(--fs-sm); color: var(--ink-soft); line-height: 1.3; }
.mark-t { font-size: var(--fs-meta); color: var(--ink-faint); margin-top: 2px; }
/* «aciertos a la primera» es un acierto: lima. «lecciones completadas» es un
   logro: fucsia, y solo en la cifra grande (30 px). */
.mark.is-first .mark-ic, .mark.is-lesson .mark-ic { background: var(--lime); color: var(--lime-ink); }
.mark.is-lesson .mark-v { color: var(--fuchsia); }

.markstrip { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.markchip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--white); border-radius: var(--r-pill);
  padding: 7px 15px 7px 11px; font-size: var(--fs-meta); color: var(--ink-soft);
}
.markchip svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--violet); }
.markchip b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.markchip.is-topic { background: var(--lila); color: var(--violet-deep); }
.markchip.is-topic b { color: var(--violet-deep); }

.markfoot { margin-top: var(--sp-5); border-top: 1px solid var(--lila-idle); padding-top: var(--sp-4); }
.markfoot-t { font-size: var(--fs-meta); color: var(--ink-faint); }
.markchips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.markwhat { margin-top: var(--sp-4); }
.markwhat summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); color: var(--violet-deep); min-height: 44px; display: flex; align-items: center; }
.markwhat ul { margin: var(--sp-2) 0 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--ink-soft); line-height: var(--lh-body); }
.markwhat strong { color: var(--ink); }

/* «Lo que llevas hecho» encabeza el bloque entero: píldoras y marcador. */
.progress-block { display: block; }
.marks-mini { text-align: center; }
.marks-mini-t { font-size: var(--fs-meta); font-weight: 400; color: var(--ink-faint); text-align: center; }
.marks-mini .markstrip { justify-content: center; margin-top: var(--sp-2); }
.marks-mini .markchip { background: var(--lila); }

/* Estado vacío del marcador: en la primera visita no hay nada que contar,
   así que en vez de tres ceros aparece Bit invitando a empezar. */
.marks-empty {
  display: flex; gap: var(--sp-3); align-items: center; text-align: left;
  margin-top: var(--sp-3); background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-4);
}
.marks-empty .mascot-tiny { width: 54px; height: 54px; flex: 0 0 auto; }
.marks-empty p { font-size: var(--fs-meta); color: var(--ink-soft); line-height: 1.45; }
.marks-empty strong { color: var(--ink); font-weight: 600; }

.final .markcard { margin-top: var(--sp-8); }
.final .markcard-head { text-align: left; }
.final .markstrip { justify-content: flex-start; }

/* ======================================================================
   13. ESTADOS
   ====================================================================== */

.sk { border-radius: var(--r-field); background: var(--lila); animation: shimmer 1.4s infinite ease-in-out; }
.sk--bubble { border-radius: var(--r-card); height: 152px; }
.sk--head { height: 44px; border-radius: var(--r-field); }
.sk--line { height: 14px; margin-top: var(--sp-2); }
.sk--card { height: 200px; border-radius: var(--r-card); }
@keyframes shimmer { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }

.state-card { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-6); margin-top: var(--sp-6); display: flex; gap: var(--sp-4); align-items: flex-start; text-align: left; }
.state-card .state-mascot { width: 72px; height: 72px; flex: 0 0 auto; }
.state-card h3 { font-size: var(--fs-h3); }
.state-card p { font-size: var(--fs-sm); color: var(--ink-soft); margin-top: var(--sp-2); }
.state-card .row { margin-top: var(--sp-4); }
@media (max-width: 460px) {
  .state-card { flex-direction: column; align-items: center; text-align: center; }
  .state-card .row { justify-content: center; }
}

/* ======================================================================
   14. MOVIMIENTO
   Curvas elásticas con un ligero rebote. Cinco momentos definidos:
   acierto, fallo, avance de paso, lección completada y carga de página.
   ====================================================================== */

@keyframes bob { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-6px) } }
@keyframes cheer { 0% { transform: scale(1) rotate(0) } 30% { transform: scale(1.12) rotate(-6deg) } 60% { transform: scale(1.12) rotate(6deg) } 100% { transform: scale(1) rotate(0) } }
@keyframes snore { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.04) } }
.m-idle { animation: bob 3.4s ease-in-out infinite; }
.m-happy { animation: cheer 760ms var(--ease-back); }
.m-sad { animation: shakeX 380ms ease-in-out; }
.m-sleep { animation: snore 3.8s ease-in-out infinite; }

/* acierto: la tarjeta vira a lima medio segundo y vuelve */
@keyframes winFlash { 0% { background: var(--white) } 30% { background: var(--lime) } 100% { background: var(--white) } }
.scard.is-win { animation: winFlash 620ms var(--ease); }

/* fallo: vibración horizontal muy breve de la opción elegida */
@keyframes shakeX { 0%, 100% { transform: translateX(0) } 25% { transform: translateX(-5px) } 75% { transform: translateX(5px) } }
.is-shake { animation: shakeX 320ms ease-in-out; }

/* avance de paso: la saliente se va a la izquierda, la entrante llega desde
   la derecha, con solape: la pantalla nunca se queda vacía */
#stepHost { position: relative; }
@keyframes stepIn { from { opacity: 0; transform: translateX(38px) } to { opacity: 1; transform: none } }
@keyframes stepOut { from { opacity: 1; transform: none } to { opacity: 0; transform: translateX(-38px) } }
.scard.is-in { animation: stepIn 380ms var(--ease-back); }
.scard.is-out { position: absolute; inset: 0; animation: stepOut 300ms var(--ease) forwards; pointer-events: none; }

/* carga de página: titular y botón escalonados */
@keyframes riseIn { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }
.reveal { animation: riseIn 520ms var(--ease-back) both; animation-delay: calc(var(--d, 0) * 90ms); }
.opt, .insight-list li, .dg-bullets li, .recap li, .lcard, .stat-card {
  animation: riseIn 420ms var(--ease-back) both; animation-delay: calc(var(--i, 0) * 45ms);
}
.opts .opt:nth-child(1) { --i: 0 } .opts .opt:nth-child(2) { --i: 1 }
.opts .opt:nth-child(3) { --i: 2 } .opts .opt:nth-child(4) { --i: 3 }
.opts .opt:nth-child(5) { --i: 4 } .opts .opt:nth-child(6) { --i: 5 }
.insight-list li:nth-child(1) { --i: 0 } .insight-list li:nth-child(2) { --i: 1 }
.insight-list li:nth-child(3) { --i: 2 } .insight-list li:nth-child(4) { --i: 3 }
.insight-list li:nth-child(5) { --i: 4 } .insight-list li:nth-child(6) { --i: 5 }
.insight-list li:nth-child(7) { --i: 6 }
.stats .stat-card:nth-child(1) { --i: 0 } .stats .stat-card:nth-child(2) { --i: 1 }
.stats .stat-card:nth-child(3) { --i: 2 }

/* ======================================================================
   15. MÓVIL
   Se diseña primero para móvil: botón principal a ancho completo y siempre
   visible abajo, opciones apiladas y barra de progreso anclada arriba.
   ====================================================================== */

@media (max-width: 639px) {
  :root { --fs-hero: clamp(32px, 9.5vw, 42px); --fs-h2: clamp(25px, 7.2vw, 31px); }
  .wrap { padding-inline: var(--sp-4); }
  .site-header .bar { gap: var(--sp-2); }
  .brand { gap: .5rem; }
  .brand-symbol { width: 2.55rem; height: 2.55rem; }
  .brand-wordmark { font-size: .95rem; gap: .22rem; }
  .menu-toggle { padding-inline: 16px; }
  /* Con la acción en la barra hay tres piezas donde antes había dos, así que
     la marca y los dos controles se aprietan para que a 390 px quepan los
     tres sin empujar nada fuera de la pantalla. */
  .nav-cta { padding-inline: 16px; }
  /* Garantía de que nada sale de la pantalla, diga lo que diga el idioma: los
     dos controles conservan su tamaño y quien cede es el nombre de la marca,
     que se recorta antes que empujar el menú fuera del viewport. */
  .brand { flex: 0 1 auto; min-width: 0; overflow: hidden; }
  .brand-wordmark { overflow: hidden; }
  .nav-cta, .menu-toggle { flex: 0 0 auto; }
  .hero { gap: var(--sp-10); }
  .hero-copy .lead { font-size: 1.08rem; }
  .hero-shot { margin-top: var(--sp-2); }
  .lesson-row { padding: var(--sp-4); gap: var(--sp-3); }
  .lesson-meta { padding-left: calc(46px + var(--sp-3)); flex-wrap: wrap; }
  .pshell { padding-inline: var(--sp-4); padding-bottom: 7.5rem; }
  .lhead { gap: var(--sp-2); }
  .lesson-brand { display: none; }
  .lhead .pill--xp { min-height: 44px; padding: 6px 12px; }
  /* el botón principal del paso vive fijo en la parte inferior */
  .scard .dock {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; margin: 0;
    background: rgba(255,255,255,.96); border-top: 1px solid var(--lila-idle);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom));
  }
  .scard .dock .btn { width: 100%; }
  body.fb-open .scard .dock { display: none; }
  .tf { flex-direction: column; }
  .match { grid-template-columns: 1fr; }
  .mcol h4 { margin-top: var(--sp-3); }
  .stats { flex-direction: column; }
  .final .stat-card { display: flex; align-items: baseline; justify-content: space-between; padding: var(--sp-4); }
  .final .stat-card .v { margin-top: 0; }

  /* El alto que se gasta ANTES de la primera lección: la bienvenida de Bit y
     el bloque de logros se aprietan para que la unidad 1 entre casi de
     primeras. Nada desaparece; todo ocupa menos. */
  .path-next { padding: var(--sp-4); margin-top: var(--sp-4); }
  .path-hero { padding: var(--sp-4); gap: var(--sp-3); margin: var(--sp-4) 0 var(--sp-2); }
  .path-hero .mascot { width: 56px; height: 56px; }
  .path-hero p { font-size: var(--fs-meta); line-height: 1.45; }
  .progress-block { margin-top: var(--sp-3); }
  .statrow { gap: var(--sp-2); margin-top: var(--sp-2); }
  .statrow .pill { min-height: 48px; padding: 6px 12px 6px 10px; gap: var(--sp-2); }
  .marks-mini .marks-empty { padding: var(--sp-3) var(--sp-4); gap: var(--sp-3); margin-top: var(--sp-2); }
  .marks-mini .marks-empty .mascot-tiny { width: 42px; height: 42px; }
  .path-side .card { padding: var(--sp-4); }
  .unit { margin-top: var(--sp-8); }
  .omap { margin-top: var(--sp-8); padding-top: var(--sp-6); }
  .badge { white-space: normal; }
}

/* ----------------------------------------------------------------------
   Móvil estrecho: la rejilla de lecciones pasa a UNA columna.
   A dos columnas sobre 360 px cada tarjeta se queda en 148 px de ancho: los
   títulos se parten en tres o cuatro líneas y las tarjetas quedan con
   alturas distintas. A una columna la tarjeta se reordena en horizontal
   —icono y estado a la izquierda, texto a la derecha—, así que además de
   respirar ocupa MENOS alto que la versión apilada de dos columnas.
   ---------------------------------------------------------------------- */
/* Móvil estrecho de verdad (390 px y por debajo): la barra sigue llevando
   marca + acción + menú, y los tres caben porque el símbolo, el nombre y los
   dos controles bajan un punto. Nada desaparece. */
@media (max-width: 429px) {
  .site-header .bar { gap: 6px; }
  .brand-symbol { width: 2.2rem; height: 2.2rem; }
  .brand-wordmark { font-size: .85rem; gap: .18rem; }
  /* Se aprieta el ancho, nunca el área táctil: los 44 px de alto se quedan. */
  .nav-cta, .menu-toggle { padding-inline: 13px; font-size: 13px; }
}

@media (max-width: 519px) {
  .trail { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
  .trail .lcard {
    display: grid; grid-template-columns: 2.4rem minmax(0, 1fr);
    column-gap: var(--sp-3); row-gap: 2px; align-items: start;
    min-height: 92px; padding: calc(var(--sp-4) + 6px) var(--sp-4) var(--sp-4);
  }
  /* El icono ocupa la columna de la izquierda a lo alto de la tarjeta; la
     etiqueta de estado se saca del flujo y se ancla arriba a la derecha, y la
     línea «lección N» le reserva el hueco. La anatomía de escritorio (franja,
     icono en chip, numeración, título) no cambia. */
  .trail .lcard-top { grid-column: 1; grid-row: 1 / span 5; display: block; }
  .trail .lcard-tag { position: absolute; top: calc(var(--sp-4) + 4px); right: var(--sp-4); }
  .trail .lcard-n { grid-column: 2; grid-row: 1; min-height: 1.5rem; padding-right: 5.75rem; }
  .trail .lcard-title,
  .trail .lcard-sub,
  .trail .lcard-note,
  .trail .lcard-go { grid-column: 2; }
  .trail .lcard-title { font-size: var(--fs-body); }
  .trail .lcard-sub { font-size: var(--fs-sm); }
  .trail .lcard-note { margin-top: var(--sp-1); }
  .trail .lcard-go { justify-self: start; align-self: start; margin-top: var(--sp-3); }
}

@media (min-width: 640px) {
  :root { --fs-body: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .btn:hover:not(:disabled), .btn:active:not(:disabled),
  .opt:active:not(:disabled), .chip:active, .card-link:hover,
  a.lcard:hover, button.lcard:hover, a.lcard:active, button.lcard:active { transform: none; }
  .lcard.is-sweep::before { display: none; }
}

/* ---------------------------------------------------------------------
   Selector de idioma. Vive en el sistema violeta y en ningún otro: canvas
   lila para el grupo, violeta sólido para el idioma activo. Ninguno de los
   cinco colores de lección se acerca a este control, que es navegación.
   --------------------------------------------------------------------- */
/* T3.8 · MENOS PESO, no menos función. Tres pastillas con la activa en violeta
   sólido, en el centro de la cabecera, competían con el botón principal por la
   atención: en la cabecera solo puede haber un violeta, y es el botón. El
   selector sigue siendo tres opciones visibles (no un desplegable: decisión
   del titular), pero ahora es un control tranquilo — grupo sin fondo, opción
   activa en chip blanco con contorno y tinta principal. */
.langpick{display:inline-flex;align-items:center;gap:2px;padding:2px;
  background:transparent;border-radius:999px}
.langpick .langopt{display:inline-flex;align-items:center;justify-content:center;
  min-width:2.25rem;min-height:32px;padding:0 .5rem;border-radius:999px;
  font-size:.75rem;font-weight:400;color:var(--ink-soft);text-decoration:none;
  transition:background .18s ease,color .18s ease}
.langpick .langopt:hover{color:var(--ink);background:var(--lila)}
.langpick .langopt.is-on{background:var(--lila);color:var(--ink);font-weight:600}
.langpick .langopt:focus-visible{outline:3px solid var(--violet);outline-offset:2px}
.langpick-sm{margin:0 .5rem}
.langrow{display:flex;align-items:center;gap:.75rem;padding:.75rem 0;
  border-top:1px solid var(--lila-idle);margin-top:.5rem}
.langrow .langlabel{font-size:.875rem;color:var(--ink-soft)}
.langrow .langpick .langopt{min-height:44px;min-width:auto;padding:0 1rem;font-size:.9375rem}
/* El desplegable móvil tiene fondo lila, así que ahí el chip activo es blanco:
   lila sobre lila no se vería. */
.langrow .langpick .langopt:hover{background:var(--white)}
.langrow .langpick .langopt.is-on{background:var(--white);color:var(--ink)}
@media (prefers-reduced-motion:reduce){.langpick .langopt{transition:none}}

/* Conversion elements: factual offer framing, restrained proof, no overlays. */
.free-hook{display:grid;gap:.35rem;padding:1rem 1.125rem;border:1px solid var(--lila-idle);
  border-left:4px solid var(--violet);border-radius:var(--r-card);background:var(--lila)}
.free-hook strong{font-size:1.05rem;color:var(--ink)}
.free-hook span{font-size:.9rem;line-height:1.5;color:var(--ink-soft)}
.social-proof{font-size:.9rem;font-weight:600;color:var(--ink-soft)}
.price-later{margin:.75rem 0 0;font-size:.9rem;color:var(--ink-soft)}

/* ----------------------------------------------------------------------
   La LÍNEA DE DATOS del hero («20 lecciones · 199 pasos · desde el móvil»).
   Antes era una sola cadena con puntos medios dentro y en pantalla estrecha
   se partía por donde caía, dejando un dato cortado a mitad. Ahora son tres
   elementos de una lista: el separador lo pinta el CSS entre hermanos, y en
   móvil la lista apila y el separador desaparece solo.
   ---------------------------------------------------------------------- */
/* T4.2 · Son TRES ARGUMENTOS DE VENTA, no un pie de la caja de arriba. Antes
   se apilaban pegados a la caja de «tres lecciones gratis», sin separación y
   en el gris que no cumplía contraste, y se leían como una nota al pie. Ahora
   van separadas por una regla, cada dato con su propio punto violeta y en el
   gris corregido, así que se leen como tres cosas distintas. */
.facts-line{list-style:none;margin:0;padding:var(--sp-5) 0 0;display:flex;flex-wrap:wrap;
  align-items:center;gap:var(--sp-2) var(--sp-5);font-size:var(--fs-sm);color:var(--ink-soft);
  border-top:1px solid var(--lila-idle)}
.facts-line li{display:flex;align-items:center;gap:.5rem;white-space:nowrap}
.facts-line li::before{content:'';flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  background:var(--violet)}
@media (max-width:479px){
  .facts-line{flex-direction:column;align-items:flex-start;gap:var(--sp-2)}
}

/* ----------------------------------------------------------------------
   LA GARANTÍA. Vive pegada al precio, en las tres superficies que lo
   enseñan. Lienzo blanco sobre la tarjeta lila para que se despegue de la
   lista de características sin convertirse en un botón rival.
   ---------------------------------------------------------------------- */
.guarantee{display:flex;gap:var(--sp-4);align-items:flex-start;
  background:var(--white);border-radius:var(--r-card);padding:var(--sp-4) var(--sp-5)}
.guarantee .g-badge{flex:0 0 auto;font-size:var(--fs-meta);font-weight:600;
  color:var(--violet-deep);background:var(--lila);border-radius:var(--r-pill);padding:.3rem .8rem}
.guarantee .g-title{font-size:var(--fs-body);font-weight:600;color:var(--ink);line-height:var(--lh-title)}
.guarantee .g-body{font-size:var(--fs-sm);color:var(--ink-soft);line-height:var(--lh-body);margin-top:.35rem}
.guarantee-line{align-items:center;gap:var(--sp-3);font-size:var(--fs-sm);color:var(--ink-soft)}
@media (max-width:520px){.guarantee{flex-direction:column;gap:var(--sp-3)}}

/* Para quién es y para quién no: dos tarjetas iguales, sin rojo ni alarma.
   La columna del «no» solo cambia el icono por una raya. */
.fit-grid{display:grid;gap:var(--sp-5);grid-template-columns:1fr}
@media (min-width:768px){.fit-grid{grid-template-columns:1fr 1fr}}
.promises-no .ic{background:var(--lila-idle);color:var(--ink-soft)}
/* T3.6 · el bloque se encoge hasta su línea más larga y ESE bloque se centra;
   las líneas siguen alineadas a la izquierda entre sí. Con `max-width` a secas
   el conjunto se veía desplazado a la izquierda. */
.closing-list{width:fit-content;max-width:34rem;margin-inline:auto;text-align:left}

/* El cierre comercial del final de la lección 1, dentro del reproductor. */
.lesson-close h3{font-size:var(--fs-h3);line-height:var(--lh-title)}
.lesson-close-price{border-top:1px solid var(--lila-idle);padding-top:var(--sp-5)}
/* El aviso temprano del precio: UNA línea de texto con su enlace. Ni caja, ni
   botón, ni regla: no puede parecer un segundo llamamiento al lado del botón
   de seguir con la lección 2. */
.close-heads{line-height:var(--lh-body)}

/* ======================================================================
   EL MURO: la oferta resuelta EN EL SITIO.
   ====================================================================== */
/* Los títulos de verdad de lo que se abre. Lista numerada a mano (el número es
   el de la lección en el curso, no el orden de esta lista). */
.unlock{border-top:1px solid var(--lila-idle);padding-top:var(--sp-5)}
.unlock-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.unlock-list li{display:flex;gap:var(--sp-3);align-items:baseline;font-size:var(--fs-sm);
  line-height:var(--lh-body)}
.unlock-list .ul-n{flex:0 0 auto;min-width:1.6rem;color:var(--violet);font-weight:600;
  font-variant-numeric:tabular-nums}
.unlock-list .ul-t{color:var(--ink)}
/* El formulario de compra dentro del muro ocupa el ancho de la tarjeta: aquí
   no hay columna de página que lo limite, como sí la hay en /pro. */
.gate-buy .buyform{max-width:none}
.gate-buy .btn{width:100%}
/* «Ahora no»: un enlace con forma de enlace, no un segundo botón. */
.linkbtn{background:none;border:0;padding:var(--sp-2);color:var(--ink-soft);
  text-decoration:underline;cursor:pointer;font:inherit;min-height:44px}
.linkbtn.xs{font-size:var(--fs-meta)}
.linkbtn:hover{color:var(--violet)}

/* Qué se sabe hacer al terminar cada lección: es lo que separa el catálogo
   (venta y búsqueda) del camino (estado y progreso). */
.lesson-outcome{font-size:var(--fs-meta);color:var(--ink-soft);margin-top:3px;
  overflow-wrap:anywhere}

/* La etiqueta «gratis» de una tarjeta del camino: verde lima del sistema, el
   mismo que marca un acierto. Nunca compite con el violeta de la acción, y va
   también sobre las lecciones 2 y 3 mientras siguen con candado: es lo que
   hace visible que la promesa de las tres gratis se cumple. */
.lcard .lcard-free{background:var(--lime);color:var(--lime-ink)}

/* El bloque de «aquí irá tu avance», mientras no haya nada que contar. */
.progress-empty{background:var(--lila);border-radius:var(--r-card);padding:var(--sp-4) var(--sp-5)}
.progress-empty[hidden],.progress-block[hidden]{display:none}
/* La frase que deja por escrito que 59 € es el precio futuro y no una rebaja.
   Va bajo la cifra, no escondida en un desplegable: es información sustancial. */
.price-honest{margin:.25rem 0 0;font-size:var(--fs-meta);line-height:1.5;color:var(--ink-soft)}
textarea.input{resize:vertical;min-height:7rem;line-height:1.5}

/* ======================================================================
   Fichas de lección y artículos.

   Dos superficies nuevas, cero componentes nuevos de color: todo se apoya en
   el sistema violeta (lienzo lila, tinta y tinta suave) y en los radios y
   espacios ya declarados. Los cinco colores de lección siguen entrando solo
   por --lc/--lt/--ls dentro de una tarjeta de lección, nunca desde aquí.
   Móvil primero: ninguna regla de este bloque fija un ancho mayor que la
   pantalla y todo apila por defecto.
   ====================================================================== */

/* El índice de pasos de una ficha: es un sumario, no una lista de tareas. */
.steplist { margin: 0; padding-left: 1.35rem; max-width: var(--prose); }
.steplist li { font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--ink-soft); }
.steplist li + li { margin-top: var(--sp-2); }
.steplist li::marker { color: var(--violet-deep); font-variant-numeric: tabular-nums; }

/* Listas de enlaces (lecciones relacionadas, seguir leyendo). */
.linklist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.linklist a {
  display: block; background: var(--lila); border-radius: var(--r-card);
  padding: var(--sp-4) var(--sp-5); text-decoration: none; color: var(--ink-soft);
  font-size: var(--fs-sm); line-height: var(--lh-body); min-height: 44px;
  transition: background var(--dur-fast) var(--ease);
}
.linklist a b { display: block; color: var(--ink); font-weight: 600; font-size: var(--fs-body); }
.linklist a:hover { background: var(--lila-idle); }

/* El índice de artículos. */
.postlist { display: grid; gap: var(--sp-4); }
.postcard { background: var(--lila); border-radius: var(--r-card); padding: var(--sp-5) var(--sp-5); }
.postcard-t { font-size: var(--fs-h3); line-height: var(--lh-title); letter-spacing: -.01em; }
.postcard-t a { color: var(--ink); text-decoration: none; }
.postcard-t a:hover { color: var(--violet-deep); text-decoration: underline; }
.postcard-a { margin-top: var(--sp-3); font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--ink-soft); }
.postcard-m { margin-top: var(--sp-3); font-size: var(--fs-meta); color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* Un artículo. La respuesta corta va en un bloque propio porque es la parte
   que se lee sola: quien tiene prisa, un buscador y un asistente de IA leen
   exactamente lo mismo, y no hay una segunda versión escrita para el robot. */
.article { max-width: var(--prose); }
.article-meta { font-size: var(--fs-meta); color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.answerbox {
  background: var(--lila); border-left: 4px solid var(--violet);
  border-radius: var(--r-card); padding: var(--sp-5);
}
.answerbox-k { font-size: var(--fs-meta); font-weight: 600; color: var(--violet-deep); }
.article-answer { margin-top: var(--sp-2); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--ink); }
.article-take { margin-top: var(--sp-6); font-weight: 600; color: var(--ink); }
.article .prose h2 { margin-top: var(--sp-8); }
.article .prose h2:first-child { margin-top: 0; }

@media (max-width: 560px) {
  .postcard, .answerbox { padding: var(--sp-4); }
  .linklist a { padding: var(--sp-4); }
  .steplist { padding-left: 1.15rem; }
}

/* ======================================================================
   La alternativa del muro: dejar el correo si hoy no se compra.

   Vive DENTRO de la misma tarjeta que el botón de compra, separada por una
   línea fina y en tipografía pequeña. Ni caja de color, ni segundo botón
   primario, ni ancla de precio repetida: el muro tiene una sola acción
   principal —comprar— y esto es la salida para quien todavía no está.
   Móvil primero, como todo lo demás: apila y no fija anchos.
   ====================================================================== */
.gate-alt { border-top: 1px solid var(--lila-idle); padding-top: var(--sp-5); }
.gate-alt .stack { gap: var(--sp-4); }
.gate-alt .label { color: var(--ink-soft); }
.gate-alt .btn { font-size: var(--fs-sm); }

/* ======================================================================
   El mismo formulario, fuera del reproductor: al final de la página de venta
   y al final de una ficha o un artículo.

   PESO. Es siempre secundario. En /pro el único botón violeta sólido sigue
   siendo el de comprar; aquí el botón es de contorno y la letra pequeña. En
   contenido (.capture-quiet) baja otro escalón: sin fondo, con una regla fina
   arriba, el botón al tamaño del texto y sin ocupar el ancho — se lee como
   una nota al pie, no como un anuncio.

   NO INTERRUMPE. No hay ventana emergente, ni barra fija, ni nada que se
   superponga a la lectura: es un bloque más del documento, el último.
   Móvil primero, como todo: apila y no fija anchos.
   ====================================================================== */
.capture {
  max-width: 32rem;
  padding: var(--sp-5);
  border: 1px solid var(--lila-idle);
  border-radius: var(--r-card);
  text-align: left;
}
.capture .stack { gap: var(--sp-4); }
.capture .label { color: var(--ink-soft); }
.capture .btn { font-size: var(--fs-sm); }
.capture-title { font-size: var(--fs-body); }

.capture-quiet {
  margin-top: var(--sp-10);
  padding: var(--sp-5) 0 0;
  border: 0;
  border-top: 1px solid var(--lila-idle);
  border-radius: 0;
}
.capture-quiet .capture-title { font-size: var(--fs-sm); color: var(--ink-soft); }
.capture-quiet .btn { align-self: flex-start; }

@media (max-width: 560px) {
  .capture { padding: var(--sp-4); }
  .capture-quiet { padding: var(--sp-5) 0 0; }
  .capture-quiet .btn { align-self: stretch; }
}

/* El mismo formulario, en la pantalla de vuelta de una compra sin cuenta a la
   que la pasarela no nos dio ninguna dirección: sin correo no hay recibo. */
.receipt-ask { text-align: left; max-width: 32rem; margin-left: auto; margin-right: auto; }

/* ======================================================================
   16. EL AVISO DE COOKIES

   Una tira blanca abajo, dentro del sistema: nada de cortina negra ni de
   ventana modal que tape la página. Las DOS opciones son el mismo botón dos
   veces —mismo tamaño, mismo color, mismo peso—, porque rechazar tiene que
   costar exactamente lo que cuesta aceptar (Guía de cookies de la AEPD).
   Ninguno usa `.btn-primary`: si uno fuera violeta sólido y el otro no, la
   elección dejaría de ser libre y, de paso, habría dos violetas compitiendo
   en la misma pantalla.
   ====================================================================== */
/* UNA TIRA DE UNA LÍNEA, NO UN CARTEL.
   Medido en un móvil de 360 px: el aviso ocupaba 238 px de alto —título,
   párrafo de tres líneas y los dos botones apilados a lo ancho— fijo abajo en
   TODAS las páginas, y en /pro se comía el botón de comprar. Ahora es una
   tira de una sola fila: texto corto a la izquierda, los dos botones a la
   derecha, y el detalle a un clic en la política. Alrededor de 60 px.

   Lo que NO cambia, porque no puede: aceptar y rechazar siguen siendo el
   mismo botón dos veces —mismo tamaño, mismo color, mismo peso, un clic cada
   uno— y ninguno usa `.btn-primary` (Guía de cookies de la AEPD). Encoger el
   aviso no puede convertirse en encoger el «Rechazar». */
.cookiebar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--white); border-top: 2px solid var(--lila-idle);
  padding: 8px var(--sp-4) calc(8px + env(safe-area-inset-bottom));
}
.cookiebar[hidden] { display: none; }
.cookiebar-in {
  max-width: var(--wrap); margin: 0 auto;
  display: flex; gap: var(--sp-4); align-items: center; flex-wrap: nowrap;
}
.cookiebar-w {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--fs-meta); color: var(--ink-soft); line-height: 1.35;
}
.cookiebar-acts { display: flex; gap: var(--sp-2); flex: 0 0 auto; }
.cc-btn {
  min-height: 40px; padding: 8px 18px;
  background: var(--white); color: var(--violet-deep);
  border: 2px solid var(--violet); border-radius: var(--r-pill);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 600; line-height: 1.2;
  cursor: pointer; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.cc-btn:hover { background: var(--lila); }
.cc-btn:active { background: var(--lila-idle); }
@media (max-width: 560px) {
  .cookiebar { padding: 6px 12px calc(6px + env(safe-area-inset-bottom)); }
  .cookiebar-in { gap: 10px; }
  /* El texto se queda en dos líneas como mucho: la primera capa del aviso dice
     de qué va, no lo cuenta entero. Lo entero está en «/privacidad». */
  .cookiebar-w { font-size: 12px; line-height: 1.25; }
  /* 40 px sigue siendo un objetivo tocable con el dedo; por debajo de eso el
     aviso dejaría de ser accesible, que es peor que ser alto. */
  .cc-btn { padding: 8px 12px; font-size: 13px; }
}

/* «Cookies», en el pie, para volver a abrir el aviso. Es un botón porque no
   navega a ningún sitio, pero se lee y se pulsa como el resto de la lista. */
.footer-linkbtn {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: inherit; font-size: inherit; font-weight: 400; color: inherit;
  text-align: left; text-decoration: none;
}
.footer-linkbtn:hover { color: var(--violet); text-decoration: underline; }

/* ======================================================================
   17. LA DEMOSTRACIÓN DEL HERO

   El primer paso de la lección 1, con el marcado del reproductor, animado por
   clases. Ocupa EXACTAMENTE el hueco de la captura (misma proporción), así
   que encenderla no mueve la página. Todo se mide en `cqw` —tanto por ciento
   del ancho del propio escenario—, que es lo que hace que se vea igual de
   proporcionada en un móvil de 360 px y en un monitor grande, como una
   imagen.
   ====================================================================== */
.hero-stage { position: relative; container-type: inline-size; aspect-ratio: 1180 / 1033; }
.hero-stage .shotpic { width: 100%; height: 100%; }
.hero-stage img.shot { width: 100%; height: 100%; object-fit: contain; object-position: top center; }
.hero-stage.has-demo img.shot { visibility: hidden; }

.hdemo {
  position: absolute; inset: 0; overflow: hidden;
  background: var(--white); border-radius: var(--r-card);
  padding: 3cqw 7.6cqw 0;
  opacity: 0; transition: opacity var(--dur-slow) var(--ease);
}
.hdemo[hidden] { display: none; }
.hdemo.is-live { opacity: 1; }
.hdemo-card { padding: 0; }
.hdemo .step-kicker { font-size: 2.4cqw; }
.hdemo .q { font-size: 3.9cqw; line-height: 1.18; margin: 1.4cqw 0 .8cqw; }
.hdemo .qlead { font-size: 2.2cqw; line-height: 1.5; }
.hdemo .opts { gap: 1.4cqw; margin-top: 3.4cqw; }
.hdemo .opt {
  min-height: 9.2cqw; padding: 0 2.6cqw; gap: 2.4cqw; font-size: 2.2cqw;
  border-radius: 1.7cqw; border-width: .17cqw; cursor: default;
}
.hdemo .opt .key { width: 3.7cqw; height: 3.7cqw; font-size: 1.9cqw; }
.hdemo .opt.is-ok::after { font-size: 2.6cqw; }
/* El toque: la opción se hunde un instante, como cuando la pulsa un dedo. */
.hdemo .opt.is-press { background: var(--lila); border-color: var(--lila); transform: scale(.985); }

.hdemo-fb {
  position: absolute; left: 2cqw; right: 2cqw; bottom: 1.6cqw;
  padding: 2.4cqw; border-radius: 2.4cqw;
  transform: translateY(120%);
  transition: transform var(--dur-slow) var(--ease-back);
}
.hdemo.is-solved .hdemo-fb { transform: none; }
.hdemo .fb-in { gap: 2.4cqw; max-width: none; }
.hdemo .fb-mascot { width: 5.6cqw; height: 5.6cqw; }
.hdemo .fb-t { font-size: 2.6cqw; gap: 1cqw; }
.hdemo .fb-w {
  font-size: 1.9cqw; margin-top: .6cqw; line-height: 1.45;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
}
.hdemo .fb .btn {
  min-height: 5cqw; margin-top: 1.6cqw; padding: 0 2cqw;
  font-size: 2.2cqw; border-radius: 2.5cqw; cursor: default;
}

/* El dedo: un círculo, no una foto. Entra por abajo, se posa sobre la opción
   correcta y se levanta. `--x`/`--y` los pone site.js con la posición real de
   esa opción, así que sigue siendo cierto en cualquier idioma, donde la
   respuesta puede caer en otra línea. */
.hdemo-finger {
  position: absolute; left: 0; top: 0; width: 5.4cqw; height: 5.4cqw; border-radius: 50%;
  background: var(--ink); opacity: 0; pointer-events: none;
  transform: translate(-50%, -50%) scale(1);
  transition: transform var(--dur-slow) var(--ease), opacity var(--dur) var(--ease);
}
.hdemo.is-reaching .hdemo-finger,
.hdemo.is-tapping .hdemo-finger { opacity: .22; }
.hdemo.is-reaching .hdemo-finger { transform: translate(calc(var(--x) - 50%), calc(var(--y) - 50%)) scale(1); }
.hdemo.is-tapping .hdemo-finger { transform: translate(calc(var(--x) - 50%), calc(var(--y) - 50%)) scale(.7); }

@media (prefers-reduced-motion: reduce) {
  /* Menos movimiento significa NADA de movimiento: se sirve la captura, que
     es el mismo fotograma final. `public/site.js` ni siquiera la enciende;
     esto es el cinturón por si alguien cambia de preferencia con la página
     abierta. */
  .hdemo { display: none !important; }
  .hero-stage.has-demo img.shot { visibility: visible !important; }
}

/* ==========================================================================
   LA ENTRADA DEL ANUNCIO Y EL MURO DE LA LECCIÓN 4
   ========================================================================== */

/* -- el aviso de cookies no puede taparle a nadie la primera respuesta ------
   El aviso es una barra fija abajo (z 60) y el reproductor tiene ahí su
   muelle de respuesta (`.fb`, z 45): en un móvil, la primera pregunta de la
   lección 1 quedaba debajo del aviso y quien llegaba de un anuncio no podía
   tocar la opción correcta sin decidir antes sobre las cookies. Eso es
   exactamente lo que la norma llama muro de cookies, y además mata la
   campaña.

   Dos reglas y ya está:
     · mientras el aviso está abierto, la página reserva su altura debajo del
       contenido (`--cookiebar-h`, que mide `public/site.js`), así que no tapa
       nada y se puede jugar con él abierto;
     · el muelle de respuesta pasa por ENCIMA del aviso, porque su botón
       «Continuar» es la única acción de ese instante. */
.fb { z-index: 70; }
body.cookiebar-open main { padding-bottom: var(--cookiebar-h, 8rem); }
body.cookiebar-open .fb { margin-bottom: 0; }

/* EL BOTÓN DE COMPRAR NUNCA DEBAJO DEL AVISO.
   Reservar hueco al final de `main` permite apartar el aviso scrolleando,
   pero no impide que el botón de /pro quede tapado justo cuando alguien va a
   pulsarlo. Con el aviso abierto, el formulario de compra lleva debajo un
   colchón de la altura exacta de la tira, así que entre el botón y el aviso
   siempre hay hueco vacío: lo que el aviso tapa no es nunca el botón. */
body.cookiebar-open .buyform { margin-bottom: var(--cookiebar-h, 5rem); }
.buyform { scroll-margin-bottom: calc(var(--cookiebar-h, 5rem) + var(--sp-4)); }

/* -- el muro de la lección 4 ---------------------------------------------- */
/* Sin mayúsculas completas: la marca escribe en formato frase en todas sus
   superficies y `scripts/design-test.mjs` lo vigila. */
.wall-kicker { font-size: var(--fs-meta); color: var(--ink-faint); font-weight: 600; }
.gate-offer h1 { font-size: var(--fs-h2); color: var(--ink); margin-top: var(--sp-2); }
.gate-offer .guarantee { margin-top: var(--sp-4); }

/* -- el ofrecimiento de cuenta del final de la lección 1 -------------------
   Crear cuenta y seguir sin ella pesan lo MISMO: no es un peaje, es una
   oferta, y las lecciones 2 y 3 se abren igual sin cuenta. Por eso el botón
   de saltar no es un enlace escondido en gris claro. */
.play-save { border: 2px solid var(--lila-idle); }
.play-save .play-skip {
  display: block; width: 100%; margin-top: var(--sp-3);
  min-height: 44px; padding: 10px 22px;
  background: none; border: 0; border-radius: var(--r-pill);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 600; line-height: 1.2;
  color: var(--violet-deep); cursor: pointer;
}
.play-save .play-skip:hover { background: var(--lila); }
.play-save .play-skip-note { font-size: var(--fs-meta); color: var(--ink-soft); margin-top: var(--sp-2); text-align: center; }
