/* Capa `animations`: la declara este mismo archivo. Antes se la asignaba el
   `@import ... layer(animations)` de main.css; ahora cada hoja se encola por
   separado para que descarguen en paralelo. Ver inc/enqueue.php. */
@layer animations {
/* ==========================================
   ANIMACIONES DE ENTRADA (scroll)
   ==========================================

   Sistema principal (una sola vez, vía JS):
   El observer de scripts/animations.js añade .animate--is-animated a los
   elementos .animate--scroll cuando entran en el viewport.

   Uso automático (recomendado): edita la lista AUTO_ANIMATE al inicio de
   scripts/animations.js — "los .card con animate--up, los .icon-txt con
   animate--zoom…" — y se aplica en todas las páginas, con stagger incluido.

   Uso manual puntual desde el JSON del PageBuilder (los componentes aceptan clases):
     "ClaseSeccion": "section animate--scroll animate--up"
     "ClaseTitulo":  "title title--2 animate--scroll animate--zoom"

   Clases combinables con .animate--scroll:
     (sin variante)    fade simple
     .animate--fade    fade simple (alias explícito)
     .animate--up      entra desde abajo
     .animate--down    entra desde arriba
     .animate--left    entra desde la derecha
     .animate--right   entra desde la izquierda
     .animate--zoom    escala desde el 92%
     .animate--blur    entra desenfocado (combinable con up/down/left/right/zoom)
     .animate--slow    transición lenta (1s)
     .animate--fast    transición rápida (0.35s)
     .animate--slower  transición muy lenta (1.6s)
     .animate--delay-1 / -2 / -3   retardo fijo de 0.2s / 0.4s / 0.6s
     .animate--repeat  el efecto se reinicia al salir de pantalla y volver
                       a entrar (por defecto solo anima la primera vez)

   Efectos avanzados (sustituyen al fade, no se combinan entre sí):
     .animate--persiana-left/right/up/down
                       el contenido se desvela con un barrido de recorte
                       (clip-path); la dirección indica hacia dónde avanza
                       el barrido
     .animate--cortina-left/right/up/down
                       una cortina de color (--color-secondary) cubre el
                       elemento y al retirarse descubre el contenido; la
                       dirección indica desde dónde entra la cortina
     .animate--zoom-img
                       la <img> entra con un zoom lento que se asienta
                       (Ken Burns); aplicable al contenedor de la imagen
                       o directamente a la <img>

   Stagger (cards/grids): .animate--stagger en el contenedor aplica un
   retardo incremental a cada hijo. Los hijos deben llevar .animate--scroll.
     "ClaseGaleria": "gallery-light animate--stagger"
   También se puede fijar un retardo puntual inline: style="--animate-delay: .3s"

   Capa opcional ligada al scroll (CSS puro, sin JS):
   Utilidades .sda--* con animation-timeline: view(). Progresan y se
   revierten con el scroll. Solo en navegadores con soporte (@supports);
   en el resto el contenido se muestra normal, sin animación.
     .sda--fade      aparece progresivamente al entrar en el viewport
     .sda--grow      escala suave ligada a la entrada
     .sda--parallax  desplazamiento vertical sutil del elemento entero
     .sda--parallax-img
                     parallax de imagen: aplicar al contenedor que hace de
                     marco de una <img> (p. ej. .sectionImage__img); el marco
                     queda fijo y la imagen se desliza por detrás. Ajustes:
                     --sda-parallax-scale y --sda-parallax-move. En los
                     .sectionImage__img de escritorio la holgura se crea con
                     altura extra (--sda-parallax-shift, 300px) en vez de con
                     scale: la foto no se amplía
   ========================================== */

/* ==========================================
   1. SISTEMA PRINCIPAL (JS, una sola vez)
   ========================================== */
/* La entrada corre con @keyframes (no transiciones): las animaciones ganan
   siempre a las transition de hover de los componentes mientras duran y las
   sueltan al terminar, y quitar la clase (reset del repeat) corta en seco
   sin que se vea el efecto deshaciéndose */
.animate--scroll {
  --animate-duration: 0.6s;
  --animate-distance: 30px;
  opacity: 0;
}

@keyframes animate-in {
  from {
    opacity: 0;
    transform: var(--animate-from, none);
    filter: var(--animate-filter-from, none);
  }
}

/* Variantes de efecto: cada una define su estado inicial vía variable */
.animate--scroll.animate--fade {
  /* alias explícito: el fade es el efecto base de .animate--scroll */
  --animate-from: none;
}

.animate--scroll.animate--up {
  --animate-from: translateY(var(--animate-distance));
}

.animate--scroll.animate--down {
  --animate-from: translateY(calc(var(--animate-distance) * -1));
}

.animate--scroll.animate--left {
  --animate-from: translateX(var(--animate-distance));
}

.animate--scroll.animate--right {
  --animate-from: translateX(calc(var(--animate-distance) * -1));
}

.animate--scroll.animate--zoom {
  --animate-from: scale(0.92);
}

/* Los desplazamientos laterales pueden asomar fuera de la sección:
   se recorta solo el eje X para evitar scroll horizontal */
.section:has(.animate--left, .animate--right) {
  overflow-x: clip;
}

/* Velocidades */
.animate--scroll.animate--slow {
  --animate-duration: 1s;
}

.animate--scroll.animate--fast {
  --animate-duration: 0.35s;
}

.animate--scroll.animate--slower {
  --animate-duration: 1.6s;
}

/* Retardos fijos (para el JSON del PageBuilder, donde no hay estilos inline).
   El stagger tiene prioridad sobre estas clases dentro de .animate--stagger */
.animate--delay-1 {
  --animate-delay: 0.2s;
}
.animate--delay-2 {
  --animate-delay: 0.4s;
}
.animate--delay-3 {
  --animate-delay: 0.6s;
}

/* Estado final (lo añade el observer de scripts/animations.js).
   backwards: durante el retardo se mantiene el estado inicial del keyframe */
.animate--scroll.animate--is-animated {
  opacity: 1;
  animation: animate-in var(--animate-duration) ease-out
    var(--animate-delay, 0s) backwards;
}

/* Stagger: retardo incremental para los hijos de un contenedor */
.animate--stagger > :nth-child(1) {
  --animate-delay: 0s;
}
.animate--stagger > :nth-child(2) {
  --animate-delay: 0.1s;
}
.animate--stagger > :nth-child(3) {
  --animate-delay: 0.2s;
}
.animate--stagger > :nth-child(4) {
  --animate-delay: 0.3s;
}
.animate--stagger > :nth-child(5) {
  --animate-delay: 0.4s;
}
.animate--stagger > :nth-child(6) {
  --animate-delay: 0.5s;
}
.animate--stagger > :nth-child(7) {
  --animate-delay: 0.6s;
}
.animate--stagger > :nth-child(n + 8) {
  --animate-delay: 0.7s;
}

/* ==========================================
   2. EFECTOS AVANZADOS
   ========================================== */

/* Blur: entra desenfocado. Combinable con up/down/left/right/zoom */
.animate--scroll.animate--blur {
  --animate-filter-from: blur(12px);
}

/* Persiana: el contenido se desvela con un barrido de recorte (clip-path).
   La dirección indica hacia dónde avanza el barrido */
.animate--scroll[class*="animate--persiana"] {
  opacity: 1;
  clip-path: var(--persiana-from);
}

.animate--persiana-right {
  --persiana-from: inset(0 100% 0 0);
}
.animate--persiana-left {
  --persiana-from: inset(0 0 0 100%);
}
.animate--persiana-down {
  --persiana-from: inset(0 0 100% 0);
}
.animate--persiana-up {
  --persiana-from: inset(100% 0 0 0);
}

@keyframes persiana-in {
  from {
    clip-path: var(--persiana-from);
  }
}

.animate--scroll[class*="animate--persiana"].animate--is-animated {
  clip-path: inset(0 0 0 0);
  animation: persiana-in var(--animate-duration) ease-out
    var(--animate-delay, 0s) backwards;
}

/* Cortina: una capa de color cubre el elemento y al retirarse descubre el
   contenido. La dirección indica desde dónde entra la cortina. Dura el
   doble que --animate-duration (ida y vuelta) */
@keyframes cortina {
  0% {
    clip-path: var(--cortina-from);
  }
  50% {
    clip-path: inset(0 0 0 0);
  }
  100% {
    clip-path: var(--cortina-from);
  }
}

.animate--scroll[class*="animate--cortina"] {
  position: relative;
  opacity: 1;
}

/* la cortina anima con su ::after; el contenedor no corre animate-in */
.animate--scroll[class*="animate--cortina"].animate--is-animated {
  animation: none;
}

.animate--scroll[class*="animate--cortina"]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--color-secondary);
  clip-path: var(--cortina-from);
  animation: cortina calc(var(--animate-duration) * 2) ease
    var(--animate-delay, 0s);
}

