@charset "utf-8";
/* ============================================================
   base.css — el sistema de la plantilla de Talkademy.

   Un solo archivo para las once páginas. No hay framework ni compilación:
   se edita y se recarga.

   DE DÓNDE SALE LA PALETA. Es la de la plataforma, no una inventada: azul de
   marca, coral de racha, ámbar de XP, jade de acierto, violeta premium,
   turquesa de vocabulario, y la escalera A1→C2. Y es la única: la aplicación
   ya no tiene una hoja de fichas propia, carga esta misma desde
   `/web/css/base.css`, así que quien llega desde un anuncio y luego entra en
   la aplicación ve los mismos colores en el mismo sitio.

   PERO CADA COLOR APARECE DOS VECES, y hay que saber cuál se usa:
   el color VIVO (#10B981) sirve de relleno grande con tinta oscura encima;
   el color TINTA (#0B7F58) es el mismo tono llevado al contraste que hace
   falta para escribir TEXTO sobre fondo claro. El jade vivo sobre el fondo da
   2,36:1 — se lee como un gris verdoso. Están todos medidos con la fórmula
   WCAG 2.1, y el par correcto está anotado en cada bloque. La regla corta:
   `--x` para rellenar, `--x-tinta` para escribir, `--x-lavado` para chips.

   EL COLOR DE UNA SECCIÓN SE HEREDA, no se escribe pantalla por pantalla. Es
   la regla de la plataforma y aquí funciona igual: se pone `--seccion` en el
   contenedor de la sección y todo lo de dentro —el filete, el chip, el título
   de bloque, el icono— lo toma de ahí. Dar color a una sección nueva no es
   escribir reglas para ella: es ponerle su línea de `--seccion`.

   LO QUE NO SE HACE AQUÍ, porque el producto lo prohíbe por escrito:
   ni un emoji haciendo de icono, ninguna mecánica de castigo (ni vidas, ni
   corazones, ni cuenta atrás que bloquee), ninguna cifra que no se pueda
   señalar en el repositorio, y ningún testimonio, estrella o contador de
   alumnos inventado.
   ============================================================ */

/* ============================================================
   1. Fichas de color y medida
   ============================================================ */
