/* ============================================================
   EYUB' - movimiento.css
   ------------------------------------------------------------
   El vocabulario de animación del sitio: la entrada del hero,
   las variantes de revelado al hacer scroll y los efectos que
   siguen la posición de la página.

   Tres reglas que se cumplen en todo este archivo:

     1. Nada depende de JavaScript para verse. Si un guion falla,
        el contenido aparece igual; lo que se pierde es el adorno.
     2. Nada anima lo que cuesta caro. Solo `opacity`, `transform`,
        `clip-path` y `filter`: lo que la tarjeta gráfica hace sola.
     3. Todo se apaga con `prefers-reduced-motion`. Quien pidió
        menos movimiento no negocia.
   ============================================================ */


/* ============================================================
   0. EL COMPÁS
   ------------------------------------------------------------
   La escena de entrada espera a que la pantalla de carga se
   aparte. Sin esto, el hero se anima detrás del loader y cuando
   por fin se ve, ya terminó: el trabajo se pierde entero.

   Se resuelve en CSS, no en JavaScript, porque `sin-carga` ya la
   pone la cabecera antes de pintar el primer píxel.
   ============================================================ */

:root {
  /* Con pantalla de carga: 3 s de mínimo + el desvanecido */
  --espera-escena: 3.15s;

  /*
     La curva de la entrada.

     No se reutiliza --ease-out del resto del sitio a propósito: esa
     es una exponencial muy adelantada, que a los 150 ms ya ha
     recorrido el 97 % del camino. Va perfecta para que un botón
     responda al instante, y fatal para un titular que debe
     *subir* — se ve como un salto, no como un movimiento.

     Esta es una cúbica de salida: arranca decidida y se posa.
  */
  --ease-escena: cubic-bezier(.33, 1, .68, 1);
}

/* Al moverse entre páginas del propio sitio no hay loader que esperar */
html.sin-carga { --espera-escena: 0s; }

@media (prefers-reduced-motion: reduce) {
  :root { --espera-escena: 0s; --paso-escena: 0ms; }
}


/* ============================================================
   1. ENTRADA DEL HERO
   ============================================================ */

/* ---------- El titular, línea por línea ----------
   Cada línea vive dentro de una ventana que la recorta, y sube
   desde debajo del borde. Es lo que hace que un titular se sienta
   compuesto en vez de simplemente aparecido. */

.titulo-lineas { overflow: visible; }

/* El nombre importa: `.linea` ya estaba cogido en base.css por un
   filete decorativo de 1 px de alto, y heredarlo aplastaba cada
   renglón del titular contra el suelo. `renglon` es además la
   palabra correcta para una línea de texto. */
.titulo-lineas .renglon {
  display: block;
  /* La ventana recorta por arriba y por abajo, y eso se comería las
     colas de la g, la y y la p. El relleno las devuelve; el margen
     negativo deshace el hueco que ese relleno abriría entre líneas,
     para que la interlínea del titular no cambie.

     0.16em no es un número redondo por gusto: medido en el navegador,
     el texto rebasa la caja de línea un 2,2 % del cuerpo de letra
     (0,9 px con fuente de 38 px; 1,5 px con fuente de 70 px). Con
     0.12em seguía cortando por abajo. */
  overflow: hidden;
  padding-bottom: .16em;
  margin-bottom: -.16em;
}

.titulo-lineas .renglon > span {
  display: block;
  transform: translateY(110%);
  animation: linea-sube 1.15s var(--ease-escena) both;
}

@keyframes linea-sube {
  from { transform: translateY(110%); }
  to   { transform: none; }
}

/* El escalonado entre líneas: cada una arranca con la anterior
   todavía en movimiento, que es lo que las encadena. */
.titulo-lineas .renglon:nth-child(1) > span { animation-delay: calc(var(--espera-escena) + 0.10s); }
.titulo-lineas .renglon:nth-child(2) > span { animation-delay: calc(var(--espera-escena) + 0.24s); }
.titulo-lineas .renglon:nth-child(3) > span { animation-delay: calc(var(--espera-escena) + 0.38s); }
.titulo-lineas .renglon:nth-child(4) > span { animation-delay: calc(var(--espera-escena) + 0.52s); }


/* ---------- El resto de la caja ---------- */

.hero__texto > * {
  opacity: 0;
  animation: subir-hero 1.05s var(--ease-escena) forwards;
}

