/* ==========================================================================
   Motor SCORM — estilos de los layouts
   El lienzo de autoría es 1280×720. En móvil (.es-movil) cada layout pasa a
   una columna con alturas naturales.
   ========================================================================== */

.layout {
  position: relative;
  width: 100%;
  height: 100%;
  padding: var(--marca-esp-xl) var(--marca-margen-lateral);
  background: var(--marca-fondo);
}

.layout.con-fondo {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.es-movil .layout {
  height: auto;
  min-height: 100%;
  padding: var(--marca-esp-lg) var(--marca-esp-md);
}

/* --------------------------------------------------------------- portada */

/* Panel claro a la izquierda (no un velo azul oscuro con texto blanco — eso era una
   invención sin la referencia real). La foto se confina a la derecha, se desvanece hacia
   blanco en la costura, y una diagonal roja decorativa marca la esquina inferior derecha. */
.layout-portada { display: grid; align-items: center; }

.portada-velo {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, var(--marca-fondo) 0%, var(--marca-fondo) 36%, rgba(255, 255, 255, 0.85) 45%, rgba(255, 255, 255, 0) 58%);
}

/* Dos franjas diagonales paralelas y finas (no una cuña sólida): gris del lado del panel
   de texto, roja del lado de la foto, con un hueco entre ambas. Aparecen con un fade propio
   de la lámina, no atadas a los cues de audio. Medidas exactas del panel de Storyline
   (lienzo 1280×720, «Tamaño y posición», esquina superior izquierda): el motor usa el mismo
   lienzo de autoría, así que se transcriben en px tal cual, sin reinterpretar a porcentaje. */
.portada-diagonal {
  position: absolute;
  transform-origin: center center;
  z-index: 0;
  opacity: 0;
  /* «Entrar flotando» de Storyline: 0,75 s, no un fade plano. */
  animation: flotarDiagonal 750ms var(--marca-mov-curva) forwards;
}

.portada-diagonal--gris {
  left: -216px;
  top: 153px;
  width: 742px;
  height: 86px;
  transform: rotate(315deg);
  background: var(--marca-fondo-alt);
  --op-diagonal: 0.64;
}

.portada-diagonal--rojo {
  left: 646px;
  top: 451px;
  width: 861px;
  height: 176px;
  transform: rotate(315deg);
  background: var(--marca-secundario);
  --op-diagonal: 0.3;
  animation-delay: 150ms;
}

@keyframes flotarDiagonal {
  from { opacity: 0; transform: translateY(50px) rotate(315deg); }
  to   { opacity: var(--op-diagonal, 1); transform: rotate(315deg); }
}

@media (prefers-reduced-motion: reduce) {
  .portada-diagonal { animation: none; opacity: var(--op-diagonal, 1); }
}

.portada-caja {
  position: relative;
  max-width: 620px;
  z-index: 1;
}

.portada-logo {
  display: block;
  width: 200px;
  max-width: 60%;
  height: auto;
  margin-bottom: var(--marca-esp-lg);
}

/* Portada (no cierre, que reusa la misma clase pero sigue en flujo dentro de `.portada-caja`):
   medidas exactas del panel «Tamaño y posición» de Storyline sobre el lienzo 1280×720. El
   logo se ancla directo al lienzo, no al bloque de texto, por eso se saca del flujo. */
.layout > .portada-logo {
  position: absolute;
  left: 250px;
  top: 78px;
  width: 262px;
  height: 152px;
  max-width: none;
  margin-bottom: 0;
  z-index: 1;
}

.portada-titulo {
  margin: 0 0 var(--marca-esp-md);
  font-size: var(--marca-h1);
  line-height: 1.12;
  font-weight: 700;
  color: var(--marca-primario);
}

/* Portada (no cierre): caja de texto con posición, tamaño y color exactos del panel de
   Storyline. Igual truco que el logo — `.layout > .selector` solo alcanza al hijo directo del
   lienzo, no al de cierre que sigue anidado en `.portada-caja`.
   El alto es fijo a propósito: `ajustarAlaCaja()` (layouts.js) reduce el cuerpo de letra
   hasta que el texto entre, así un título más largo en otro curso se adapta en vez de
   desbordar. */
.layout > .portada-titulo {
  position: absolute;
  left: 55px;
  top: 238px;
  width: 585px;
  height: 274px;
  margin: 0;
  color: var(--marca-texto);
  line-height: 1.5;
  overflow: hidden;
  /* El ajuste automático escribe `--tam-titulo` en el elemento. Va por custom property y no
     por `style.fontSize` inline a propósito: un inline le ganaría a la regla móvil de abajo
     y el título quedaría encogido también en el teléfono, donde la caja fija no aplica. */
  font-size: var(--tam-titulo, var(--marca-h1));
}

/* Título y botón de portada entran con fade puro (sin el translateY que trae `.es-entrando`
   por defecto en el resto del motor) — las franjas ya aportan el movimiento de la lámina.
   Solo se pisa `animation-name`; duración y curva se heredan de `.es-entrando` por cascada. */
.layout > .portada-titulo.es-entrando,
.layout > .portada-cta.es-entrando {
  animation-name: apareceFade;
}

@keyframes apareceFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.portada-bajada {
  margin: 0 0 var(--marca-esp-lg);
  font-size: var(--marca-cuerpo-lg);
  line-height: 1.5;
  color: var(--marca-texto-fuerte);
}

mark.resaltado { background: none; color: var(--marca-secundario); font-weight: 700; }

.portada-bajada mark.resaltado { color: var(--marca-secundario); }

.portada-cta { background: var(--marca-primario); }
.portada-cta:hover { background: var(--marca-primario-claro); }

/* El botón de la lámina late cuando se puede usar, con el mismo criterio que «Siguiente»:
   acá el que avisa es este, porque el de la barra se retira (§0bg).
   El pulso es un halo y no un cambio de relleno: el botón ya es primario sólido y oscurecerlo
   lo apagaría en vez de destacarlo. El halo va en terciario, que es el acento de marca y el
   único de la paleta que se ve tanto sobre foto clara como sobre el navy del botón. */
@keyframes latido-cta {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--marca-terciario-rgb), 0); }
  50%      { box-shadow: 0 0 0 8px rgba(var(--marca-terciario-rgb), 0.45); }
}

.avance-libre .portada-cta:not(.es-oculto) {
  animation: latido-cta 1.6s var(--marca-mov-curva) infinite;
}

.portada-cta:hover { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .avance-libre .portada-cta:not(.es-oculto) {
    animation: none;
    box-shadow: 0 0 0 4px rgba(var(--marca-terciario-rgb), 0.45);
  }
}

.layout > .portada-cta {
  position: absolute;
  left: 171px;
  top: 590px;
  width: 259px;
  height: 63px;
}

.es-movil .layout-portada { min-height: 70vh; }
.es-movil .portada-titulo,
.es-movil .portada-bajada { color: var(--marca-blanco); text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); }
/* Único color de marca que no coincidía con ningún token: era rgb(0,20,56) literal. Pasa a
   `primario-oscuro` (rgb(0,27,70)) para que también se re-tematice — a 55% de alfa sobre una
   foto la diferencia es imperceptible, y deja de haber navy hardcodeado en el motor. */
.es-movil .portada-velo { background: rgba(var(--marca-primario-oscuro-rgb), 0.55); }
.es-movil .portada-diagonal { display: none; }

/* Las medidas exactas de Storyline son solo para el lienzo 1280×720 de escritorio; en móvil
   logo, título y botón de portada vuelven a fluir como bloques normales en vez de anclarse a
   coordenadas fijas. `order` restaura la secuencia visual correcta: al pasar a `static` se
   vuelven ítems del grid igual que `.portada-caja`, pero llegan después en el DOM porque el
   panel de Storyline los exige como hermanos del lienzo, no como hijos de la caja de texto. */
.es-movil .layout > .portada-logo {
  position: static;
  order: 1;
  width: 200px;
  max-width: 60%;
  height: auto;
  margin: 0 0 var(--marca-esp-lg);
}

.es-movil .layout > .portada-titulo {
  position: static;
  order: 2;
  width: auto;
  height: auto;
  max-width: none;
  overflow: visible;
  font-size: var(--marca-h1);   /* descarta el encogido que calculó el ajuste de escritorio */
  margin: 0 0 var(--marca-esp-md);
}

.es-movil .layout > .portada-caja { order: 3; }

.es-movil .layout > .portada-cta {
  position: static;
  order: 4;
  width: auto;
  height: auto;
}

/* --------------------------------------------------------------- descripción */

/* Medidas exactas del panel «Tamaño y posición» de Storyline sobre el lienzo 1280×720.
   El rectángulo rojo, el ícono y el texto forman UNA unidad (`.desc-banda`): se revelan
   juntos cuando la narración termina de leer la pregunta, no por separado. */
.layout-descripcion { padding: 0; }

.desc-pregunta {
  position: absolute;
  left: 55px;
  top: 168px;
  width: 585px;
  height: 211px;
  margin: 0;
  overflow: hidden;
  color: var(--marca-primario);
  font-size: var(--tam-pregunta, var(--marca-h1));
  line-height: 1.2;
}

.desc-banda {
  position: absolute;
  left: 0;
  top: 436px;
  width: var(--marca-lienzo-ancho);
  height: calc(var(--marca-lienzo-alto) - 436px);
  background: var(--marca-secundario);
}

/* Coordenadas del panel de Storyline menos el origen de la banda (0, 436). */
.desc-icono {
  position: absolute;
  left: 101px;
  top: 58px;
  width: 153px;
  height: 157px;
  object-fit: contain;
  color: var(--marca-blanco);   /* el SVG pinta con currentColor */
}

.desc-cuerpo {
  position: absolute;
  left: 284px;
  top: 42px;
  width: 981px;
  height: 200px;
  overflow: hidden;
  font-size: var(--tam-cuerpo-desc, var(--marca-cuerpo-lg));
}

.desc-banda .texto {
  color: var(--marca-blanco);
  font-weight: 700;
  font-size: inherit;
  line-height: 1.5;
}

/* En móvil no hay lienzo fijo: todo vuelve a fluir en una columna. */
.es-movil .layout-descripcion { padding: var(--marca-esp-lg) var(--marca-esp-md); }

.es-movil .desc-pregunta {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  font-size: var(--marca-h1);
  margin: 0 0 var(--marca-esp-md);
}

.es-movil .desc-banda {
  position: static;
  width: auto;
  height: auto;
  display: grid;
  gap: var(--marca-esp-md);
  margin: var(--marca-esp-lg) calc(-1 * var(--marca-esp-md)) 0;
  padding: var(--marca-esp-lg) var(--marca-esp-md);
}

.es-movil .desc-icono,
.es-movil .desc-cuerpo {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
}

.es-movil .desc-icono { width: 96px; height: 96px; }
.es-movil .desc-cuerpo { font-size: var(--marca-cuerpo-lg); }

/* --------------------------------------------------------------- acordeón */

/* Panel de navegación lateral navy fijo — no un acordeón que se expande en línea ni un popup.
   Al elegir una categoría, el contenido cambia en el mismo panel: la lista de categorías
   nunca se mueve ni desaparece. */
.layout-acordeon { display: flex; flex-direction: column; padding-bottom: 0; }

/* Alto FIJO de 464px, el de la foto de panel que entrega el cliente (432×464). Antes era
   `flex: 1`, o sea «todo lo que sobre», y el panel terminaba en y=732 — 12px fuera del lienzo,
   que el escenario recortaba en silencio. Ahora va de 216 a 680 y quedan 40px de margen. */
.acordeon-panel {
  position: relative;
  display: flex;
  height: 464px;
  flex: none;
  margin: var(--marca-esp-md) calc(-1 * var(--marca-margen-lateral)) 0;
  overflow: hidden;
}

/* Antes de elegir una categoría, alguien invita a hacerlo — no hay texto ni foto de ninguna
   categoría en particular todavía. */
.acordeon-presentador {
  position: absolute;
  inset: 0 0 0 33%;
  width: 67%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  background: var(--marca-fondo-alt);
  z-index: 2;
  pointer-events: none;
}

.acordeon-sidebar {
  display: flex;
  flex-direction: column;
  width: 33%;
  flex-shrink: 0;
  background: var(--marca-primario);
  overflow-y: auto;
}

/* Tres estados, tal como en la referencia: reposo navy (heredado del sidebar), hover celeste
   sólido, y una vez visitada vuelve al mismo navy — sin resaltado propio — y queda marcada
   con una insignia de check en la esquina superior izquierda. */
.acordeon-cabecera {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--marca-esp-sm);
  flex: 1;
  min-height: 88px;
  padding: var(--marca-esp-sm) var(--marca-esp-lg);
  border: 0;
  background: transparent;
  color: var(--marca-blanco);
  font-family: inherit;
  font-size: var(--marca-cuerpo);
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva);
}

.acordeon-cabecera:hover:not(.es-apagada) { background: var(--marca-terciario); }
.acordeon-cabecera:focus-visible { outline: 3px solid var(--marca-terciario); outline-offset: -3px; }

/* Una pestaña bloqueada tiene que VERSE bloqueada — misma regla y misma razón que en las
   flipcards: un click sin efecto sobre un control idéntico a los demás se lee como una falla
   del curso. Cubre los dos casos: mientras corre la narración de entrada están las cuatro
   apagadas, y mientras narra una pestaña están apagadas las otras (la que suena nunca lo
   está, así que se lee sola cuál manda). */
