/* ==========================================================================
   CMCS — Actos: la capa narrativa de scroll
   --------------------------------------------------------------------------
   La página no "tiene animaciones": la página SE TEJE. Cada acto añade una
   hilada, la urdimbre se densifica al descender, y la lanzadera baja por el
   costado marcando el avance.

   Todo en CSS nativo. Cero librerías, cero JavaScript. Sin soporte de
   `animation-timeline`, todo queda legible y en su sitio — el contenido nunca
   depende del movimiento para existir.
   ========================================================================== */

/* ---- La lanzadera: hilo de progreso del documento ------------------------
   Baja por el borde izquierdo conforme avanza la lectura. Es el único
   indicador de progreso y no tapa contenido.                                */

.lanzadera {
  position: fixed;
  left: 0;
  top: 0;
  width: 3px;
  height: 100vh;
  background: var(--ceruleo);
  transform-origin: top center;
  transform: scaleY(0);
  z-index: 90;
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .lanzadera {
      animation: bajar-lanzadera linear both;
      animation-timeline: scroll(root block);
    }
  }
}
@keyframes bajar-lanzadera { to { transform: scaleY(1); } }

/* ---- Acto: capítulo a escala de pantalla --------------------------------- */

.acto {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding-block: var(--e-9);
  overflow: clip;
}