:root {
  /* ---------- los seis colores del producto ----------
     relleno / para escribir sobre claro / lavado de chip / tinta sobre relleno */
  --marca: #2563FF;        --marca-tinta: #1C5CFF;   --marca-lavado: #E8EFFF;   --sobre-marca: #FFFFFF;
  --racha: #FF5A3C;        --racha-tinta: #D82100;   --racha-lavado: #FFEEEB;   --sobre-racha: #0B1020;
  --xp: #FFB020;           --xp-tinta: #996300;      --xp-lavado: #FFF7E8;      --sobre-xp: #0B1020;
  --acierto: #10B981;      --acierto-tinta: #0B7D57; --acierto-lavado: #E6F8F2; --sobre-acierto: #0B1020;
  --premium: #7C3AED;      --premium-tinta: #7C3AED; --premium-lavado: #F1EAFD; --sobre-premium: #FFFFFF;
  --mirar: #06B6D4;        --mirar-tinta: #04788D;   --mirar-lavado: #E5F7FA;   --sobre-mirar: #0B1020;

  /* ---------- la escalera de niveles ----------
     Recorre toda la plataforma: la barra de progreso, la insignia del perfil,
     el borde de la lección, el certificado. Subir de nivel se ve, no solo se
     lee. Aquí se usa igual, y con los mismos tonos. */
  --n-a1: #10B981;  --n-a1-tinta: #0B7D57;  --n-a1-lavado: #E6F8F2;  --sobre-a1: #0B1020;
  --n-a2: #06B6D4;  --n-a2-tinta: #04788D;  --n-a2-lavado: #E5F7FA;  --sobre-a2: #0B1020;
  --n-b1: #2563FF;  --n-b1-tinta: #1C5CFF;  --n-b1-lavado: #E8EFFF;  --sobre-b1: #FFFFFF;
  --n-b2: #7C3AED;  --n-b2-tinta: #7C3AED;  --n-b2-lavado: #F1EAFD;  --sobre-b2: #FFFFFF;
  --n-c1: #DB2777;  --n-c1-tinta: #CA226C;  --n-c1-lavado: #FBE8F1;  --sobre-c1: #FFFFFF;
  /* Medido: #B94E05 daba 4,497:1 sobre --papel-2. Se queda a tres
     milesimas del minimo, que es peor que fallar de lejos: pasa
     cualquier revision a ojo y no pasa la norma. #B74E05 lo deja en
     4,551 sobre papel-2, 4,587 sobre su propio lavado y 5,115 sobre el
     papel. */
  --n-c2: #F97316;  --n-c2-tinta: #B74E05;  --n-c2-lavado: #FEF0E7;  --sobre-c2: #0B1020;

  /* ---------- el fondo de cada color ----------
     Un degradado de azul a violeta es lo que delata una página generada: son
     DOS familias, y el ojo lo lee como efecto pegado encima. El mismo azul
     llevado a su tono hondo se lee como material —tinta sobre papel, plástico
     teñido—, porque es lo que hace la luz de verdad al caer sobre una
     superficie de un solo color. Por eso el degradado nunca sale de la familia.

     En OKLAB y no en sRGB: mezclar #FF5A3C con negro en sRGB lo apaga a pardo
     porque el verde y el azul caen a distinta velocidad; en OKLAB baja la luz
     y deja el coral donde estaba.

     EL 90% NO ES UN GUSTO, ES EL TOPE QUE AGUANTA EL CONTRASTE. El extremo
     hondo lleva encima la misma tinta que el color vivo (`--sobre-*`), y en
     seis de los doce esa tinta es OSCURA: oscurecer el fondo les RESTA
     contraste en vez de sumarlo. Medido con la fórmula WCAG 2.1 sobre los doce:
       · al 82% el coral hondo se queda en 3,77:1 y el naranja C2 en 4,13:1
         —por debajo del mínimo—, y de noche el rosa C1 cae a 4,01:1;
       · al 90% el peor de día es el coral, 4,70:1; el peor de noche, el rosa
         C1, 4,98:1. Pasan los veinticuatro.
     Si algún día se quiere más profundidad no se sube el porcentaje: se cambia
     la tinta del bloque, que es lo que pone el techo.

     Se derivan con var() y NO se repiten en los dos bloques de noche: `--marca`
     se redeclara allí sobre este mismo :root, y un var() dentro de una ficha se
     resuelve con el valor que gana en el elemento donde está escrita. El hondo
     de noche sale solo. Repetir la fórmula solo abriría la puerta a que un día
     las tres copias digan cosas distintas. */
  --marca-hondo:   color-mix(in oklab, var(--marca) 90%, #000);
  --racha-hondo:   color-mix(in oklab, var(--racha) 90%, #000);
  --xp-hondo:      color-mix(in oklab, var(--xp) 90%, #000);
  --acierto-hondo: color-mix(in oklab, var(--acierto) 90%, #000);
  --premium-hondo: color-mix(in oklab, var(--premium) 90%, #000);
  --mirar-hondo:   color-mix(in oklab, var(--mirar) 90%, #000);

  --n-a1-hondo: color-mix(in oklab, var(--n-a1) 90%, #000);
  --n-a2-hondo: color-mix(in oklab, var(--n-a2) 90%, #000);
  --n-b1-hondo: color-mix(in oklab, var(--n-b1) 90%, #000);
  --n-b2-hondo: color-mix(in oklab, var(--n-b2) 90%, #000);
  --n-c1-hondo: color-mix(in oklab, var(--n-c1) 90%, #000);
  --n-c2-hondo: color-mix(in oklab, var(--n-c2) 90%, #000);

  /* ---------- neutros ----------
     Con una pizca de azul, no grises puros: al lado del azul eléctrico un gris
     neutro se ve sucio. */
  --fondo: #F4F7FC;
  --papel: #FFFFFF;
  --papel-2: #EDF2FA;
  --tinta: #0B1020;
  --tinta-2: #333C52;
  /* Medido contra los QUINCE fondos claros sobre los que puede caer, no
     contra uno. Han hecho falta dos correcciones: #667187 fallaba sobre
     --papel-2 (4,37), y #636E83 lo arreglaba ahi pero seguia fallando sobre
     cinco fondos de seccion tenida —los rotulos de cifra viven dentro de
     `.s-marca` y compañia, que pintan el fondo con su --lavado, mas oscuro
     que --papel-2: 4,38 sobre el rosa de C1 y el violeta de B2.
     Con #606B7F el peor par es 4,59:1. Un token que se usa sobre quince
     fondos se calibra contra el peor de los quince, no contra el que uno
     tenia delante al escribirlo. */
  --tinta-3: #606B7F;
  --linea: #DEE5F0;
  --linea-suave: #EAEFF7;

  /* El relieve del botón: sombra SÓLIDA, sin difuminar. Es lo que hace que se
     sienta pulsable antes de tocarlo; difuminada se convierte en la sombra
     genérica de cualquier tarjeta y deja de decir nada. */
  --relieve-marca: #0036BE;
  --relieve-acierto: #0A7854;
  --relieve-racha: #CD2000;

  --sombra: 0 1px 2px rgba(11,16,32,.05), 0 10px 30px rgba(11,16,32,.07);
  --sombra-alta: 0 2px 4px rgba(11,16,32,.06), 0 18px 44px rgba(11,16,32,.12);

  /* La sombra del color de su sección, como `--sh-seccion` en la plataforma.
     Una sombra GRIS debajo de una captura llena de color es lo que hace que la
     imagen parezca pegada encima en vez de estar puesta en la página: la luz
     que cae sobre algo azul rebota azul, no gris.

     Va en tres piezas y no en una sola ficha a propósito. Una ficha entera que
     dijera `... color-mix(in srgb, var(--seccion) 55%, transparent)` se
     resolvería AQUÍ, en :root, donde `--seccion` todavía es la marca: todas las
     capturas tendrían halo azul aunque estuvieran en una sección jade. Las
     piezas se juntan en el elemento (ver `.telefono`), que es donde `--seccion`
     ya vale lo que tiene que valer. */
  --sh-seccion-gris: 0 1px 2px rgba(11,16,32,.05);
  --sh-seccion-tiro: 0 14px 34px -14px;
  --sh-seccion-carga: 55%;

  /* ---------- letra ---------- */
  --display: "Source Serif 4", "Source Serif Pro", Charter, Cambria, Georgia, serif;
  --texto: Archivo, "Helvetica Neue", Arial, system-ui, sans-serif;
  /* Charis SIL es la tipografía de SIL International para transcripción
     fonética. El corte de Google Fonts NO trae θ (U+03B8), ˈ (U+02C8) ni
     ː (U+02D0) — justo los tres que llevan /ˈθɪŋk/ y /ɔː/ —, así que Noto
     Serif va detrás y el navegador rellena esos signos glifo a glifo. */
  --fonetica: "Charis SIL", "Noto Serif", "Doulos SIL", "Gentium Plus", serif;

  /* Escala fluida. La fórmula de cada clamp interpola entre 360 px y 1280 px
     de ancho de ventana, así que no hay ningún salto brusco de tamaño al
     girar un móvil o abrir una ventana a medias. */
  --t-xs: .75rem;
  --t-sm: .8125rem;
  --t-base: 1rem;
  --t-md: 1.0625rem;
  --t-lg: clamp(1.125rem, 1.05rem + .33vw, 1.3125rem);
  --t-xl: clamp(1.375rem, 1.22rem + .65vw, 1.75rem);
  --t-2xl: clamp(1.75rem, 1.45rem + 1.3vw, 2.5rem);
  --t-3xl: clamp(2.125rem, 1.6rem + 2.3vw, 3.5rem);

  --e-1: .25rem; --e-2: .5rem;  --e-3: .75rem; --e-4: 1rem;
  --e-5: 1.5rem; --e-6: 2rem;   --e-7: 3rem;   --e-8: 4.5rem;

  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-full: 999px;

  --ancho: 1160px;
  /* La medida de lectura va en `em` y no en `ch`, aunque `ch` sea la unidad
     que parece hecha para esto. `1ch` es el avance del glifo «0» de la fuente
     que esté puesta EN ESE MOMENTO, y mientras la tipografía real viaja está
     puesta la de respaldo. Medido a 1280 px: en Archivo `1ch` son 0,573 em y
     en su respaldo (Arial calibrada) 0,548 em — la caja nace un 4,3 % más
     estrecha y se ensancha de golpe cuando la fuente llega. En los titulares
     el desvío es del 22 % (Source Serif 4, 0,547 em/ch, contra Georgia
     calibrada, 0,667), y ahí no es que la caja se mueva: el titular cambia de
     número de líneas y empuja la página entera hacia abajo. `em` depende solo
     del cuerpo de letra, que no cambia, así que la caja mide lo mismo antes y
     después y no hay nada que recomponer.
     66ch x 0,573 em/ch = 37,8em. */
  --medida: 37.8em;

  --seccion: var(--marca);
  --seccion-tinta: var(--marca-tinta);
  --seccion-lavado: var(--marca-lavado);
  --seccion-hondo: var(--marca-hondo);
  --sobre-seccion: var(--sobre-marca);

  color-scheme: light dark;
}

/* ============================================================
   2. La edición de noche

   Se declara sobre :root:not([data-theme="light"]) para que la elección
   explícita del visitante gane sobre el ajuste del sistema, y se repite en
   :root[data-theme="dark"] para que el interruptor mande en los dos sentidos.
   Sin la segunda copia, quien tiene el sistema en claro no podría llegar
   nunca al tema oscuro.

   En oscuro NINGÚN color de la paleta admite texto blanco encima: el mejor de
   ellos, el azul claro, con blanco da 2,69:1, y el ámbar 1,61:1. Por eso `--sobre-*` pasa a ser tinta oscura en
   bloque, y los colores suben en claridad y bajan en saturación.
   ============================================================ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --marca: #6E9BFF;   --marca-tinta: #6E9BFF;   --marca-lavado: #222F4A;   --sobre-marca: #080B14;
    --racha: #FF7A63;   --racha-tinta: #FF7A63;   --racha-lavado: #3A2931;   --sobre-racha: #080B14;
    --xp: #F5C561;      --xp-tinta: #F5C561;      --xp-lavado: #383531;      --sobre-xp: #080B14;
    --acierto: #34D3A0; --acierto-tinta: #34D3A0; --acierto-lavado: #19383B; --sobre-acierto: #080B14;
    --premium: #A98BF5; --premium-tinta: #A98BF5; --premium-lavado: #2C2C49; --sobre-premium: #080B14;
    --mirar: #3ECFE4;   --mirar-tinta: #3ECFE4;   --mirar-lavado: #1B3746;   --sobre-mirar: #080B14;

    --n-a1: #34D3A0; --n-a1-tinta: #34D3A0; --n-a1-lavado: #19383B; --sobre-a1: #080B14;
    --n-a2: #3ECFE4; --n-a2-tinta: #3ECFE4; --n-a2-lavado: #1B3746; --sobre-a2: #080B14;
    --n-b1: #6E9BFF; --n-b1-tinta: #6E9BFF; --n-b1-lavado: #222F4A; --sobre-b1: #080B14;
    --n-b2: #A98BF5; --n-b2-tinta: #A98BF5; --n-b2-lavado: #2C2C49; --sobre-b2: #080B14;
    --n-c1: #E66AA1; --n-c1-tinta: #E66AA1; --n-c1-lavado: #36273B; --sobre-c1: #080B14;
    --n-c2: #FB9956; --n-c2-tinta: #FB9956; --n-c2-lavado: #392E2F; --sobre-c2: #080B14;

    --fondo: #080B14;
    --papel: #141A28;
    --papel-2: #1C2436;
    --tinta: #E9EEF9;
    --tinta-2: #C0C9DA;
    /* Aclarada de #8B95AC a #959FB3. El mismo fallo que en el tema claro y
       peor: fallaba en DIEZ de los quince fondos oscuros, y el peor par
       —sobre el lavado de XP— se quedaba en 4,06:1. Aqui pasa lo contrario
       que en claro: para ganar contraste hay que ACLARAR, porque el fondo es
       lo oscuro. Peor par nuevo: 4,57:1. */
    --tinta-3: #959FB3;
    --linea: #26304A;
    --linea-suave: #1D2537;

    --relieve-marca: #23406F;
    --relieve-acierto: #14624D;
    --relieve-racha: #7A3527;

    --sombra: 0 1px 2px rgba(0,0,0,.4), 0 14px 36px rgba(0,0,0,.55);
    --sombra-alta: 0 2px 6px rgba(0,0,0,.5), 0 22px 52px rgba(0,0,0,.7);

    /* De noche el halo de color se alarga y se aclara: sobre un fondo casi
       negro un 55% de color es una mancha, y el mismo tiro corto no separa
       nada porque no hay blanco debajo contra el que recortar. */
    --sh-seccion-gris: 0 1px 2px rgba(0,0,0,.45);
    --sh-seccion-tiro: 0 18px 44px -16px;
    --sh-seccion-carga: 42%;

    /* Los `--x-hondo` NO se repiten aquí: son var() de los colores de arriba,
       que sí se redeclaran en este bloque, así que el hondo baja solo. */
  }
}

:root[data-theme="dark"] {
  --marca: #6E9BFF;   --marca-tinta: #6E9BFF;   --marca-lavado: #222F4A;   --sobre-marca: #080B14;
  --racha: #FF7A63;   --racha-tinta: #FF7A63;   --racha-lavado: #3A2931;   --sobre-racha: #080B14;
  --xp: #F5C561;      --xp-tinta: #F5C561;      --xp-lavado: #383531;      --sobre-xp: #080B14;
  --acierto: #34D3A0; --acierto-tinta: #34D3A0; --acierto-lavado: #19383B; --sobre-acierto: #080B14;
  --premium: #A98BF5; --premium-tinta: #A98BF5; --premium-lavado: #2C2C49; --sobre-premium: #080B14;
  --mirar: #3ECFE4;   --mirar-tinta: #3ECFE4;   --mirar-lavado: #1B3746;   --sobre-mirar: #080B14;

  --n-a1: #34D3A0; --n-a1-tinta: #34D3A0; --n-a1-lavado: #19383B; --sobre-a1: #080B14;
  --n-a2: #3ECFE4; --n-a2-tinta: #3ECFE4; --n-a2-lavado: #1B3746; --sobre-a2: #080B14;
  --n-b1: #6E9BFF; --n-b1-tinta: #6E9BFF; --n-b1-lavado: #222F4A; --sobre-b1: #080B14;
  --n-b2: #A98BF5; --n-b2-tinta: #A98BF5; --n-b2-lavado: #2C2C49; --sobre-b2: #080B14;
  --n-c1: #E66AA1; --n-c1-tinta: #E66AA1; --n-c1-lavado: #36273B; --sobre-c1: #080B14;
  --n-c2: #FB9956; --n-c2-tinta: #FB9956; --n-c2-lavado: #392E2F; --sobre-c2: #080B14;

  --fondo: #080B14;
  --papel: #141A28;
  --papel-2: #1C2436;
  --tinta: #E9EEF9;
  --tinta-2: #C0C9DA;
  --tinta-3: #959FB3;
  --linea: #26304A;
  --linea-suave: #1D2537;

  --relieve-marca: #23406F;
  --relieve-acierto: #14624D;
  --relieve-racha: #7A3527;

  --sombra: 0 1px 2px rgba(0,0,0,.4), 0 14px 36px rgba(0,0,0,.55);
  --sombra-alta: 0 2px 6px rgba(0,0,0,.5), 0 22px 52px rgba(0,0,0,.7);

  /* Las mismas tres piezas del halo que en el bloque de arriba. Si solo
     estuvieran allí, quien tiene el sistema en claro y da al interruptor se
     quedaría con el halo corto y cargado del día sobre un fondo negro. */
  --sh-seccion-gris: 0 1px 2px rgba(0,0,0,.45);
  --sh-seccion-tiro: 0 18px 44px -16px;
  --sh-seccion-carga: 42%;

  /* Los `--x-hondo` NO se repiten aquí: son var() de los colores de arriba,
     que sí se redeclaran en este bloque, así que el hondo baja solo. */
}

/* ============================================================
   3. Base
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

/* `scrollbar-gutter: stable` reserva el hueco de la barra de desplazamiento
   SIEMPRE, tenga la página barra o no. Sin esto, una página que cabe en
   pantalla no tiene barra, y en cuanto crece —se despliega una pregunta, el
   panel recibe sus datos, el formulario enseña un error— la barra aparece y el
   área útil se estrecha de golpe: todo el contenido se desplaza a la
   izquierda. Medido en un marco de 1280x900 con `entrar.html`, que cabe justa:
   al crecer, el ancho útil pasaba de 1280 a 1265 px, 15 px de un tirón; con el
   hueco reservado, 0.
   En el móvil no cuesta nada: donde la barra va superpuesta el hueco vale 0. */
html { scroll-behavior: smooth; scrollbar-gutter: stable; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--texto);
  /* En rem y no en px: quien ha subido el tamaño base de letra en su
     navegador tiene que notarlo aquí también. */
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  font-synthesis-weight: none;
}

img, video, svg { max-width: 100%; height: auto; }
a { color: inherit; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.13;
  letter-spacing: -.018em;
  text-wrap: balance;
}
h1 { font-size: var(--t-3xl); letter-spacing: -.028em; }
h2 { font-size: var(--t-2xl); letter-spacing: -.024em; }
h3 { font-size: var(--t-xl); }
h4 { font-size: var(--t-lg); }

/* El texto largo se lee en una medida corta; no hereda el ancho del bloque. */
.medida { max-width: var(--medida); }
p + p { margin-top: var(--e-4); }

/* La transcripción fonética siempre en su tipografía: mezclada con la de
   texto, los símbolos salen con otra altura de x y parecen una errata. */
/* Se retiró `.ipa` del selector: nadie la escribía. La fonética del marcado va
   con `.unidad-ipa fon`, y `.unidad-ipa` no la alcanza un selector `.ipa`. */
.fon { font-family: var(--fonetica); font-feature-settings: "kern"; }

.solo-lectores {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.salto {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--marca); color: var(--sobre-marca);
  padding: var(--e-3) var(--e-5); font-weight: 600; text-decoration: none;
  border-radius: 0 0 var(--r-md) 0;
}
.salto:focus { left: 0; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--marca);
  outline-offset: 2px;
  border-radius: 3px;
}

/* La cabecera es pegajosa: sin esto, un salto a #precios deja el título
   debajo de la barra. */
:where(section, div, article)[id] { scroll-margin-top: 5.5rem; }

/* ============================================================
   4. Rejilla de página
   ============================================================ */
.pliego {
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  /* El respiro lateral se pone UNA vez y en padding-inline, nunca en el
     atajo `padding`, que lo dejaría a cero al escribir el vertical. */
  padding-inline: var(--e-5);
}
.pliego-estrecho { max-width: 780px; }

section { padding-block: clamp(2.75rem, 6vw, 5.5rem); }
/* Una sección que solo lleva un aviso, una fila de cifras o una llamada final
   no necesita el mismo aire que una que desarrolla una idea. Y la primera de
   cada página sí lo necesita más: es la que fija el ritmo de lectura. */
section.aire-corto { padding-block: clamp(1.75rem, 3vw, 2.75rem); }
section.aire-largo { padding-block: clamp(4rem, 9vw, 8rem); }

/* Rejillas que se apilan solas. El mínimo va dentro de min() porque con
   `minmax(280px, 1fr)` a secas una pantalla de 360 px no puede satisfacer los
   280 y la columna desborda: la página entera se va de lado. */
.rejilla { display: grid; gap: var(--e-4); }
.rejilla-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr)); }
.rejilla-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.rejilla-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }

/* ============================================================
   5. Cabecera de sección

   El folio (la etiqueta pequeña) toma el color de la sección. Es el único
   sitio donde el color va en texto pequeño, así que usa la variante tinta.
   ============================================================ */
.folio {
  display: inline-flex; align-items: center; gap: var(--e-2);
  font-size: var(--t-xs); font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--seccion-tinta);
  margin-bottom: var(--e-3);
}
.folio::before {
  content: ""; width: 1.5rem; height: 3px; border-radius: 2px;
  background: var(--seccion); flex: none;
}

.cabeza { max-width: 42rem; margin-bottom: var(--e-7); }
.cabeza.centrada { margin-inline: auto; text-align: center; }
.cabeza.centrada .folio::before { display: none; }
.cabeza p { margin-top: var(--e-4); color: var(--tinta-2); font-size: var(--t-lg); }

/* ============================================================
   6. Botones

   El relieve es un borde inferior SÓLIDO del propio color, más oscuro, y al
   pulsar el botón baja los 4 px que mide ese borde. Es la firma táctil de
   Duolingo y funciona porque no es una sombra difusa: una sombra difusa dice
   «tarjeta», esta dice «esto se hunde».
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  font-family: var(--texto); font-size: .9375rem; font-weight: 700;
  letter-spacing: .02em;
  padding: .875rem 1.5rem; min-height: 3rem;
  border: 0; border-radius: var(--r-md);
  cursor: pointer; text-decoration: none; text-align: center;
  transition: transform .08s ease, box-shadow .08s ease, background-color .15s ease;
}
.btn-principal {
  background: var(--marca); color: var(--sobre-marca);
  box-shadow: 0 4px 0 var(--relieve-marca);
}
.btn-acierto {
  background: var(--acierto); color: var(--sobre-acierto);
  box-shadow: 0 4px 0 var(--relieve-acierto);
}
.btn-racha {
  background: var(--racha); color: var(--sobre-racha);
  box-shadow: 0 4px 0 var(--relieve-racha);
}

/* LA MANO HUNDE EL COLOR, no lo aclara. El hover de la marca era `#3C74FF`
   escrito a mano: un azul MÁS CLARO que el de reposo, que sobre el blanco de
   su texto daba 4,09:1 —por debajo del mínimo— y que de noche seguía siendo
   ese mismo azul de día, ajeno a la paleta oscura. Aclarar al pasar por encima
   es además lo que hace una web hecha a ojo; una superficie real se oscurece
   donde se apoya la mano.
   Ahora el hover baja un 8% en OKLAB y la pulsación cae hasta el tono hondo de
   la propia sección, así que el botón aterriza exactamente en el color del
   fondo de su familia. Medido: azul 4,88 → 5,87 → 6,15 de día y 7,30 → 5,87 →
   5,57 de noche; el peor de los seis pares es el coral pulsado, 4,70:1. */
.btn-principal:hover { background: color-mix(in oklab, var(--marca) 92%, #000); }
.btn-acierto:hover   { background: color-mix(in oklab, var(--acierto) 92%, #000); }
.btn-racha:hover     { background: color-mix(in oklab, var(--racha) 92%, #000); }

.btn-principal:active, .btn-acierto:active, .btn-racha:active {
  transform: translateY(4px); box-shadow: 0 0 0 currentColor;
}
.btn-principal:active { background: var(--marca-hondo); }
.btn-acierto:active   { background: var(--acierto-hondo); }
.btn-racha:active     { background: var(--racha-hondo); }

/* Quien pide menos movimiento no lo pide solo para los carruseles: el botón
   sigue respondiendo, pero con color en vez de con desplazamiento. Que el
   color cambie no es un adorno aquí: sin el hundimiento de 4 px es la ÚNICA
   señal de que el dedo ha llegado. */
@media (prefers-reduced-motion: reduce) {
  .btn:active { transform: none; }
}

.btn-borde {
  background: var(--papel); color: var(--tinta);
  border: 2px solid var(--linea);
  box-shadow: 0 3px 0 var(--linea);
  padding-block: calc(.875rem - 2px);
}
/* El botón de borde solo se teñía por el filo: el interior seguía siendo papel
   y la mano no recibía nada. Ahora el hover trae también el lavado, y la
   pulsación lo llena del color entero — un contorno que se rellena al apretar
   es la respuesta que da un interruptor de verdad.
   Medido: tinta de marca sobre lavado, 4,53:1 de día y 4,95:1 de noche; blanco
   sobre marca llena, 4,88:1 de día, y tinta oscura sobre marca clara, 7,30:1 de
   noche. Se descartó hundir el lavado un 12% más al pulsar: dejaba el texto en
   3,88:1. */
.btn-borde:hover {
  border-color: var(--marca); color: var(--marca-tinta);
  background: var(--marca-lavado);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--marca) 45%, var(--papel));
}
.btn-borde:active {
  transform: translateY(3px); box-shadow: none;
  background: var(--marca); color: var(--sobre-marca); border-color: var(--marca);
}

.btn-texto {
  background: none; color: var(--marca-tinta); font-weight: 600;
  padding: .5rem .25rem; min-height: 0;
  border-bottom: 2px solid transparent; border-radius: 0;
  text-decoration: none;
}
/* Aquí el subrayado solo no basta: aparece a 2 px de alto al final de una
   línea de texto y en una pantalla brillante no se ve llegar. El lavado da la
   superficie que el subrayado no tiene. Tinta de marca sobre lavado de marca:
   4,53:1 de día, 4,95:1 de noche. */
.btn-texto:hover {
  border-bottom-color: currentColor;
  background: var(--marca-lavado);
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  padding-inline: .5rem;
  margin-inline: -.25rem;
}

.btn-grande { font-size: 1.0625rem; padding: 1.0625rem 2rem; min-height: 3.5rem; }
/* Se retiró `.btn-bloque { width: 100% }`: ninguna página la usaba. Los botones
   a línea completa del móvil los pone `.acciones` aquí debajo, no una clase. */

.acciones { display: flex; flex-wrap: wrap; gap: var(--e-3); }
/* En el móvil dos botones de anchos distintos uno debajo del otro se leen
   como un descuadre. A línea completa son dos opciones del mismo peso. */
@media (max-width: 30rem) {
  .acciones .btn { width: 100%; }
}

/* ============================================================
   7. Superficies
   ============================================================ */
.tarjeta {
  background: var(--papel);
  border: 2px solid var(--linea);
  border-radius: var(--r-xl);
  padding: var(--e-5);
  /* Corta, y solo de color: la tarjeta no se mueve ni crece al pasar por
     encima —eso la haría parecer un botón—, únicamente se tiñe. Quien pide
     menos movimiento ya tiene la duración a cero por la regla de arriba. */
  transition: background-color .15s ease, border-color .15s ease;
}
/* El borde ES la elevación. Sombra solo en lo que de verdad flota sobre el
   resto; si todo lleva sombra, nada destaca. */
.tarjeta-alta { box-shadow: var(--sombra); border-color: transparent; }
.tarjeta-seccion { border-color: color-mix(in srgb, var(--seccion) 38%, transparent); }

/* La tarjeta de sección lleva su color solo en el filo, al 38%: por debajo del
   cursor no pasaba nada de nada. Ahora el filo sube a color entero y el papel
   coge un 4% de tinte — suficiente para que el color responda a la mano, poco
   para que la tarjeta parezca un botón (son <article>, no enlaces).
   El 4% tampoco es un gusto: `--tinta-3`, el gris más flojo que se escribe
   dentro de una tarjeta, ya está en 4,91:1 sobre papel blanco, y un tinte del
   6% lo dejaba en 4,49:1. Al 4% se queda en 4,62:1 de día y 5,37:1 de noche.
   Dentro de @media (hover: hover) para que en una pantalla táctil el tinte no
   se quede pegado después de tocar. */
@media (hover: hover) {
  .tarjeta-seccion:hover {
    border-color: var(--seccion);
    background: color-mix(in srgb, var(--seccion) 4%, var(--papel));
  }
}
.tarjeta > .chip + h3, .tarjeta > h3:not(:first-child) { margin-top: var(--e-4); }
.tarjeta > h3 + p, .tarjeta > p + p { margin-top: var(--e-3); }
.tarjeta > h3 + p { color: var(--tinta-2); }

.chip {
  display: inline-flex; align-items: center; gap: .4em;
  font-size: var(--t-sm); font-weight: 700;
  letter-spacing: .04em;
  padding: .3rem .7rem; border-radius: var(--r-full);
  background: var(--seccion-lavado); color: var(--seccion-tinta);
  white-space: nowrap;
}

/* Bloque de color a sangre: la sección entera vestida de su color. Es lo que
   da ritmo a la página larga — el lector sabe que ha cambiado de asunto sin
   leer el título. */
.bloque-color {
  /* El color plano de antes era un rectángulo de pintura: en una pantalla de
     27 pulgadas se ve que es UN valor repetido, y eso es exactamente lo que
     delata una página generada. Dos cosas lo arreglan.

     1) EL DEGRADADO, siempre dentro de la familia (ver `--marca-hondo`). A 160°
        —casi vertical, ligeramente escorado— porque es por donde cae la luz en
        una habitación, y el ojo lo acepta sin preguntarse de dónde viene.

     2) EL GRANO. Un degradado liso en pantalla grande hace BANDAS: el panel
        solo tiene 256 escalones por canal y a lo largo de 800 px de alto se ven
        las fronteras entre uno y el siguiente. El grano las rompe porque mete
        ruido por debajo del escalón —es tramado, la misma razón por la que una
        foto impresa lleva trama—. Son dos capas de puntos de medio píxel, una
        clara y otra oscura, en rejillas de 3 y 5 px: primos entre sí, así que
        el patrón no se repite hasta los 15 px y no se lee como rejilla. Las dos
        a la misma opacidad para que la media de luz no se mueva ni una décima
        y el contraste medido siga valiendo.
        No se ve. Se nota. */
  background-color: var(--seccion);
  background-image:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,.05) .5px, transparent .55px),
    radial-gradient(circle at 50% 50%, rgba(0,0,0,.05) .5px, transparent .55px),
    linear-gradient(160deg, var(--seccion), var(--seccion-hondo));
  background-size: 3px 3px, 5px 5px, 100% 100%;
  background-position: 0 0, 1px 2px, 0 0;
  color: var(--sobre-seccion);
}
/* Sin opacidad. Medido: al 82 % sobre el rosa de C1 daba 3,50:1, y sobre
   el azul de marca 3,79. La tinta plena pasa en los veinticuatro pares, y
   la jerarquia ya la marca el tamano de letra. */
.bloque-color .folio { color: var(--sobre-seccion); }
.bloque-color .folio::before { background: currentColor; }
.bloque-color .cabeza p { color: inherit; }
.bloque-color .tarjeta { background: var(--papel); color: var(--tinta); border-color: transparent; }

.bloque-lavado { background: var(--seccion-lavado); }

/* ---------- los filos de sección ----------
   Hoy una sección de color empieza y acaba en una línea recta, y el color se
   queda encajonado dentro de su rectángulo. Estas dos clases sacan un filete de
   3 px del color de la sección hasta el borde mismo de la pantalla —van en la
   <section>, que es lo único que llega de lado a lado; `.pliego` no, porque
   tiene tope de ancho—, así el color toca el filo del papel como en una
   portada impresa.

   Son OPCIONALES y no cambian nada de lo ya construido: ninguna página las
   pide todavía. Se ponen donde una sección lavada necesita quedar cosida a la
   de al lado.

   El filete es DECORACIÓN, no información: repite un color que la sección ya
   anuncia en el folio y en el chip, los dos escritos con `--seccion-tinta` a
   contraste de texto completo. Sobre `--fondo` va de 1,70:1 (el ámbar) a
   5,31:1 (el violeta), la misma horquilla que la barrita de `.folio::before`,
   que lleva ahí desde el principio y también mide 3 px. Nada queda colgando de
   que se vea. */
.filo-arriba, .filo-abajo { position: relative; }
.filo-arriba::before, .filo-abajo::after {
  content: ""; position: absolute; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--seccion), var(--seccion-hondo));
  pointer-events: none;
}
.filo-arriba::before { top: 0; }
.filo-abajo::after { bottom: 0; }

/* ============================================================
   8. Cabecera del sitio
   ============================================================ */
.barra {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--fondo) 88%, transparent);
  backdrop-filter: saturate(1.3) blur(10px);
  border-bottom: 1px solid var(--linea);
}
/* EL ÚNICO SITIO DONDE LOS SEIS COLORES DE NIVEL VAN JUNTOS, y va aquí porque
   aquí significan algo: A1 → C2 de izquierda a derecha es el programa entero,
   el mismo recorrido que la barra de progreso y la insignia del perfil. En
   cualquier otro sitio seis colores seguidos serían un arcoíris de adorno.
   2 px y al 55%: tiene que leerse como el canto de una pila de papeles de
   colores, no como una cinta. Va en ::after y no en el border-bottom porque el
   borde ya está ocupado por la línea de 1 px que separa la barra del contenido,
   y las dos cosas juntas —línea fina arriba del filete— es lo que le da canto.
   `bottom: 0` cae en el borde interior de esa línea: la barra no tiene relleno,
   así que el filete cruza de lado a lado de la ventana. */
.barra::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg,
    var(--n-a1), var(--n-a2), var(--n-b1), var(--n-b2), var(--n-c1), var(--n-c2));
  opacity: .55;
  pointer-events: none;
}
.barra-fila {
  display: flex; align-items: center; gap: var(--e-4);
  min-height: 4.25rem; padding-block: var(--e-2);
}