.hero__estado     { animation-delay: calc(var(--espera-escena) + 0.05s); }
.hero__texto h1    { animation-delay: calc(var(--espera-escena) + 0.10s); }
.hero__texto .lede { animation-delay: calc(var(--espera-escena) + 0.62s); }
.hero__acciones   { animation-delay: calc(var(--espera-escena) + 0.78s); }
.hero__sellos     { animation-delay: calc(var(--espera-escena) + 0.94s); }

/* El titular no debe subir además de sus líneas: solo aparece,
   y el movimiento lo ponen las líneas por dentro. */
.hero__texto h1 { animation-name: aparecer-hero; }

@keyframes aparecer-hero {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes subir-hero {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* Los sellos de confianza entran uno detrás de otro */
.hero__sellos span {
  opacity: 0;
  animation: subir-hero .9s var(--ease-escena) forwards;
}
.hero__sellos span:nth-child(1) { animation-delay: calc(var(--espera-escena) + 0.98s); }
.hero__sellos span:nth-child(2) { animation-delay: calc(var(--espera-escena) + 1.08s); }
.hero__sellos span:nth-child(3) { animation-delay: calc(var(--espera-escena) + 1.18s); }

/* La flecha de bajar llega la última: invita cuando ya se leyó todo,
   y solo entonces empieza a rebotar.

   Aparecer no toca `transform` a propósito. El rebote sí lo usa, y
   dos animaciones peleando por la misma propiedad producen saltos.
   Repartidas —una la opacidad, otra el movimiento— conviven. */
.hero__bajar {
  opacity: 0;
  animation: bajar-aparece .9s var(--ease-escena) forwards,
             rebotar 2.4s var(--ease) infinite;
  animation-delay: calc(var(--espera-escena) + 1.32s),
                   calc(var(--espera-escena) + 2.10s);
}

@keyframes bajar-aparece {
  from { opacity: 0; }
  to   { opacity: .92; }
}


/* ---------- El fondo se asienta ----------
   Un acercamiento que se relaja durante los primeros segundos.
   Muy poco recorrido a propósito: si se nota, está mal hecho.

   Se anima la propiedad `scale`, no `transform`. Es deliberado: el
   paralaje de más abajo usa `translate` sobre este mismo elemento,
   y dos reglas escribiendo `transform` se pisan la una a la otra.
   Como propiedades independientes conviven sin estorbarse.

   En un navegador viejo que no las entienda, sencillamente no hay
   ni asentamiento ni paralaje: el fondo se queda quieto, que es un
   final perfectamente digno. */

.hero__fondo {
  animation: fondo-asienta 3.2s var(--ease-escena) both;
  animation-delay: var(--espera-escena);
}

/* Holgura arriba y abajo. Sin ella, en cuanto el fondo se rezaga
   unos píxeles aparece una franja vacía en el borde del hero. */
.hero__fondo[data-paralaje] {
  top: -9%;
  bottom: -9%;
}

@keyframes fondo-asienta {
  from { scale: 1.06; }
  to   { scale: 1; }
}


/* ---------- La portada de las páginas internas ----------
   Mismo compás que el hero del inicio, más corto: aquí la persona
   ya sabe dónde está y viene a leer, no a impresionarse. */

.portada__contenido > * {
  opacity: 0;
  animation: subir-hero .9s var(--ease-escena) forwards;
}

.portada .migas            { animation-delay: calc(var(--espera-escena) + 0.04s); }
.portada .etiqueta-seccion { animation-delay: calc(var(--espera-escena) + 0.12s); }
.portada__contenido h1     { animation-delay: calc(var(--espera-escena) + 0.20s); }
.portada__contenido .lede  { animation-delay: calc(var(--espera-escena) + 0.32s); }
.portada__acciones         { animation-delay: calc(var(--espera-escena) + 0.44s); }

/* La fotografía entra a la vez que el titular, no después: forma
   parte de la misma imagen mental. */
.portada__foto {
  opacity: 0;
  animation: portada-foto 1.2s var(--ease-escena) forwards;
  animation-delay: calc(var(--espera-escena) + 0.18s);
}

@keyframes portada-foto {
  from { opacity: 0; scale: 1.035; translate: 0 20px; }
  to   { opacity: 1; scale: 1;     translate: none; }
}


/* ============================================================
   2. VARIANTES DE REVELADO AL HACER SCROLL
   ------------------------------------------------------------
   Se suman a `.revelar` de base.css, que es quien pone el estado
   inicial y recibe la clase `.visible` desde principal.js.
   ============================================================ */

/* Todas estas variantes animan `translate`, `scale`, `filter` o
   `clip-path`, nunca `transform`. Ese queda libre para el hover y
   la pulsación; la explicación completa está en base.css. */

/* Emerge desde un desenfoque muy leve: el más suave de todos */
.revelar--flotar {
  opacity: 0;
  translate: 0 34px;
  scale: .985;
  filter: blur(7px);
  transition: opacity 1s var(--ease-escena),
              translate 1s var(--ease-escena),
              scale 1s var(--ease-escena),
              filter .8s var(--ease-escena);
  transition-delay: var(--retraso, 0ms);
}
.revelar--flotar.visible {
  opacity: 1;
  translate: none;
  scale: none;
  filter: none;
}

/* La imagen se descubre como una persiana, de izquierda a derecha */
.revelar--persiana {
  opacity: 1;
  translate: none;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1.15s var(--ease-escena);
  transition-delay: var(--retraso, 0ms);
}
.revelar--persiana.visible { clip-path: inset(0 0 0 0); }

/* Para bloques anchos: crece desde el centro sin moverse de sitio */
.revelar--abrir {
  opacity: 0;
  translate: none;
  scale: .94 1;
  transition: opacity .8s var(--ease-escena), scale .9s var(--ease-escena);
  transition-delay: var(--retraso, 0ms);
}
.revelar--abrir.visible { opacity: 1; scale: none; }


/* ---------- Subrayado que se dibuja ----------
   Para los títulos de sección: la línea se traza cuando el título
   entra, en vez de estar ya ahí. */

.subrayado-anima { position: relative; display: inline-block; }

.subrayado-anima::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -.18em;
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--azul-corporativo), var(--azul-interactivo));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1s var(--ease-escena) .25s;
}