.acto--marino  { background: var(--campo-marino); color: #FFF; }
.acto--lana    { background: var(--lana); color: var(--tinta); }
/* Campo cerúleo a página completa: el segundo hilo también es superficie. */
.acto--ceruleo { background: var(--campo-ceruleo); color: #FFF; }
.acto--ceruleo .acto__declaracion { color: #FFF; }
.acto--ceruleo .acto__apoyo { color: #CDEBF9; }
.acto--ceruleo .urdimbre { --color-urdimbre: rgba(255,255,255,0.14); }

/* Declaración: el enunciado a escala de acto */
.acto__declaracion {
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--display-2);
  line-height: var(--interlinea-titular);
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
  max-width: 24ch;
  margin: 0;
}
.acto--marino .acto__declaracion { color: #FFF; }
.acto--lana   .acto__declaracion { color: var(--marino); }

.acto__apoyo {
  margin-top: var(--e-6);
  font-size: var(--t-md);
  line-height: var(--interlinea-lead);
  max-width: 50ch;
}
.acto--marino .acto__apoyo { color: var(--marino-tinte); }
.acto--lana   .acto__apoyo { color: var(--tinta-suave); }

/* ---- Densificación de la urdimbre ---------------------------------------
   Cada acto teje más apretado que el anterior: la tela se cierra conforme
   avanza la lectura. Es la progresión, no un adorno repetido.               */

.urdimbre--6  { --pasos: 6; }
.urdimbre--12 { --pasos: 12; }
.urdimbre--24 { --pasos: 24; }

.urdimbre[class*="urdimbre--"] {
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(100% / var(--pasos) - var(--hilo-fino)),
    var(--color-urdimbre, rgba(255, 255, 255, 0.09)) calc(100% / var(--pasos) - var(--hilo-fino)),
    var(--color-urdimbre, rgba(255, 255, 255, 0.09)) calc(100% / var(--pasos))
  );
}

/* La urdimbre entra tejiéndose de arriba hacia abajo */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .acto .urdimbre {
      animation: urdir var(--dur-larga) linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 90%;
    }
  }
}
@keyframes urdir {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* ---- LA RUTA PEDAGÓGICA ------------------------------------------------
   Rediseñada el 2026-09-07 sobre el Figma de Andrés. Sale el apilado oscuro
   con retroceso; entran campos claros, un anillo grande y la lámina
   fotográfica encima, alternando lado en cada etapa.

   EL ANILLO SE DIBUJA CON EL SCROLL. No gira ni parpadea: se traza, como si
   alguien lo estuviera pintando mientras el lector baja. Es lo único que se
   mueve de verdad en la sección, y marca el avance por la ruta.

   EL ORO. Los anillos van en oro, pero el oro NUNCA toca texto: sobre campo
   cielo da 1,65:1 y sería ilegible, y la ley del sistema lo reserva para
   evidencia verificable. Lo que se LEE en oro sigue siendo sólo el código de
   una resolución.                                                          */

/* El ángulo que traza el anillo. Registrado para poder animarlo: una variable
   sin `@property` no interpola, se salta de golpe. */
@property --trazo {
  syntax: '<angle>';
  inherits: false;
  initial-value: 360deg;
}


.campo-cielo { background: var(--campo-cielo); color: var(--tinta); }

/* ---- El resaltador ------------------------------------------------------
   La palabra marcada no lleva subrayado: lleva MANCHA. Es la trama, que es
   superficie, frente a la urdimbre, que es línea.

   EL ORO. Andrés decidió el 2026-09-07 que la mancha va en oro, como su Figma.
   Es oro como SUPERFICIE con texto marino encima —6,7:1—, nunca oro como color
   de letra, que sobre campo claro daría 1,65:1. Consecuencia a vigilar: el oro
   ya no es exclusivo de la evidencia verificable, así que los códigos de
   resolución necesitan otra señal si alguna vez compiten. */
.marca {
  font-weight: var(--peso-enfasis);
  color: var(--marino);
  background: var(--oro);
  padding: 0.01em 0.22em 0.04em;
  /* LA ESQUINA, EN `em` Y NO EN PÍXELES (2026-09-10, por petición del cliente,
     con la referencia de `viens-la.com`). En em la mancha se redondea igual en
     un titular de 70 px que en una línea de texto de 16: con un valor fijo, el
     mismo radio que en grande se ve suave, en pequeño se come la palabra.
     Sobre la regla de radios de `tokens.css`: aquí no hay alternativa de
     píldora —una mancha de texto con las puntas redondas del todo deja de
     leerse como subrayado y pasa a leerse como etiqueta—, así que la elección
     real era recta o apenas suavizada, y el cliente pidió lo segundo. */
  border-radius: 0.14em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* «competencia» es la urdimbre: estructura, no mancha. Se marca con PESO, no
   con línea — un hilo marino bajo texto marino no se lee, y el Figma lleva una
   sola marca. */
.urde { font-weight: var(--peso-enfasis); }

/* ---- La promesa, sobre campo claro ------------------------------------- */

.promesa { position: relative; overflow: clip; isolation: isolate; }
.promesa__caja { position: relative; z-index: 3; text-align: center; }
.promesa .promesa__frase {
  color: var(--marino);
  margin-inline: auto;
  /* Medida en `em` y no en `ch`: acompaña al tamaño y el corte cae siempre en
     el mismo sitio — tres líneas, con «competencia y humanidad» juntas en la
     segunda, que es donde está la tesis. */
  width: min(100%, 15.4em);
  max-width: none;
  font-size: var(--display-2);
  line-height: 1.14;
  letter-spacing: -0.035em;
  text-wrap: wrap;
}

/* El anillo de la promesa va ENTERO dentro de la sección: cortado por el borde
   se leía como un error de maquetación, no como una forma. */
.anillo--abajo-izq {
  width: clamp(13rem, 20vw, 20rem);
  --grosor-anillo: clamp(1.6rem, 2.6vw, 2.6rem);
  left: clamp(var(--e-5), 3vw, var(--e-8));
  bottom: clamp(var(--e-5), 3vw, var(--e-7));
}

/* ---- EL APILADO CON REPOSO ---------------------------------------------
   Cinco paneles: el pórtico y las cuatro etapas. Cada uno se queda QUIETO un
   rato antes de que el siguiente empiece a taparlo. Sin ese reposo el anillo
   no alcanzaba a trazarse y el lector no llegaba a leer nada.

   LA CUENTA, que es lo único delicado de toda la sección:

     alto del panel = 100svh (subida) + REPOSO + 100svh (lo tapan)
     margen superior = -100svh, para montarse sobre el anterior

   Dentro, `.panel__pantalla` es pegajosa y mide exactamente una pantalla, así
   que se queda clavada arriba mientras su panel recorre esos tres tramos.
   Resultado, por panel:

     · sube y cubre al anterior   (100svh)
     · REPOSO: quieto, sin nadie encima — aquí se traza el anillo
     · el siguiente lo cubre a él (100svh)

   El reposo se ajusta en UN solo sitio, abajo. Subirlo hace la sección más
   lenta; bajarlo, más rápida.                                              */

.ruta-telar {
  position: relative;
  /* Lo que dura cada etapa quieta. Es la perilla del ritmo. */
  --reposo: 85svh;
  background: var(--marino-hondo);
  timeline-scope: --pant-0, --pant-1, --pant-2, --pant-3, --pant-4,
                  --panel-0, --panel-1, --panel-2, --panel-3, --panel-4;
}

.panel {
  position: relative;
  min-height: calc(200svh + var(--reposo));
}
.panel + .panel { margin-top: -100svh; }

.panel__pantalla {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  align-content: center;
  overflow: clip;
  isolation: isolate;
  background: var(--campo-cielo);
  border-top: var(--hilo-trama) solid var(--ceruleo);
  box-shadow: 0 -26px 70px rgba(16, 22, 48, 0.22);
  transform-origin: 50% 42%;
}

/* DOS lineas de tiempo por panel, y no es redundancia:

   · La de la PANTALLA (`--pant-N`) sirve para lo que ocurre mientras el panel
     SUBE: la entrada de la lámina y del texto, y el retroceso del panel
     anterior. Su fase `entry` es exactamente ese tramo.

   · La del PANEL entero (`--panel-N`) sirve para lo que ocurre mientras el
     panel está QUIETO. Hace falta porque la pantalla es pegajosa: mientras
     está clavada arriba mide lo mismo que el hueco de vista, así que su fase
     `contain` no avanza y su `exit` no llega hasta que ya está tapada. Ese fue
     el fallo: el anillo se trazaba escondido y sólo se veía en el último panel,
     que es el único que no tiene quien lo tape.

   En el panel entero, `contain` cubre reposo + relevo. Con `--reposo: 85svh`,
   el reposo ocupa el primer 46 % de `contain`. */
.panel:nth-child(1) .panel__pantalla { view-timeline-name: --pant-0; }
.panel:nth-child(2) .panel__pantalla { view-timeline-name: --pant-1; }
.panel:nth-child(3) .panel__pantalla { view-timeline-name: --pant-2; }
.panel:nth-child(4) .panel__pantalla { view-timeline-name: --pant-3; }
.panel:nth-child(5) .panel__pantalla { view-timeline-name: --pant-4; }

.panel:nth-child(1) { view-timeline-name: --panel-0; }
.panel:nth-child(2) { view-timeline-name: --panel-1; }
.panel:nth-child(3) { view-timeline-name: --panel-2; }
.panel:nth-child(4) { view-timeline-name: --panel-3; }
.panel:nth-child(5) { view-timeline-name: --panel-4; }

/* El pórtico: campo marino a pantalla completa. */
.panel--portico .panel__pantalla {
  background: var(--campo-marino);
  color: #FFF;
  border-top: 0;
}
/* Las etapas alternan tono: si las cuatro fueran iguales el apilado no se
   notaría al pasar de una a otra. */
.panel--etapa:nth-of-type(even) .panel__pantalla { background: var(--campo-cielo-h); }

/* ---- El retroceso ------------------------------------------------------
   Lo dispara el panel SIGUIENTE. Su `entry` dura exactamente una pantalla,
   que es justo el tramo en que sube desde el borde inferior hasta cubrir. */

@supports (timeline-scope: --a) {
  @media (prefers-reduced-motion: no-preference) {
    .panel:nth-child(1) .panel__pantalla { animation: recular linear both; animation-timeline: --pant-1; }
    .panel:nth-child(2) .panel__pantalla { animation: recular linear both; animation-timeline: --pant-2; }
    .panel:nth-child(3) .panel__pantalla { animation: recular linear both; animation-timeline: --pant-3; }
    .panel:nth-child(4) .panel__pantalla { animation: recular linear both; animation-timeline: --pant-4; }
    .panel:nth-child(-n+4) .panel__pantalla { animation-range: entry 0% entry 100%; }
    /* El quinto no retrocede: no tiene quien lo cubra. */
  }
}
@keyframes recular {
  0%   { transform: scale(1);    opacity: 1; }
  86%  { transform: scale(0.9);  opacity: 0.5; }
  100% { transform: scale(0.88); opacity: 0; }
}

/* ---- El anillo se traza DURANTE EL REPOSO ------------------------------
   La pantalla mide lo mismo que el hueco de vista, así que su fase `contain`
   no existe y el reposo cae dentro de `exit`. Con `--reposo: 85svh`, el reposo
   ocupa el 85 % de esa fase; el trazo se cierra en el 45 %, o sea a mitad del
   reposo, y el lector ve el anillo COMPLETO el resto del tiempo.            */

@property --trazo {
  syntax: '<angle>';
  inherits: false;
  initial-value: 360deg;
}

.anillo {
  position: absolute;
  z-index: 0;
  display: block;
  aspect-ratio: 1;
  border-radius: 50%;
  border: var(--grosor-anillo, 2.6rem) solid currentColor;
  pointer-events: none;
  --trazo: 360deg;
  mask-image: conic-gradient(#000 var(--trazo), transparent 0);
  -webkit-mask-image: conic-gradient(#000 var(--trazo), transparent 0);
}
.anillo--ceruleo { color: var(--ceruleo); }
.anillo--oro     { color: var(--oro); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .panel:nth-child(1) .anillo { animation-timeline: --panel-0; }
    .panel:nth-child(2) .anillo { animation-timeline: --panel-1; }
    .panel:nth-child(3) .anillo { animation-timeline: --panel-2; }
    .panel:nth-child(4) .anillo { animation-timeline: --panel-3; }
    .panel:nth-child(5) .anillo { animation-timeline: --panel-4; }
    .panel .anillo {
      animation-name: trazar-anillo;
      animation-timing-function: linear;
      animation-fill-mode: both;
      /* Dentro del reposo, que es el primer 46 % de `contain`. Cierra en el
         26 %, o sea a poco más de la mitad del reposo: el resto del tiempo el
         anillo se ve ENTERO, que es de lo que se trata. */
      animation-range: contain 3% contain 26%;
    }
    /* El de la promesa vive fuera del apilado y lee su propia vista. */
    .promesa .anillo {
      animation: trazar-anillo linear both;
      animation-timeline: view();
      animation-range: entry 25% cover 28%;
    }
  }
}
@keyframes trazar-anillo {
  from { --trazo: 0deg; }
  to   { --trazo: 360deg; }
}

/* ---- La lámina y el texto entran mientras el panel SUBE ---------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .panel:nth-child(1) .foto-suelta { animation-timeline: --pant-0; }
    .panel:nth-child(2) .etapa__lamina, .panel:nth-child(2) .etapa__dicho { animation-timeline: --pant-1; }
    .panel:nth-child(3) .etapa__lamina, .panel:nth-child(3) .etapa__dicho { animation-timeline: --pant-2; }
    .panel:nth-child(4) .etapa__lamina, .panel:nth-child(4) .etapa__dicho { animation-timeline: --pant-3; }
    .panel:nth-child(5) .etapa__lamina, .panel:nth-child(5) .etapa__dicho { animation-timeline: --pant-4; }

    .panel .etapa__lamina {
      animation-name: entrar-lamina; animation-timing-function: linear;
      animation-fill-mode: both; animation-range: entry 35% entry 95%;
    }
    .panel .etapa__dicho {
      animation-name: entrar-dicho; animation-timing-function: linear;
      animation-fill-mode: both; animation-range: entry 30% entry 90%;
    }
    .panel .foto-suelta {
      animation-name: brotar-disco; animation-timing-function: linear;
      animation-fill-mode: both;
    }
    /* LA CASCADA. Los cinco brotan con la misma subida pero cada uno en su
       tramo, corrido un 8 % respecto al anterior. Es lo que hace que el portico
       se lea como un campo que se puebla y no como cinco cosas que aparecen a
       la vez —que es justo lo que se ve en la referencia de Andres, donde los
       circulos van llegando de uno en uno—.
       Aqui el reloj es el scroll, no un temporizador: se puebla mientras se
       baja y se despuebla al subir, como todo lo demas de esta pagina. */
    .panel .foto--a { animation-range: entry 26% entry 62%; }
    .panel .foto--b { animation-range: entry 34% entry 70%; }
    .panel .foto--c { animation-range: entry 42% entry 78%; }
    .panel .foto--d { animation-range: entry 50% entry 86%; }
    .panel .foto--e { animation-range: entry 58% entry 94%; }
  }
}
@keyframes entrar-lamina {
  from { opacity: 0; translate: 0 3.5rem; scale: 0.94; }
  to   { opacity: 1; translate: 0 0;      scale: 1; }
}
@keyframes entrar-dicho {
  from { opacity: 0; translate: 0 1.6rem; }
  to   { opacity: 1; translate: 0 0; }
}
/* Del punto al disco. El 14 % es lo que importa: la opacidad llega a uno cuando
   el circulo todavia mide un cuarto, asi que lo primero que ve el lector es un
   PUNTO CERULEO, y solo despues crece hasta ser una cara. Si la opacidad
   subiera a la vez que el tamano se leeria como un desvanecido, no como algo
   que brota. El 1,06 del final es el rebote justo antes de asentarse. */
@keyframes brotar-disco {
  0%   { opacity: 0; scale: 0.14; }
  14%  { opacity: 1; scale: 0.24; }
  86%  { opacity: 1; scale: 1.06; }
  100% { opacity: 1; scale: 1; }
}

/* ---- El pórtico --------------------------------------------------------- */

.ruta__portico-caja {
  position: relative;
  z-index: 3;              /* por encima de las fotos sueltas, que son adorno */
  text-align: center;
  max-width: 76rem;
  margin-inline: auto;
}
.panel--portico .acto__declaracion {
  /* Medida en `em` y `text-wrap: wrap`: con `balance` el navegador conservaba
     cuatro líneas hiciera lo que hiciera la medida. Así caen TRES, como el
     Figma: «Una ruta pedagógica / continua desde el preescolar / hasta la
     educación media». */
  width: min(100%, 15.4em);
  max-width: none;
  margin-inline: auto;
  color: #FFF;
  text-wrap: wrap;
}
.panel--portico .acto__apoyo { margin-inline: auto; color: var(--marino-tinte); }

/* Los anillos van ENTEROS dentro del panel: cortados por el borde se leían
   como un error de maquetación, no como una forma. */
.anillo--portico {
  width: clamp(16rem, 26vw, 26rem);
  --grosor-anillo: clamp(1.8rem, 3vw, 3rem);
  left: clamp(var(--e-5), 3vw, var(--e-8));
  top: 50%;
  translate: 0 -50%;
}

/* Las fotos del pórtico son DISCOS, no polaroids. Andrés lo pidió el
   2026-09-08 y el cambio va más allá del gusto: el marco blanco introducía la
   única esquina viva de la página en la sección donde manda el anillo, y dos
   geometrías compitiendo en el mismo plano se leen como dos sistemas.
   En círculo riman con el anillo que se traza, y el conjunto pasa a ser uno.

   DOS ELEMENTOS, no uno, y es a propósito: `translate` no se compone entre dos
   animaciones —la última de la lista gana entera—, así que la entrada por
   scroll vive en la figura y el flotar continuo en el disco de dentro. Juntar
   las dos en el mismo elemento apagaría una de ellas sin avisar. */

.foto-suelta {
  position: absolute;
  z-index: 2;
  margin: 0;
  width: var(--tam, clamp(9rem, 14.5vw, 13.5rem));
}
.foto-suelta__disco {
  display: block;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: clip;
  /* EL FONDO CERULEO NO ES ADORNO: es el circulo que se ve ANTES que la cara.
     Asi entra en la referencia que trajo Andres —cienciaparticipativa.net—: no
     aparece una fotografia, aparece un circulo de color y la cara se resuelve
     dentro. Y de paso arregla algo que estaba mal desde el 08-sep: en el cruce
     del relevo el disco quedaba transparente y se veia un agujero con sombra.
     El aro repite el ceruleo del anillo que se traza detras: mismo sistema. */
  background: var(--ceruleo);
  box-shadow: 0 0 0 var(--hilo-trama) rgba(143, 208, 240, 0.6),
              0 18px 44px rgba(8, 10, 22, 0.45);
}
.foto-suelta img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Cinco, no tres, y en dos tallas. Con tres del mismo tamaño el pórtico se leía
   como una composición fija; con cinco desiguales se lee como un campo. */
.foto--a { top:  7%; right:  8%; }
.foto--b { top: 64%; left:   6%; }
.foto--c { top: 60%; right:  7%; }
.foto--d { top: 11%; left:  13%; --tam: clamp(6.8rem, 10.8vw, 10.2rem); }
.foto--e { top: 82%; left:  44%; --tam: clamp(6.2rem, 9.6vw, 9rem); }

/* ---- El relevo de los discos -------------------------------------------
   Andrés lo pidió el 2026-09-08: que unos se vayan y lleguen otros. El
   2026-09-09 lo corrigió, y la corrección es lo que hay ahora:

     «que no se cambien dentro del mismo círculo, sino que desaparezcan.
      Entran, desaparecen, entran, desaparecen.»

   Antes el disco se quedaba quieto y la FOTOGRAFÍA se fundía dentro de él. Eso
   no es lo mismo: el círculo permanecía y sólo cambiaba su contenido, así que
   se leía como un marco con diapositivas. Ahora desaparece el CÍRCULO ENTERO
   —se encoge hasta un punto y se va— y el siguiente vuelve a brotar desde un
   punto, igual que en la entrada por scroll y que en el arranque del vídeo del
   cabezote. La sección entera dice entonces la misma frase con tres bocas
   distintas.

   Por eso el relevo se mudó de la imagen al disco. Tres elementos, tres
   trabajos, y no se pueden juntar: `translate`, `scale` y `opacity` no se
   componen entre animaciones —la última de la lista gana entera—.

     .foto-suelta        entrada por scroll  (opacity + scale)
     .foto-suelta__disco flotar  (translate)  +  relevo  (opacity + scale)
     .foto-suelta img    nada

   El flotar y el relevo SÍ pueden convivir en el disco porque no se disputan
   ninguna propiedad: uno mueve, el otro escala.

   El relevo empieza y termina EN CERO. Así el cambio de fotografía —que lo hace
   el guion al oír `animationiteration`— cae siempre con el disco ausente. */
@media (prefers-reduced-motion: no-preference) {
  /* Duraciones primas entre sí —11, 13, 9, 15, 12 en el flotar; 13, 17, 15, 19,
     21 en el relevo— para que los cinco no vuelvan a coincidir nunca. Si dos
     desaparecieran a la vez el pórtico parpadearía. */
  .foto--a .foto-suelta__disco { animation: flotar-a 11s ease-in-out infinite,
                                            relevar-disco 13s linear infinite; }
  .foto--b .foto-suelta__disco { animation: flotar-b 13s ease-in-out -3s infinite,
                                            relevar-disco 17s linear -5s infinite; }
  .foto--c .foto-suelta__disco { animation: flotar-c  9s ease-in-out -6s infinite,
                                            relevar-disco 15s linear -11s infinite; }
  .foto--d .foto-suelta__disco { animation: flotar-b 15s ease-in-out -9s infinite,
                                            relevar-disco 19s linear -7s infinite; }
  .foto--e .foto-suelta__disco { animation: flotar-a 12s ease-in-out -4s infinite,
                                            relevar-disco 21s linear -16s infinite; }
}
/* Amplitud casi doble que la anterior —antes 1rem, ahora hasta 2,2rem— y con
   deriva horizontal: subir y bajar en vertical pura se lee como un `hover`
   atascado, no como flotar. */
@keyframes flotar-a {
  0%, 100% { translate: 0 0; }
  33%      { translate:  1.1rem -1.6rem; }
  66%      { translate: -0.6rem -2.2rem; }
}
@keyframes flotar-b {
  0%, 100% { translate: 0 0; }
  33%      { translate: -1.3rem -1.1rem; }
  66%      { translate:  0.5rem -2rem; }
}
@keyframes flotar-c {
  0%, 100% { translate: 0 0; }
  33%      { translate:  0.9rem -2.1rem; }
  66%      { translate: -1rem   -0.9rem; }
}
/* Entra como un punto que crece y se va como un punto que se apaga. El 4 % es
   el mismo truco que en `brotar-disco`: la opacidad llega a uno cuando el
   círculo todavía mide una sexta parte, así que lo primero que aparece es un
   PUNTO CERULEO y sólo después una cara. El 1,04 del 15 % es el rebote.
   En la salida el orden se invierte: primero encoge, y sólo al final se apaga.
   Si se apagara antes de encoger se leería como un fundido, no como un círculo
   que se va. */
@keyframes relevar-disco {
  0%   { opacity: 0; scale: 0.06; }
  4%   { opacity: 1; scale: 0.17; }
  15%  { opacity: 1; scale: 1.04; }
  19%  { opacity: 1; scale: 1; }
  84%  { opacity: 1; scale: 1; }
  96%  { opacity: 1; scale: 0.18; }
  100% { opacity: 0; scale: 0.06; }
}

/* ---- La composición de cada etapa -------------------------------------- */

.etapa__fila {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(var(--e-6), 5vw, var(--e-9));
  align-items: center;
}
.panel--derecha .etapa__dicho { grid-column: 2; grid-row: 1; }
.panel--derecha .etapa__visto { grid-column: 1; grid-row: 1; }

.etapa__nombre {
  font-family: var(--fuente-titular); font-weight: var(--peso-titular);
  /* Baja a display-2 el 2026-09-10: era el titular más grande del sitio, por
     encima del H1 de la portada, y Andrés lo vio antes que nadie. Es un H2. */
  font-size: var(--display-2); line-height: 0.94;
  letter-spacing: var(--tracking-display); color: var(--marino);
  text-decoration: none; display: block;
}
.etapa__nombre:hover { color: var(--ceruleo-hondo); }

/* EL AVAL DEL SENA. Sólo lo lleva Media, que es la única etapa donde existe la
   articulación. Va en el mismo renglón el logotipo y el convenio a propósito:
   una marca institucional sin su número se lee como decoración, y esta web
   tiene la regla de que toda afirmación comprobable sale con su documento.
   El sello va en la versión marino porque esta etapa cae en campo claro. */
.etapa__aval {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  margin: var(--e-6) 0 0;
  padding-top: var(--e-5);
  border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.18);
  max-width: 34ch;
}
.etapa__aval .sello {
  flex: none;
  width: auto;
  height: clamp(2.2rem, 3.4vw, 2.9rem);
  opacity: 0.9;
}
.etapa__aval-dicho {
  display: grid;
  gap: var(--e-1);
  font-size: var(--t-sm);
  line-height: 1.32;
  color: var(--tinta-suave);
}
.etapa__aval-codigo { color: var(--ceruleo-hondo); font-weight: 400; }
.etapa__texto {
  margin: var(--e-5) 0 0; font-size: var(--t-base);
  line-height: var(--interlinea-lead); color: var(--tinta-suave); max-width: 34ch;
}
.etapa__grados {
  display: flex; flex-wrap: wrap; gap: var(--e-2);
  list-style: none; margin: var(--e-6) 0 0; padding: 0;
}
.etapa__grados li {
  font-family: var(--fuente-codigo); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: var(--tracking-codigo); text-transform: uppercase;
  color: var(--marino); padding: var(--e-2) var(--e-3);
  border: var(--hilo-fino) solid rgba(42, 46, 104, 0.35);
}
.etapa__jornada {
  margin: var(--e-4) 0 0; font-family: var(--fuente-codigo);
  font-size: var(--t-xs); letter-spacing: var(--tracking-codigo);
  color: var(--tinta-suave);
}

.etapa__visto {
  position: relative; display: grid; place-items: center;
  min-height: clamp(22rem, 37vw, 34rem); isolation: isolate;
}
.anillo--etapa {
  width: clamp(21rem, 36vw, 34rem);
  --grosor-anillo: clamp(2rem, 3.4vw, 3.4rem);
  top: 50%; left: 50%; translate: -50% -50%;
}
/* EL DESPLAZAMIENTO NO ES SIMÉTRICO, y tiene que serlo así. La fila es
   5fr / 6fr, y al invertirla el anillo cambia de columna: en `izquierda` vive en
   la ANCHA y en `derecha` en la ESTRECHA. Con el 38/62 de antes eso dejaba
   40 px de aire en un lado y DOS en el otro —medido a 1440—, que es lo que
   Andrés vio el 2026-09-09 en Primaria y en Media y Futuro: el anillo tocando
   el titular.

   Los dos números de abajo no son un 38/62 corregido a ojo: salen de exigirle a
   los dos lados el MISMO hueco de unos 60 px entre el borde del anillo y la
   columna de texto. Por eso uno se movió cuatro puntos y el otro once.

   Si algún día cambian las proporciones de la fila, el tamaño del anillo o el
   canal, estos dos números hay que volver a sacarlos midiendo, no ajustarlos
   hasta que «se vea bien»: el hueco es lo que se conserva, no el porcentaje. */
.panel--izquierda .anillo--etapa { left: 42%; }
.panel--derecha   .anillo--etapa { left: 51%; }

/* LA LÁMINA ES UN DISCO. Andrés lo pidió el 2026-09-08 y no es un capricho del
   cliente: en esta sección manda el anillo que se traza, y una fotografía
   rectangular metida dentro de un anillo pone dos geometrías a competir en el
   mismo plano. En círculo, foto y anillo son la misma figura a dos tamaños —uno
   lleno, otro hueco— y la etapa se lee como una sola pieza.
   Crece respecto al rectángulo (de 23rem a 27rem de lado máximo) porque un
   círculo pierde por recorte las cuatro esquinas: a igual medida se veía menor. */
.etapa__lamina {
  position: relative; z-index: 2; margin: 0;
  width: clamp(14rem, 27vw, 27rem);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: clip;
  box-shadow: 0 26px 60px rgba(8, 10, 22, 0.28);
}
.panel--izquierda .etapa__lamina { justify-self: end; }
.panel--derecha   .etapa__lamina { justify-self: start; }
/* `object-position` al 40 %, no al centro: las fotos que trajo Andrés el
   2026-09-08 son dos verticales y dos apaisadas, y un recorte centrado le comía
   la frente a los de las apaisadas. Al 40 % las caras quedan dentro en las
   cuatro. */
.etapa__lamina img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 40%;
  display: block;
}