.animate--scroll[class*="animate--cortina"]:not(.animate--is-animated)::after {
  animation: none;
}

/* El contenido queda oculto hasta que la cortina lo cubre (mitad del barrido) */
.animate--scroll[class*="animate--cortina"] > * {
  opacity: 0;
}

.animate--scroll[class*="animate--cortina"].animate--is-animated > * {
  opacity: 1;
  transition: opacity 0s linear
    calc(var(--animate-duration) + var(--animate-delay, 0s));
}

.animate--cortina-left {
  --cortina-from: inset(0 100% 0 0);
}
.animate--cortina-right {
  --cortina-from: inset(0 0 0 100%);
}
.animate--cortina-up {
  --cortina-from: inset(0 0 100% 0);
}
.animate--cortina-down {
  --cortina-from: inset(100% 0 0 0);
}

/* Zoom de imagen (Ken Burns): la <img> entra con un zoom lento que se
   asienta. Se puede aplicar al contenedor de la imagen o directamente a la
   <img> (p. ej. ".dual img" en AUTO_ANIMATE); en el segundo caso el padre
   —normalmente el <picture>— recorta el zoom vía :has() */
.animate--scroll.animate--zoom-img {
  opacity: 1;
  overflow: hidden;
}

/* quien anima es la <img>; el contenedor no corre animate-in */
.animate--scroll.animate--zoom-img.animate--is-animated {
  animation: none;
}