/* Se apagan el TEXTO y el FONDO por separado, no con un `opacity` sobre el botón. La cabecera
   tiene fondo transparente —el navy lo pone el sidebar de atrás—, así que bajarle la opacidad
   apagaba solo las letras y el fondo quedaba idéntico al de una pestaña activa: no se leía
   como bloqueada. Con un velo oscuro propio, la pestaña entera se hunde contra el sidebar. */
.acordeon-cabecera.es-apagada {
  cursor: default;
  background: rgba(0, 0, 0, 0.3);
  color: rgba(255, 255, 255, 0.45);
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva),
              color var(--marca-mov-entrada) var(--marca-mov-curva);
}

/* La insignia de «visto» acompaña el apagado: si quedara en celeste pleno sobre una pestaña
   hundida, sería lo único encendido y tiraría el ojo justo a la que no se puede tocar. */
.acordeon-cabecera.es-apagada .acordeon-check { opacity: 0.45; }

@media (prefers-reduced-motion: reduce) {
  .acordeon-cabecera.es-apagada { transition: none; }
}

.acordeon-etiqueta { flex: 1; }

/* Check de «visto»: insignia en la esquina, no un ícono en la fila — aparece la primera vez
   que se elige la categoría, igual que las variables vio_acord* de la referencia. */
.acordeon-check {
  visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 0 8px 0;
  background: var(--marca-terciario);
  color: var(--marca-blanco);
  font-size: 12px;
  font-weight: 700;
}

.acordeon-cabecera.visto .acordeon-check { visibility: visible; }

/* El panel central va en ARENA (9043 C), no en el primario. Antes compartía el navy con el
   sidebar y las dos zonas se leían como un solo bloque: no se distinguía la lista de pestañas
   del contenido de la pestaña abierta. Pedido del cliente (§0ar).

   La elección no fue libre: el manual de marca del cliente admitía fondo blanco, el neutro o
   el primario, y nada más. De los tres, el blanco abre un hueco en la lámina y el primario es
   el que ya está en el sidebar. El neutro separa por valor sin sumar un color nuevo, y es la
   misma superficie que ya usan las casillas de `clasificar` y el fondo de `descripcion`. */
.acordeon-contenido {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Centrado vertical: con el texto ya ajustado a la caja, las categorías cortas tienen que
     verse centradas igual que las largas — si no, cambiar de pestaña mueve el bloque de sitio.
     Pedido de Pablo.
     El centrado NO se puede usar mientras se mide: un panel más alto que su caja se sale por
     arriba y por abajo a la vez, y encima queda invisible para el motor (`scrollHeight` sigue
     valiendo lo mismo que `clientHeight`). Por eso el ajuste se hace con `.es-midiendo`, que
     alinea arriba, y el centrado vuelve recién cuando el tamaño ya está decidido (§0az). */
  justify-content: center;
  padding: var(--marca-esp-md) var(--marca-esp-lg);
  overflow: hidden;
  background: var(--marca-fondo-alt);
  /* 17px y no 15: con las viñetas arregladas a 15 el bloque quedaba chico dentro del rectángulo
     y la distancia contra «¿Qué hacer?» se leía como un salto. A 17 el texto llena la caja y la
     diferencia entre viñeta y acción se lee como jerarquía, no como dos tamaños distintos. */
  font-size: var(--tam-acordeon-cuerpo, 17px);
  line-height: 1.35;
}

/* 432×464 exactos: es el tamaño en que el cliente entrega la foto de cada categoría. Antes era
   un 33% (422px) dentro de un panel de 516 de alto, así que el `cover` recortaba la imagen por
   los costados y por abajo. Con la caja igual a la foto, entra completa. */
.acordeon-foto {
  width: 432px;
  flex-shrink: 0;
  background-size: cover;
  background-position: center;
  background-color: var(--marca-fondo-alt);
}

/* TODO el panel se mide en `em`, o sea en múltiplos del contenedor. Es la única forma de que el
   auto-ajuste no pueda romper la jerarquía: achicando un solo número —el del contenedor— el
   bloque entero encoge junto y las proporciones quedan intactas por construcción.
   Antes cada pieza resolvía su tamaño por su cuenta a partir de la variable, y bastaba con que
   una no la tomara para que la acción terminara MÁS CHICA que las viñetas. Eso le quita la
   fuerza justo a lo que el alumno se tiene que llevar de la categoría (§0ax). */

/* Mientras se busca el tamaño, el contenido se alinea arriba: es la única forma de que el
   desborde se pueda MEDIR. Centrado, lo que no entra se reparte entre los dos bordes y
   `scrollHeight` sigue valiendo lo mismo que `clientHeight`, así que el ajuste no se entera de
   nada. Dura lo que dura `igualarTexto()`; en pantalla nunca se ve este estado. */
.acordeon-contenido.es-midiendo { justify-content: flex-start; }

/* Y ESTA es la regla que hacía falta. Las viñetas y la intro llevan la clase `.texto`, que les
   fija `font-size: var(--marca-cuerpo)` —20px— con más peso que la herencia. O sea que el panel
   decía 15px, las viñetas se dibujaban a 20 y NO encogían con el auto-ajuste: el único que sí
   encogía era «¿Qué hacer?», y terminaba más chico que las viñetas. Exactamente al revés de la
   jerarquía, y perdiendo la fuerza justo donde está lo que el alumno se lleva.
   Con esto todo lo de adentro vuelve a ser un múltiplo del contenedor. */
.acordeon-contenido .texto { font-size: 1em; }

/* Sobre arena el texto va en primario, no en blanco. Medido: 11,51:1. */
.acordeon-intro { margin: 0 0 8px; font-weight: 600; color: var(--marca-primario); font-size: 1em; }

.acordeon-bullets { margin: 0 0 var(--marca-esp-sm); padding-left: 1.2em; font-size: 1em; }
.acordeon-bullets li { margin-bottom: 0; color: var(--marca-primario); }
.acordeon-bullets li::marker { color: var(--marca-secundario); }

/* La acción es lo que la persona se lleva de la categoría, así que conserva su jerarquía. El
   terciario celeste que tenía sobre navy acá NO sirve: contra el arena da 2,17:1 y desaparece.
   Se reparte según la escala de datos destacados del manual (§11): el rótulo «¿Qué hacer?» en
   Red 032 C —jerarquía muy alta, y a 22px bold cuenta como texto grande, así que le basta 3:1 y
   mide 3,38— y la frase en 281 C, que es donde está el contenido y llega a 11,51:1. */
/* EM del contenedor, no un cálculo propio sobre la variable: así la acción guarda SIEMPRE la
   misma proporción con las viñetas, achique lo que achique el auto-ajuste.
   1,3 y no 1,47: con el cuerpo en 17px la acción sigue dando sus ~22px de referencia, pero la
   distancia entre las dos deja de leerse como un salto. */
.acordeon-accion {
  margin: 0;
  font-size: 1.3em;
  line-height: 1.3;
  color: var(--marca-primario);
}

.acordeon-accion strong {
  display: block;
  margin-bottom: 2px;
  color: var(--marca-secundario);
}

.es-movil .acordeon-contenido { font-size: var(--marca-cuerpo); line-height: 1.5; overflow-y: auto; }

.es-movil .acordeon-panel { flex-direction: column; margin: var(--marca-esp-md) 0 0; }
.es-movil .acordeon-presentador { position: static; width: 100%; height: 200px; inset: auto; }
.es-movil .acordeon-sidebar,
.es-movil .acordeon-foto { width: 100%; }
.es-movil .acordeon-foto { height: 180px; }
.es-movil .acordeon-cabecera { min-height: 56px; }

/* ------------------------------------------------- botones (familia Syncore) */

/* Lámina de botones que abren capas — composición medida del Storyline publicado de Syncore
   (analisis/especificaciones-laminas/syncore-familia.md), NO la composición base. Retícula:
   columna de título en x=109, contenido de x=399 a 1214. Las coordenadas Y del original
   incluían una franja de cromo de 78px dentro de la lámina que acá vive en el reproductor;
   se conservan las Y originales para respetar el aire del diseño.
   Todos los colores por ROL (§10): navy = primario, naranjo = secundario. */
.layout-botones { padding: 0; position: relative; }

/* ---- cromo Syncore dentro de la lámina (verificado contra captura del original):
   franja naranja fina a lo ancho que se ENSANCHA a la derecha en un bloque con esquina
   inferior izquierda redondeada, donde van los dos logos en blanco. */
.botones-cromo { position: absolute; inset: 0; pointer-events: none; z-index: 1; }

/* La banda del cliente, tal cual: corre fina desde la izquierda y se abre en una CURVA suave
   (no un ángulo, no una esquina redonda) hasta la altura completa del bloque derecho. Es el
   PNG que entrega el propio SCORM — dos rondas de correcciones de Pablo demostraron que la
   curva no se reproduce a ojo, y el criterio del proyecto es no reconstruir lo que el cliente
   ya entrega. */
.botones-cromo-banda {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  display: block;
}

/* Reserva para un curso que no traiga `cromo_banda`: aproximación angulosa, deliberadamente
   menos fiel. Si se ve esto en un curso de Syncore, falta el asset. */
.botones-cromo.es-banda-dibujada::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 68px;
  background: var(--marca-secundario);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 66% 100%, 57.5% 20.5%, 0 20.5%);
}

/* Los logos van SOBRE la banda, centrados en su bloque derecho. 78px es el alto real de la
   banda del cliente a 1280 de ancho (2047×125 → 1280×78). */
.botones-cromo-logos {
  position: absolute;
  top: 0;
  right: 0;
  height: 78px;
  padding: 0 14px 0 48px;
  display: flex;
  align-items: center;
  gap: 30px;
}

/* Alturas del original: SYNCORE 37px, SYNCORE CAPACITACIONES 52px (el segundo es un lockup
   de dos líneas, por eso es más alto). */
.botones-cromo-logo { height: 37px; width: auto; }
.botones-cromo-logo:last-child { height: 52px; }

/* Insignia «CURSO HABILITANTE»: círculo naranja con el engranaje, montado sobre una
   pastilla navy con el texto en blanco. Posición del original: (65,31)-(123,49). */
.botones-cromo-insignia {
  position: absolute;
  top: 31px;
  left: 65px;
  display: flex;
  align-items: center;
}

/* Medidas del original: círculo 61×61 en (65,31), engranaje 46×46 centrado en él (75 % del
   círculo), pastilla navy desde x=96 con el texto arrancando en x=123. El círculo sobresale
   por arriba y por abajo de la pastilla, que lleva la esquina inferior derecha muy
   redondeada — se abre como una coma. */
.botones-cromo-circulo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 61px;
  height: 61px;
  flex: none;
  border-radius: 50%;
  background: var(--marca-secundario);
  z-index: 1;
}
.botones-cromo-icono { width: 46px; height: auto; }

.botones-cromo-pastilla {
  margin-left: -30px;               /* la pastilla nace en x=96, bajo el círculo (65..126) */
  padding: 7px 16px 7px 30px;       /* el texto arranca en x=123 */
  border-radius: 5px 8px 22px 5px;
  background: var(--marca-primario);
  color: var(--marca-blanco);
  font-size: 13px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  max-width: 140px;
}

.botones-columna-titulo {
  position: absolute;
  left: 109px;
  top: 196px;
  width: 290px;
}

/* La flecha del isotipo REAL, extraída del logo del cliente y teñida al secundario
   (contenido.flecha). El glifo ❯ queda solo como reserva si un curso no la trae. */
.botones-flecha-img {
  display: block;
  width: 34px;
  height: auto;
  margin-bottom: var(--marca-esp-md);
}
.botones-flecha {
  display: block;
  margin-bottom: var(--marca-esp-md);
  color: var(--marca-secundario);
  font-size: 58px;
  font-weight: 900;
  line-height: 1;
}

/* Primera línea FUERTE, segunda fina — así lo pinta el original (captura 2026-08-11). */
.botones-titulo { margin: 0; color: var(--marca-primario); line-height: 1.25; }
.botones-antetitulo {
  display: block;
  font-size: 38px;
  font-weight: 800;
}
.botones-titulo-fuerte {
  display: block;
  font-size: 34px;
  font-weight: 300;
}

/* Intro centrada sobre la zona de tarjetas, en bold — como en la captura. */
.botones-intro {
  position: absolute;
  left: 399px;
  top: 127px;
  width: 815px;
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  text-align: center;
  color: var(--marca-primario);
}

/* Tres columnas de 239px con paso de 288 (gap 49). Con más de 3 botones la rejilla envuelve;
   esa variante no está cerrada todavía (el esquema avisa). */
.botones-rejilla {
  position: absolute;
  left: 399px;
  top: 225px;
  width: 815px;
  display: grid;
  grid-template-columns: repeat(3, 239px);
  column-gap: 49px;
  row-gap: var(--marca-esp-md);
}

/* La tarjeta ENTERA es un bloque navy redondeado con cabecera naranja — la composición de la
   captura del original, no una lista de texto sobre blanco. */
.botones-tarjeta {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: 10px;
  background: var(--marca-primario);
  overflow: visible;
}

.botones-tarjeta-cabecera {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 78px;
  padding: var(--marca-esp-xs) var(--marca-esp-sm);
  border-radius: 10px 10px 0 0;
  background: var(--marca-secundario);
}

.botones-tarjeta-titulo {
  margin: 0;
  font-size: 22px;
  line-height: 1.15;
  font-weight: 800;
  text-align: center;
  color: var(--marca-blanco);
}

