/* =============================================================================
   Savage Innovations — Animation Framework v1
   -----------------------------------------------------------------------------
   A class-based animation system designed to integrate cleanly with Elementor
   widgets. Add a class (and optionally a modifier or two) to any widget and it
   inherits the right animation and styling. No JS framework required; works
   alongside Elementor's built-in Motion Effects but is more composable.

   Pair with: js/savage-animations.js (IntersectionObserver triggers + Lenis)

   Lenis recommended CSS (required): without the scroll-behavior reset below,
   any stylesheet that sets scroll-behavior smooth (Elementor frontend.min.css
   does) makes the browser re-animate every Lenis frame, which reads as a long
   delay before scrolling starts.
              php/enqueue.php (Elementor child theme integration)

   Class structure:
     .sv-anim                 — required marker (everything that animates wears this)
     .sv-{name}               — one entry animation (fade-up, scale, blur-in, …)
     .sv-delay-{ms}           — optional delay modifier (100..1000)
     .sv-duration-{name}      — optional duration override (fast, slow)
     .sv-ease-{name}          — optional easing override (out, bounce, expo)
     .sv-stagger              — on a container, animates direct children in order
     .sv-stagger-{ms}         — stagger gap (default 100ms)
     .sv-parallax             — Lenis-driven parallax (set --sv-parallax-speed)
     .sv-scrub                — scroll-position-driven (uses Lenis progress)
     .sv-hover-{name}         — hover state (lift, glow, tilt)
     .sv-once                 — animate once on first reveal (default)
     .sv-repeat               — re-animate every time element enters viewport
============================================================================== */

/* -----------------------------------------------------------------------------
   0. Lenis recommended CSS (standard setup, lenis README)
----------------------------------------------------------------------------- */

html.lenis,
html.lenis body {
  height: auto;
}

html.lenis,
.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

/* -----------------------------------------------------------------------------
   1. Tokens — overridable per-project via :root or via Elementor Global Styles
----------------------------------------------------------------------------- */

:root {
  /* Durations */
  --sv-dur-fast: 300ms;
  --sv-dur: 600ms;
  --sv-dur-slow: 900ms;

  /* Easings */
  --sv-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --sv-ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --sv-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --sv-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
  --sv-ease-expo: cubic-bezier(0.16, 1, 0.3, 1);

  /* Distances (for slide-style entries) */
  --sv-distance-sm: 16px;
  --sv-distance-md: 32px;
  --sv-distance-lg: 64px;

  /* Default scale floor (for sv-scale) */
  --sv-scale-from: 0.92;

  /* Blur (for sv-blur-in) */
  --sv-blur-from: 12px;

  /* Parallax */
  --sv-parallax-speed: 0.4; /* 0 = locked, 1 = matches scroll */
}

/* -----------------------------------------------------------------------------
   2. Base — every animated element
----------------------------------------------------------------------------- */

.sv-anim {
  opacity: 0;
  transform: translate3d(0, 0, 0);
  transition:
    opacity var(--sv-dur) var(--sv-ease-out),
    transform var(--sv-dur) var(--sv-ease-out),
    filter var(--sv-dur) var(--sv-ease-out);
  will-change: opacity, transform;
}

/* JS toggles this class when the element enters viewport. */
.sv-anim.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  filter: blur(0);
}

/* -----------------------------------------------------------------------------
   3. Entry animations — pre-state (before .is-visible)
----------------------------------------------------------------------------- */

.sv-fade {
  /* opacity 0 already on .sv-anim */
}

.sv-fade-up {
  transform: translate3d(0, var(--sv-distance-md), 0);
}
.sv-fade-down {
  transform: translate3d(0, calc(var(--sv-distance-md) * -1), 0);
}
.sv-fade-left {
  transform: translate3d(var(--sv-distance-md), 0, 0);
}
.sv-fade-right {
  transform: translate3d(calc(var(--sv-distance-md) * -1), 0, 0);
}

.sv-scale {
  transform: scale(var(--sv-scale-from));
}
.sv-scale-fade {
  transform: scale(var(--sv-scale-from));
  /* opacity 0 from .sv-anim */
}

.sv-blur-in {
  filter: blur(var(--sv-blur-from));
}

.sv-rise {
  /* combines fade-up + slight scale, useful for hero copy */
  transform: translate3d(0, var(--sv-distance-md), 0) scale(var(--sv-scale-from));
}

