/* ==========================================================================
   Coppelius · animaciones
   Catálogo: docs/investigacion/animaciones.md (§3). Motor: Assets/js/animaciones.js
   (GSAP core + IntersectionObserver propio; SplitText solo en la portada).

   API declarativa (en Bricks: pestaña Atributos del elemento):
     data-anim="fade-up | rise | fade | zoom"   el elemento entra solo
     data-anim-stagger="fade-up | rise | fade"  sus hijos directos entran escalonados
     data-anim-step="80"                        ms entre hijos (por defecto 80)
     data-anim-delay="120"                      ms de retraso
     data-anim-duration="700"                   ms (por defecto, los del catálogo)

   MEJORA PROGRESIVA: nada se oculta si <html> no lleva .js-anim. Esa clase la pone
   el snippet del <head> y animaciones.js la retira si no puede animar (sin GSAP,
   movimiento reducido o dentro del builder de Bricks). Sin JS, todo se ve.

   Solo se anima opacity y transform (y en hover, la propiedad individual
   `scale`): ninguna regla de aquí cambia el layout.

   Producción: coppelius-core/assets/css/animaciones.css, encolado por el plugin.
   ========================================================================== */

:root {
  --anim-distance: 24px;
  --anim-distance-lg: 32px;
  --anim-duration: 700ms;                              /* catálogo #1 */
  --anim-ease-out: cubic-bezier(0.22, 1, 0.36, 1);     /* GSAP: power4.out */
  --anim-ease-expo: cubic-bezier(0.19, 1, 0.22, 1);    /* GSAP: expo.out */
  --anim-ken-burns-duration: 7s;                       /* catálogo #3 */
  --anim-ken-burns-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --anim-hover-ease: cubic-bezier(0.4, 0, 0.2, 1);     /* catálogo #5 */
  --anim-page-duration: 250ms;                         /* catálogo #6 */
}

/* --------------------------------------------------------------------------
   1 · Estados iniciales (solo con .js-anim y mientras no se ha animado)
   GSAP parte de aquí y, al terminar, el elemento recibe .is-anim-done y GSAP
   borra sus estilos en línea: el estado final es el del CSS de la página.
   -------------------------------------------------------------------------- */
.js-anim [data-anim]:not(.is-anim-done),
.js-anim [data-anim-stagger] > :not(.is-anim-done) {
  opacity: 0;
}

.js-anim [data-anim="fade-up"]:not(.is-anim-done),
.js-anim [data-anim-stagger=""] > :not(.is-anim-done),
.js-anim [data-anim-stagger="fade-up"] > :not(.is-anim-done) {
  transform: translateY(var(--anim-distance));
}

.js-anim [data-anim="rise"]:not(.is-anim-done),
.js-anim [data-anim-stagger="rise"] > :not(.is-anim-done) {
  transform: translateY(var(--anim-distance-lg));
}

/* Títulos por líneas (data-anim-split, catálogo #2): ocultos hasta que SplitText
   los parte (.is-split). Si el plugin no está, animaciones.js pone .is-split al
   momento; si el JS no llega, el snippet del <head> retira .js-anim a los 4 s. */
.js-anim [data-anim-split]:not(.is-split) {
  opacity: 0;
}

/* «zoom»: solo dentro de un contenedor con overflow:hidden (imágenes de hero,
   portadas), para que el 1,04 no se salga de la caja */
.js-anim [data-anim="zoom"]:not(.is-anim-done) {
  transform: scale(1.04);
}

/* --------------------------------------------------------------------------
   2 · Ken Burns (catálogo #3): CSS puro
   Portada: la diapositiva activa del carrusel (clase que pone main.js).
   Ficha de evento: la imagen del hero, una vez.
   -------------------------------------------------------------------------- */
.hero__slide--active .hero__image,
.event-hero__image {
  animation: anim-ken-burns var(--anim-ken-burns-duration) var(--anim-ken-burns-ease) both;
}

@keyframes anim-ken-burns {
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}

/* --------------------------------------------------------------------------
   3 · Hover editorial (catálogo #5): imagen de tarjeta a 1,03
   Con la propiedad `scale`, que se suma al `transform` que ya tenga la imagen
   (los retratos --from-circle van a scale(1.45)). Su contenedor recorta.
   -------------------------------------------------------------------------- */
@media (hover: hover) {
  .team-card__image {
    transition: scale 600ms var(--anim-hover-ease);
  }

  .team-card:hover .team-card__image {
    scale: 1.03;
  }
}

/* --------------------------------------------------------------------------
   4 · Transición entre páginas (catálogo #6): mejora progresiva, sin JS
   Chrome 126+ y Safari 18.2+; Firefox navega sin transición.
   -------------------------------------------------------------------------- */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--anim-page-duration);
  animation-timing-function: ease;
}

/* --------------------------------------------------------------------------
   5 · Movimiento reducido: todo en su estado final, sin animar
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .js-anim [data-anim],
  .js-anim [data-anim-stagger] > *,
  .js-anim [data-anim-split] {
    opacity: 1 !important;
    transform: none !important;
  }

  .hero__slide--active .hero__image,
  .event-hero__image {
    animation: none;
  }

  .team-card__image {
    transition: none;
  }

  .team-card:hover .team-card__image {
    scale: none;
  }

  @view-transition {
    navigation: none;
  }
}