/* Cuerpo blanco centrado sobre el navy; tamaño único entre tarjetas (igualarTextos). */
.botones-tarjeta-cuerpo {
  height: 150px;
  overflow: hidden;
  padding: var(--marca-esp-sm) var(--marca-esp-sm) 0;
  font-size: var(--tam-boton-cuerpo, 19px);
  line-height: 1.35;
  text-align: center;
  color: var(--marca-texto-inverso);
}
.botones-tarjeta-parrafo { margin: 0 0 0.6em; font-size: 1em; }

/* «Ver más»: pastilla del MISMO navy con borde blanco, centrada — como en la captura. */
.botones-ver-mas {
  align-self: center;
  width: 150px;
  height: 44px;
  margin: var(--marca-esp-xs) 0 var(--marca-esp-sm);
  border: 2px solid var(--marca-blanco);
  border-radius: 8px;
  background: transparent;
  color: var(--marca-texto-inverso);
  font-family: inherit;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva);
}
.botones-ver-mas:hover:not(.es-apagada) { background: rgba(255, 255, 255, 0.16); }
.botones-ver-mas:focus-visible { outline: 3px solid var(--marca-terciario); outline-offset: 2px; }

/* Un botón bloqueado tiene que VERSE bloqueado (§0ap) — misma regla que acordeón/tarjetas. */
.botones-ver-mas.es-apagada { cursor: default; opacity: 0.4; }

/* Check de visto: círculo GRIS con tilde blanca colgando de la esquina inferior derecha de
   la tarjeta (así está en el original); al verse, pasa a naranjo. */
.botones-check {
  position: absolute;
  bottom: -12px;
  right: -8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 3px solid var(--marca-blanco);
  background: var(--marca-neutro);
  color: var(--marca-blanco);
  font-size: 18px;
  font-weight: 800;
}
.botones-tarjeta.visto .botones-check { background: var(--marca-secundario); }

/* ---- la capa: pantalla completa sobre la lámina, con la imagen del botón de fondo. */
.botones-capa {
  position: absolute;
  inset: 0;
  z-index: 5;
  background-size: cover;
  background-position: center;
  background-color: var(--marca-primario);
}
.botones-capa.es-cerrada { display: none; }
/* Destapada pero invisible mientras igualarTextos() mide (mismo truco que .es-midiendo del
   acordeón: oculta con display no hay nada que medir). */
.botones-capa.es-midiendo { display: block; visibility: hidden; }

/* Velo de legibilidad: garantiza contraste del texto aunque la imagen no traiga el panel navy
   pintado (las del SCORM clonado lo traen; una foto generada no). Sobre un fondo ya navy es
   invisible. */
.botones-capa-velo {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(var(--marca-primario-oscuro-rgb), 0.72) 0%,
    rgba(var(--marca-primario-oscuro-rgb), 0.55) 45%,
    rgba(var(--marca-primario-oscuro-rgb), 0) 75%);
}

/* Título de capa: (399,127) 815×109, 28pt→37px, en SECUNDARIO y alineado a la DERECHA —
   la foto ocupa la izquierda de la imagen, así que el texto se apoya en el borde opuesto. */
.botones-capa-titulo {
  position: absolute;
  left: 399px;
  top: 127px;
  width: 815px;
  margin: 0;
  font-size: 37px;
  line-height: 1.15;
  font-weight: 800;
  text-align: right;
  color: var(--marca-secundario);
}

/* Cuerpo de capa: (399,288) 815 de ancho, 20pt→27px, blanco y JUSTIFICADO (así se compone en
   el original: los renglones llegan parejos a los dos bordes). Alto fijo con tamaño único
   entre capas (--tam-capa-cuerpo, lo fija igualarTextos()). */
.botones-capa-cuerpo {
  position: absolute;
  left: 399px;
  top: 288px;
  width: 815px;
  height: 300px;
  overflow: hidden;
  font-size: var(--tam-capa-cuerpo, 27px);
  line-height: 1.45;
  text-align: justify;
  color: var(--marca-texto-inverso);
}
.botones-capa-parrafo { margin: 0 0 0.8em; font-size: 1em; }
/* El último renglón de un párrafo justificado no se estira: sin esto, un párrafo de una sola
   línea sale con los espacios abiertos de borde a borde. */
.botones-capa-parrafo:last-child { margin-bottom: 0; }

/* CERRAR: 191×51 centrado abajo (545,638 en el original).
   LA GEOMETRÍA SALE DEL PATH DE STORYLINE, no de mirar la captura: dos esquinas RECTAS y dos
   totalmente redondeadas, en diagonal (superior izquierda e inferior derecha, radio 25,33 =
   la mitad del alto). Es la «caja contenedora» del brandbook (p.36: «bordes rectos y
   curvos»), y las tres versiones que hice a ojo —bordes suaves, cuatro radios distintos—
   estaban todas mal. Ver `paths.js` → `Lib['commandset-16']`. */
.botones-capa-cerrar {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 31px;
  width: 191px;
  height: 51px;
  border: 0;
  border-radius: 25px 0 25px 0;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva);
}
.botones-capa-cerrar:hover:not(.es-apagada) { background: var(--marca-secundario-oscuro); }
.botones-capa-cerrar:focus-visible { outline: 3px solid var(--marca-blanco); outline-offset: 3px; }
.botones-capa-cerrar.es-apagada { cursor: default; opacity: 0.45; }

/* CERRAR late en cuanto la capa termina de narrarse, que es justo cuando deja de estar
   apagado. Cuelga de `:not(.es-apagada)` y no de una clase nueva: «listo para cerrar» ya es
   un ESTADO que el DOM representa, y atarlo a la clase que lo gobierna hace imposible que
   los dos se desincronicen — mismo razonamiento que el latido infinito de §0as. */
.botones-capa-cerrar:not(.es-apagada) {
  animation: latido-cta-sync 1.6s var(--marca-mov-curva) infinite;
}
.botones-capa-cerrar:hover { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .botones-capa-cerrar:not(.es-apagada) {
    animation: none;
    box-shadow: 0 0 0 5px rgba(var(--marca-secundario-rgb), 0.45);
  }
}

/* Los términos [[resaltados]] sobre la capa navy van en secundario, no en el rojo de texto
   sobre claro. */
.botones-capa-cuerpo .resaltado { color: var(--marca-secundario); background: none; }

/* En portada la pastilla de la insignia se invierte: fondo claro con el texto navy. */
.es-insignia-clara .botones-cromo-pastilla {
  background: var(--marca-blanco);
  color: var(--marca-primario);
}

/* ------------------------------------------- portada de la familia Syncore */

/* Foto a lienzo completo con velo navy (viene compuesto en el propio asset), curvas
   decorativas a la derecha y la pila de texto a la izquierda. Nada del panel claro ni de las
   diagonales de la portada base: es otra composición, no un ajuste de la misma. */
.layout-portada-sync { padding: 0; position: relative; overflow: hidden; }

/* Las curvas del original: 492×720 ancladas al borde derecho (x=788). */
.portada-sync-curvas {
  position: absolute;
  left: 788px;
  top: 0;
  width: 492px;
  height: 720px;
  object-fit: cover;
  opacity: 0.9;
}

/* La caja no posiciona: cada pieza va en su coordenada exacta del original, igual que en
   `botones`. Así el texto puede ocupar todo el ancho útil mientras el filete naranja
   conserva su largo fijo de 332px. */
.portada-sync-caja { position: static; }

.portada-sync-flecha { position: absolute; left: 109px; top: 196px; width: 32px; height: auto; }

/* Etiqueta de módulo (109,274) y título (109,330), cada uno con su filete naranja debajo —
   el separador corto del original, que NO acompaña el ancho del texto.
   El bloque completo bajó 17px (257→274, 313→330, y bajada/cta con él): la flecha mide 64px
   de alto real (196-260) y tocaba la etiqueta, que arrancaba en 257 — 3px de superposición
   real, no solo de la caja — pedido de Pablo, 2026-08-12: «bajo un poco el texto para que
   [quede] solo el ícono». Verificado con los píxeles no-transparentes del PNG (no solo el
   bounding box): el trazo ocupa del 0 % al 99,8 % de su alto, así que la caja SÍ es el
   dibujo real. */
.portada-sync-etiqueta {
  position: absolute;
  left: 109px;
  top: 274px;
  width: 1061px;
  margin: 0;
  font-size: 28px;
  font-weight: 400;
  color: var(--marca-texto-inverso);
}

.portada-sync-titulo {
  position: absolute;
  left: 109px;
  top: 330px;
  width: fit-content;
  max-width: 1061px;
  margin: 0;
  font-size: 43px;
  line-height: 1.15;
  font-weight: 800;
  color: var(--marca-texto-inverso);
}

/* UN solo filete, bajo el título, del ancho del texto y separado — «Módulo 1» NO lleva
   línea (corrección de Pablo, 2026-08-12). Por eso el título se ajusta al texto con
   `fit-content` y el filete toma su 100 %: un ancho fijo se veía corto contra un titular
   largo y desalineado contra uno corto. */
.portada-sync-titulo::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -20px;
  width: 100%;
  height: 3px;
  background: var(--marca-secundario);
}

.portada-sync-bajada {
  position: absolute;
  left: 109px;
  top: 446px;
  width: 724px;
  margin: 0;
  font-size: 36px;
  font-weight: 700;
  color: var(--marca-texto-inverso);
}

/* CTA: la misma caja contenedora que CERRAR, con la geometría del path de Storyline —
   esquinas superior izquierda e inferior derecha redondeadas al 50 % del alto, las otras dos
   rectas. (109,524) 191×51 en el original. */
.portada-sync-cta {
  position: absolute;
  left: 109px;
  top: 541px;
  display: block;
  width: 191px;
  height: 51px;
  border: 0;
  border-radius: 25px 0 25px 0;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva);
}
.portada-sync-cta:hover { background: var(--marca-secundario-oscuro); }
.portada-sync-cta:focus-visible { outline: 3px solid var(--marca-blanco); outline-offset: 3px; }

/* ------------------------------------------- cierre de la familia Syncore */

/* Fondo navy a lienzo completo (imagen, no color plano — trae su propio degradé) con las
   MISMAS curvas decorativas de `portada` (mismo asset, misma posición): es la lámina de
   cierre de la serie, no una composición nueva. Primera versión desde la captura que mandó
   Pablo (2026-08-12) — sin panel de Storyline propio para este slide, así que las medidas
   son una lectura de esa captura, no una extracción exacta; puede necesitar un ajuste fino
   contra el original. */
.layout-cierre-sync { padding: 0; position: relative; overflow: hidden; }
.layout-cierre-sync .portada-sync-curvas { opacity: 0.5; }
.layout-cierre-sync .portada-sync-flecha { top: 168px; }

.cierre-sync-caja { position: static; }

/* Todo el bloque bajó 36px (210→246, y descripción/botonera con él): la flecha mide 64px de
   alto real (168-232) y el título arrancaba en 210 — 22px de superposición real, mismo
   hallazgo y mismo pedido que en `portada` (2026-08-12). */
.cierre-sync-titulo {
  position: absolute;
  left: 109px;
  top: 246px;
  margin: 0;
  font-size: 42px;
  font-weight: 800;
  color: var(--marca-secundario);
}

.cierre-sync-descripcion {
  position: absolute;
  left: 109px;
  width: 760px;
  margin: 0;
  color: var(--marca-texto-inverso);
  line-height: 1.3;
}
.cierre-sync-descripcion--1 { top: 314px; font-size: 30px; font-weight: 300; }
.cierre-sync-descripcion--2 { top: 356px; font-size: 30px; font-weight: 800; }

.cierre-sync-botonera {
  position: absolute;
  left: 109px;
  top: 456px;
  display: flex;
  gap: var(--marca-esp-md);
}

/* Misma geometría que COMENZAR/CERRAR/CTA de portada — la «caja contenedora» del brandbook
   (25px 0 25px 0), no un botón inventado. */
.cierre-sync-cta {
  position: static;
  display: block;
  width: 191px;
  height: 51px;
  border: 0;
  border-radius: 25px 0 25px 0;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva);
}
.cierre-sync-cta:hover { background: var(--marca-secundario-oscuro); }
.cierre-sync-cta:focus-visible { outline: 3px solid var(--marca-blanco); outline-offset: 3px; }

.es-movil .layout-cierre-sync .portada-sync-curvas { display: none; }
.es-movil .cierre-sync-caja {
  position: static;
  padding: var(--marca-esp-lg) var(--marca-esp-md);
  display: flex;
  flex-direction: column;
  gap: var(--marca-esp-sm);
}
.es-movil .cierre-sync-titulo,
.es-movil .cierre-sync-descripcion,
.es-movil .cierre-sync-botonera {
  position: static;
  width: 100%;
  top: auto;
  left: auto;
}

/* El botón late cuando la narración terminó y ya se puede avanzar — mismo criterio y mismo
   ritmo que «Siguiente» (§0as). Acá el que avisa es este, porque en la familia Syncore la
   navegación de la barra se retira en las láminas con CTA (§0bg).
   El halo va en SECUNDARIO y no en terciario: el botón ya es naranja pleno, y es el mismo
   pulso que usan los círculos de navegación — dos avisos distintos para el mismo mensaje se
   leerían como dos cosas distintas. */
@keyframes latido-cta-sync {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--marca-secundario-rgb), 0.55); }
  50%      { box-shadow: 0 0 0 12px rgba(var(--marca-secundario-rgb), 0); }
}