.animate--scroll.animate--zoom-img img,
img.animate--scroll.animate--zoom-img {
  opacity: 0;
  transform: scale(1.15);
}

@keyframes zoom-img-fade {
  from {
    opacity: 0;
  }
}

@keyframes zoom-img-in {
  from {
    transform: scale(1.15);
  }
}

.animate--scroll.animate--zoom-img.animate--is-animated img,
img.animate--scroll.animate--zoom-img.animate--is-animated {
  opacity: 1;
  transform: none;
  animation:
    zoom-img-fade calc(var(--animate-duration) * 1.5) ease-out
      var(--animate-delay, 0s) backwards,
    zoom-img-in calc(var(--animate-duration) * 3) ease-out
      var(--animate-delay, 0s) backwards;
}

/* Recorte del zoom cuando la clase va directamente en la <img> */
picture:has(> img.animate--zoom-img) {
  display: block;
  overflow: hidden;
}

/* :where() para no imponer overflow con especificidad sobre otros padres
   (p. ej. el propio grid) que ya definan el suyo */
:where(:not(picture)):has(> img.animate--zoom-img) {
  overflow: hidden;
}

/* ==========================================
   3. CAPA OPCIONAL LIGADA AL SCROLL (CSS puro)
   ========================================== */
@supports (animation-timeline: view()) {
  .sda--fade {
    animation: sda-fade linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 80%;
  }

  .sda--grow {
    animation: sda-grow linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 100%;
  }

  .sda--parallax {
    animation: sda-parallax linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }

  /* Parallax de imagen: aplicar al contenedor que hace de marco (el padre
     de la <img>, p. ej. .sectionImage__img). El marco y el resto de la
     sección quedan fijos; la imagen, sobredimensionada con scale, se
     desliza por detrás a menor velocidad que el scroll.
     Ajustes: --sda-parallax-scale (1.35) y --sda-parallax-move (±12%);
     para no descubrir el marco, move ≤ (scale − 1) / 2 / scale.
     clip y no hidden: overflow hidden crearía un scroll container y el
     view() de la imagen se mediría contra él (quedaría congelado) */
  .sda--parallax-img {
    overflow: clip;
    --sda-parallax-scale: 1.25;
    /* 10% = máximo para scale 1.25 sin descubrir el marco */
    --sda-parallax-move: 10%;
  }

  .sda--parallax-img img {
    scale: var(--sda-parallax-scale, 1.15);
    animation: sda-parallax-img linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }

  /* Modo sin zoom: cuando la imagen es un fondo absoluto cuya altura la
     fija el marco (los .sectionImage__img desde 601px), la holgura se
     crea con altura extra en vez de con scale y la foto no se amplía.
     Amplitud en px: --sda-parallax-shift (300px) */
  @media (min-width: 601px) {
    .sectionImage:not(.sectionImage--3)
      .sectionImage__img.sda--parallax-img
      img {
      scale: none;
      height: calc(100% + var(--sda-parallax-shift, 300px));
      animation-name: sda-parallax-img-px;
    }
  }
}

@keyframes sda-fade {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
}

@keyframes sda-grow {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
}

@keyframes sda-parallax {
  from {
    transform: translateY(40px);
  }
  to {
    transform: translateY(-40px);
  }
}

/* La imagen arranca mostrando su parte baja y termina mostrando la alta,
   siempre cubriendo el marco gracias a la holgura que da el scale */
@keyframes sda-parallax-img {
  from {
    transform: translateY(calc(var(--sda-parallax-move, 12%) * -1));
  }
  to {
    transform: translateY(var(--sda-parallax-move, 12%));
  }
}

/* Ídem para el modo sin zoom: la holgura la da la altura extra (px) */
@keyframes sda-parallax-img-px {
  from {
    transform: translateY(calc(var(--sda-parallax-shift, 300px) * -1));
  }
  to {
    transform: translateY(0);
  }
}

/* ==========================================
   4. ACCESIBILIDAD (reducir movimiento)
   ========================================== */
@media (prefers-reduced-motion: reduce) {
  /* !important: debe ganar a cualquier regla del sistema, incluidas las de
     mayor especificidad (persiana, zoom-img img). Solo afecta al subárbol
     de elementos animados */
  .animate--scroll,
  .animate--scroll img,
  img.animate--scroll,
  .animate--scroll > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
    clip-path: none !important;
    filter: none !important;
  }

  .animate--scroll[class*="animate--cortina"]::after {
    content: none;
  }

  .sda--fade,
  .sda--grow,
  .sda--parallax {
    animation: none;
  }

  .sda--parallax-img img {
    animation: none;
    scale: none;
  }

  /* misma especificidad que el modo sin zoom para poder anularlo */
  .sectionImage:not(.sectionImage--3) .sectionImage__img.sda--parallax-img img {
    animation: none;
    height: 100%;
  }
}
}