.rotulo { display: inline-flex; align-items: center; gap: .55rem; text-decoration: none; flex: none; }
.rotulo img, .rotulo svg { width: 2rem; height: 2rem; }
.rotulo b { font-family: var(--display); font-size: 1.25rem; font-weight: 600; letter-spacing: -.03em; }

.menu { display: flex; align-items: center; gap: var(--e-5); margin-left: var(--e-4); }
.menu a { font-size: .9375rem; font-weight: 500; color: var(--tinta-2); text-decoration: none; }
.menu a:hover { color: var(--marca-tinta); }
.menu a[aria-current="page"] { color: var(--marca-tinta); font-weight: 700; }

.barra-acciones { display: flex; align-items: center; gap: var(--e-2); margin-left: auto; }
.barra-acciones .btn { min-height: 2.75rem; padding: .625rem 1.125rem; font-size: .875rem; }

.luz {
  width: 2.75rem; height: 2.75rem; flex: none;
  border: 2px solid var(--linea); border-radius: var(--r-md);
  background: var(--papel); color: var(--tinta-2);
  display: grid; place-items: center; cursor: pointer;
}
/* El interruptor de luz es un cuadrado de 44 px con un icono dentro: si solo
   cambia el filo, el cambio ocurre en el 6% de su superficie y no se ve. */