.avance-libre .portada-sync-cta:not(.es-oculto) {
  animation: latido-cta-sync 1.6s var(--marca-mov-curva) infinite;
}
.portada-sync-cta:hover { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .avance-libre .portada-sync-cta:not(.es-oculto) {
    animation: none;
    box-shadow: 0 0 0 5px rgba(var(--marca-secundario-rgb), 0.45);
  }
}

.es-movil .layout-portada-sync { padding: var(--marca-esp-lg) var(--marca-esp-md); }
.es-movil .portada-sync-curvas { display: none; }
.es-movil .portada-sync-caja { position: static; width: 100%; }
.es-movil .portada-sync-etiqueta,
.es-movil .portada-sync-titulo { width: 100%; }

/* ------------------- objetivos con el marco Syncore (rejilla de la composición base) */

/* La rejilla numerada es la MISMA que la base —el número toma el rol primario, que con los
   tokens de Syncore ya sale navy— y solo cambia el marco: cromo arriba y columna de título
   a la izquierda, en la retícula 109/399 de la familia. */
.layout-objetivos.es-syncore { padding: 0; position: relative; }

.layout-objetivos.es-syncore > .botones-columna-titulo { top: 240px; }

/* `height: auto` es la regla que hace falta: la intro de la composición base tiene alto fijo
   para su versión centrada, y heredarlo acá la estiraba 142px hasta pisar la rejilla. */
.layout-objetivos.es-syncore > .objetivos-intro {
  position: absolute;
  left: 399px;
  top: 112px;
  width: 815px;
  height: auto;
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--marca-primario);
}

/* La rejilla base reparte el lienzo COMPLETO (celdas de 546px, número hacia el centro).
   Acá vive dentro de los 815px de la zona de contenido, así que las columnas se recalculan:
   sin esto los dos bloques de la derecha terminaban en x=1517, fuera del lienzo. */
.layout-objetivos.es-syncore > .objetivos-rejilla {
  position: absolute;
  left: 399px;
  top: 170px;
  width: 815px;
  height: 470px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  column-gap: 28px;
  row-gap: 26px;
}

.layout-objetivos.es-syncore .objetivo-bloque { width: auto; min-width: 0; }

/* ---- móvil: columna única, capa en flujo. El cromo de lámina se oculta: en pantalla
   chica duplicaría la marca que ya lleva la barra del reproductor. */
.es-movil .layout-objetivos.es-syncore { padding: var(--marca-esp-lg) var(--marca-esp-md); }
.es-movil .layout-objetivos.es-syncore > .botones-columna-titulo,
.es-movil .layout-objetivos.es-syncore > .objetivos-intro,
.es-movil .layout-objetivos.es-syncore > .objetivos-rejilla {
  position: static;
  width: 100%;
  height: auto;
}
.es-movil .botones-cromo { display: none; }
.es-movil .layout-botones { padding: var(--marca-esp-lg) var(--marca-esp-md); }
.es-movil .botones-columna-titulo,
.es-movil .botones-intro,
.es-movil .botones-rejilla { position: static; width: 100%; }
.es-movil .botones-rejilla { grid-template-columns: 1fr; margin-top: var(--marca-esp-md); }
.es-movil .botones-tarjeta-cuerpo { height: auto; overflow: visible; }
.es-movil .botones-capa { position: fixed; inset: 0; }
.es-movil .botones-capa-titulo,
.es-movil .botones-capa-cuerpo {
  position: static;
  width: auto;
  margin: var(--marca-esp-md);
}
.es-movil .botones-capa-cuerpo { height: auto; overflow-y: auto; }

/* -------------------------------------------------- galería (familia Syncore) */

/* Imagen a lienzo completo, centrada y escalada a cubrir el lienzo entero — sin panel
   lateral y sin ningún velo (el pedido explícito de Pablo, 2026-08-12): esta lámina no llama
   a `diagonales()` ni agrega `.portada-velo` como sí hacen `portada`/`contenido`. La regla
   de abajo es una redundancia deliberada sobre `.con-fondo` (que ya hace lo mismo): así,
   aunque cambie la clase base, esta lámina nunca hereda un fade por accidente. */
.layout-galeria {
  padding: 0;
  position: relative;
  background-size: cover !important;
  background-position: center !important;
}

/* La etiqueta ORIGINAL de Storyline (verificado en su path: `paths.js` → commandset-110) es
   un rectángulo liso de un solo color y radio parejo en las cuatro esquinas — sin sombra, sin
   capas. Pablo lo describió bien: «muy plano». Acá no se clona esa geometría a propósito —
   se rediseña, con dos decisiones que sí vienen del resto de la familia:
     1. Esquinas asimétricas (superior izquierda + inferior derecha), la MISMA geometría que
        CERRAR/CTA — que esa sí es real (sale del path de Storyline del botón COMENZAR). Dos
        esquinas curvas y dos rectas leen más «cuadrado» que el óvalo parejo del original.
     2. Sombra en dos capas (una ambiental larga + un filo ajustado) en vez de una sola sombra
        plana: es lo que da la sensación de placa elevada sobre la foto, no una pegatina.
   Más angosta que el original (menos «tira ancha», más «chip») y con un borde interno claro
   que separa la placa del fondo — el «otra capa de diseño» que pidió Pablo.
   PRIMARIO (navy), no secundario: con la idea de fuerza también en naranjo, las seis
   etiquetas competían con ella por el mismo acento y todo se leía «igual» (Pablo, 2026-08-12).
   El naranjo se reserva para lo que de verdad importa que se distinga: la idea de fuerza. */
.galeria-etiqueta {
  position: absolute;
  z-index: 2;
  max-width: 200px;
  padding: 10px 14px;
  border-radius: 14px 3px 14px 3px;
  background: var(--marca-primario);
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  box-shadow:
    0 10px 18px rgba(0, 0, 0, 0.30),
    0 2px 4px rgba(0, 0, 0, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.galeria-etiqueta-texto {
  margin: 0;
  color: var(--marca-blanco);
  font-size: 15px;
  font-weight: 800;
  line-height: 1.25;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

/* «Titile» al aparecer: un pulso de ATENCIÓN, no el latido infinito que el motor reserva
   para lo accionable (nav, CTAs — §0as). Esta etiqueta no se toca, así que un pulso sin fin
   mentiría sobre qué se puede hacer con ella. Dos vueltas y se asienta — se dispara solo
   cuando el cue la revela, porque recién ahí empieza a calzar `:not(.es-oculto)`. */
@keyframes galeria-destaque {
  0%   { transform: scale(0.8); box-shadow: 0 0 0 0 rgba(var(--marca-primario-rgb), 0.65); }
  60%  { transform: scale(1.08); box-shadow: 0 0 0 14px rgba(var(--marca-primario-rgb), 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--marca-primario-rgb), 0); }
}

.galeria-etiqueta:not(.es-oculto) {
  animation: galeria-destaque 700ms var(--marca-mov-curva) 2;
}

@media (prefers-reduced-motion: reduce) {
  .galeria-etiqueta:not(.es-oculto) { animation: none; }
}

/* De vuelta abajo y centrada horizontal — no al medio del lienzo (se probó esa ronda y
   Pablo pidió volver: con las etiquetas ahora en navy, el naranjo de acá es el ÚNICO acento
   de ese color en toda la lámina, y abajo — separado de las etiquetas y del collage — es
   donde más se distingue, no compitiendo al centro contra las fotos). Tope de ancho para no
   tocar los círculos de navegación (arrancan en x≈1017): con 640px centrado, el borde
   derecho llega como mucho a 960. */
.galeria-cierre {
  position: absolute;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%);
  max-width: 640px;
  margin: 0;
  padding: 16px 32px;
  border-radius: 10px 10px 26px 10px;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-size: 22px;
  font-weight: 800;
  text-align: center;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.35);
  z-index: 3;
}

.es-movil .layout-galeria .botones-columna-titulo { position: static; width: 100%; margin-bottom: var(--marca-esp-sm); }
.es-movil .layout-galeria .galeria-etiqueta { position: static; max-width: 100%; width: 100%; margin-bottom: var(--marca-esp-xs); }
.es-movil .layout-galeria .galeria-cierre { position: static; transform: none; max-width: 100%; margin-top: var(--marca-esp-md); }

/* -------------------------------------------------- normas (familia Syncore) */

/* Retícula estándar de la familia: título en x=109, contenido de x=399 a 1214. */
.layout-normas { padding: 0; position: relative; }

.layout-normas > .normas-columna {
  position: absolute;
  left: 399px;
  top: 127px;
  width: 815px;
}

/* Cada fila: la barra ocupa TODO el ancho de la fila, y el chip se dibuja ENCIMA, corrido
   hacia la izquierda hasta que se sale del borde — la superposición real del original
   (barra desde x=147/816 ≈ 18%, chip de 0 a 168/816 ≈ 21%: se pisan). El chip lleva su
   propia sombra para que la superposición se LEA como dos capas, no como un error de
   maquetación. */
.normas-fila {
  position: relative;
  height: 71px;
  margin-bottom: 18px;
}

.normas-barra {
  position: absolute;
  left: 18%;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  /* Justificado a la izquierda, casi pegado al chip — Pablo revirtió el centrado de la ronda
     anterior (2026-08-12): con el chip flotando encima del arranque de la barra, dejar el
     texto centrado alejaba las dos piezas en vez de leerse como una sola unidad. */
  justify-content: flex-start;
  border-radius: 0 10px 10px 0;
  background: var(--marca-primario);
  padding: 12px 28px 12px 26%;
}

.normas-texto {
  margin: 0;
  color: var(--marca-texto-inverso);
  /* Antes 16px: se veía chico para el alto de la barra (71px) — «más personalidad», pidió
     Pablo. Subir el tamaño también reduce el aire suelto de las filas de una sola línea.
     Negrita y a la izquierda, pedido de la misma ronda que el justify-content de arriba. */
  font-size: 20px;
  font-weight: 700;
  line-height: 1.3;
  text-align: left;
}

/* Ancho mínimo 21 % de la fila: es la medida real (168px de chip contra una barra que
   arranca al 18 %) — con menos, el chip queda CORTO del borde de la barra y el hueco se lee
   como un error de maquetación en vez de la superposición que es en el original. */
.normas-chip {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  box-sizing: border-box;
  min-width: 21%;
  padding: 12px 18px;
  /* Misma geometría diagonal que COMENZAR/CERRAR (25px 0 25px 0) — Pablo pidió que el chip
     sea de la misma familia de botones, no una píldora pareja (corregido 2026-08-12). */
  border-radius: 25px 0 25px 0;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-size: 18px;
  font-weight: 800;
  text-align: center;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.28);
  z-index: 1;
}

/* Zona libre bajo la última fila de la lista: de ahí hasta el borde del lienzo, ancho
   completo. `flex` centra a su hijo horizontal Y verticalmente DENTRO de ese espacio sin
   medir nada por JS ni asumir el alto real de la caja — pedido de Pablo, 2026-08-12: «que
   estén bien posicionadas verticalmente al centro de la línea horizontal de la lámina
   completa». El `top` lo fija JS (depende de cuántos ítems traiga el guion — ver
   layouts.js). */
.normas-zona-inferior {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Ancho FIJO, no `fit-content`: con `fit-content` el ancho del envoltorio dependía de qué
   hijos ya se habían revelado (comparación sola vs. comparación+cierre, que se muestran en
   cues distintos), y el texto de «Control Operacional» saltaba de una línea a dos —y la caja
   entera se «estiraba»— en cuanto aparecía la idea de fuerza (bug detectado por Pablo,
   2026-08-12). 636px es el ancho medido con AMBOS hijos visibles a la vez: fijarlo evita que
   el layout cambie según el momento del cue. */
.normas-envoltorio-tabla {
  width: 636px;
}

/* Caja gris comparativa: radio parejo (no la geometría diagonal — esa es de los botones de
   acción; acá el original usa un rectángulo redondeado normal, medido: ~18px). */
.normas-comparacion {
  padding: 16px 28px;
  border-radius: 18px;
  background: var(--marca-neutro);
}

/* La idea de fuerza del guion — mismo tratamiento que `galeria-cierre`: geometría diagonal,
   naranjo pleno. En flujo justo debajo de la caja comparativa (mismo envoltorio de arriba). */
.normas-cierre {
  margin: 20px 0 0;
  padding: 16px 32px;
  border-radius: 10px 10px 26px 10px;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-size: 20px;
  font-weight: 800;
  text-align: center;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.35);
}

.normas-comparacion-titulo {
  margin: 0 0 14px;
  color: var(--marca-primario);
  font-size: 17px;
  font-weight: 800;
  text-align: center;
}

.normas-comparacion-fila {
  display: flex;
  align-items: center;
  justify-content: space-evenly;
}

.normas-comparacion-item {
  flex: 1;
  padding: 0 var(--marca-esp-md);
  color: var(--marca-primario);
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  /* El divisor entre columnas — medido del original: línea de 1px en un azul apagado, no un
     gris genérico. Es el mismo primario derivado a media intensidad, no un hex suelto. */
  border-left: 1px solid rgba(var(--marca-primario-rgb), 0.35);
}
.normas-comparacion-item:first-child { border-left: 0; }

