/* ==========================================================================
   CMCS — Portada en dos tiempos sobre un mismo plano
   --------------------------------------------------------------------------
   El video ocupa la pantalla desde el primer fotograma. No hay fotografía
   detrás ni recuadro que se abra: lo que se mueve es el TEXTO.

     1º tiempo   Titular, entrada y las dos acciones, centrados sobre el video.
     tránsito    Al bajar, ese bloque sube y se retira COMPLETO.
     respiro     Sólo el video, sin una palabra encima.
     2º tiempo   Entra la frase de identidad; un instante después vuelven las
                 acciones, enfrentadas a ella por el inferior derecho.

   Ese desfase entre frase y botones es el efecto: el usuario ve que su propio
   desplazamiento construye la escena, y el video no se detiene nunca.

   `scroll-timeline` + `opacity`/`transform`: cero librerías, cero JavaScript
   para el efecto, cero reflujo — el CLS queda intacto.

   Estado por defecto = TODO VISIBLE. Sin soporte de scroll-driven o con
   `prefers-reduced-motion`, los dos bloques están quietos y no falta nada.
   ========================================================================== */

.expansion {
  position: relative;
  height: 340svh;                 /* recorrido que dura la secuencia */
  background: var(--campo-marino);
}

.expansion__fijo {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: clip;
  isolation: isolate;
}

/* ---- Fotografía: ya NO se ve en escritorio -------------------------------
   El video manda desde el fotograma cero. La foto se queda como red de
   seguridad: es lo que sostiene la portada en móvil, donde no se descarga el
   video, y mientras el primer fotograma no ha pintado.                      */

.expansion__fondo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  z-index: 0;
  filter: saturate(0.72) contrast(1.05) brightness(0.78);
}

/* ---- El video ------------------------------------------------------------ */

.expansion__marco {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.expansion__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---- Los dos velos -------------------------------------------------------
   Cada tiempo tiene el suyo, y se relevan. El alto acompaña al titular arriba
   y se retira cuando el titular se va; el bajo entra cuando llega la frase de
   identidad. Así el video se ve limpio en el respiro del medio y el texto
   nunca pierde contraste medible.                                           */

.expansion__fijo::before,
.expansion__fijo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.expansion__fijo::before {          /* velo del 1º tiempo: arriba */
  z-index: 2;
  background: radial-gradient(126% 82% at 50% 26%,
    rgba(8,10,22,0.84) 0%,
    rgba(8,10,22,0.68) 32%,
    rgba(8,10,22,0.30) 60%,
    rgba(8,10,22,0.00) 84%);
}

.expansion__fijo::after {           /* velo del 2º tiempo: abajo */
  z-index: 2;
  opacity: 0;
  background: linear-gradient(to top,
    rgba(8,10,22,0.88) 0%,
    rgba(8,10,22,0.66) 26%,
    rgba(8,10,22,0.28) 52%,
    rgba(8,10,22,0.00) 76%);
}

/* ---- 1º tiempo: titular, entrada y acciones ----------------------------- */

.expansion__titular {
  position: relative;
  z-index: 4;
  height: 100%;
  display: grid;
  align-content: start;
  justify-items: center;
  text-align: center;
  gap: var(--e-5);
  padding: clamp(var(--e-7), 11vh, var(--e-9)) var(--canal) var(--e-7);
  /* 74rem, y es la SEGUNDA vez que hay que ensanchar esto por lo mismo, asi que
     conviene dejar dicha la regla y no solo el numero: el titular tiene que
     caber en DOS lineas -- "Formacion academica" / "y desarrollo humano" -- y
     "Formacion academica" mide 10,43 em. La columna util es
     `max-width - 2 x --canal`, o sea 1.072 px a 74rem, contra los 1.035 que
     pide la primera linea. Si el titular crece otra vez, esta cuenta se rehace:
     ancho minimo = 10,43 x tamano + 2 x canal.
       62rem  ->  880 px de columna  ->  tres lineas
       70rem  -> 1.008 px            ->  dos, hasta que el H1 subio a 6,2rem
       74rem  -> 1.072 px            ->  dos                                  */
  max-width: 74rem;
  margin-inline: auto;
}
/* La portada sube por debajo de la cabecera (`--tope`, definido en home.css a
   partir de 68 rem), asi que el texto tiene que bajar lo mismo para no chocar
   con la navegacion. Va DESPUES del atajo `padding` de arriba a proposito:
   home.css se carga antes que este archivo y el atajo lo pisaria. */
.expansion__titular {
  padding-top: calc(var(--tope, 0px) + clamp(var(--e-6), 7vh, var(--e-8)));
}

.expansion__antetitulo {
  font-family: var(--fuente-titular);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-codigo);
  text-transform: uppercase;
  color: #B9C6E8;
  margin: 0;
}