.luz:hover { border-color: var(--marca); color: var(--marca-tinta); background: var(--marca-lavado); }
.luz .noche { display: none; }
:root[data-theme="dark"] .luz .dia { display: none; }
:root[data-theme="dark"] .luz .noche { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .luz .dia { display: none; }
  :root:not([data-theme="light"]) .luz .noche { display: block; }
}

/* ---------- el menú de móvil ----------
   Con <details>/<summary>: se abre y se cierra sin una línea de JavaScript, y
   el navegador ya se encarga del foco y de anunciarlo como desplegable. */
.desplegable { display: none; position: relative; }
.desplegable > summary {
  list-style: none; cursor: pointer;
  width: 2.75rem; height: 2.75rem;
  border: 2px solid var(--linea); border-radius: var(--r-md);
  background: var(--papel); color: var(--tinta);
  display: grid; place-items: center;
}
.desplegable > summary::-webkit-details-marker { display: none; }
.desplegable[open] > summary { border-color: var(--marca); color: var(--marca-tinta); }
.desplegable .cierre { display: none; }
.desplegable[open] .abre { display: none; }
.desplegable[open] .cierre { display: block; }

.desplegable-panel {
  position: absolute; right: 0; top: calc(100% + .5rem);
  min-width: 14rem;
  background: var(--papel); border: 2px solid var(--linea);
  border-radius: var(--r-lg); box-shadow: var(--sombra-alta);
  padding: var(--e-2);
  display: grid; gap: 2px;
}
.desplegable-panel a {
  display: block; padding: .75rem var(--e-3);
  border-radius: var(--r-sm); text-decoration: none;
  font-weight: 500; color: var(--tinta-2);
}
.desplegable-panel a:hover { background: var(--papel-2); color: var(--marca-tinta); }
.desplegable-panel a[aria-current="page"] { background: var(--marca-lavado); color: var(--marca-tinta); font-weight: 700; }

@media (max-width: 62rem) {
  .menu { display: none; }
  .desplegable { display: block; }
}
@media (max-width: 26rem) {
  .barra-acciones .btn-borde { display: none; }
}

/* ============================================================
   9. Pie
   ============================================================ */
.pie { background: var(--papel); border-top: 1px solid var(--linea); padding-block: var(--e-7) var(--e-6); }
.pie-rejilla { display: grid; grid-template-columns: minmax(0, 1.6fr) repeat(auto-fit, minmax(9rem, 1fr)); gap: var(--e-6); }
@media (max-width: 48rem) { .pie-rejilla { grid-template-columns: 1fr 1fr; } }
@media (max-width: 26rem) { .pie-rejilla { grid-template-columns: 1fr; gap: var(--e-5); } }
.pie h3 { font-family: var(--texto); font-size: var(--t-xs); font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--tinta-3); margin-bottom: var(--e-3); }
.pie ul { list-style: none; display: grid; gap: var(--e-2); }
.pie a { font-size: var(--t-sm); color: var(--tinta-2); text-decoration: none; }
.pie a:hover { color: var(--marca-tinta); text-decoration: underline; }
/* 32ch x 0,573 em/ch = 18,3em. Ver el porqué en `--medida`. */
.pie-nota { color: var(--tinta-2); font-size: var(--t-sm); margin-top: var(--e-3); max-width: 18.3em; }
.pie-registro {
  margin-top: var(--e-7); padding-top: var(--e-4); border-top: 1px solid var(--linea-suave);
  display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-5); justify-content: space-between;
  font-size: var(--t-xs); color: var(--tinta-3);
}

/* ============================================================
   10. Avisos

   El aviso de que hoy no se cobra tiene que ir ANTES de cualquier tabla de
   precios: la propia página de planes de la plataforma dice que no se puede
   contratar, y una tabla sin esa cabecera contradice al producto.
   ============================================================ */
.aviso {
  display: grid; grid-template-columns: auto 1fr; gap: var(--e-3) var(--e-4);
  align-items: start;
  background: var(--seccion-lavado);
  border: 2px solid color-mix(in srgb, var(--seccion) 34%, transparent);
  border-radius: var(--r-lg);
  padding: var(--e-4) var(--e-5);
}
.aviso svg { width: 1.5rem; height: 1.5rem; color: var(--seccion-tinta); flex: none; }
.aviso b { display: block; }
/* 62ch x 0,573 em/ch = 35,5em. Ver el porqué en `--medida`. */
.aviso p { color: var(--tinta-2); font-size: var(--t-sm); margin-top: var(--e-1); max-width: 35.5em; }

/* ============================================================
   11. Cifras
   ============================================================ */
.cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); gap: var(--e-5); }
.cifra dt { font-size: var(--t-xs); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-3); }
.cifra dd {
  margin: var(--e-1) 0 0;
  font-family: var(--display); font-size: clamp(1.875rem, 1.4rem + 2vw, 2.75rem);
  font-weight: 600; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--tono, var(--marca-tinta));
}
.cifra dd small { display: block; font-family: var(--texto); font-size: var(--t-sm); font-weight: 400; color: var(--tinta-2); letter-spacing: 0; margin-top: var(--e-2); line-height: 1.45; }
.bloque-color .cifra dt, .bloque-color .cifra dd small { color: inherit; }
.bloque-color .cifra dd { color: inherit; }

