/* ============================================================
   RWX ANIMATIONS
   Lightweight animation framework for Bricks Builder
   Version 1.2.0 — rocketwebx.com

   Values are driven by CSS custom properties injected by PHP.
   Defaults are set in :root here as fallbacks; the PHP-generated
   block (output via wp_add_inline_style) will override them with
   whatever is saved in wp_options.
   ============================================================ */


/* ============================================================
   CSS CUSTOM PROPERTIES — Fallback defaults
   PHP overrides these with saved settings
   ============================================================ */

:root {
  --rwx-duration:       0.6s;
  --rwx-fade-duration:  0.6s;
  --rwx-distance-y:     24px;
  --rwx-distance-x:     28px;
  --rwx-lift-distance:  5px;
  --rwx-lift-sm:        3px;
  --rwx-zoom-scale:     1.06;
  --rwx-zoom-sm-scale:  1.03;
}


/* ============================================================
   ACCESSIBILITY
   All animations disabled for users who prefer reduced motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .rwx-reveal,
  .rwx-reveal-left,
  .rwx-reveal-right,
  .rwx-reveal-scale,
  .rwx-reveal-fade,
  .rwx-stagger > * {
    opacity: 1 !important;
    transform: none !important;
  }
}


/* ============================================================
   SCROLL REVEAL — Hidden state
   JS observer adds .is-visible when element enters viewport
   ============================================================ */

.rwx-reveal {
  opacity: 0;
  transform: translateY(var(--rwx-distance-y));
  transition:
    opacity var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94),
    transform var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.rwx-reveal-left {
  opacity: 0;
  transform: translateX(calc(-1 * var(--rwx-distance-x)));
  transition:
    opacity var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94),
    transform var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.rwx-reveal-right {
  opacity: 0;
  transform: translateX(var(--rwx-distance-x));
  transition:
    opacity var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94),
    transform var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.rwx-reveal-scale {
  opacity: 0;
  transform: scale(var(--rwx-reveal-scale));
  transition:
    opacity var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94),
    transform var(--rwx-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.rwx-reveal-fade {
  opacity: 0;
  transition: opacity var(--rwx-fade-duration) ease;
}


/* ============================================================
   SCROLL REVEAL — Visible state
   Added by JS observer on front end
   Added immediately in builder canvas
   ============================================================ */

.rwx-reveal.is-visible,
.rwx-reveal-left.is-visible,
.rwx-reveal-right.is-visible,
.rwx-reveal-scale.is-visible,
.rwx-reveal-fade.is-visible {
  opacity: 1;
  transform: none;
}


/* ============================================================
   STAGGER CHILDREN
   Apply to parent container — children animate in sequence.
   JS observes each child independently and uses setTimeout to
   apply genuine time-based stagger delays. The stagger_delay
   setting from the admin is passed via rwxConfig.staggerDelay.
   ============================================================ */

.rwx-stagger > * {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94),
    transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* Visible state — per-child, applies on all screen sizes */
.rwx-stagger > *.is-visible {
  opacity: 1;
  transform: none;
}


/* ============================================================
   DELAY MODIFIERS
   Static fallback — PHP-generated block overrides these
   ============================================================ */

.rwx-delay-1 { transition-delay: 100ms !important; }
.rwx-delay-2 { transition-delay: 200ms !important; }
.rwx-delay-3 { transition-delay: 300ms !important; }
.rwx-delay-4 { transition-delay: 400ms !important; }
.rwx-delay-5 { transition-delay: 500ms !important; }


/* ============================================================
   DURATION MODIFIERS
   ============================================================ */

.rwx-fast  { transition-duration: 0.35s !important; }
.rwx-slow  { transition-duration: 0.9s !important; }
.rwx-xslow { transition-duration: 1.2s !important; }


/* ============================================================
   HOVER — CARD LIFT
   ============================================================ */

.rwx-lift {
  transition:
    transform 0.28s cubic-bezier(0.25, 0.46, 0.45, 0.94),
    box-shadow 0.28s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}

.rwx-lift:hover {
  transform: translateY(calc(-1 * var(--rwx-lift-distance)));
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
}

.rwx-lift-sm {
  transition:
    transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94),
    box-shadow 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}

.rwx-lift-sm:hover {
  transform: translateY(calc(-1 * var(--rwx-lift-sm)));
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.10);
}


/* ============================================================
   HOVER — IMAGE ZOOM
   Apply to the image wrapper element.

   Carousel / Slider context:
   Bricks carousel and slider elements use Swiper, which sets
   overflow: hidden on .swiper-wrapper and .swiper-slide.
   When rwx-zoom sits inside a slide, those ancestor overflows
   clip the zoom. We solve this by:
   1. Ensuring rwx-zoom itself clips (overflow: hidden), which
      is what the user actually wants — the image scales inside
      its own box, not spilling into adjacent slides.
   2. Expanding the image selector to cover all Bricks image
      renderings: img, .bricks-img, .bricks-picture img,
      .bricks-carousel-image, and picture > img.
   ============================================================ */