.expansion__h1 {
  /* El H1 de la portada: el titular MAYOR del sitio, y el único display-1.
     Subió el 2026-09-10 al tamaño que tenían los nombres de etapa, que es el
     que Andrés señaló como el bueno. */
  font-size: var(--display-1);
  line-height: 0.94;
  letter-spacing: var(--tracking-display);
  color: #FFF;
  /* Medida en `em`, no en `ch`: acompana al tamano de fuente y el corte cae
     siempre en el mismo sitio -- "Formacion academica" / "y desarrollo humano".
     Con `balance` el navegador partia el titular en TRES lineas aunque las dos
     cupieran, asi que aqui el ajuste es explicito. */
  /* `width` explicito, no solo `max-width`: el titular es un item de rejilla
     con `justify-items: center`, asi que se dimensiona a fit-content y la caja
     salia mas estrecha que su propio maximo -- por eso partia en tres lineas. */
  width: min(100%, 11.1em);
  max-width: 11.1em;
  text-wrap: wrap;   /* `normal` NO es valor valido de text-wrap: se descarta */
  margin: 0;
  text-shadow: 0 2px 28px rgba(8,10,22,0.55);
}

/* EL TITULAR APROBADO, A SU TALLA (2026-09-15). Manuel pidió de vuelta el texto
   de PGC-001 —nueve palabras, «Formación académica de calidad y desarrollo
   humano en Soacha»— y que se adapte el tratamiento, no el texto. A display-1 y
   con la medida de 11,1em que se calculó para cinco palabras, salían cinco
   renglones y el video dejaba de verse. Baja a la escala de display-2 y la
   medida se abre a 16em: tres renglones que dejan respirar la imagen. Sigue
   siendo el titular mayor del sitio por sitio y por peso, sobre el video. */
.expansion__h1.expansion__h1--aprobado {
  font-size: clamp(2.2rem, 5vw, 4.4rem);
  line-height: 0.98;
  width: min(100%, 16em);
  max-width: 16em;
}

.expansion__entrada {
  font-size: clamp(1rem, 1.25vw, 1.2rem);
  line-height: 1.5;
  color: #DDE3F5;
  /* 58ch desde el 2026-09-15: la entrada aprobada son 240 caracteres, y a 46ch
     eran seis renglones sobre el video. */
  max-width: 58ch;
  margin: 0;
  text-shadow: 0 1px 16px rgba(8,10,22,0.6);
}

.expansion__acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e-4);
  margin-top: var(--e-3);
}

/* ---- La pista de scroll --------------------------------------------------
   Fuera del titular, porque el titular se va y ella tiene que sobrevivirlo:
   debajo hay mucha web y el usuario tiene que saber que sigue bajando. Sólo
   se retira cuando entra el segundo tiempo, que ya es señal suficiente.     */

.expansion__pista {
  position: absolute;
  left: 0; right: 0;
  bottom: var(--e-6);
  z-index: 5;
  margin: 0;
  /* `p` lleva `max-width: var(--medida-lectura)` de base.css y eso dejaba la
     pista pegada a la izquierda en vez de centrada. */
  max-width: none;
  display: grid;
  justify-items: center;
  gap: var(--e-2);
  font-family: var(--fuente-titular);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-codigo);
  text-transform: uppercase;
  color: #FFF;
  text-shadow: 0 1px 14px rgba(8,10,22,0.7);
  pointer-events: none;
}
.expansion__pista svg { width: 1.5rem; height: 1.5rem; }
@media (prefers-reduced-motion: no-preference) {
  .expansion__pista svg { animation: bajar-flecha 1.9s var(--sale) infinite; }
}
@keyframes bajar-flecha {
  0%, 100% { transform: translateY(0); opacity: .75; }
  50%      { transform: translateY(7px); opacity: 1; }
}