.es-movil .layout-normas > .normas-columna {
  position: static;
  width: 100%;
  margin-top: var(--marca-esp-md);
}
.es-movil .normas-fila { height: auto; padding-top: 26px; }
.es-movil .normas-barra { position: static; padding: 10px var(--marca-esp-sm); justify-content: flex-start; border-radius: 10px; }
.es-movil .normas-chip { position: absolute; top: 0; transform: none; }
.es-movil .normas-comparacion-fila { flex-direction: column; gap: var(--marca-esp-sm); }
.es-movil .normas-comparacion-item { border-left: 0 !important; border-top: 1px solid rgba(var(--marca-primario-rgb), 0.35); padding-top: var(--marca-esp-sm); }
.es-movil .normas-comparacion-item:first-child { border-top: 0; }
/* La zona flex y el ancho fijo asumen el lienzo 1280×720 — en columna única reflow no
   aplica: todo vuelve al flujo, después de la lista, a ancho completo. */
.es-movil .normas-zona-inferior {
  position: static;
  display: block;
}
.es-movil .normas-envoltorio-tabla {
  width: 100%;
  margin-top: var(--marca-esp-md);
}

/* --------------------------------------------------------------- pregunta */

/* La lámina se compone como una columna centrada en el lienzo: márgenes izquierdo y derecho
   iguales, en vez del bloque pegado a la izquierda que dejaba 277px muertos a la derecha.
   El texto sigue alineado a la izquierda DENTRO de la columna — lo que se centra es el bloque,
   no los renglones.

   `--hueco-pregunta` es el ritmo vertical único de la lámina: separa las alternativas entre sí
   y también la última del botón, así todo queda distribuido con el mismo aire. Cambiarlo acá
   los mueve a todos a la vez. */
.layout-pregunta {
  --hueco-pregunta: 14px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow-y: auto;
}

.layout-pregunta > .titulo-seccion,
.layout-pregunta > .pregunta-grupo {
  width: 100%;
  max-width: 940px;
}

.pregunta-grupo {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border: 0;
}

.pregunta-enunciado {
  padding: 0;
  margin: 0 0 var(--marca-esp-lg);
  font-size: var(--marca-cuerpo-lg);
  line-height: 1.4;
  font-weight: 400;
  color: var(--marca-texto);
}

.pregunta-opciones { display: grid; gap: var(--hueco-pregunta); margin: 0; }

/* El botón queda a la misma distancia de la última alternativa que las alternativas entre sí:
   ese es el «distribuido uniformemente». */
.pregunta-enviar {
  display: flex;
  margin: var(--hueco-pregunta) auto 0;
  min-width: 220px;
  justify-content: center;
}

.opcion {
  display: flex;
  align-items: center;
  gap: var(--marca-esp-sm);
  width: 100%;
  min-height: 56px;
  padding: var(--marca-esp-sm) var(--marca-esp-md);
  border: 2px solid var(--marca-borde);
  /* «15% de redondeo» sobre una caja de 940×64: el 15% literal daría 141px de radio horizontal
     y 9,6 vertical — una lonja, no una tarjeta. Se toma el 15% del ALTO, que es la dimensión
     que gobierna la forma de la esquina en una caja ancha. */
  border-radius: 10px;
  /* Tarjeta translúcida: deja ver la foto y baja el contraste con el fondo. Va sobre el
     FONDO y no como `opacity` del elemento, que también desvanecería el texto — y esta
     audiencia necesita legibilidad (§10, contraste AA).

     El 50% no es una preferencia estética sino el PISO medido: componiendo blanco sobre los
     píxeles reales de la foto en la franja de las alternativas, a 30% el 6,3% del área queda
     bajo el mínimo AA (peor caso 2,73:1) y a 50% no queda nada (peor caso 4,94:1). Bajarlo
     vuelve a romper el contraste sobre las zonas claras de la foto — ver §0ag. */
  background: color-mix(in srgb, var(--marca-blanco) 50%, transparent);
  font-family: inherit;
  font-size: var(--marca-cuerpo);
  line-height: 1.4;
  color: var(--marca-texto-fuerte);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--marca-mov-entrada) var(--marca-mov-curva),
              background var(--marca-mov-entrada) var(--marca-mov-curva);
}

.opcion:hover:not(:disabled) { border-color: var(--marca-terciario); background: var(--marca-fondo-alt); }
.opcion:focus-visible { outline: 3px solid var(--marca-terciario); outline-offset: 2px; }
.opcion:disabled { cursor: default; }

/* Mientras corre el enunciado hablado, la pregunta se ve inerte — la misma regla que en
   acordeón, flipcards y clasificar. Era la única lámina interactiva sin ella: se podía
   responder mientras la voz todavía estaba leyendo la pregunta.
   El apagado va en una clase propia y no en `:disabled`, porque `disabled` también se usa
   DESPUÉS de responder, y ahí las alternativas tienen que seguir viéndose: hay que poder leer
   cuál se eligió y su marca de acierto o error. Son dos estados distintos con el mismo atributo.
   Baja el 45 % la caja entera, texto incluido: acá la alternativa tiene fondo propio, así que
   no hace falta el velo aparte que sí necesitó la pestaña transparente del acordeón. */
.opcion.es-apagada {
  cursor: default;
  opacity: 0.45;
  transition: opacity var(--marca-mov-entrada) var(--marca-mov-curva);
}

/* El botón de responder no se puede pulsar hasta elegir una alternativa, así que ya se ve
   inerte por su propio estado: no necesita apagado extra. Lo que sí se oculta es la pista de
   interacción mientras corre la instrucción. */
.pregunta-grupo.esperando-intro .opcion { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .opcion.es-apagada { transition: none; }
}

/* Radio circular (aro + punto), no un botón con letra A/B/C/D: así se ve en el original. */
.opcion-marca {
  position: relative;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--marca-borde);
  background: var(--marca-blanco);
}

.opcion-marca::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: transparent;
}

/* El selector va en el rol PRIMARIO y el rojo se mudó a los puntos de avance (más abajo).
   El rojo lo pidió Pablo para darle dinamismo a una lámina que es navy sobre foto lavada, pero
   en el selector chocaba con `.es-incorrecta`: el mismo color significaba «esta elegí» antes de
   responder y «esta estaba mal» después. Intercambiándolo con los puntos, la lámina conserva el
   acento rojo y el rojo vuelve a significar una sola cosa dentro del ejercicio. */
.opcion.elegida .opcion-marca { border-color: var(--marca-primario); }
.opcion.elegida .opcion-marca::after { background: var(--marca-primario); }

/* El color no es el único indicador del resultado: se añade un glifo al final de la fila,
   por accesibilidad (WCAG 1.4.1, no depender solo del color). */
.opcion-texto { flex: 1; }

.opcion.es-correcta,
.opcion.es-incorrecta { padding-right: var(--marca-esp-sm); }

.opcion.es-correcta::after,
.opcion.es-incorrecta::after {
  flex-shrink: 0;
  width: 32px;
  font-size: 24px;
  font-weight: 700;
  text-align: center;
}

.opcion.es-correcta { border-color: var(--marca-correcto); background: color-mix(in srgb, var(--marca-correcto) 8%, white); }
.opcion.es-correcta .opcion-marca { border-color: var(--marca-correcto); }
.opcion.es-correcta .opcion-marca::after { background: var(--marca-correcto); }
.opcion.es-correcta::after { content: '✓'; color: var(--marca-correcto); }

.opcion.es-incorrecta { border-color: var(--marca-secundario); background: color-mix(in srgb, var(--marca-secundario) 8%, white); }
.opcion.es-incorrecta .opcion-marca { border-color: var(--marca-secundario); }
.opcion.es-incorrecta .opcion-marca::after { background: var(--marca-secundario); }
.opcion.es-incorrecta::after { content: '✕'; color: var(--marca-secundario); }

/* --------------------------------------------------------------- capa de feedback */

/* Modal centrado, sólido en verde o rojo según el resultado: se siente correcto o incorrecto
   de un vistazo, no solo por un detalle de color en el borde. */
.capa-feedback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--marca-esp-lg);
  background: rgba(0, 0, 0, 0.55);
  z-index: 20;
}

.capa-feedback-tarjeta {
  width: min(560px, 100%);
  padding: var(--marca-esp-xl) var(--marca-esp-lg);
  border-radius: var(--marca-radio-md);
  text-align: center;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
  animation: aparecerModal 0.25s var(--marca-mov-curva) both;
}

@keyframes aparecerModal {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: none; }
}

.capa-feedback.es-correcta .capa-feedback-tarjeta { background: var(--marca-correcto); }
.capa-feedback.es-incorrecta .capa-feedback-tarjeta { background: var(--marca-secundario); }

.capa-feedback-titulo {
  margin: 0 0 var(--marca-esp-sm);
  font-size: var(--marca-h1);
  font-weight: 700;
  color: var(--marca-blanco);
}

.capa-feedback-texto {
  margin: 0 0 var(--marca-esp-lg);
  font-size: var(--marca-cuerpo-lg);
  line-height: 1.5;
  color: var(--marca-blanco);
}

.capa-feedback-boton {
  background: var(--marca-blanco);
  color: var(--marca-texto-fuerte);
  border-color: transparent;
}

.capa-feedback-boton:hover { background: var(--marca-fondo-alt); }

/* Bloqueado mientras se narra el resultado: mismo tratamiento «apagada» que el resto de las
   piezas que esperan una narración antes de poder tocarse (acordeón, flipcards, clasificar).
   Sin audio generado todavía, `mostrarFeedback()` nunca aplica esta clase — el botón se ve
   como siempre (§0bh). */
.capa-feedback-boton.es-apagada { cursor: default; opacity: 0.45; }

@media (prefers-reduced-motion: reduce) {
  .capa-feedback-boton.es-apagada { transition: none; }
}

.es-movil .capa-feedback-tarjeta { padding: var(--marca-esp-lg) var(--marca-esp-md); }

/* --------------------------------------------------------------- puntos de avance */

.grupo-dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: var(--marca-esp-lg);
}

/* En la lámina de pregunta los puntos NO van en el flujo, entre las alternativas y el botón:
   ahí partían el bloque justo donde tiene que leerse seguido. Van anclados abajo a la
   izquierda, como indicador de avance del grupo de preguntas y no como parte del ejercicio.
   `clasificar` es la otra lámina que viene en grupo y comparte la regla: son el mismo indicador
   cumpliendo el mismo papel, y tenerlo en dos posiciones distintas según el ejercicio hacía que
   el alumno tuviera que buscarlo de nuevo en cada bloque. */
.layout-pregunta .grupo-dots,
.layout-clasificar .grupo-dots {
  position: absolute;
  left: 55px;
  bottom: 40px;
  margin: 0;
  justify-content: flex-start;
  /* Los puntos van directo sobre la foto, sin tarjeta debajo. El rojo corporativo contra el
     piso claro de esa esquina da 2,85:1 y el mínimo para un componente de interfaz es 3:1: no
     pasa por poco. El anillo blanco lo resuelve sin tocar el color de marca — el punto pasa a
     recortarse contra blanco (4,22:1) en vez de contra la foto. Vale para los tres estados,
     así que además el indicador deja de depender de qué foto tenga la lámina. */
  padding: 6px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--marca-blanco) 85%, transparent);
}

.es-movil .layout-pregunta .grupo-dots,
.es-movil .layout-clasificar .grupo-dots {
  position: static;
  margin-top: var(--marca-esp-md);
  justify-content: center;
}

.grupo-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--marca-borde);
  transition: background var(--marca-mov-entrada) var(--marca-mov-curva),
              transform var(--marca-mov-entrada) var(--marca-mov-curva);
}

.grupo-dot.visto { background: var(--marca-terciario); }
/* El punto activo lleva el rojo corporativo: es el acento de color de la lámina de pregunta.
   Estaba en el selector de alternativa y se intercambió con estos, porque allá el rojo chocaba
   con el estado «incorrecta» (ver el comentario de `.opcion.elegida`). Acá no compite con
   nada: los puntos son indicador de avance, fuera del ejercicio. */
.grupo-dot.activo { background: var(--marca-secundario); transform: scale(1.35); }

/* --------------------------------------------------------------- pantalla final */

.layout-final { display: grid; place-content: center; text-align: center; gap: var(--marca-esp-md); }

.final-titulo { margin: 0; font-size: var(--marca-h1); color: var(--marca-primario); }

.final-resumen {
  display: grid;
  grid-template-columns: auto auto;
  gap: 8px var(--marca-esp-md);
  justify-content: center;
  margin: 0;
  padding: var(--marca-esp-md) var(--marca-esp-lg);
  border-radius: var(--marca-radio-md);
  background: var(--marca-neutro);
}

.final-resumen dt { font-weight: 600; color: var(--marca-texto-fuerte); text-align: right; }
.final-resumen dd { margin: 0; color: var(--marca-texto); text-align: left; }

/* --- repaso de lo que se falló al primer intento (§0bc) ---
   La pantalla final estaba centrada y con poco contenido; el repaso es una LISTA de lectura, así
   que va alineada a la izquierda y con ancho de lectura acotado. Centrarla, como el resto de la
   pantalla, haría que cada línea empiece en un sitio distinto. */
.final-repaso-titulo {
  margin: var(--marca-esp-md) 0 0;
  font-size: var(--marca-h3);
  color: var(--marca-primario);
}

.final-repaso-intro { margin: 0; color: var(--marca-texto); }

/* El peor caso son las 8 interacciones del módulo falladas al primer intento, y es el que manda
   el diseño: con una columna a 760px solo entraban DOS en pantalla y las otras seis quedaban
   detrás de un scroll interno. Para esta audiencia eso es lo peor posible — el refuerzo que más
   falta hace es el que no se ve (§0bd).

   Con 5 o más pasa a DOS columnas y a todo el ancho útil del lienzo. El reparto lo decide el
   layout, que sabe cuántas hay; el CSS solo lo aplica. */