/* ---- Móvil: sin apilado, sin reposo, sin retroceso --------------------- */

@media (max-width: 52rem) {
  .ruta-telar { background: var(--campo-cielo); }
  .panel,
  .panel + .panel { min-height: auto; margin-top: 0; }
  .panel__pantalla {
    position: relative; top: auto; height: auto;
    min-height: auto; padding-block: var(--e-8);
    animation: none; opacity: 1; transform: none; box-shadow: none;
  }
  .panel--portico .panel__pantalla { min-height: 80svh; }
  .etapa__fila { grid-template-columns: 1fr; gap: var(--e-7); }
  .panel--derecha .etapa__dicho,
  .panel--derecha .etapa__visto { grid-column: 1; grid-row: auto; }
  .etapa__lamina { justify-self: center !important; }
  .panel--izquierda .anillo--etapa,
  .panel--derecha .anillo--etapa { left: 50%; }
  .anillo--portico { width: 16rem; left: -6rem; }
  /* Dos discos, no cinco: en una pantalla de teléfono los otros tres caerían
     encima del titular. Los que quedan son los de las esquinas opuestas, que es
     lo que sostiene la diagonal. */
  /* En el telefono sólo quedan dos, y por eso son más grandes que antes —7,5rem
     frente a 6,5—: desde el 2026-09-09 lo que hay dentro es una CARA, y una
     cara de 104 px al lado de un titular de 40 px no se lee, se adivina. */
  .foto--a { --tam: 7.5rem; top: 4%; right: 4%; }
  .foto--b { --tam: 7.5rem; top: 72%; left: 3%; }
  .foto--c, .foto--d, .foto--e { display: none; }
}