/* ---- 2º tiempo: la identidad y, después, las acciones ------------------- */

.expansion__remate {
  position: absolute;
  left: 0; right: 0;
  /* Alto de sobra respecto al borde: abajo a la izquierda vive el control de
     pausa del video y no debe leerse como un tercer boton del bloque. */
  bottom: clamp(var(--e-8), 15vh, var(--e-10));
  z-index: 5;
}

.expansion__remate-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--e-6) var(--e-8);
}

/* 24rem parte "Ser Cervantista" en dos lineas a proposito -- rima con las dos
   del titular de arriba y gana presencia -- y deja la linea de apoyo entera. */
.remate__frase { margin: 0; max-width: 24rem; }
.remate__frase b {
  display: block;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(2rem, 5.2vw, 4.2rem);
  letter-spacing: var(--tracking-display);
  line-height: 0.96;
  color: #FFF;
  text-shadow: 0 2px 30px rgba(8,10,22,0.7);
}
.remate__frase span {
  display: block;
  margin-top: var(--e-3);
  font-family: var(--fuente-titular);
  font-size: var(--t-xs);
  font-weight: var(--peso-titular);
  letter-spacing: var(--tracking-codigo);
  text-transform: uppercase;
  color: #CFE0F5;
  text-shadow: 0 1px 14px rgba(8,10,22,0.8);
}

/* Enfrentadas a la frase, por el inferior derecho. En columna: la primaria
   arriba, la secundaria debajo, y las dos alineadas a la derecha para que el
   ojo cierre el bloque contra el mismo borde. */
.remate__acciones {
  display: grid;
  justify-items: end;
  gap: var(--e-2);
}

/* ==========================================================================
   EL MOVIMIENTO
   --------------------------------------------------------------------------
   La portada es el PRIMER elemento del documento, así que una línea de tiempo
   `view()` nace ya avanzada y los bloques aparecerían a medio camino. Se atan
   al scroll de la página. El rango del primer bloque arranca en `0%`: si
   arrancara después, en scroll cero la animación queda en fase previa, el
   navegador no aplica el estado inicial y el bloque nace equivocado.

   `visibility` se apaga en el último tramo de cada salida y se enciende en el
   primero de cada entrada: un bloque invisible no debe recibir el foco del
   teclado, y hay dos juegos de acciones con el mismo destino.
   ========================================================================== */

@supports (animation-timeline: scroll(root block)) {
  @media (prefers-reduced-motion: no-preference) {

    /* 1º tiempo — sale entero: titular, entrada y botones juntos. */
    .expansion__titular {
      animation: ceder linear both;
      animation-timeline: scroll(root block);
      animation-range: 0% 85svh;
    }

    /* El velo alto se va con el texto al que servía. */
    .expansion__fijo::before {
      animation: ceder-velo linear both;
      animation-timeline: scroll(root block);
      animation-range: 12svh 90svh;
    }

    /* La flecha aguanta el respiro y se retira al llegar el segundo tiempo. */
    .expansion__pista {
      animation: ceder-pista linear both;
      animation-timeline: scroll(root block);
      animation-range: 95svh 125svh;
    }

    /* El velo bajo se adelanta a la frase para recibirla. */
    .expansion__fijo::after {
      animation: entrar-velo linear both;
      animation-timeline: scroll(root block);
      animation-range: 100svh 148svh;
    }

    /* 2º tiempo — primero la frase... */
    .remate__frase {
      animation: entrar-remate linear both;
      animation-timeline: scroll(root block);
      animation-range: 108svh 162svh;
    }

    /* ...y DESPUÉS los botones. El desfase es el efecto, no un descuido.
       Terminan en 196svh y el recorrido pegajoso dura 240svh: quedan 44svh de
       pausa con la escena completa antes de que la portada suelte. */
    .remate__acciones {
      animation: entrar-acciones linear both;
      animation-timeline: scroll(root block);
      animation-range: 145svh 196svh;
    }

  }
}