/* ============================================================
   12. La ficha de unidad — el producto enseñado, no descrito
   ============================================================ */
.unidad {
  background: var(--papel);
  border: 2px solid var(--linea);
  border-top: 5px solid var(--seccion);
  border-radius: var(--r-lg);
  padding: var(--e-5);
  text-align: left;
}
.unidad-alto { display: flex; align-items: baseline; justify-content: space-between; gap: var(--e-3); flex-wrap: wrap; }
.unidad-en { font-family: var(--display); font-size: var(--t-2xl); font-weight: 600; letter-spacing: -.025em; line-height: 1.05; }
.unidad-ipa { font-size: var(--t-lg); color: var(--seccion-tinta); font-weight: 700; margin-top: var(--e-1); }
.unidad-pron { font-size: var(--t-sm); color: var(--tinta-3); letter-spacing: .05em; margin-top: 2px; }
.unidad-es { font-size: var(--t-md); margin-top: var(--e-3); }
.unidad-es b { font-weight: 700; }
/* Es un <blockquote>, y el navegador le pone de fábrica 40 px a cada lado y
   un renglón debajo. Con solo `margin-top` la cita salía sangrada respecto al
   resto de la ficha —el filete no caía bajo la palabra— y la tarjeta ganaba
   un hueco al pie. Se fija el margen entero. */
.unidad-cita {
  margin: var(--e-4) 0 0; padding-left: var(--e-4);
  border-left: 3px solid var(--linea);
  font-size: var(--t-base);
}
.unidad-cita i { font-style: italic; }
.unidad-cita span { display: block; color: var(--tinta-2); font-size: var(--t-sm); margin-top: 2px; }
.unidad-nota {
  margin-top: var(--e-4); padding: var(--e-3) var(--e-4);
  background: var(--xp-lavado); border-radius: var(--r-md);
  border-left: 4px solid var(--xp);
  font-size: var(--t-sm); color: var(--tinta-2); line-height: 1.5;
}
.unidad-nota b {
  display: block; color: var(--xp-tinta); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; margin-bottom: 3px;
}

/* ============================================================
   13. Tabla de niveles

   Es una tabla de verdad —seis filas comparables con las mismas columnas—,
   no seis tarjetas. Un lector de pantalla que encuentra «393» dentro de un
   div no sabe que son unidades; dentro de una celda con su encabezado, sí.
   ============================================================ */
.tabla-envoltorio { overflow-x: auto; }
table.datos { width: 100%; border-collapse: collapse; }
table.datos caption { text-align: left; color: var(--tinta-3); font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; font-weight: 600; padding-bottom: var(--e-3); }
table.datos th, table.datos td { text-align: left; padding: var(--e-4) var(--e-3); border-bottom: 1px solid var(--linea); vertical-align: baseline; }
table.datos thead th { font-size: var(--t-xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-3); border-bottom: 2px solid var(--linea); padding-block: var(--e-2) var(--e-3); }
table.datos td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

th.clave-nivel {
  font-family: var(--display); font-size: var(--t-lg); font-weight: 700;
  color: var(--sobre-seccion); background: var(--seccion);
  border-radius: var(--r-sm);
  text-align: center; width: 3.5rem; padding: var(--e-2);
}

@media (max-width: 45rem) {
  /* La tabla se convierte en fichas apiladas. Seis columnas con scroll
     lateral en un móvil no las lee nadie; así cada fila se lee sola.
     thead se oculta con clip-path, no con display:none, para que el lector
     de pantalla siga teniendo los encabezados. */
  table.datos thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.datos tr { display: grid; grid-template-columns: auto 1fr; gap: var(--e-2) var(--e-4); padding-block: var(--e-4); border-bottom: 1px solid var(--linea); }
  table.datos th, table.datos td { border: 0; padding: 0; }
  th.clave-nivel { grid-row: span 3; align-self: start; }
  table.datos td.num { text-align: left; font-size: var(--t-sm); color: var(--tinta-2); }
  table.datos td.num::before { content: attr(data-etiqueta) ": "; color: var(--tinta-3); }
}

/* ============================================================
   14. El sendero de lecciones

   Un solo camino, sin ramas: el alumno nunca tiene que decidir qué hace hoy.
   Es lo que mejor funciona de Duolingo y no arrastra ninguna de sus trampas.
   ============================================================ */
.sendero { list-style: none; display: grid; gap: 0; position: relative; }
.paso { display: grid; grid-template-columns: 3.5rem 1fr; gap: var(--e-4); align-items: start; position: relative; padding-bottom: var(--e-5); }
/* La línea que une los nodos se dibuja con un pseudo-elemento del propio
   paso, para que el último no la lleve y el camino termine limpio. */
.paso::before {
  content: ""; position: absolute; left: 1.6875rem; top: 3.5rem; bottom: 0;
  width: 3px; background: var(--linea); border-radius: 2px;
}
.paso:last-child::before { display: none; }
.paso-nodo {
  width: 3.5rem; height: 3.5rem; border-radius: var(--r-full);
  display: grid; place-items: center; flex: none;
  background: var(--seccion); color: var(--sobre-seccion);
  font-family: var(--display); font-weight: 700; font-size: var(--t-lg);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--seccion) 65%, #000);
  position: relative; z-index: 1;
}
.paso-nodo svg { width: 1.5rem; height: 1.5rem; }
.paso h3 { font-size: var(--t-lg); margin-top: .4rem; }
.paso p { color: var(--tinta-2); font-size: var(--t-base); margin-top: var(--e-2); }
.paso-meta { display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-4); margin-top: var(--e-3); font-size: var(--t-sm); color: var(--tinta-3); }

/* ============================================================
   15. Barra de progreso
   ============================================================ */
.progreso {
  height: 1rem; border-radius: var(--r-full);
  background: var(--papel-2); overflow: hidden;
}
/* Con el color vivo, el relleno sobre su pista daba 2,26:1 en jade y 2,76
   en coral: por debajo del 3:1 que pide un elemento grafico, o sea que no
   se distinguia cuanto llevaba llena. La variante tinta da 5,64:1. */
.progreso > i {
  display: block; height: 100%; border-radius: var(--r-full);
  background: var(--seccion-tinta);
  /* La franja clara de arriba es lo que hace que la barra parezca llena y no
     pintada. Va dentro del relleno, no encima de la pista. */
  box-shadow: inset 0 3px 0 color-mix(in srgb, #fff 32%, transparent);
}

/* ============================================================
   16. Precios
   ============================================================ */
.planes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: var(--e-4); align-items: stretch; }
/* Las fichas de dato —un plan, una muestra de color— llevan radio corto.
   El radio largo se reserva para la tarjeta que desarrolla una idea. */
.plan { display: flex; flex-direction: column; gap: var(--e-4); border-radius: var(--r-md); }
.plan-importe { font-family: var(--display); font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem); font-weight: 600; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.plan-importe small { font-family: var(--texto); font-size: var(--t-sm); font-weight: 500; color: var(--tinta-2); letter-spacing: 0; }
.plan-anual { font-size: var(--t-sm); color: var(--tinta-2); }
.plan ul { list-style: none; display: grid; gap: var(--e-3); font-size: var(--t-sm); }
.plan li { display: grid; grid-template-columns: 1.25rem 1fr; gap: var(--e-3); align-items: start; color: var(--tinta-2); line-height: 1.45; }
.plan li svg { width: 1.125rem; height: 1.125rem; margin-top: .15rem; color: var(--acierto-tinta); }
.plan li.fuera svg { color: var(--tinta-3); }
.plan li b { color: var(--tinta); font-weight: 700; }
.plan .btn { margin-top: auto; }
/* Un plan es lo que más se compara de la página: el cursor va y viene entre
   tres columnas leyendo líneas equivalentes, y si nada se mueve se pierde cuál
   se estaba mirando. El tinte del 4% marca la columna activa sin prometer que
   la tarjeta entera sea pulsable —la que se pulsa es el botón de dentro—.
   Va después de `.bloque-color .tarjeta` a propósito: las dos reglas pesan
   igual y gana la última, así que un plan dentro de un bloque de color
   también reacciona. Contrastes sobre el papel teñido: `--tinta` 17,83:1 de
   día y 13,86:1 de noche; `--tinta-2` 10,36:1 y 9,67:1. */
@media (hover: hover) {
  .plan:hover { background: color-mix(in srgb, var(--seccion) 4%, var(--papel)); }
}

/* ============================================================
   17. Formularios
   ============================================================ */
.campo { display: grid; gap: var(--e-2); margin-bottom: var(--e-4); }
.campo > label { font-weight: 600; font-size: var(--t-sm); }
.campo .pista { font-size: var(--t-sm); color: var(--tinta-3); }
.campo input, .campo textarea, .campo select {
  font: inherit; font-size: var(--t-base);
  padding: .75rem var(--e-3);
  border: 2px solid var(--linea); border-radius: var(--r-md);
  background: var(--papel); color: var(--tinta);
  width: 100%;
}
.campo textarea { min-height: 8rem; resize: vertical; }
.campo input:focus, .campo textarea:focus, .campo select:focus { border-color: var(--marca); }
/* :user-invalid y no :invalid — :invalid pinta de rojo un campo obligatorio
   vacío desde el primer instante, antes de que nadie haya escrito nada. */
.campo input:user-invalid, .campo textarea:user-invalid { border-color: var(--racha-tinta); }
.campo input:user-invalid ~ .error, .campo textarea:user-invalid ~ .error { display: block; }
.campo .error { display: none; color: var(--racha-tinta); font-size: var(--t-sm); font-weight: 600; }

.consentimiento { display: grid; grid-template-columns: auto 1fr; gap: var(--e-3); align-items: start; font-size: var(--t-sm); color: var(--tinta-2); }
.consentimiento input { width: 1.25rem; height: 1.25rem; margin-top: .15rem; accent-color: var(--marca); }

/* Se retiró `.cazamoscas` (position:absolute; left:-9999px; opacity:0;
   pointer-events:none): los dos formularios que tienen cazamoscas —la
   convocatoria y el contacto— lo ocultan con `<div hidden aria-hidden="true">`
   y nunca llegaron a pedir esta clase. Solo vivía en los comentarios. */

/* ============================================================
   18. Acordeón de preguntas
   ============================================================ */
.faq { display: grid; gap: var(--e-3); }
.faq details {
  background: var(--papel); border: 2px solid var(--linea); border-radius: var(--r-lg);
  padding: var(--e-4) var(--e-5);
}
.faq details[open] { border-color: color-mix(in srgb, var(--seccion) 40%, transparent); }
.faq summary {
  cursor: pointer; font-weight: 700; font-size: var(--t-md);
  list-style: none; display: flex; justify-content: space-between; gap: var(--e-4); align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: none; width: .625rem; height: .625rem;
  border-right: 3px solid var(--seccion-tinta); border-bottom: 3px solid var(--seccion-tinta);
  transform: rotate(45deg); transition: transform .18s ease; margin-right: .25rem;
}
.faq details[open] summary::after { transform: rotate(-135deg); }
/* 68ch x 0,573 em/ch = 39em. Ver el porqué en `--medida`. */
.faq details > *:not(summary) { margin-top: var(--e-3); color: var(--tinta-2); font-size: var(--t-base); max-width: 39em; }
.faq .fuente { font-size: var(--t-xs); color: var(--tinta-3); }