/* ---- Lienzo de etapa: la fotografía entra en la retícula, no la rompe ----
   Sin esquinas redondeadas y con un hilo de trama en el borde superior: la
   imagen es una hilada más del tejido, no una tarjeta pegada encima.        */

.etapa__lienzo {
  margin: var(--e-6) 0 0;
  border-top: var(--hilo-trama) solid var(--ceruleo);
  overflow: hidden;
}
.etapa__lienzo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
  filter: saturate(0.92) contrast(1.02);
}

/* ---- Ranura fotográfica --------------------------------------------------
   Marcada, medida y vacía a propósito. No hay fotografía utilizable del
   colegio: las imágenes del sitio heredado son generadas por IA, clip-art o
   incumplen la norma de privacidad de menores. Cuando llegue material real,
   entra aquí sin rehacer nada.                                              */

.ranura {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--lana-honda);
  border: var(--hilo-fino) dashed var(--marino);
  display: grid;
  place-content: center;
  text-align: center;
  padding: var(--e-5);
}
.acto--marino .ranura { background: rgba(255,255,255,0.06); border-color: var(--marino-tinte); }

.ranura__nota {
  font-family: var(--fuente-codigo);
  font-size: var(--t-xs);
  letter-spacing: var(--tracking-codigo);
  text-transform: uppercase;
  color: var(--marino);
  max-width: 26ch;
}
.acto--marino .ranura__nota { color: var(--marino-tinte); }