.final-repaso {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--columnas-repaso, 1), minmax(0, 1fr));
  gap: 10px;
  width: min(1168px, 100%);
  text-align: left;
  justify-self: center;
  font-size: 15px;
  /* El scroll queda como última red, no como el caso normal: con dos columnas las 8 entran.
     360 es lo que necesitan las 8 del peor caso medido, con el encabezado ya compactado. */
  max-height: 360px;
  overflow-y: auto;
}

/* Con una sola columna no hace falta todo el ancho: una línea de 1168px es incómoda de leer. */
.final-repaso:not([style*="--columnas-repaso: 2"]) { width: min(760px, 100%); }

.final-repaso li {
  padding: 8px var(--marca-esp-sm);
  border-radius: var(--marca-radio-md);
  background: var(--marca-neutro);
  /* Filete en el rol secundario: marca que ESTO es lo que hay que mirar, sin pintar de rojo un
     bloque entero que además lleva la respuesta correcta. */
  border-left: 4px solid var(--marca-secundario);
}

.final-repaso-pregunta {
  margin: 0 0 2px;
  font-weight: 600;
  color: var(--marca-texto-fuerte);
  line-height: 1.3;
}

.final-repaso-respuesta { margin: 0; color: var(--marca-texto); line-height: 1.3; }
.final-repaso-respuesta strong { color: var(--marca-primario); }

/* Con la lista larga, el encabezado de la pantalla tiene que ocupar menos: es la misma cantidad
   de píxeles repartida entre lo que informa y lo que enseña, y lo segundo importa más.
   El `max-height` de la lista no alcanza para ganar espacio —está limitada por lo que sobra en
   el lienzo, no por su tope—, así que hay que recortar arriba (§0bd). */
.layout-final.tiene-repaso { gap: var(--marca-esp-sm); }
.layout-final.tiene-repaso .final-titulo { font-size: var(--marca-h2); }
.layout-final.tiene-repaso .final-resumen { padding: var(--marca-esp-sm) var(--marca-esp-lg); }
.layout-final.tiene-repaso .final-repaso-titulo { margin-top: var(--marca-esp-xs); font-size: var(--marca-cuerpo-lg); }

.es-movil .final-repaso {
  max-height: none;
  grid-template-columns: 1fr;
}

/* --------------------------------------------------------------- objetivos (franja de columnas) */

/* Medidas exactas del panel de Storyline sobre el lienzo 1280×720. */
.layout-objetivos { padding: 0; }

.layout-objetivos > .titulo-seccion {
  position: absolute;
  left: 81px;
  top: 100px;
  width: 585px;
  height: 77px;
  margin: 0;
  overflow: hidden;
  font-size: var(--tam-obj-titulo, var(--marca-h2));
}

.objetivos-intro {
  position: absolute;
  left: 87px;
  top: 178px;
  width: 1178px;
  height: 142px;
  margin: 0;
  max-width: none;
  overflow: hidden;
  font-size: var(--tam-obj-intro, var(--marca-cuerpo));
  color: var(--marca-texto-fuerte);
}

/* Rejilla 2×2 con las medidas exactas. Storyline dio una sola celda —546×174 en (81,320)—
   y el resto se derivó por simetría: con 26px de hueco, los márgenes laterales dan 81 a
   ambos lados (81+546+26+546+81 = 1280) y el hueco vertical coincide con el margen inferior
   (320+174+26+174 = 694, y 720−694 = 26). Que las dos cuentas cierren solas confirma que el
   hueco es ése y no otro.
   El número va siempre hacia el centro del lienzo (`--izq` lo pone a la derecha del texto y
   `--der` a la izquierda), así los cuatro numerales forman el bloque navy del original. */
.objetivos-rejilla {
  position: absolute;
  left: 81px;
  top: 320px;
  width: 1118px;
  height: 374px;
  max-width: none;
  display: grid;
  grid-template-columns: 546px 546px;
  grid-template-rows: 174px 174px;
  gap: 26px;
}

/* Número y texto son un solo bloque: se ocultan, se revelan y se desplazan juntos — no un
   rectángulo azul fijo desde el inicio con el texto apareciendo por separado. Caja blanca
   translúcida detrás de cada objetivo completo, para que se destaque del fondo sin taparlo —
   así estaba en el Storyline original. */
.objetivo-bloque {
  display: flex;
  align-items: stretch;
  gap: var(--marca-esp-md);
  padding: var(--marca-esp-sm);
  border-radius: var(--marca-radio-md);
  background: rgba(255, 255, 255, 0.7);
}

/* El texto ocupa todo el espacio que le sobra al número (flex:1), en vez de encogerse a su
   contenido y empujarse con justify-content: eso hacía que el texto corto (ítem 1) y el
   texto largo (ítem 3) arrancaran en columnas X distintas, sin verse alineados entre sí. */

/* El número llega a los bordes de la caja en su lado largo: cancela con márgenes negativos
   el padding que sí conserva el texto, así ocupa el alto completo de la tarjeta. */
.objetivo-numero {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 74px;
  margin-top: calc(-1 * var(--marca-esp-sm));
  margin-bottom: calc(-1 * var(--marca-esp-sm));
  background: var(--marca-primario);
  color: var(--marca-blanco);
  font-size: 32px;
  font-weight: 700;
  border-radius: 2px;
}

/* Ícono real (extraído del SCORM publicado, no generado) en vez del numeral — es blanco
   sobre transparente, igual tratamiento de color que el número al que reemplaza. */
.objetivo-icono { width: 34px; height: 34px; object-fit: contain; }

.objetivo-texto-col { display: flex; align-items: center; flex: 1; min-width: 0; }

/* Cada bloque entra desde su propio lado, número y texto juntos: 1 y 3 llegan desde la
   izquierda, 2 y 4 desde la derecha. */
.es-entrando.objetivo-bloque--izq { animation-name: entrarDesdeIzquierda; }
.es-entrando.objetivo-bloque--der { animation-name: entrarDesdeDerecha; }

@keyframes entrarDesdeIzquierda {
  from { opacity: 0; transform: translateX(-48px); }
  to   { opacity: 1; transform: none; }
}

@keyframes entrarDesdeDerecha {
  from { opacity: 0; transform: translateX(48px); }
  to   { opacity: 1; transform: none; }
}
.objetivo-texto {
  margin: 0;
  font-size: var(--tam-obj-item, var(--marca-cuerpo));
  color: var(--marca-texto-fuerte);
}

/* Las medidas exactas valen para el lienzo de escritorio; en móvil todo vuelve a fluir. */
.es-movil .layout-objetivos { padding: var(--marca-esp-lg) var(--marca-esp-md); display: flex; flex-direction: column; }

.es-movil .layout-objetivos > .titulo-seccion,
.es-movil .objetivos-intro,
.es-movil .objetivos-rejilla {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
}

.es-movil .layout-objetivos > .titulo-seccion { font-size: var(--marca-h2); margin: 0 0 var(--marca-esp-sm); }
.es-movil .objetivos-intro { font-size: var(--marca-cuerpo); margin: 0 0 var(--marca-esp-lg); }

.es-movil .objetivos-rejilla {
  grid-template-columns: 1fr;
  grid-template-rows: none;
  gap: var(--marca-esp-md);
  text-align: center;
}

.es-movil .objetivo-texto { font-size: var(--marca-cuerpo); }

.es-movil .objetivo-bloque,
.es-movil .objetivo-bloque--izq,
.es-movil .objetivo-bloque--der { flex-direction: column; justify-content: center; }
.es-movil .objetivo-numero { width: 100%; height: 56px; margin: 0; }

/* --------------------------------------------------------------- texto (título + párrafo) */

/* Mismo patrón que portada/cierre: panel claro a un lado (título navy, cuerpo gris) + foto al
   otro + las dos franjas diagonales. Medidas exactas del panel «Tamaño y posición» de
   Storyline sobre el lienzo 1280×720, transcritas en px tal cual (mismo criterio que portada).

   Vertical: título 131→342, caja de texto 359→676, margen inferior 44px.
   Horizontal: título en x=55 y caja en x=63 — los 8px de diferencia son del propio panel de
   Storyline, no un error de transcripción (en `objetivos` pasa lo mismo entre título e intro). */
.layout-contenido { position: relative; }

.layout-contenido .contenido-titulo,
.layout-contenido .contenido-caja {
  position: absolute;
  z-index: 1;
}

/* El título usa el cuerpo de h1, no el h2 que trae `.titulo-seccion` por defecto: la caja es
   la misma 585×211 de `descripcion` y con interlineado 1,5 (§0o) entran exactamente 3 líneas
   de 66px. Alto fijo + `ajustarAlaCaja()`: un título más largo encoge en vez de desbordar. */
/* Isotipo del cliente sobre el título — pedido de Pablo (2026-08-12), lo notó ausente
   comparando contra el resto de la familia. Tamaño reducido frente a columnaTitulo (34px):
   el hueco real entre la banda de cromo (termina en y=78) y el título (top:131) mide 53px,
   contra los ~95px que tiene columnaTitulo — verificado con valores computados. */
.contenido-flecha {
  position: absolute;
  left: 55px;
  top: 83px;
  width: 20px;
  height: auto;
}
.layout-contenido--espejo .contenido-flecha { left: 640px; }

.layout-contenido .contenido-titulo {
  left: 55px;
  top: 131px;
  width: 585px;
  height: 211px;
  margin: 0;
  overflow: hidden;
  font-size: var(--tam-contenido-titulo, var(--marca-h1));
  line-height: 1.5;
  color: var(--marca-primario);
}

/* La caja medida contiene los párrafos Y la frase de fuerza — en Storyline son un solo cuadro
   de texto. Acá se reparte en dos sub-cajas porque cada mitad se comporta distinto:
     · cuerpo (201px): alto fijo, la letra encoge si el guion trae texto largo.
     · cierre: anclado al fondo de la caja, SIN encoger. Le quedan 96px, que es lo que ocupan
       2 líneas de --marca-h3 con su relleno; el presupuesto de `cajas.js` lo garantiza y el
       compilador falla si se pasa.
   Anclar uno arriba y otro abajo deja la composición estable por los dos extremos: lo único
   que varía es el hueco del medio. */
.contenido-caja {
  left: 63px;
  top: 359px;
  width: 532px;
  height: 317px;
}

.contenido-cuerpo {
  height: 201px;
  overflow: hidden;
  font-size: var(--tam-contenido-cuerpo, var(--marca-cuerpo-lg));
}

/* Frase de fuerza: bloque sólido en el rol secundario con letra blanca, no texto rojo suelto.
   Rima visualmente con el rectángulo rojo de `descripcion` — en todo el curso, «bloque rojo»
   significa «esto es lo que te tenés que llevar». El ancho se ajusta al contenido para que
   siga leyéndose como un acento y no como un fondo dominante (el manual pide usar los
   secundarios «en su justa medida»), y el cuerpo es mayor que el del párrafo porque es lo que
   el alumno tiene que llevarse: si pesara igual que el cuerpo, no destacaría nada. */
.contenido-cierre {
  position: absolute;
  left: 0;
  bottom: 0;
  max-width: 100%;
  margin: 0;
  padding: 0.5em 0.75em;
  border-radius: var(--marca-radio-sm);
  background: var(--marca-secundario);
  color: var(--marca-texto-inverso);
  font-size: var(--marca-h3);
  font-weight: 700;
  line-height: 1.3;
}

/* Dentro del bloque rojo, un `[[término]]` resaltado no puede volver a pintarse de rojo. */
.contenido-cierre mark.resaltado { color: var(--marca-texto-inverso); text-decoration: underline; }

/* Variante `--flujo`: la idea de fuerza queda en MEDIO del texto (párrafo, caja, párrafo),
   no anclada abajo — pedido de Pablo, 2026-08-12 («Principio rector»). Las dos sub-cajas de
   alto fijo se sueltan: todo pasa a flujo normal, uno debajo del otro, alto según contenido.
   El resto de la anulación para el modo `cromo:lamina` + espejo está más abajo, DESPUÉS de
   la regla de 263px que ese modo aplica — con especificidad igual (mismos 3 selectores de
   ancestro), gana la que viene última en el archivo, así que no puede ir acá arriba. */
/* Sube de 359 a 230: el título reserva una caja de 211px por el auto-ajuste de letra (§0z),
   pero el TEXTO real de un título de una línea termina en ~190 — 169px de aire que nadie usa.
   Pablo lo pidió expresamente («colocar el párrafo más arriba, cercano al título») y de paso
   es lo que le da lugar al remate sin pisar los círculos de navegación (ver más abajo). */
.contenido-caja--flujo { top: 220px; height: auto; }
.contenido-caja--flujo .contenido-cuerpo { height: auto; overflow: visible; }
.contenido-caja--flujo .contenido-cierre { position: static; margin: var(--marca-esp-md) 0; }
.contenido-remate { margin: 0; }

/* Espejo: la segunda lámina de contenido (y la cuarta, y la sexta…) se da vuelta para que dos
   seguidas no se vean iguales. Se refleja TODO el eje horizontal —panel, degradado del velo y
   las dos franjas— porque dar vuelta solo el texto dejaría el panel claro encima de la foto.
   Las coordenadas espejadas salen de `1280 − x − ancho`, no de un `scaleX(-1)` sobre el
   lienzo: un `scaleX` también daría vuelta las letras. */
