/* =============================================================================
   GSW ANIMATIONS LIBRARY v1.1.0
   Scroll-triggered entrance animations for Bricks Builder

   Klassen werden über den Bricks Class-Field gesetzt.
   JS (IntersectionObserver) fügt .gsw-visible hinzu, wenn das Element
   ins Viewport scrollt.

   NEU in 1.1.0:
   Die Einblendungen laufen über `animation` statt `transition`.
   Dadurch können globale Klassen mit eigener `transition` (z.B. Hover auf
   Cards oder Buttons) die Einblendung und den Stagger nicht mehr
   überschreiben. Der Startzustand gilt nur, solange .gsw-visible fehlt.
   Nach der Animation sind opacity, transform und filter wieder frei
   für Hover-Effekte.

   Das JS aus 1.0.0 funktioniert unverändert weiter.
   ============================================================================= */


/* --- Custom Properties (global überschreibbar) ----------------------------- */

:root {
  --gsw-duration:      700ms;
  --gsw-ease:          cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --gsw-distance:      36px;
  --gsw-scale-in:      0.93;
  --gsw-scale-out:     1.07;
  --gsw-stagger-step:  120ms;
  --gsw-i:             0;    /* Stagger-Index: gesetzt per Bricks {query_loop_index},
                                data-gsw-index, oder JS-Auto-Count (.gsw-stagger) */
}


/* =============================================================================
   ENTRANCE ANIMATIONS (scroll-triggered)
   ============================================================================= */

/* --- Keyframe: eine für alle Varianten ------------------------------------- */
/* Nur "from" ist definiert. Das Ziel ist der normale Zustand des Elements,
   also das, was Bricks bzw. die eigenen Klassen vorgeben. */

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


/* --- Basiswerte pro Entrance-Element --------------------------------------- */
/* Setzt die Variablen pro Element zurück, damit verschachtelte Elemente
   (z.B. .gsw-fade in einer .gsw-fade-up-Card) nichts vom Elternelement erben. */

.gsw-fade,
.gsw-fade-up,
.gsw-fade-down,
.gsw-fade-left,
.gsw-fade-right,
.gsw-zoom-in,
.gsw-zoom-out,
.gsw-blur-in {
  --gsw-from:        none;
  --gsw-filter-from: none;
  --gsw-delay:       0ms;
}


/* --- Startwerte pro Klasse ------------------------------------------------- */

.gsw-fade-up    { --gsw-from: translateY(var(--gsw-distance)); }
.gsw-fade-down  { --gsw-from: translateY(calc(var(--gsw-distance) * -1)); }
.gsw-fade-left  { --gsw-from: translateX(var(--gsw-distance)); }              /* kommt von rechts */
.gsw-fade-right { --gsw-from: translateX(calc(var(--gsw-distance) * -1)); }   /* kommt von links */
.gsw-zoom-in    { --gsw-from: scale(var(--gsw-scale-in)); }
.gsw-zoom-out   { --gsw-from: scale(var(--gsw-scale-out)); }
.gsw-blur-in    { --gsw-from: translateY(16px); --gsw-filter-from: blur(8px); }


/* --- Hidden State: solange .gsw-visible fehlt ------------------------------ */

:is(.gsw-fade,
    .gsw-fade-up,
    .gsw-fade-down,
    .gsw-fade-left,
    .gsw-fade-right,
    .gsw-zoom-in,
    .gsw-zoom-out,
    .gsw-blur-in):not(.gsw-visible) {
  opacity: 0;
  transform: var(--gsw-from);
  filter: var(--gsw-filter-from);
}


/* --- Visible State: JS addet .gsw-visible ---------------------------------- */
/* fill-mode "backwards": Während der Stagger-Verzögerung bleibt das Element
   im Startzustand. Nach dem Ende gibt die Animation alle Eigenschaften frei. */

:is(.gsw-fade,
    .gsw-fade-up,
    .gsw-fade-down,
    .gsw-fade-left,
    .gsw-fade-right,
    .gsw-zoom-in,
    .gsw-zoom-out,
    .gsw-blur-in).gsw-visible {
  animation-name:            gsw-in;
  animation-duration:        var(--gsw-duration);
  animation-timing-function: var(--gsw-ease);
  animation-fill-mode:       backwards;
  animation-delay:           calc(var(--gsw-i, 0) * var(--gsw-stagger-step) + var(--gsw-delay, 0ms));
}


/* =============================================================================
   KEN BURNS (always-on, kein Scroll-Trigger)
   Auf den Bild-Container setzen, nicht auf das img selbst.
   ============================================================================= */

@keyframes gsw-ken-burns {
  0%   { transform: scale(1)    translate(0%, 0%); }
  33%  { transform: scale(1.06) translate(-0.8%, -0.6%); }
  66%  { transform: scale(1.04) translate(0.5%, -0.8%); }
  100% { transform: scale(1)    translate(0%, 0%); }
}

.gsw-ken-burns {
  overflow: hidden;
}

.gsw-ken-burns > img,
.gsw-ken-burns img {
  animation: gsw-ken-burns 14s ease-in-out infinite;
  will-change: transform;
}

/* Wenn direkt auf ein <img> gesetzt (z.B. Bricks Image-Element) */
img.gsw-ken-burns {
  animation: gsw-ken-burns 14s ease-in-out infinite;
  will-change: transform;
}


/* =============================================================================
   DURATION MODIFIER
   ============================================================================= */

.gsw-duration-fast { --gsw-duration: 380ms; }
.gsw-duration-slow { --gsw-duration: 1100ms; }


/* =============================================================================
   MANUAL DELAY MODIFIER (additiv zum Stagger-Delay)
   Nützlich wenn man ein einzelnes Element etwas später reinkommen lassen will.
   Muss nach den Basiswerten stehen, damit es --gsw-delay überschreibt.
   ============================================================================= */

.gsw-delay-1 { --gsw-delay: 100ms; }
.gsw-delay-2 { --gsw-delay: 200ms; }
.gsw-delay-3 { --gsw-delay: 350ms; }
.gsw-delay-4 { --gsw-delay: 500ms; }
.gsw-delay-5 { --gsw-delay: 700ms; }


/* =============================================================================
   REDUCED MOTION – Barrierefreiheit
   Nutzer mit aktiviertem "Reduced Motion" sehen keine Bewegung,
   aber Inhalte sind sofort sichtbar.
   ============================================================================= */

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

  :is(.gsw-fade,
      .gsw-fade-up,
      .gsw-fade-down,
      .gsw-fade-left,
      .gsw-fade-right,
      .gsw-zoom-in,
      .gsw-zoom-out,
      .gsw-blur-in):not(.gsw-visible) {
    opacity: 1;
    transform: none;
    filter: none;
  }

  :is(.gsw-fade,
      .gsw-fade-up,
      .gsw-fade-down,
      .gsw-fade-left,
      .gsw-fade-right,
      .gsw-zoom-in,
      .gsw-zoom-out,
      .gsw-blur-in).gsw-visible {
    animation: none;
  }

  .gsw-ken-burns > img,
  .gsw-ken-burns img,
  img.gsw-ken-burns {
    animation: none;
  }
}