/* ============================================================
   19. Vídeo y capturas reales
   ============================================================ */
figure { margin: 0; }
.marco-video {
  border-radius: var(--r-lg); overflow: hidden;
  border: 2px solid var(--linea); background: #0B1220;
  /* aspect-ratio fijo para que el hueco esté reservado antes de que cargue
     el vídeo y la página no dé el salto. */
  aspect-ratio: 16 / 9;
}
.marco-video video { width: 100%; height: 100%; display: block; object-fit: cover; }
figcaption { margin-top: var(--e-3); font-size: var(--t-sm); color: var(--tinta-2); }
figcaption b { color: var(--tinta); display: block; font-size: var(--t-base); }

/* El teléfono que enmarca una captura real de la aplicación. El marco es
   CSS; la imagen de dentro es la pantalla de verdad, sin retocar. */
.telefono {
  border: 10px solid var(--tinta);
  border-radius: 2rem;
  overflow: hidden;
  background: var(--tinta);
  /* El halo es del color de SU sección, no gris. Una sombra gris debajo de una
     captura llena de color es lo que hace que la imagen parezca pegada encima
     en vez de estar puesta en la página: la luz que rebota en algo azul llega
     azul al papel de al lado.
     Las tres piezas se juntan AQUÍ y no en una ficha de :root porque aquí es
     donde `--seccion` ya vale lo que tiene que valer; escrita arriba, la mezcla
     se resolvería con la marca y todos los teléfonos tendrían halo azul. */
  box-shadow:
    var(--sh-seccion-gris),
    var(--sh-seccion-tiro) color-mix(in srgb, var(--seccion) var(--sh-seccion-carga), transparent);
  max-width: 16rem;
  aspect-ratio: 500 / 890;
}
.telefono img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ============================================================
   20. Utilidades de color de sección

   Poner una de estas clases en una <section> tiñe todo lo de dentro. Es la
   única forma prevista de dar color a una sección: nada de escribir reglas
   nuevas para cada pantalla.
   ============================================================ */
/* `--seccion-hondo` viaja con las demás y no se deriva aquí de `--seccion`:
   un var() dentro de una ficha se resuelve en el elemento donde está escrita,
   así que `--seccion-hondo: color-mix(..., var(--seccion), ...)` puesto en
   :root se quedaría congelado con el azul de marca y todas las secciones
   tendrían el mismo fondo. Cada clase trae el suyo hecho. */
.s-marca   { --seccion: var(--marca);   --seccion-tinta: var(--marca-tinta);   --seccion-lavado: var(--marca-lavado);   --seccion-hondo: var(--marca-hondo);   --sobre-seccion: var(--sobre-marca); }
.s-acierto { --seccion: var(--acierto); --seccion-tinta: var(--acierto-tinta); --seccion-lavado: var(--acierto-lavado); --seccion-hondo: var(--acierto-hondo); --sobre-seccion: var(--sobre-acierto); }
.s-racha   { --seccion: var(--racha);   --seccion-tinta: var(--racha-tinta);   --seccion-lavado: var(--racha-lavado);   --seccion-hondo: var(--racha-hondo);   --sobre-seccion: var(--sobre-racha); }
.s-xp      { --seccion: var(--xp);      --seccion-tinta: var(--xp-tinta);      --seccion-lavado: var(--xp-lavado);      --seccion-hondo: var(--xp-hondo);      --sobre-seccion: var(--sobre-xp); }
.s-premium { --seccion: var(--premium); --seccion-tinta: var(--premium-tinta); --seccion-lavado: var(--premium-lavado); --seccion-hondo: var(--premium-hondo); --sobre-seccion: var(--sobre-premium); }
.s-mirar   { --seccion: var(--mirar);   --seccion-tinta: var(--mirar-tinta);   --seccion-lavado: var(--mirar-lavado);   --seccion-hondo: var(--mirar-hondo);   --sobre-seccion: var(--sobre-mirar); }

.n-a1 { --seccion: var(--n-a1); --seccion-tinta: var(--n-a1-tinta); --seccion-lavado: var(--n-a1-lavado); --seccion-hondo: var(--n-a1-hondo); --sobre-seccion: var(--sobre-a1); }
.n-a2 { --seccion: var(--n-a2); --seccion-tinta: var(--n-a2-tinta); --seccion-lavado: var(--n-a2-lavado); --seccion-hondo: var(--n-a2-hondo); --sobre-seccion: var(--sobre-a2); }
.n-b1 { --seccion: var(--n-b1); --seccion-tinta: var(--n-b1-tinta); --seccion-lavado: var(--n-b1-lavado); --seccion-hondo: var(--n-b1-hondo); --sobre-seccion: var(--sobre-b1); }
.n-b2 { --seccion: var(--n-b2); --seccion-tinta: var(--n-b2-tinta); --seccion-lavado: var(--n-b2-lavado); --seccion-hondo: var(--n-b2-hondo); --sobre-seccion: var(--sobre-b2); }
.n-c1 { --seccion: var(--n-c1); --seccion-tinta: var(--n-c1-tinta); --seccion-lavado: var(--n-c1-lavado); --seccion-hondo: var(--n-c1-hondo); --sobre-seccion: var(--sobre-c1); }
.n-c2 { --seccion: var(--n-c2); --seccion-tinta: var(--n-c2-tinta); --seccion-lavado: var(--n-c2-lavado); --seccion-hondo: var(--n-c2-hondo); --sobre-seccion: var(--sobre-c2); }

/* ============================================================
   21. El dúo: texto a un lado, algo que mirar al otro

   Estaba escrito con `style="grid-template-columns:1fr 1fr"` en línea en cada
   sección, y eso NO se apila en el móvil: una media query no puede alcanzar un
   atributo style. El resultado eran dos columnas de 160 px en un teléfono, con
   el titular partido letra a letra. Aquí se apila a los 56rem, una sola vez y
   para todas.
   ============================================================ */
.duo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.duo-ancho    { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
.duo-estrecho { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: start; }

@media (max-width: 56rem) {
  .duo, .duo-ancho, .duo-estrecho { grid-template-columns: 1fr; }
  /* En el móvil la figura va debajo del texto y centrada; al apilarse, un
     teléfono pegado al margen izquierdo se lee como un descuadre. */
  .duo > figure { justify-self: center; }
}

/* ============================================================
   22. Aligerar el móvil sin quitar contenido

   La petición era que no se viera recargada en pantalla pequeña. La respuesta
   NO es esconder secciones —el contenido es el argumento de venta—, sino
   quitar la decoración, dejar que el navegador no pinte lo que no se ve, y
   reducir el aire entre bloques para que el pulgar llegue antes al final.
   ============================================================ */
@media (max-width: 48rem) {
  section { padding-block: clamp(2.25rem, 7vw, 3rem); }
  .cabeza { margin-bottom: var(--e-5); }

  /* content-visibility salta el pintado de lo que queda fuera de pantalla;
     contain-intrinsic-size reserva una altura estimada para que la barra de
     desplazamiento no dé saltos mientras se baja. */
  section:not(:first-of-type) { content-visibility: auto; contain-intrinsic-size: auto 32rem; }

  /* El sendero se estrecha: los nodos de 3,5rem se comen media pantalla. */
  .paso { grid-template-columns: 2.75rem 1fr; gap: var(--e-3); }
  .paso-nodo { width: 2.75rem; height: 2.75rem; font-size: var(--t-base); }
  .paso::before { left: 1.3125rem; top: 2.75rem; }

  .tarjeta { padding: var(--e-4); }
  .telefono { max-width: 13rem; }
}

/* En pantallas con poco ancho, un titular de 3,5rem parte palabras por la
   mitad. text-wrap:pretty evita además la línea huérfana al final. */
p, li, dd, figcaption { text-wrap: pretty; }

/* ============================================================
   23. Preferencias del sistema

   Quien pide más contraste suele tener el fondo casi blanco y el texto casi
   negro forzados por el sistema; lo que se rompe entonces son los elementos
   que solo se distinguían por una sombra.
   ============================================================ */
@media (prefers-contrast: more) {
  :root { --tinta-2: var(--tinta); --tinta-3: var(--tinta); }
  .tarjeta, .btn, .chip, .aviso { border: 2px solid currentColor; }
  .tarjeta-alta { box-shadow: none; }

  /* Quien pide más contraste quiere fondos planos: el degradado le da dos
     valores distintos bajo la misma línea de texto —y el peor de los dos es el
     que manda—, y el grano le mete ruido justo debajo de las letras. Se
     devuelve el color vivo, que en los seis colores de tinta oscura es el
     extremo BUENO del degradado: el coral vuelve de 4,70:1 a 6,11:1 y el
     naranja C2 de 5,18:1 a 6,75:1. */
  .bloque-color { background-image: none; background-color: var(--seccion); }

  /* El halo de color es lo primero que se pierde con el fondo forzado casi
     blanco; el marco del teléfono tiene que sostenerse solo. */
  .telefono { box-shadow: none; }

  /* Y el tinte del 4% deja de ser señal suficiente cuando el resto de la
     página se ha ido a los extremos: el filo entero lo dice mejor. */
  .tarjeta-seccion:hover, .plan:hover { background: var(--papel); }
  .tarjeta-seccion:hover { border-color: currentColor; }
}
@media (prefers-reduced-transparency: reduce) {
  .barra { backdrop-filter: none; background: var(--fondo); }
}
@media (forced-colors: active) {
  /* Con colores forzados, box-shadow desaparece: el relieve del botón dejaría
     de verse y no habría nada que marcara su contorno. */
  .btn { border: 1px solid ButtonText; }
  .progreso > i { background: Highlight; }

  /* Los degradados SÍ se pintan con colores forzados —no son sombras—, y ahí
     se convierten en manchas de un color que el sistema no eligió, encima de
     un texto que sí. Los tres se retiran y se deja que manden Canvas y
     CanvasText; la línea de 1 px de la barra y el borde del teléfono siguen
     dibujando los mismos límites. */
  .bloque-color { background-image: none; }
  .barra::after { display: none; }
  .filo-arriba::before, .filo-abajo::after { background: CanvasText; }
}

/* ============================================================
   24. La prueba de nivel

   Estas clases las escribe `js/prueba.js` y faltaban aquí: los botones de
   respuesta salían con el aspecto de fábrica del navegador —gris, borde
   biselado, Arial de 13 px— y, peor, `.es-correcta` no existía, así que al
   fallar no se veía cuál era la buena. El ejercicio quedaba en decir «mal» y
   pasar a la siguiente, que es exactamente lo que no enseña nada.
   ============================================================ */
.prueba-intro { /* el contenedor que se retira al empezar la muestra */ }
.prueba-intro[hidden] { display: none !important; }

/* La caja recibe el foco en cada repintado, así que necesita poder recibirlo
   (tabindex="-1" en el HTML) pero sin dibujar el anillo: quien llega con el
   ratón no ha pedido ver un recuadro alrededor de media pantalla. */
#prueba:focus { outline: none; }
#prueba:focus-visible { outline: 3px solid var(--marca); outline-offset: 4px; }

.prueba-paso {
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--seccion-tinta);
  margin-bottom: var(--e-3);
}
.prueba-paso span { color: var(--tinta-3); font-weight: 500; }