.layout-contenido--espejo .contenido-titulo { left: 640px; }   /* 1280 − 55 − 585 */
.layout-contenido--espejo .contenido-caja   { left: 685px; }   /* 1280 − 63 − 532 */

/* En modo `cromo:lamina` (familia Syncore) la navegación son dos círculos flotantes abajo a
   la derecha (x:1118-1240, y:642-696 medido) — el panel espejado (685-1217) los tapa a menos
   que la caja termine antes. Pablo lo notó: la esquina inferior derecha del bloque naranjo
   quedaba detrás de los círculos (2026-08-12). La caja se acorta 54px (317→263, termina en
   622 en vez de 676, 20px de aire sobre el círculo).
   El reparto interno de esos 263px NO es el mismo que el de la caja base (201/96): Pablo
   pidió que la idea de fuerza («CERO INGRESO…») sea la frase larga y quede destacada
   completa, así que `cierre` se lleva más (118px, 3 líneas — medido por búsqueda binaria,
   entran hasta 125 caracteres, ver `cajas.js` → `cierreEspejoLamina`) y `cuerpo` cede el
   resto (125px, tiene auto-ajuste de letra — `cierre` no lo tiene, tope duro §0z). */
.es-cromo-lamina .layout-contenido--espejo .contenido-caja { height: 263px; }
.es-cromo-lamina .layout-contenido--espejo .contenido-cuerpo { height: 125px; }
/* En móvil no hay círculos flotantes que esquivar (el reflow ya cae en columna): el reset de
   abajo (`.es-movil .contenido-caja/-cuerpo { height:auto }`) tiene MENOS especificidad que
   las dos reglas de arriba, así que sin este empate explícito el recorte ganaba igual en
   móvil. `es-movil` vive en `.app` y `es-cromo-lamina` en `.motor` (un descendiente) — dos
   clases en selectores DISTINTOS, no un compuesto en el mismo elemento. */
.es-movil .es-cromo-lamina .layout-contenido--espejo .contenido-caja,
.es-movil .es-cromo-lamina .layout-contenido--espejo .contenido-cuerpo { height: auto; }

/* `--flujo` (contenido.remate) vs. el recorte de 263/125px de arriba: mismos 3 selectores de
   ancestro en los dos, especificidad empatada — como ESTA regla viene DESPUÉS en el archivo,
   gana ella. El reparto fijo de esa lámina no aplica cuando la caja pasa a flujo normal. */
.es-cromo-lamina .layout-contenido--espejo .contenido-caja--flujo { height: auto; }
.es-cromo-lamina .layout-contenido--espejo .contenido-caja--flujo .contenido-cuerpo { height: auto; }

.layout-contenido--espejo .portada-velo {
  background: linear-gradient(260deg, var(--marca-fondo) 0%, var(--marca-fondo) 36%, rgba(255, 255, 255, 0.85) 45%, rgba(255, 255, 255, 0) 58%);
}

.layout-contenido--espejo .portada-diagonal { transform: rotate(45deg); }
.layout-contenido--espejo .portada-diagonal--gris { left: auto; right: -216px; }
.layout-contenido--espejo .portada-diagonal--rojo { left: auto; right: 646px; }

/* El `@keyframes` compartido fija `rotate(315deg)` en ambos fotogramas, así que en espejo hay
   que reescribirlo con el ángulo reflejado o la franja gira al terminar la animación. */
.layout-contenido--espejo .portada-diagonal { animation-name: flotarDiagonalEspejo; }

@keyframes flotarDiagonalEspejo {
  from { opacity: 0; transform: translateY(50px) rotate(45deg); }
  to   { opacity: var(--op-diagonal, 1); transform: rotate(45deg); }
}

/* En móvil las coordenadas exactas no aplican: todo vuelve a fluir en una columna, y el
   espejo deja de tener sentido porque no hay dos lados que alternar. */
.es-movil .layout-contenido {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding-top: var(--marca-esp-lg);
}

.es-movil .contenido-flecha { position: static; width: 20px; margin-bottom: var(--marca-esp-xs); }

.es-movil .layout-contenido .contenido-titulo,
.es-movil .layout-contenido .contenido-caja {
  position: static;
  left: auto;
  top: auto;
  width: auto;
  height: auto;
  font-size: var(--marca-h2);
}

.es-movil .contenido-cuerpo { height: auto; font-size: var(--marca-cuerpo-lg); }

.es-movil .contenido-cierre {
  position: static;
  display: inline-block;
  margin-top: var(--marca-esp-md);
  font-size: var(--marca-cuerpo-lg);
}

/* --------------------------------------------------------------- cierre (lámina final)

   Medidas exactas del panel «Tamaño y posición» de Storyline sobre el lienzo 1280×720.
   `cierre` comparte el marcado de `portada` (mismas clases `.portada-*`), así que TODAS las
   reglas de acá van prefijadas con `.layout-cierre`: las de portada usan el combinador de hijo
   directo `.layout > .portada-*` y no alcanzan a estas, que siguen anidadas en `.portada-caja`
   (mismo truco de §0l, al revés).

   Vertical: logo 78→230, título 229→306, caja de texto 320→525, botón 608→671. */
.layout-cierre .portada-caja {
  position: static;
  max-width: none;
}

.layout-cierre .portada-logo,
.layout-cierre .portada-titulo,
.layout-cierre .cierre-caja,
.layout-cierre .cierre-cta {
  position: absolute;
  z-index: 1;
}

.layout-cierre .portada-logo {
  left: 250px;
  top: 78px;
  width: 262px;
  height: 152px;
  max-width: none;
  margin: 0;
  object-fit: contain;
}

.layout-cierre .portada-titulo {
  left: 55px;
  top: 229px;
  width: 585px;
  height: 77px;
  margin: 0;
  overflow: hidden;
  font-size: var(--tam-cierre-titulo, var(--marca-h1));
  line-height: 1.15;
  color: var(--marca-primario);
}

/* La caja medida contiene los párrafos Y la idea de fuerza — en Storyline es un solo cuadro
   con la última frase en rojo. Mismo reparto que en `contenido`, y por la misma razón: el
   cuerpo encoge la letra si hace falta, la idea de fuerza NO (encogerla la haría entrar y
   dejaría de destacar, en silencio).
   Ampliada de 205 a 304px (M3, §0): con un `texto` de dos oraciones el cuerpo de 101px
   cortaba la segunda a la mitad — no hay auto-ajuste de ALTURA para `cierre.texto`, solo de
   letra, y la idea de fuerza tampoco se achica. Medido en el navegador: este texto necesita
   ~165px de cuerpo y ~118px de idea de fuerza (a veces envuelve 3 líneas, no 2). Para que
   entren los dos sin pisar nada, la caja sube 8px (320→312) y el CTA baja 22px (608→630) —
   quedaba con 49px libres hasta el borde del lienzo, sobraba margen.*/
.layout-cierre .cierre-caja {
  left: 69px;
  top: 312px;
  width: 473px;
  height: 304px;
}

.layout-cierre .cierre-cuerpo {
  height: 175px;
  overflow: hidden;
  font-size: var(--tam-cierre-cuerpo, var(--marca-cuerpo-lg));
}

.layout-cierre .cierre-cuerpo .portada-bajada {
  margin: 0;
  font-size: inherit;
}

.layout-cierre .cierre-cta {
  left: 162px;
  top: 630px;
  width: 259px;
  height: 63px;
  margin: 0;
}

/* En móvil las coordenadas exactas no aplican: todo vuelve a fluir en una columna. */
.es-movil .layout-cierre .portada-caja { position: static; }

.es-movil .layout-cierre .portada-logo,
.es-movil .layout-cierre .portada-titulo,
.es-movil .layout-cierre .cierre-caja,
.es-movil .layout-cierre .cierre-cta {
  position: static;
  left: auto;
  top: auto;
  width: auto;
  height: auto;
}

.es-movil .layout-cierre .portada-titulo { font-size: var(--marca-h2); }
.es-movil .layout-cierre .cierre-cuerpo { height: auto; font-size: var(--marca-cuerpo-lg); }
.es-movil .layout-cierre .cierre-frase { position: static; margin-top: var(--marca-esp-md); }

/* --------------------------------------------------------------- tarjetas (flip cards) */

/* El fondo es el patrón compartido —foto + velo + las dos franjas diagonales— igual que
   portada, contenido y cierre. Antes esta lámina tenía un fondo plano con una cuña roja propia,
   que la dejaba fuera del sistema: no era una decisión, era que nunca llamó a los helpers. */
.layout-tarjetas {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.layout-tarjetas > .titulo-seccion,
.layout-tarjetas > .instruccion,
.layout-tarjetas > .tarjetas-fila { position: relative; z-index: 1; }

/* La tarjeta mide SIEMPRE 274px de ancho, venga la lámina con 2, 3 o 4. Lo que cambia es la
   distribución, no el tamaño: la fila se centra en el lienzo y las tarjetas quedan simétricas
   respecto del eje. Es regla de Pablo y tiene sentido de sistema — una tarjeta que cambia de
   porte según cuántas la acompañan deja de leerse como la misma pieza de un módulo a otro.

   Antes eran 4 columnas fijas: con 3 tarjetas quedaba una columna muerta a la derecha y el
   bloque descentrado. Y una primera corrección mía las estiraba a 320px, que es justo lo que
   esta regla prohíbe. */
.tarjetas-fila {
  display: grid;
  grid-template-columns: repeat(var(--n-tarjetas, 4), 274px);
  justify-content: center;
  gap: var(--marca-esp-md);
  flex: 1;
  align-items: stretch;
  perspective: 1400px;
}

.tarjeta-flip {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  min-height: 220px;
}

.tarjeta-flip:focus-visible .tarjeta-cara { outline: 3px solid var(--marca-terciario); outline-offset: 2px; }

/* Una tarjeta bloqueada tiene que VERSE bloqueada. Antes quedaban `disabled` pero idénticas,
   así que un click que no hacía nada se leía como una falla del curso. Cubre los dos casos con
   una sola regla: durante la narración de entrada están las cuatro apagadas, y mientras una
   tarjeta narra están apagadas las otras tres —la que suena nunca está `disabled`, así que se
   queda encendida y se lee como la que manda. */
.tarjeta-flip.es-apagada {
  cursor: default;
  opacity: 0.45;
  transition: opacity var(--marca-mov-entrada) var(--marca-mov-curva);
}

/* Mientras corre la instrucción, además baja la pista de «Haz click»: todavía no toca. */
.tarjetas-fila.esperando-intro .tarjeta-pista { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .tarjeta-flip.es-apagada { transition: none; }
}

.tarjeta-flip-interior {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 220px;
  transition: transform var(--marca-mov-feedback) var(--marca-mov-curva);
  transform-style: preserve-3d;
}

.tarjeta-flip.volteada .tarjeta-flip-interior { transform: rotateY(180deg); }

.tarjeta-cara {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  border-radius: var(--marca-radio-md);
  backface-visibility: hidden;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(var(--marca-primario-rgb), 0.15);
}

/* Frente: base en el rol primario + foto a sangre + capa oscura + rótulo blanco centrado.
   La base navy no es decorativa: es lo que se ve mientras el cliente no entregue las fotos,
   y el rótulo sigue legible igual. */
.tarjeta-frente {
  justify-content: center;
  padding: var(--marca-esp-md);
  background: var(--marca-primario);
}

.tarjeta-foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Capa oscura sobre la foto: deja verla y sostiene el blanco del rótulo. El valor está medido
   contra las cuatro fotos reales, no elegido a ojo. El rótulo es 20px bold, o sea «texto
   grande» para WCAG (mínimo 3:1), y a 45% ya pasaba ese piso — pero con un tercio del área
   bajo el 4.5:1 del texto normal, o sea sin margen. A 55% no queda nada bajo 4.5:1 en ninguna
   de las cuatro, y la foto se sigue viendo. Las fotos son de clave alta a propósito (§0ab), y
   eso es justamente lo que obliga a un velo más denso que el que pediría una foto oscura. */
.tarjeta-velo {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
}

.tarjeta-frente-texto {
  position: relative;
  margin: 0;
  font-weight: 700;
  color: var(--marca-blanco);
  font-size: 20px;
  line-height: 1.25;
  text-align: center;
  text-wrap: balance;
}

.tarjeta-pista {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
}

.tarjeta-voltear {
  position: absolute;
  right: 10px;
  bottom: 8px;
  font-size: 18px;
  color: rgba(255, 255, 255, 0.85);
}

/* Reverso: fondo navy sólido, texto blanco grande y bien espaciado — el problema reportado
   era justo este lado: texto chico, pegado arriba, sin centrar. */
.tarjeta-reverso {
  justify-content: center;
  padding: var(--marca-esp-lg);
  background: var(--marca-primario);
  transform: rotateY(180deg);
}

.tarjeta-reverso-texto {
  margin: 0;
  color: var(--marca-blanco);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.45;
  text-align: left;
}

.es-movil .tarjetas-fila { grid-template-columns: 1fr 1fr; }

/* --------------------------------------------------------------- clasificar (arrastrar y soltar) */

.layout-clasificar { display: flex; flex-direction: column; }

/* Con el cromo de la familia dentro de la lámina, el contenido tiene que arrancar DEBAJO de
   la banda (78px). Los dos layouts de actividad centran su contenido con flex, así que un
   padding superior lo empuja sin tocar ninguna coordenada: sin esto el título se metía 22px
   dentro de la banda (medido). Acotado a `.es-cromo-lamina`, así que la composición sin
   familia visual no se mueve. */
.es-cromo-lamina .layout-clasificar,
.es-cromo-lamina .layout-pregunta { padding-top: 94px; }
/* En móvil el cromo no se dibuja (`.es-movil .botones-cromo { display:none }`), así que ese
   despeje sobraría. `es-movil` vive en `.app` y `es-cromo-lamina` en `.motor`, un
   descendiente: van como selector descendiente, no compuesto. */
.es-movil .es-cromo-lamina .layout-clasificar,
.es-movil .es-cromo-lamina .layout-pregunta { padding-top: var(--marca-esp-md); }

/* Las dos medidas del ejercicio salen de una sola cuenta, acá arriba, porque tienen que
   coincidir: la tarjeta que se arrastra mide lo mismo que una casilla de destino. Antes la
   tarjeta estaba fija en 520 px y con 3 casillas —que dan 373— quedaba más ancha que su
   destino: se veía como una pieza de otro juego.

   `--ancho-fila` es «lo que ocuparían N casillas de 520 px», topado por el ancho disponible.
   Con 2 casillas caben a 520 y la fila se centra; con 3 o 4 se reparten el ancho del contenido.
   El 100 % es literal: la zona ya mide el ancho útil del lienzo, así que no hay ningún 1168
   escrito a mano que se desincronice si cambian los márgenes. */
.clasificar-zona {
  --n-categorias: 2;
  --ancho-fila: min(100%, calc(var(--n-categorias) * 520px +
                (var(--n-categorias) - 1) * var(--marca-esp-md)));
  --ancho-pieza: calc((var(--ancho-fila) - (var(--n-categorias) - 1) * var(--marca-esp-md))
                / var(--n-categorias));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--marca-esp-lg);
  flex: 1;
  justify-content: center;
}