.revelar.visible .subrayado-anima::after,
.subrayado-anima.visible::after { transform: scaleX(1); }


/* ============================================================
   3. EFECTOS QUE SIGUEN AL SCROLL
   ------------------------------------------------------------
   movimiento.js escribe aquí: `--paralaje` en píxeles y
   `--progreso` de 0 a 1 según lo avanzado que esté el elemento
   dentro de la ventana. El CSS decide qué hacer con ellos.
   ============================================================ */

/* El paralaje va en `translate`, no en `transform`, por lo mismo
   que el asentamiento va en `scale`: para que puedan convivir.

   Y se aplica siempre al contenedor, nunca a la imagen: la imagen
   ya lleva su propio `transform` de encuadre y lo perdería. */
[data-paralaje] {
  translate: 0 var(--paralaje, 0px);
  will-change: translate;
}

/* Una barra que se llena conforme se lee la sección */
.progreso-lectura {
  height: 2px;
  border-radius: 999px;
  background: var(--borde);
  overflow: hidden;
}
.progreso-lectura::after {
  content: '';
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--azul-corporativo), var(--azul-interactivo));
  transform: scaleX(var(--progreso, 0));
  transform-origin: left center;
}


/* ============================================================
   4. LA SALIDA DE EMERGENCIA
   ------------------------------------------------------------
   Si JavaScript no llega, `.revelar` se queda invisible para
   siempre. La cabecera ya tiene un <noscript> para eso; esto
   cubre el otro caso: que el guion cargue pero falle a medias.
   ============================================================ */

.revelar--flotar,
.revelar--abrir {
  animation: rescate-revelado 0s linear 8s forwards;
}
.revelar--persiana {
  animation: rescate-persiana 0s linear 8s forwards;
}

@keyframes rescate-revelado {
  to { opacity: 1; translate: none; scale: none; filter: none; }
}
@keyframes rescate-persiana {
  to { clip-path: inset(0 0 0 0); }
}


/* ============================================================
   5. SIN MOVIMIENTO
   ------------------------------------------------------------
   Todo lo de este archivo desaparece. No queda "una versión
   suave": queda el contenido, quieto y completo.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {

  .titulo-lineas .renglon       { overflow: visible; }
  .titulo-lineas .renglon > span,
  .hero__texto > *,
  .hero__sellos span,
  .hero__bajar,
  .hero__fondo,
  .portada__contenido > *,
  .portada__foto {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__bajar { opacity: .92 !important; }

  .revelar--flotar,
  .revelar--abrir,
  .revelar--persiana {
    opacity: 1 !important;
    translate: none !important;
    scale: none !important;
    filter: none !important;
    clip-path: none !important;
    transition: none !important;
    animation: none !important;
  }

  .subrayado-anima::after { transform: scaleX(1); transition: none; }

  [data-paralaje] { translate: none !important; }
  .hero__fondo     { scale: none !important; }
}


/* El filete del marcador no se dibuja si el visitante pidio quieto */
@media (prefers-reduced-motion: reduce) {
  .marcador::after { transform: scaleX(1); transition: none; }
}