.prueba-pide { margin-top: var(--e-5); font-size: var(--t-sm); color: var(--tinta-3); }

/* La palabra que se pregunta es lo único grande de la pantalla: si compite con
   el resto, la vista salta entre cuatro sitios antes de llegar a ella. */
.prueba-voz {
  font-family: var(--display); font-size: var(--t-2xl); font-weight: 600;
  letter-spacing: -.025em; line-height: 1.1; margin-top: var(--e-1);
}

.prueba-opciones { display: grid; gap: var(--e-3); margin-top: var(--e-5); }

.opcion {
  font: inherit; font-size: var(--t-md); font-weight: 500; text-align: left;
  padding: var(--e-4); min-height: 3.25rem;
  background: var(--papel); color: var(--tinta);
  border: 2px solid var(--linea); border-radius: var(--r-md);
  box-shadow: 0 3px 0 var(--linea);
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease, transform .08s ease, box-shadow .08s ease;
}
.opcion:hover:not([disabled]) { border-color: var(--seccion); background: var(--seccion-lavado); }
/* Al pulsar, el lavado se hunde un 12% hacia el color vivo. Sin esto la única
   señal era el desplazamiento de 3 px, que desaparece para quien pide menos
   movimiento y no existe en una pantalla táctil, donde el dedo tapa justo el
   botón que acaba de tocar: el color que asoma alrededor es lo que confirma
   que se ha registrado. `--tinta` sobre el lavado pulsado: 13,68:1 de día y
   7,98:1 de noche. */
.opcion:active:not([disabled]) {
  transform: translateY(3px); box-shadow: none;
  border-color: var(--seccion);
  background: color-mix(in srgb, var(--seccion) 12%, var(--seccion-lavado));
}
.opcion[disabled] { cursor: default; }

/* Acierto y fallo no se distinguen solo por el color: el acierto lleva su
   marca de verificación y el fallo su aspa, dibujadas con bordes. Quien no
   separa el verde del rojo tiene que poder leer el resultado igual. */
.opcion.es-correcta {
  border-color: var(--acierto); background: var(--acierto-lavado);
  color: var(--acierto-tinta); font-weight: 700; box-shadow: none;
  position: relative; padding-right: 3rem;
}
.opcion.es-correcta::after {
  content: ""; position: absolute; right: 1.25rem; top: 50%;
  width: .5rem; height: .9rem; margin-top: -.55rem;
  border-right: 3px solid currentColor; border-bottom: 3px solid currentColor;
  transform: rotate(45deg);
}
.opcion.es-fallo {
  border-color: var(--racha); background: var(--racha-lavado);
  color: var(--racha-tinta); box-shadow: none;
  position: relative; padding-right: 3rem;
}
.opcion.es-fallo::before, .opcion.es-fallo::after {
  content: ""; position: absolute; right: 1.25rem; top: 50%;
  width: .9rem; height: 3px; background: currentColor; border-radius: 2px;
}
.opcion.es-fallo::before { transform: rotate(45deg); }
.opcion.es-fallo::after { transform: rotate(-45deg); }
/* Las que no se eligieron y tampoco eran la buena se apagan: sobran. */
.opcion[disabled]:not(.es-correcta):not(.es-fallo) { opacity: .5; box-shadow: none; }

.prueba-juicio {
  margin-top: var(--e-4); font-weight: 600; font-size: var(--t-md);
}
.prueba-juicio.bien { color: var(--acierto-tinta); }
.prueba-juicio.mal { color: var(--racha-tinta); }
.prueba-juicio + .btn { margin-top: var(--e-4); }

/* El nivel del resultado, en grande y con el color de su escalón. */
.prueba-nivel { margin: var(--e-4) 0 var(--e-3); }
.prueba-nivel span {
  display: inline-grid; place-items: center;
  width: 5rem; height: 5rem; border-radius: var(--r-lg);
  background: var(--seccion); color: var(--sobre-seccion);
  font-family: var(--display); font-size: var(--t-2xl); font-weight: 700;
  letter-spacing: -.02em;
}

#prueba .progreso { margin-bottom: var(--e-4); }

@media (max-width: 30rem) {
  .prueba-voz { font-size: var(--t-xl); }
  .opcion { font-size: var(--t-base); padding: var(--e-3); }
}

/* ============================================================
   25. Lo que cambia DENTRO de un bloque de color

   Un bloque a sangre no es un fondo distinto: es un contexto distinto, y todo
   lo que cae dentro tiene que responder. Sin esto pasaba lo de la portada: el
   boton principal seguia siendo verde jade sobre azul marca —dos colores
   saturados peleandose a dos centimetros— y el pie de la figura seguia en
   `--tinta-2`, que sobre el azul es ilegible.

   La regla: dentro de color, el elemento que manda se pone del color del
   PAPEL. Es el contraste maximo posible y ademas invierte la jerarquia sin
   introducir un tercer color, que es lo que ensucia.
   ============================================================ */
.bloque-color .btn-principal,
.bloque-color .btn-acierto,
.bloque-color .btn-racha {
  background: var(--papel);
  color: var(--seccion-tinta);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--seccion) 55%, #000);
}
.bloque-color .btn-principal:hover,
.bloque-color .btn-acierto:hover,
.bloque-color .btn-racha:hover {
  background: var(--papel-2);
  color: var(--seccion-tinta);
}

/* El secundario se queda en contorno, pero del color del papel: un borde gris
   sobre azul desaparece. */
.bloque-color .btn-borde {
  background: transparent;
  color: var(--sobre-seccion);
  border-color: color-mix(in srgb, var(--sobre-seccion) 45%, transparent);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--sobre-seccion) 22%, transparent);
}
/* Al 12 % el relleno robaba contraste al texto: sobre coral daba 3,86:1.
   Al 6 % se nota igual que se puede pulsar y el texto se conserva. */
.bloque-color .btn-borde:hover {
  background: color-mix(in srgb, var(--sobre-seccion) 6%, transparent);
  border-color: var(--sobre-seccion);
  color: var(--sobre-seccion);
}

/* Todo el texto secundario hereda del bloque y se apaga con opacidad, no con
   un gris: un gris fijo sobre un fondo de color se ve sucio, y ademas deja de
   funcionar en cuanto la seccion cambia de tono. */
.bloque-color figcaption,
.bloque-color .medida,
.bloque-color p:not(.folio):not([class*="unidad"]) { color: inherit; }
.bloque-color figcaption { opacity: 1; }
.bloque-color a:not(.btn):not(.btn-texto) { color: inherit; }
.bloque-color .btn-texto { color: var(--sobre-seccion); border-bottom-color: currentColor; }

/* La captura dentro de color: el marco oscuro del telefono sobre un fondo
   saturado se pierde. Un halo del papel lo recorta contra el fondo. */
.bloque-color .telefono {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sobre-seccion) 22%, transparent),
              0 24px 60px -20px rgba(0, 0, 0, .5);
}

/* ---------- dos bloques de color seguidos ----------
   Pasaba entre la portada y la franja de cifras: dos azules casi iguales con
   una costura horizontal a media pantalla, que se lee como un fallo de
   maquetacion y no como una decision. Si van seguidos, el segundo pierde su
   degradado propio y continua el del primero, con un filete finisimo que
   marca la juntura a proposito. */