/* ---- Cierre -------------------------------------------------------------- */

.cierre__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-4);
  margin-top: var(--e-7);
}

/* ==========================================================================
   Los tres actos que faltaban: la promesa, la identidad y la invitación.
   Con ellos la web cuenta la misma historia que el video, a otra velocidad.
   ========================================================================== */

/* ---- La promesa: las dos palabras SON los dos hilos --------------------- */

.promesa__frase {
  max-width: 20ch;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.8rem, 4.4vw, 3.6rem);
  /* Interlinea holgada A PROPOSITO: los hilos van bajo cada palabra y con
     interlinea cerrada chocaban contra la linea siguiente. */
  line-height: 1.28;
  letter-spacing: var(--tracking-titular);
  color: #FFF;
  max-width: 22ch;
  margin: 0;
  text-wrap: balance;
}

/* Cada palabra lleva su hilo debajo, con el color que le corresponde en el
   tejido. No es subrayado decorativo: es la urdimbre y la trama nombradas. */
.hilo {
  font-weight: var(--peso-enfasis);
  position: relative;
  white-space: nowrap;
}
.hilo::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -0.06em;
  height: 0.07em;
  transform-origin: left center;
}
.hilo--urdimbre::after { background: var(--marino-tinte); }
.hilo--trama::after    { background: var(--ceruleo); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hilo::after {
      animation: tejer var(--dur-larga) var(--sale) both;
      animation-timeline: view();
      animation-range: entry 15% entry 75%;
    }
  }
}