@keyframes ceder {
  0%   { opacity: 1; transform: none; visibility: visible; }
  99%  { visibility: visible; }
  100% { opacity: 0; transform: translateY(-4rem); visibility: hidden; }
}

@keyframes ceder-pista {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes ceder-velo {
  from { opacity: 1; }
  to   { opacity: 0.12; }
}

@keyframes entrar-velo {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes entrar-remate {
  0%   { opacity: 0; transform: translateY(2.5rem); visibility: hidden; }
  1%   { visibility: visible; }
  62%  { opacity: 1; transform: none; }
  100% { opacity: 1; transform: none; }
}

@keyframes entrar-acciones {
  0%   { opacity: 0; transform: translateY(1.6rem); visibility: hidden; }
  1%   { visibility: visible; }
  70%  { opacity: 1; transform: none; }
  100% { opacity: 1; transform: none; }
}

/* ---- Sin scroll-driven, o con movimiento reducido -----------------------
   Los dos bloques conviven quietos y completos. Nunca se pierde contenido. */

@supports not (animation-timeline: scroll(root block)) {
  .expansion { height: auto; }
  .expansion__fijo { position: static; height: auto; min-height: auto; }
  .expansion__titular { padding-block: var(--e-9) var(--e-8); }
  /* El remate deja de estar anclado al fondo de la pantalla: si no, se montaria
     encima del titular en cuanto el contenedor deja de ser pegajoso. */
  .expansion__remate { position: static; padding-bottom: var(--e-9); }
  .expansion__fijo::after { opacity: 0.9; }
}
/* Con movimiento reducido no hay nada que animar, asi que un recorrido de
   340svh serian tres pantallas de scroll sin que pase nada. La portada se
   encoge y los dos bloques se leen uno detras de otro. */
@media (prefers-reduced-motion: reduce) {
  .expansion { height: auto; margin-top: 0; }
  .expansion__fijo { position: static; height: auto; min-height: auto; }
  .expansion__titular { padding-block: var(--e-9) var(--e-8); }
  .expansion__pista { display: none; }
  .expansion__remate { position: static; padding-bottom: var(--e-9); }
  .expansion__fijo::after { opacity: 0.9; }
}

/* ---- Móvil: sin video y sin recorrido largo -----------------------------
   El encuadre del video es horizontal y el ancho de banda es caro. Queda la
   fotografía, y los dos bloques se leen uno detrás de otro, en orden.       */

@media (max-width: 48rem) {
  .expansion { height: auto; }
  .expansion__fijo { position: static; height: auto; min-height: auto; }
  .expansion__marco { display: none; }
  .expansion__pista { display: none; }

  .expansion__titular { padding-block: var(--e-9) var(--e-8); }
  /* En columna estrecha el reparto codicioso deja "humano" solo en su linea. */
  .expansion__h1 { max-width: none; text-wrap: balance; }

  /* Los dos velos conviven sobre la misma fotografia: juntos oscurecen mas de
     la cuenta, asi que cada uno cede un poco. */
  .expansion__fijo::before { opacity: 0.86; }
  .expansion__fijo::after  { opacity: 0.72; }

  .expansion__remate {
    position: static;
    padding-bottom: var(--e-9);
  }
  .expansion__remate-fila {
    grid-template-columns: 1fr;
    justify-items: start;
  }
  .remate__acciones { justify-items: start; }

  /* NADA de animaciones por scroll en movil: la portada aqui no es pegajosa ni
     dura tres pantallas, asi que los rangos en svh no se cumplirian nunca y los
     bloques se quedaban invisibles. Todo quieto y a la vista. */
  .expansion__titular,
  .expansion__pista,
  .remate__frase,
  .remate__acciones,
  .expansion__fijo::before,
  .expansion__fijo::after { animation: none; }
  .expansion__titular,
  .remate__frase,
  .remate__acciones { opacity: 1; visibility: visible; transform: none; }
}