.bloque-color + .bloque-color {
  background-image: none;
  background-color: color-mix(in srgb, var(--seccion) 88%, #000);
  border-top: 1px solid color-mix(in srgb, var(--sobre-seccion) 14%, transparent);
}

/* ============================================================
   26. Todo lo que pone su propio fondo pone también su propio color

   Era una limitación de verdad, no un detalle: `.unidad`, `.faq details` y
   `.aviso` declaraban `background` pero no `color`, así que dentro de un
   `.bloque-color` heredaban `--sobre-seccion` —la tinta pensada para ir SOBRE
   el color de la sección— y acababan escribiendo con ella sobre su propio
   fondo de papel. En tema claro pasaba desapercibido; en oscuro quedaba tinta
   casi negra sobre tarjeta casi negra.

   Consecuencia práctica: ninguna de esas tres piezas podía meterse en una
   sección a sangre, que son justo las que más se lucen ahí. La regla es
   sencilla y vale para siempre: quien pinta su fondo, pinta su tinta.
   ============================================================ */
.unidad, .faq details, .aviso, .tarjeta, .plan, .telefono {
  color: var(--tinta);
}
.bloque-color .unidad,
.bloque-color .faq details,
.bloque-color .aviso,
.bloque-color .tarjeta,
.bloque-color .plan { color: var(--tinta); }

/* Y sus textos secundarios vuelven a su gris, que dentro del bloque habían
   perdido por la regla de herencia de la sección 25. */
/* El :not() no es adorno. Sin el, esta regla (0,2,0 y mas abajo en el archivo)
   le ganaba a .campo .error (0,2,0 tambien), y un mensaje de error dentro de un
   bloque de color salia gris en vez de rojo. Lo mismo con .fon, que es el ocre
   de la fonetica, y con .guardado. Consecuencia practica: ninguna seccion con
   formulario podia ir a sangre, que es justo donde una llamada a la accion se
   luce. Se excluyen por nombre las que llevan color propio con significado.
   En la ficha de unidad se excluyen tambien la palabra (.unidad-en) y su
   traduccion (.unidad-es): son lo que se ensena, no texto de apoyo, y en
   gris la palabra inglesa de una ficha dentro de un bloque de color salia
   mas apagada que la nota de debajo. Se quedan con la --tinta de la ficha. */
.bloque-color .tarjeta p:not(.error):not(.pista):not(.guardado),
.bloque-color .unidad p:not(.unidad-ipa):not(.fon):not(.unidad-en):not(.unidad-es),
.bloque-color .faq details > *:not(summary),
.bloque-color .aviso p { color: var(--tinta-2); }

/* Y por si alguien añade otra clase con color propio: las semanticas mandan
   siempre dentro de un bloque de color. */
.bloque-color .error { color: var(--racha-tinta); }
.bloque-color .guardado { color: var(--acierto-tinta); }
.bloque-color .fon, .bloque-color .unidad-ipa { color: var(--seccion-tinta); }
.bloque-color .unidad .unidad-pron { color: var(--tinta-3); }
.bloque-color .plan li { color: var(--tinta-2); }

/* ============================================================
   27. 320 px: el movil que nadie prueba

   A 320 px la barra desbordaba 56 px. La cuenta: el rotulo ocupa 135 px con
   `flex: none`, el respiro lateral 48, y las acciones 201. Son 352 en una caja
   de 272.

   Se midio apretar el respiro, el hueco y el relleno de los botones sin
   esconder nada: recupera 25 de los 56. No llega. Algo tiene que ceder, y lo
   que menos duele es la palabra «Talkademy» al lado del emblema — el emblema
   solo ya identifica la marca, y a 390 px la palabra vuelve. De ahi el corte
   en 22rem y no en un valor redondo: 352 px es justo donde deja de caber.
   ============================================================ */
/* A 22rem (352 px) ni apretando cabe, y lo que menos duele es la palabra
   «Talkademy» al lado del emblema: el emblema solo ya identifica la marca.
   De 23rem para arriba vuelve, porque con la seccion 30 ya cabe. */
@media (max-width: 23rem) {
  .rotulo b { display: none; }
}

/* La zona pulsable minima es 44x44. Menos que eso obliga a apuntar, y apuntar
   con el pulgar en un movil es lo que hace que la gente pulse dos veces. */
.rotulo, .panel-rotulo, .panel-grupo a { min-height: 2.75rem; }
.consentimiento, .campo label:has(input[type="checkbox"]) { min-height: 2.75rem; align-items: center; }

/* ============================================================
   28. La apertura de color no puede ser media pantalla vacía

   Las secciones de apertura llevan `.cabeza`, que limita el texto a 42rem
   para que el renglón se lea. Eso está bien en una sección normal —el texto
   ocupa la izquierda y a la derecha va otra cosa—, pero en una apertura a
   sangre no hay otra cosa: quedaba media pantalla de violeta desierto y
   doscientos píxeles de aire arriba y abajo. Mucho color para nada.

   La solución no es quitar el color: es que la apertura sea una apertura.
   El titular crece, el texto ocupa una medida cómoda pero no ridícula, y el
   bloque respira lo justo. Un titular grande llena el color mejor que el
   color solo.
   ============================================================ */
section.bloque-color:first-of-type .cabeza,
section.bloque-color.aire-largo .cabeza {
  max-width: 54rem;
  margin-bottom: 0;
}
section.bloque-color:first-of-type h1,
section.bloque-color.aire-largo h1 {
  font-size: clamp(2.25rem, 1.5rem + 3.4vw, 4rem);
  /* 18ch x 0,547 em/ch (Source Serif 4 a peso 600) = 9,85em. En `ch` este
     titular medía 768 px con la fuente de respaldo y 630 px con la real: al
     estrecharse 138 px pasaba de dos líneas a tres y bajaba 57 px todo lo que
     tenía debajo. Era el salto más caro de la plantilla. */
  max-width: 9.85em;
}
section.bloque-color:first-of-type .cabeza p,
section.bloque-color.aire-largo .cabeza p {
  /* 58ch x 0,573 em/ch = 33,2em. Ver el porqué en `--medida`. */
  max-width: 33.2em;
  font-size: clamp(1.0625rem, 1rem + .4vw, 1.25rem);
}
/* Y menos aire: `aire-largo` son hasta 128 px por lado, que en una apertura
   con solo titular y entradilla deja el bloque flotando. */
section.bloque-color.aire-largo { padding-block: clamp(3rem, 6vw, 5rem); }


/* ============================================================
   29. La pantalla de acceso

   Una sola tarjeta centrada, sin cabecera de navegacion y sin pie. No es
   minimalismo: una pantalla donde se escribe una contrasena no deberia
   ofrecer quince sitios mas a los que ir. Cuantos menos enlaces haya, menos
   posibilidades de que alguien pulse el equivocado con la contrasena a medio
   escribir, y mas facil es reconocer de un vistazo que esta es LA pagina de
   entrada y no una copia: una pagina sobria es mas dificil de falsificar de
   forma convincente que una llena de adornos.

   El ancho es 24rem y no un porcentaje. Un formulario de dos campos estirado
   a 1400 px es incomodo de leer y de rellenar: el ojo tiene que recorrer toda
   la pantalla para ir de la etiqueta al campo.
   ============================================================ */

.acceso-marco {
  /* `min-height: 100svh` y no `100vh`: en el movil, `vh` cuenta la barra del
     navegador como si no estuviera, asi que la tarjeta quedaba centrada
     respecto a una pantalla mas alta que la real y se iba hacia abajo. */
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--e-5) var(--e-4);
  background: var(--papel-2);
}

.acceso {
  width: 100%;
  max-width: 24rem;
  background: var(--papel);
  border: 2px solid var(--linea);
  border-radius: var(--r-xl);
  padding: var(--e-6);
  box-shadow: var(--sombra);
}

.acceso-marca {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-5);
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-lg);
  color: var(--tinta);
  text-decoration: none;
}
.acceso-marca img { display: block; }

.acceso h1 { font-size: var(--t-2xl); margin-bottom: var(--e-2); }

.acceso-entrada {
  color: var(--tinta-2);
  font-size: var(--t-sm);
  margin-bottom: var(--e-5);
}

/* El boton a todo el ancho del formulario. En una tarjeta de 24rem con dos
   campos a todo el ancho, un boton de su tamano natural queda suelto a la
   izquierda y no parece el final del formulario. */
.btn-ancho { width: 100%; justify-content: center; }

/* El recado del resultado. Ocupa sitio SIEMPRE que se muestra, y aparece
   encima del boton y no debajo: debajo queda fuera de la pantalla en un movil
   con el teclado abierto, y entonces se responde a un error que no se ve. */
.acceso-recado {
  font-size: var(--t-sm);
  font-weight: 600;
  line-height: 1.45;
  padding: var(--e-3);
  border-radius: var(--r-md);
  margin-bottom: var(--e-4);
}
/* El color no es lo unico que distingue el fallo del acierto: lleva tambien
   un borde a la izquierda de 3px. Quien no distingue rojo de verde ve igual
   los dos rellenos palidos, pero el grosor del filo si se ve. */
.acceso-recado.es-fallo {
  color: var(--racha-tinta);
  background: var(--racha-lavado);
  border-left: 3px solid var(--racha-tinta);
}
.acceso-recado.es-bien {
  color: var(--acierto-tinta);
  background: var(--acierto-lavado);
  border-left: 3px solid var(--acierto-tinta);
}

.acceso-pie {
  margin-top: var(--e-4);
  font-size: var(--t-sm);
  color: var(--tinta-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  align-items: center;
}
.acceso-pie a { color: var(--marca-tinta); }
.acceso-volver { margin-top: var(--e-3); padding-top: var(--e-3); border-top: 1px solid var(--linea); }

/* A 320 px la tarjeta pierde el marco y se pega a los bordes: un borde
   redondeado a 8 px de cada lado en una pantalla de 320 solo roba ancho al
   unico contenido que hay. */
@media (max-width: 26rem) {
  .acceso-marco { padding: var(--e-4) 0; align-content: start; }
  .acceso { border-radius: 0; border-left: 0; border-right: 0; box-shadow: none; padding: var(--e-5) var(--e-4); }
}

/* En esta pagina los errores de campo los enciende el JavaScript, no el
   navegador. `base.css` los tiene en `display:none` y solo los saca con
   `:user-invalid`, que es exactamente lo que hace falta en el formulario de
   contacto: el navegador sabe si un correo tiene forma de correo.

   Aqui no sirve. El error mas importante de esta pantalla —la contrasena es
   incorrecta— el navegador no puede saberlo, y el campo no queda
   `:user-invalid` por haber fallado contra el servidor. Con la regla de
   `base.css` intacta, quitarle `hidden` al parrafo no lo ensenaba: seguia en
   `display:none` y la persona no veia ni un mensaje.

   Asi que aqui manda `hidden` y solo `hidden`. */
.acceso-pagina .campo .error { display: block; }
.acceso-pagina .campo .error[hidden] { display: none; }

/* Y lo mismo para el recado del resultado: si algun dia una regla le pone un
   `display`, `hidden` tiene que seguir ganando. Es la leccion del panel, que
   llego a ensenar tres avisos contradictorios a la vez porque `.fallo` tenia
   `display:grid` y le ganaba al atributo. */
.acceso-pagina [hidden] { display: none !important; }


/* ============================================================
   30. La barra superior no cabia en un movil normal

   Medido en un marco de 390 px —un iPhone 13, no un caso raro—: el contenido
   de la barra pedia 383 px de los 375 utiles y se salia 8. Todas las paginas
   a la vez, porque la barra es la misma en las dieciseis. Un desbordamiento
   de 8 px no se ve como un fallo: se ve como que la pagina se arrastra un
   poco de lado al pasar el dedo, y eso se achaca al movil.

   La cuenta, con el respiro de `.pliego` a 24 px por lado:

       24 + rotulo 142 + hueco 16 + acciones 201 + 24  =  407
       disponibles                                     =  375

   La seccion 27 ya habia atacado esto, pero solo miro a 320 px y dio por
   hecho que «a 390 la palabra vuelve a caber». No cabia. Lo que se midio
   entonces —apretar respiro, hueco y relleno sin esconder nada— recupera
   unos 36 px, y a 390 eso SI es suficiente, aunque a 320 no lo fuera.

   Asi que aqui se aprieta, y solo en la barra. El resto de `.pliego` conserva
   sus 24 px por lado: ahi no son decoracion, son el margen que separa el
   renglon del borde de la pantalla. En la barra no hay renglon que leer, hay
   cuatro controles que colocar.
   ============================================================ */
/* `.barra .barra-fila` y no `.barra-fila` a secas: panel.css usa el mismo
   nombre para la fila de una barra de habilidad, y este relleno le metía 16 px
   por cada lado en el móvil —las ocho destrezas del expediente salían
   sangradas respecto al título de su bloque—. Aquí solo se aprieta la barra
   superior del sitio, que es la que no cabía. */
@media (max-width: 30rem) {
  .barra .barra-fila { padding-inline: var(--e-4); gap: var(--e-3); }
  .barra-acciones { gap: 6px; }
  /* El relleno lateral, no el vertical: la zona pulsable sigue siendo de 44
     px de alto, que es lo que importa para acertar con el pulgar. */
  .barra-acciones .btn { padding-inline: .75rem; }
}


/* ============================================================
   31. El recado de los dos formularios

   Lo crea `js/formularios.js` al enviar, y lleva su propia clase ademas de
   `.acceso-recado` por dos razones. La primera es que el JavaScript necesita
   un gancho que no dependa de como se vea: si manana el recado cambia de
   aspecto, `.acceso-recado` puede irse y el gancho se queda. La segunda es
   que aqui vive dentro de una tarjeta, pegado encima de un boton que ocupa
   todo el ancho, y ahi hace falta un respiro que en la pantalla de acceso no
   hacia falta.
   ============================================================ */
.envio-recado { margin-top: var(--e-4); }