/* ---- El proyector: el video se ve entero, no como textura --------------- */

.proyector {
  margin: var(--e-8) 0 0;
  border-top: var(--hilo-orillo) solid var(--ceruleo);
  background: var(--marino-hondo);
}
.proyector video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* ---- La invitación: el único acto centrado -------------------------------
   Andrés lo pidió centrado el 2026-09-07, y es la decisión correcta por una
   razón que conviene no perder: TODA la Home está alineada a la izquierda. El
   eje central aparece una sola vez, aquí, en el momento de decidir. Si otra
   sección se centra, ésta deja de significar algo.                          */

.conoce__caja { text-align: center; }

/* `max-width: none` porque en base.css todo `<p>` lleva la medida de lectura, y
   una caja de 68ch alineada al margen no se centra por mucho `text-align:
   center` que tenga el padre: se centra su TEXTO dentro de una caja que sigue
   pegada a la izquierda. Es el mismo tropiezo que ya costó una ronda en el
   antetítulo de «Indicadores», y lo mismo pasará con el siguiente `<p>` corto
   que alguien quiera centrar. */
.conoce__antetitulo { max-width: none; margin: 0 0 var(--e-5); }

/* ---- El cierre: campo claro, y sin montarse encima ---------------------
   DOS CAMBIOS DEL 2026-09-10, los dos pedidos por el cliente a través de
   Andrés, y los dos son la misma corrección vista desde dos lados.

   1 · FUERA LA SUPERPOSICIÓN. La había puesto Andrés el 2026-09-09 —«que tenga
   continuidad con lo que hemos estado animando»— y no funcionaba: «hay un
   salto, no se nota la animación». El diagnóstico es el que ya insinuaba el
   comentario que había aquí: el gesto pedía que se VIERA el canto de la
   sección que sube, y para eso hacía falta un filete de trama y una sombra
   fuerte, porque marino subiendo sobre marino no se lee como superposición.
   O sea que el efecto sólo existía gracias a los parches que lo hacían
   visible. Un gesto que hay que subrayar para que se note no es un gesto.
   El apilado de verdad ya está en la ruta pedagógica de arriba y en Admisiones,
   donde cada panel ocupa una pantalla entera y hay recorrido de sobra para que
   se lea. Aquí eran 14svh: demasiado poco para leerse, suficiente para dar el
   salto que el cliente notó.

   2 · Y CAMPO CLARO. Venía marino, después de un tablón marino y antes de un
   pie marino: tres franjas oscuras seguidas. En claro, el último acto —el de
   decidir— se separa del pie en vez de fundirse con él, y el eje central que
   ya tenía por ser el único acto centrado pasa a leerse de verdad.
   Es cielo y no lana para rimar con la promesa, que es el otro momento claro
   y centrado de la portada.                                                 */