.rwx-zoom {
  overflow: hidden;
  /* Isolation prevents the zoom from interacting with
     Swiper's own transform on the slide wrapper */
  isolation: isolate;
}

.rwx-zoom img,
.rwx-zoom .bricks-img,
.rwx-zoom .bricks-picture img,
.rwx-zoom .bricks-carousel-image,
.rwx-zoom picture > img {
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}

.rwx-zoom:hover img,
.rwx-zoom:hover .bricks-img,
.rwx-zoom:hover .bricks-picture img,
.rwx-zoom:hover .bricks-carousel-image,
.rwx-zoom:hover picture > img {
  transform: scale(var(--rwx-zoom-scale));
}

/* When rwx-zoom is on a swiper-slide directly, or its
   immediate parent is a swiper-slide, clip on the slide */
.swiper-slide.rwx-zoom,
.swiper-slide > .rwx-zoom {
  overflow: hidden;
}

.rwx-zoom-sm {
  overflow: hidden;
  isolation: isolate;
}

.rwx-zoom-sm img,
.rwx-zoom-sm .bricks-img,
.rwx-zoom-sm .bricks-picture img,
.rwx-zoom-sm .bricks-carousel-image,
.rwx-zoom-sm picture > img {
  transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}

.rwx-zoom-sm:hover img,
.rwx-zoom-sm:hover .bricks-img,
.rwx-zoom-sm:hover .bricks-picture img,
.rwx-zoom-sm:hover .bricks-carousel-image,
.rwx-zoom-sm:hover picture > img {
  transform: scale(var(--rwx-zoom-sm-scale));
}

.swiper-slide.rwx-zoom-sm,
.swiper-slide > .rwx-zoom-sm {
  overflow: hidden;
}


/* ============================================================
   HOVER — CAROUSEL SLIDE ZOOM
   Use rwx-zoom-slides on the Bricks Carousel or Slider element
   itself when lightbox is enabled or images are not rendered as
   <img> tags (Bricks renders them as background-image divs or
   wraps them in <a> lightbox links, so child img selectors have
   nothing to target).

   This targets .swiper-slide children directly and scales the
   entire slide block. The carousel element's own overflow clips
   the zoom cleanly between slides.

   rwx-zoom-slides    — standard zoom
   rwx-zoom-slides-sm — subtle zoom
   ============================================================ */

.rwx-zoom-slides .swiper-slide {
  overflow: hidden;
  isolation: isolate;
}

/* Ensure the lightbox anchor fills the slide so hover works correctly */
.rwx-zoom-slides .swiper-slide > a,
.rwx-zoom-slides-sm .swiper-slide > a,
.rwx-rotate-slides-cw .swiper-slide > a,
.rwx-rotate-slides-ccw .swiper-slide > a {
  display: block;
  width: 100%;
  height: 100%;
}

/* Target the actual image div inside the lightbox anchor.
   Bricks renders: .swiper-slide > <a> > <div class="image" style="background-image:...">
   Broader selectors kept as fallbacks for non-lightbox carousels. */
.rwx-zoom-slides .swiper-slide a > .image,
.rwx-zoom-slides .swiper-slide a > [style*="background"],
.rwx-zoom-slides .swiper-slide a > .bricks-carousel-image,
.rwx-zoom-slides .swiper-slide > .image,
.rwx-zoom-slides .swiper-slide > .bricks-carousel-image,
.rwx-zoom-slides .swiper-slide > [style*="background"] {
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
  display: block;
  width: 100%;
  height: 100%;
}

.rwx-zoom-slides .swiper-slide:hover a > .image,
.rwx-zoom-slides .swiper-slide:hover a > [style*="background"],
.rwx-zoom-slides .swiper-slide:hover a > .bricks-carousel-image,
.rwx-zoom-slides .swiper-slide:hover > .image,
.rwx-zoom-slides .swiper-slide:hover > .bricks-carousel-image,
.rwx-zoom-slides .swiper-slide:hover > [style*="background"] {
  transform: scale(var(--rwx-zoom-scale));
}

.rwx-zoom-slides-sm .swiper-slide {
  overflow: hidden;
  isolation: isolate;
}