/* Distance variants (apply alongside .sv-fade-*) */
.sv-distance-sm { --sv-distance-md: var(--sv-distance-sm); }
.sv-distance-lg { --sv-distance-md: var(--sv-distance-lg); }

/* -----------------------------------------------------------------------------
   4. Delay modifiers
----------------------------------------------------------------------------- */

.sv-delay-100 { transition-delay: 100ms; }
.sv-delay-200 { transition-delay: 200ms; }
.sv-delay-300 { transition-delay: 300ms; }
.sv-delay-400 { transition-delay: 400ms; }
.sv-delay-500 { transition-delay: 500ms; }
.sv-delay-600 { transition-delay: 600ms; }
.sv-delay-700 { transition-delay: 700ms; }
.sv-delay-800 { transition-delay: 800ms; }
.sv-delay-900 { transition-delay: 900ms; }
.sv-delay-1000 { transition-delay: 1000ms; }

/* -----------------------------------------------------------------------------
   5. Duration overrides
----------------------------------------------------------------------------- */

.sv-duration-fast { transition-duration: var(--sv-dur-fast); }
.sv-duration-slow { transition-duration: var(--sv-dur-slow); }

/* -----------------------------------------------------------------------------
   6. Easing overrides
----------------------------------------------------------------------------- */

.sv-ease-out      { transition-timing-function: var(--sv-ease-out); }
.sv-ease-in       { transition-timing-function: var(--sv-ease-in); }
.sv-ease-in-out   { transition-timing-function: var(--sv-ease-in-out); }
.sv-ease-bounce   { transition-timing-function: var(--sv-ease-bounce); }
.sv-ease-expo     { transition-timing-function: var(--sv-ease-expo); }

/* -----------------------------------------------------------------------------
   7. Stagger — JS adds incremental delays to direct children
----------------------------------------------------------------------------- */

.sv-stagger > * {
  /* JS sets transition-delay per child based on .sv-stagger-{ms} */
  /* Each child must also wear .sv-anim and an entry class. */
}

/* -----------------------------------------------------------------------------
   8. Hover states — pure CSS, no JS observer needed
----------------------------------------------------------------------------- */

.sv-hover-lift {
  transition: transform var(--sv-dur-fast) var(--sv-ease-out),
              box-shadow var(--sv-dur-fast) var(--sv-ease-out);
}
.sv-hover-lift:hover {
  transform: translate3d(0, -4px, 0);
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.2);
}

.sv-hover-glow {
  transition: filter var(--sv-dur-fast) var(--sv-ease-out),
              box-shadow var(--sv-dur-fast) var(--sv-ease-out);
}
.sv-hover-glow:hover {
  filter: brightness(1.1);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.08),
              0 12px 40px -4px currentColor;
}

.sv-hover-tilt {
  transition: transform var(--sv-dur-fast) var(--sv-ease-out);
  transform-style: preserve-3d;
}
.sv-hover-tilt:hover {
  transform: perspective(800px) rotateX(2deg) rotateY(-2deg) translate3d(0, -2px, 0);
}

/* -----------------------------------------------------------------------------
   9. Parallax — JS sets --sv-parallax-y based on Lenis progress
----------------------------------------------------------------------------- */

.sv-parallax {
  will-change: transform;
  transform: translate3d(0, var(--sv-parallax-y, 0), 0);
}

.sv-parallax-slow { --sv-parallax-speed: 0.2; }
.sv-parallax-fast { --sv-parallax-speed: 0.6; }

/* -----------------------------------------------------------------------------
   10. Scrub — JS sets --sv-scrub-progress (0..1) based on Lenis position
       Use this for elements that should reveal/transform with scroll position.
----------------------------------------------------------------------------- */

.sv-scrub {
  will-change: transform, opacity;
  /* --sv-scrub-progress is updated by JS each frame.
     Use it in your project CSS like:
       .my-hero-bg {
         transform: scale(calc(1 + var(--sv-scrub-progress, 0) * 0.2));
       }
  */
}

/* -----------------------------------------------------------------------------
   11. Reduced motion — respect user preference
----------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .sv-anim {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
  .sv-parallax {
    transform: none;
  }
  .sv-hover-lift:hover,
  .sv-hover-glow:hover,
  .sv-hover-tilt:hover {
    transform: none;
    filter: none;
    box-shadow: none;
  }
}