.conoce { position: relative; z-index: 2; }
.conoce .urdimbre { --color-urdimbre: rgba(42, 46, 104, 0.08); }
.conoce__antetitulo { color: var(--ceruleo-hondo); }
.conoce .conoce__entrada { color: var(--tinta-suave); }
/* Los dos datos, sobre claro. Van acotados a `.conoce` porque `.dato__*` lo
   comparte el cierre de Admisiones, que sigue siendo marino. */
.conoce .conoce__datos { border-top-color: rgba(42, 46, 104, 0.22); }
.conoce .dato__rotulo { color: var(--tinta-suave); }
.conoce .dato__valor a { color: var(--marino); }
.conoce .dato__valor a:hover { color: var(--ceruleo-hondo); }
.conoce .dato__coda { color: var(--ceruleo-hondo); border-bottom-color: rgba(0, 100, 143, 0.45); }
.conoce .dato__valor a:hover .dato__coda { color: var(--marino); border-bottom-color: var(--marino); }

.conoce .acto__declaracion {
  color: var(--marino);
  /* Ancho por em, no por `ch`: así el punto de corte sigue al tamaño de letra
     y el titular se queda en un renglón mientras quepa. */
  width: min(100%, 16.5em);
  max-width: none;
  margin-inline: auto;
}