.rwx-zoom-slides-sm .swiper-slide a > .image,
.rwx-zoom-slides-sm .swiper-slide a > [style*="background"],
.rwx-zoom-slides-sm .swiper-slide a > .bricks-carousel-image,
.rwx-zoom-slides-sm .swiper-slide > .image,
.rwx-zoom-slides-sm .swiper-slide > .bricks-carousel-image,
.rwx-zoom-slides-sm .swiper-slide > [style*="background"] {
  transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
  display: block;
  width: 100%;
  height: 100%;
}

.rwx-zoom-slides-sm .swiper-slide:hover a > .image,
.rwx-zoom-slides-sm .swiper-slide:hover a > [style*="background"],
.rwx-zoom-slides-sm .swiper-slide:hover a > .bricks-carousel-image,
.rwx-zoom-slides-sm .swiper-slide:hover > .image,
.rwx-zoom-slides-sm .swiper-slide:hover > .bricks-carousel-image,
.rwx-zoom-slides-sm .swiper-slide:hover > [style*="background"] {
  transform: scale(var(--rwx-zoom-sm-scale));
}


/* ============================================================
   HOVER — IMAGE ROTATE
   Apply rwx-rotate-cw (clockwise) or rwx-rotate-ccw (counter-
   clockwise) to the image wrapper. The container stays still;
   the image inside rotates and is clipped by overflow: hidden.

   THE CORNER-BLEED FIX:
   When an image rotates inside a fixed box its corners extend
   beyond the original bounds — no CSS clipping trick can solve
   this because the browser is geometrically correct. The only
   real fix is pre-scaling the image at rest so its corners
   always stay inside the wrapper even at full rotation.

   --rwx-rotate-prescale is calculated in PHP from the saved
   rotation angle using: prescale = 1 / cos(deg * PI / 180).
   A small safety margin is added on top. This means the image
   is imperceptibly oversized at rest, and at full rotation its
   corners still stay inside the wrapper — no bleed, no flash,
   no background revealed. Works identically in Chrome and Firefox.

   Stacks cleanly with rwx-zoom on the same wrapper:
     rwx-zoom rwx-rotate-cw

   The rotation angle is driven by --rwx-rotate-deg and the
   pre-scale by --rwx-rotate-prescale, both set via PHP.

   For Bricks carousels where images are background-image divs
   or wrapped in lightbox anchors, use rwx-rotate-slides-cw /
   rwx-rotate-slides-ccw on the carousel element itself.
   ============================================================ */

.rwx-rotate-cw,
.rwx-rotate-ccw {
  overflow: hidden;
  isolation: isolate;
}

/* Pre-scale at rest — ensures corners never escape on rotation */
.rwx-rotate-cw img,
.rwx-rotate-cw .bricks-img,
.rwx-rotate-cw .bricks-picture img,
.rwx-rotate-cw .bricks-carousel-image,
.rwx-rotate-cw picture > img,
.rwx-rotate-ccw img,
.rwx-rotate-ccw .bricks-img,
.rwx-rotate-ccw .bricks-picture img,
.rwx-rotate-ccw .bricks-carousel-image,
.rwx-rotate-ccw picture > img {
  transform: scale(var(--rwx-rotate-prescale, 1.12));
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
}

/* On hover: scale up further + rotate — corners stay contained */
.rwx-rotate-cw:hover img,
.rwx-rotate-cw:hover .bricks-img,
.rwx-rotate-cw:hover .bricks-picture img,
.rwx-rotate-cw:hover .bricks-carousel-image,
.rwx-rotate-cw:hover picture > img {
  transform: scale(var(--rwx-rotate-hover-scale, 1.18)) rotate(var(--rwx-rotate-deg, 3deg));
}

.rwx-rotate-ccw:hover img,
.rwx-rotate-ccw:hover .bricks-img,
.rwx-rotate-ccw:hover .bricks-picture img,
.rwx-rotate-ccw:hover .bricks-carousel-image,
.rwx-rotate-ccw:hover picture > img {
  transform: scale(var(--rwx-rotate-hover-scale, 1.18)) rotate(calc(-1 * var(--rwx-rotate-deg, 3deg)));
}

/* Swiper context */
.swiper-slide.rwx-rotate-cw,
.swiper-slide > .rwx-rotate-cw,
.swiper-slide.rwx-rotate-ccw,
.swiper-slide > .rwx-rotate-ccw {
  overflow: hidden;
}


/* ============================================================
   HOVER — CAROUSEL SLIDE ROTATE
   Use rwx-rotate-slides-cw / rwx-rotate-slides-ccw on the
   Bricks Carousel or Slider element itself — mirrors the
   rwx-zoom-slides pattern for background-image slides and
   lightbox-wrapped images.

   Same pre-scale fix applied here — slide content is scaled
   up at rest so rotation corners never bleed outside the slide.
   ============================================================ */

.rwx-rotate-slides-cw .swiper-slide,
.rwx-rotate-slides-ccw .swiper-slide {
  overflow: hidden;
  isolation: isolate;
}