/* La pieza que se mueve va en el rol PRIMARIO y las casillas de destino en arena: así el ojo
   distingue de un vistazo quién viaja y quién recibe, sin depender del texto. Antes era al
   revés —tarjeta arena, casillas sólidas— y las tres piezas competían por el mismo peso.
   Dirección de diseño de Pablo (§0an). */
.clasificar-tarjeta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  /* El mismo ancho que una casilla de destino: son las dos caras del ejercicio y tienen que
     leerse como piezas del mismo juego. Ver la cuenta en `.clasificar-zona`. */
  width: var(--ancho-pieza, 520px);
  max-width: 100%;
  /* Alto mínimo = el de una situación de DOS líneas, que es el porte de referencia. Sin esto,
     una situación corta entra en una línea, la tarjeta encoge 30 px y el bloque entero se
     re-centra: recorriendo las 5 láminas del ejercicio, una se corría 15 px respecto de las
     otras. Misma regla que Pablo fijó para las flipcards — las piezas de un mismo bloque no
     cambian de tamaño, solo se distribuyen. Con textos más largos sigue creciendo. */
  min-height: 133px;
  box-sizing: border-box;
  padding: var(--marca-esp-md) var(--marca-esp-lg);
  border-radius: var(--marca-radio-md);
  background: var(--marca-primario);
  border: 2px solid var(--marca-primario);
  box-shadow: 0 10px 28px rgba(var(--marca-primario-rgb), 0.28);
  cursor: grab;
  text-align: center;
}

.clasificar-tarjeta .texto { margin: 0; font-weight: 700; color: var(--marca-blanco); }
/* Sobre navy la pista tiene que aclararse: en gris quedaba en 2,1:1 contra el fondo. */
.clasificar-pista { font-size: 13px; color: rgba(255, 255, 255, 0.78); }
/* El realce de «esta elegí» va en el rol TERCIARIO, no en el secundario: el rojo significa
   «incorrecta» en el modal de feedback y usarlo acá le daría dos sentidos al mismo color, que
   es justo la colisión que ya se resolvió en «opcion_multiple». */
.clasificar-tarjeta.clasificar-seleccionada {
  border-color: var(--marca-terciario);
  box-shadow: 0 0 0 4px rgba(var(--marca-terciario-rgb), 0.35);
}
.clasificar-tarjeta:focus-visible { outline: 3px solid var(--marca-terciario); outline-offset: 3px; }

/* Mismo «porte» que la tarjeta que se arrastra: mismo ancho de columna y una altura
   comparable, para que se lean como el mismo tipo de pieza, no una tarjeta cayendo en una
   ranura delgada.
   El alto NUNCA cambia: lo que se reparte es el ancho de la fila entre las casillas que traiga
   el guion. Con 2 dan 520 cada una —la medida aprobada—, con 3 dan 373 y con 4, 274. El
   `max-width` es esa cuenta: si las casillas cupieran a 520 se quedan en 520, y si no, se
   reparten el ancho disponible. Misma idea que la rejilla de flipcards. */
.clasificar-categorias {
  display: grid;
  grid-template-columns: repeat(var(--n-categorias), minmax(0, 1fr));
  gap: var(--marca-esp-md);
  width: var(--ancho-fila);
  justify-content: center;
}

/* Las dos casillas son IDÉNTICAS entre sí: arena con marco en el rol primario. Antes la
   segunda era roja —clonado del Storyline publicado— y el rojo ya significa «incorrecta» en el
   modal de feedback, así que una de las dos categorías se leía como la mala antes de responder.
   Idénticas, además, es lo correcto: la diferencia entre ellas la tiene que hacer el alumno
   leyendo, no el color. */
.clasificar-categoria {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 130px;
  box-sizing: border-box;
  padding: var(--marca-esp-md) var(--marca-esp-lg);
  border: 2px solid var(--marca-primario);
  border-radius: var(--marca-radio-md);
  background: var(--marca-fondo-alt);
  color: var(--marca-primario);
  font-family: inherit;
  font-size: var(--marca-cuerpo);
  font-weight: 700;
  letter-spacing: 0.02em;
  /* NO lleva `cursor: pointer`: no se resuelve haciendo clic acá, y un cursor de mano sería
     prometer una interacción que la lámina no acepta. Ver el comentario del layout. */
  cursor: default;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  transition: transform var(--marca-mov-entrada) var(--marca-mov-curva),
              box-shadow var(--marca-mov-entrada) var(--marca-mov-curva),
              background var(--marca-mov-entrada) var(--marca-mov-curva);
}

/* Al pasar por encima con la tarjeta, la casilla se «enciende» tiñéndose del primario en
   transparencia. No se rellena de navy sólido a propósito: eso la dejaría igual que la tarjeta
   que viaja y por un instante habría dos piezas idénticas en pantalla.
   El realce va solo en `.sobre-drop` —cuando hay algo encima— y no en `:hover`: encender la
   casilla con el mouse quieto invitaba a hacerle clic, que es justo lo que no resuelve nada. */
.clasificar-categoria.sobre-drop {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
  background: color-mix(in srgb, var(--marca-primario) 12%, var(--marca-fondo-alt));
}
.clasificar-categoria:focus-visible { outline: 3px solid var(--marca-terciario); outline-offset: 2px; }

/* El ejercicio se ve inerte hasta que termina la instrucción hablada. Acá alcanza con bajar la
   opacidad de la pieza entera —a diferencia de la pestaña del acordeón, que era transparente y
   solo se le apagaban las letras—: tanto la tarjeta como los botones tienen fondo propio, así
   que baja el fondo Y el texto, que es lo que hace que se lea como bloqueado. */
.clasificar-zona.esperando-intro .clasificar-tarjeta { cursor: default; opacity: 0.45; }
.clasificar-zona.esperando-intro .clasificar-pista { visibility: hidden; }

.clasificar-categoria.es-apagada {
  cursor: default;
  opacity: 0.45;
  transition: opacity var(--marca-mov-entrada) var(--marca-mov-curva);
}

.clasificar-categoria.es-apagada { pointer-events: none; }

/* Mientras la tarjeta viaja bajo el dedo. `touch-action: none` es lo que evita que el navegador
   interprete el gesto como scroll y se lleve el arrastre puesto. */
.clasificar-tarjeta { touch-action: none; }
.clasificar-tarjeta.clasificar-arrastrando {
  opacity: 0.9;
  z-index: 5;
  cursor: grabbing;
}

@media (prefers-reduced-motion: reduce) {
  .clasificar-categoria.es-apagada { transition: none; }
}

/* En móvil las casillas se apilan a ancho completo, así que la tarjeta tiene que hacer lo
   mismo: `--ancho-pieza` es «una casilla de la fila» y en columna única esa cuenta daría 93px
   con 3 categorías. La regla de que tarjeta y casilla midan igual se mantiene — cambia cuánto
   mide una casilla. */
.es-movil .clasificar-categorias { grid-template-columns: 1fr; }
.es-movil .clasificar-tarjeta { width: 100%; }

/* --------------------------------------------------------------- video (cápsula) */

/* El video manda en la lámina: ocupa el ancho útil y se centra. Fondo navy para que las
   franjas negras de un clip con otra relación de aspecto no se lean como un error. */
.layout-video {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--marca-esp-md);
}

.video-marco {
  position: relative;
  width: 100%;
  max-width: 1168px;
  aspect-ratio: 16 / 9;
  margin: 0 auto;
  border-radius: var(--marca-radio-md);
  overflow: hidden;
  background: var(--marca-primario);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}

.video-medio {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  background: var(--marca-primario);
}

/* Capa de arranque: el póster se ve por debajo (es el `poster` del propio <video>) y encima
   va un botón grande. Vuelve a aparecer al terminar, así repetir el video es el mismo gesto
   que empezarlo — y se puede repetir sin límite (D22). */
.video-arranque {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(var(--marca-primario-rgb), 0.35);
  cursor: pointer;
  border: 0;
}

.video-play {
  width: 96px;
  height: 96px;
  border: 0;
  border-radius: 50%;
  background: var(--marca-secundario);
  color: var(--marca-blanco);
  font-size: 38px;
  line-height: 1;
  padding-left: 6px;            /* el glifo ▶ no está centrado ópticamente */
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
  transition: transform var(--marca-mov-entrada) var(--marca-mov-curva);
}

/* Rótulo bajo el botón: «Reproducir» y, una vez visto, «Volver a reproducir». Un ícono solo
   no alcanza para esta audiencia. */
.video-rotulo {
  margin: var(--marca-esp-sm) 0 0;
  color: var(--marca-blanco);
  font-size: var(--marca-cuerpo);
  font-weight: 700;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}

/* Barra de avance del video: INFORMA cuánto falta, no es un control. Sin escuchas de click ni
   arrastre y con `pointer-events: none`, para que ni siquiera parezca manipulable — el alumno
   no puede adelantar el video, igual que no puede adelantar el audio del resto del curso. */
.video-progreso {
  position: absolute;
  left: 0;
  bottom: 0;
  /* Ancho explícito, no `left:0; right:0`: el relleno de adentro se dimensiona en porcentaje y
     hay motores que no resuelven el porcentaje de un hijo contra un padre sizado por
     left/right — la barra quedaba en 0 y no se movía nunca. */
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.25);
  pointer-events: none;
}

/* El relleno se dibuja con `scaleX`, no con un `width` en porcentaje. El porcentaje se
   resuelve contra el ancho del padre, y este padre se dimensiona con `left/right` — hay
   motores que ahí devuelven 0 y la barra no se movía nunca. `scaleX` no depende de eso. */
.video-progreso-relleno {
  width: 0;
  height: 100%;
  background: var(--marca-secundario);
  transition: width 200ms linear;
}

/* Cuánto FALTA, que es lo que la persona quiere saber. */
.video-tiempo {
  position: absolute;
  right: 12px;
  bottom: 16px;
  padding: 2px 8px;
  border-radius: var(--marca-radio-sm);
  background: rgba(0, 0, 0, 0.55);
  color: var(--marca-blanco);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .video-progreso-relleno { transition: none; }
}

/* En pantalla completa el marco ocupa el monitor entero: sin relación de aspecto fija, sin
   bordes redondeados y sin sombra. El video se ajusta con `contain`, así una cápsula que no
   sea 16:9 no se recorta — se enmarca en negro, como cualquier reproductor. */
.video-marco:fullscreen,
.video-marco:-webkit-full-screen {
  width: 100vw;
  height: 100vh;
  max-width: none;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
  background: #000;
}

.video-marco:fullscreen .video-medio,
.video-marco:-webkit-full-screen .video-medio { background: #000; }

/* La barra de avance crece un poco en pantalla completa: a dos metros de un monitor, 6px no
   se ven. Y los subtítulos, que el reproductor muda acá adentro, se anclan sobre el video. */
.video-marco:fullscreen .video-progreso,
.video-marco:-webkit-full-screen .video-progreso { height: 10px; }

.video-marco:fullscreen .video-tiempo,
.video-marco:-webkit-full-screen .video-tiempo { bottom: 24px; font-size: 18px; }

.video-marco:fullscreen .subtitulos,
.video-marco:-webkit-full-screen .subtitulos {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 64px;
  z-index: 3;
}

.video-play:hover { transform: scale(1.06); }
.video-play:focus-visible { outline: 3px solid var(--marca-blanco); outline-offset: 4px; }

@media (prefers-reduced-motion: reduce) {
  .video-play { transition: none; }
}

.es-movil .video-marco { max-width: 100%; }
.es-movil .video-play { width: 68px; height: 68px; font-size: 28px; }

/* --------------------------------------------------------------- error de autoría */

.layout-error { display: grid; place-content: center; text-align: center; }
.layout-error .titulo-seccion { color: var(--marca-secundario); }