.conoce__entrada {
  margin: var(--e-6) auto 0;
  max-width: 44ch;
  font-size: var(--t-md);
  line-height: var(--interlinea-lead);
  color: var(--marino-tinte);
  text-wrap: balance;
}

.conoce .cierre__acciones {
  justify-content: center;
  margin-top: clamp(var(--e-7), 5vw, var(--e-8));
}

/* ---- Los dos datos ------------------------------------------------------
   Antes eran dos renglones sueltos a la izquierda bajo un filete de lado a
   lado. Ahora son dos columnas centradas, con un filete corto que sólo mide lo
   que miden ellas, y las dos SE PUEDEN PULSAR: el teléfono marca, la dirección
   abre el mapa. En un teléfono eso es la diferencia entre un dato y una
   acción.                                                                    */

.conoce__datos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  justify-content: center;
  gap: var(--e-5) clamp(var(--e-7), 7vw, var(--e-10));
  width: fit-content;
  margin: clamp(var(--e-8), 6vw, var(--e-9)) auto 0;
  padding-top: var(--e-6);
  border-top: var(--hilo-fino) solid rgba(255, 255, 255, 0.24);
}

.dato__rotulo { color: var(--marino-tinte); margin-bottom: var(--e-3); }

.dato__valor { margin: 0; }
.dato__valor a {
  display: inline-grid;
  gap: var(--e-2);
  justify-items: center;
  color: #FFF;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-md);
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.dato__valor a:hover { color: var(--ceruleo-claro); }

/* La coda es la acción, no un dato: no dice a qué hora atienden —eso no lo
   sabemos— sino qué pasa al pulsar. */
.dato__coda {
  font-family: var(--fuente-codigo);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-codigo);
  text-transform: uppercase;
  color: #8FD0F0;
  padding-bottom: 2px;
  border-bottom: var(--hilo-fino) solid rgba(143, 208, 240, 0.5);
}
.dato__valor a:hover .dato__coda { color: #FFF; border-bottom-color: #FFF; }

/* ---- Las entidades --------------------------------------------------------
   Debajo de los dos datos, con su propio filete —el mismo corto de
   `.conoce__datos`— para que se lean como un tercer escalón y no como parte de
   la dirección. La razón de cada decisión está junto al marcado, en
   `inicio.html`. */
.conoce__entidades {
  margin: clamp(var(--e-8), 6vw, var(--e-9)) auto 0;
  padding-top: var(--e-6);
  border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.22);
  max-width: 60rem;
}
.conoce__entidades-rotulo {
  max-width: none;
  margin: 0 0 var(--e-6);
  color: var(--tinta-suave);
}
.entidades {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--e-6) clamp(var(--e-6), 4vw, var(--e-8));
  margin: 0;
  padding: 0;
  list-style: none;
}
.entidades li { display: flex; align-items: center; }
.entidades img {
  display: block;
  height: var(--alto, 2.5rem);
  width: auto;
  /* Un punto por debajo del marino pleno: a tinta completa cinco logotipos
     pesan más que el titular que tienen encima. */
  opacity: 0.86;
}

@media (max-width: 38rem) {
  .entidades { gap: var(--e-5) var(--e-6); }
  .entidades img { height: calc(var(--alto, 2.5rem) * 0.82); }
}

@media (max-width: 38rem) {
  .conoce__datos { grid-template-columns: 1fr; }
  .conoce .cierre__acciones { flex-direction: column; align-items: stretch; }
  .conoce .cierre__acciones .boton { justify-content: center; }
}