/* Pre-scale slide content at rest.
   Bricks lightbox carousels render:
     .swiper-slide > <a> > <div class="image" style="background-image:...">
   The <a> is a transparent wrapper — the visual element is the div.image
   inside it. We must target that div directly, not the anchor.
   We also keep broader selectors as fallbacks for non-lightbox carousels. */
.rwx-rotate-slides-cw .swiper-slide a > .image,
.rwx-rotate-slides-cw .swiper-slide a > [style*="background"],
.rwx-rotate-slides-cw .swiper-slide a > .bricks-carousel-image,
.rwx-rotate-slides-cw .swiper-slide > .image,
.rwx-rotate-slides-cw .swiper-slide > .bricks-carousel-image,
.rwx-rotate-slides-cw .swiper-slide > [style*="background"],
.rwx-rotate-slides-ccw .swiper-slide a > .image,
.rwx-rotate-slides-ccw .swiper-slide a > [style*="background"],
.rwx-rotate-slides-ccw .swiper-slide a > .bricks-carousel-image,
.rwx-rotate-slides-ccw .swiper-slide > .image,
.rwx-rotate-slides-ccw .swiper-slide > .bricks-carousel-image,
.rwx-rotate-slides-ccw .swiper-slide > [style*="background"] {
  transform: scale(var(--rwx-rotate-prescale, 1.12));
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  will-change: transform;
  display: block;
  width: 100%;
  height: 100%;
}

/* On hover: scale up further + rotate clockwise */
.rwx-rotate-slides-cw .swiper-slide:hover a > .image,
.rwx-rotate-slides-cw .swiper-slide:hover a > [style*="background"],
.rwx-rotate-slides-cw .swiper-slide:hover a > .bricks-carousel-image,
.rwx-rotate-slides-cw .swiper-slide:hover > .image,
.rwx-rotate-slides-cw .swiper-slide:hover > .bricks-carousel-image,
.rwx-rotate-slides-cw .swiper-slide:hover > [style*="background"] {
  transform: scale(var(--rwx-rotate-hover-scale, 1.18)) rotate(var(--rwx-rotate-deg, 3deg));
}

/* On hover: scale up further + rotate counter-clockwise */
.rwx-rotate-slides-ccw .swiper-slide:hover a > .image,
.rwx-rotate-slides-ccw .swiper-slide:hover a > [style*="background"],
.rwx-rotate-slides-ccw .swiper-slide:hover a > .bricks-carousel-image,
.rwx-rotate-slides-ccw .swiper-slide:hover > .image,
.rwx-rotate-slides-ccw .swiper-slide:hover > .bricks-carousel-image,
.rwx-rotate-slides-ccw .swiper-slide:hover > [style*="background"] {
  transform: scale(var(--rwx-rotate-hover-scale, 1.18)) rotate(calc(-1 * var(--rwx-rotate-deg, 3deg)));
}


/* ============================================================
   HOVER — ICON EFFECTS
   ============================================================ */

.rwx-icon-bounce {
  display: inline-block;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.rwx-icon-bounce:hover {
  transform: translateY(-4px);
}

.rwx-icon-pulse {
  display: inline-block;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.rwx-icon-pulse:hover {
  transform: scale(1.15);
}


/* ============================================================
   HOVER — LINK UNDERLINE SLIDE
   ============================================================ */

.rwx-underline {
  position: relative;
  text-decoration: none;
  display: inline-block;
}

.rwx-underline::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background-color: currentColor;
  transition: width 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.rwx-underline:hover::after {
  width: 100%;
}


/* ============================================================
   HOVER — BUTTON SLIDE FILL
   ============================================================ */

.rwx-btn-fill {
  position: relative;
  overflow: hidden;
  z-index: 0;
  transition: color 0.3s ease;
}

.rwx-btn-fill::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: currentColor;
  opacity: 0.1;
  transform: translateX(-101%);
  transition: transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  z-index: -1;
}

.rwx-btn-fill:hover::before {
  transform: translateX(0);
}


/* ============================================================
   CONTINUOUS — FLOAT
   Use sparingly, one or two elements per page max
   ============================================================ */

.rwx-float {
  animation: rwx-float-anim 4s ease-in-out infinite;
}

@keyframes rwx-float-anim {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-8px); }
}


/* ============================================================
   CONTINUOUS — PULSE GLOW
   ============================================================ */

.rwx-pulse-glow {
  animation: rwx-pulse-glow-anim 2.4s ease-in-out infinite;
}

@keyframes rwx-pulse-glow-anim {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.08); }
  50%       { box-shadow: 0 0 0 8px rgba(0, 0, 0, 0); }
}
