/* mirrored for right-to-left pages from ../rs-motion.css; do not edit */
/* ==================================================================
   RS Motion, styles for the reusable motion components
   (companion of assets/js/rs-motion.js; see that file for usage)
   ------------------------------------------------------------------
   Everything here is transform/opacity only: no layout is affected,
   nothing paints outside its own compositor layer, and every effect
   is switched off under prefers-reduced-motion.
   ================================================================== */

/* ---------- 1. 3D abstract background host ---------- */
.rs-abstract {
    position: relative;
    isolation: isolate;           /* the canvas can't escape the host */
}

.rs-abstract__canvas {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    display: block;
    z-index: -1;                  /* behind the host's own content */
    pointer-events: none;
}

/* Reusable still ⇄ canvas cross-fade for ANY host:
     <section data-rs-abstract='{"preset":"silkFold","mouse":1,"scroll":1}'>
       <img class="rs-abstract-still" src="…webp" alt="">   ← paints first (LCP), stays
       …content…                                             without WebGL / reduced motion
     </section>
   The canvas waits, opaque, behind the still; once its first frame is drawn
   (.rs-abstract--ready) the still dissolves away. Fading both at once would
   let the host's dark background show through half way. Scoped to hosts that carry a
   still so the home hero's own choreography is untouched. */
.rs-abstract:has(> .rs-abstract-still) > .rs-abstract__canvas {
    opacity: 1;
    transition: none;
}
.rs-abstract > .rs-abstract-still {
    transition: opacity 1.4s ease;
}
.rs-abstract--ready > .rs-abstract-still {
    opacity: 0;
}

/* ---------- 1b. Hero surface ([data-rs-hero] / RSMotion.hero / RSMotion.heroTargets) ----------
   The host keeps its CSS background (first paint, no-WebGL and reduced-motion fallback).
   The canvas sits under the host's own ::before / ::after washes and hairlines, and eases
   in over the still once the first frame is drawn (the surface starts flat and exactly on
   the still, so the hand-over is seamless). */
.rs-hero > .rs-abstract__canvas {
    z-index: -2 !important;
    opacity: 0;
    transition: opacity 1.4s ease;
}
.rs-hero.rs-abstract--ready > .rs-abstract__canvas {
    opacity: 1;
}
/* exit: the copy drifts a little slower than the page as the hero scrolls away, which reads as
   depth between the copy and the surface. `translate` composes with any existing transform. */
@supports (translate: 0 1px) {
    .rs-hero > :not(.rs-abstract__canvas) {
        translate: 0 calc(var(--rs-hero-p, 0) * var(--rs-hero-drift, 36px));
    }
}

/* ---------- 2. Pointer tilt ---------- */
.rs-tilt {
    will-change: transform;
}

/* ---------- 3. Scroll reveal (only when the JS is present) ---------- */
.rs-motion-js [data-rs-reveal] {
    opacity: 0;
    /* short travel, one calm curve: the block settles into place, it does not fly in */
    transition: opacity .7s cubic-bezier(.25, .6, .3, 1), transform .7s cubic-bezier(.25, .6, .3, 1);
    will-change: opacity, transform;
}
.rs-motion-js [data-rs-reveal="up"]    { transform: translate3d(0, 16px, 0); }
.rs-motion-js [data-rs-reveal="left"]  { transform: translate3d(20px, 0, 0); }
.rs-motion-js [data-rs-reveal="right"] { transform: translate3d(-20px, 0, 0); }
.rs-motion-js [data-rs-reveal="scale"] { transform: scale(.98); }
.rs-motion-js [data-rs-reveal].is-inview {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* ---------- 4. Scroll parallax ---------- */
.rs-parallax { will-change: transform; }

/* ==================================================================
   HOMEPAGE HERO, #heroCarouselSection.rs-hero-motion
   ------------------------------------------------------------------
   · Static banner images stay in place as the no-WebGL / reduced-motion
     fallback and cross-fade out once the 3D scene has drawn its first frame.
   · Slide text + image get entrance/exit motion keyed off Bootstrap's own
     carousel classes (.active / .carousel-item-start / -end / -next / -prev).
   ================================================================== */
#heroCarouselSection.rs-abstract > .carousel {
    position: relative;
    z-index: 1;
}

#heroCarouselSection.rs-abstract .background-pattern {
    transition: opacity 1.2s ease;
}
#heroCarouselSection.rs-abstract--ready .carousel-item {
    background-color: transparent;
}
#heroCarouselSection.rs-abstract--ready .background-pattern {
    opacity: 0;
}

/* Entrance / exit of slide content.
   Driven by rs-motion.js ([data-rs-slides] on the carousel): it toggles
   .rs-in / .rs-out on each .carousel-item as Bootstrap moves the slides.
   Transitions (not filled keyframes) are used on purpose: a finished,
   filled compositor animation on the image column stopped painting on
   Chrome's GPU path, whereas transitions leave nothing behind.
   The slide that is active on page load keeps its image visible at once
   (.rs-initial) so the LCP image is never delayed. */
.rs-motion-js .rs-hero-motion .carousel-item .text-content > *,
.rs-motion-js .rs-hero-motion .carousel-item:not(.rs-initial) .image-container {
    opacity: 0;
    transform: translate3d(0, 28px, 0);
    transition: opacity .7s cubic-bezier(.22, 1, .36, 1), transform .7s cubic-bezier(.22, 1, .36, 1);
}
.rs-motion-js .rs-hero-motion .carousel-item .text-content > :nth-child(2) { transition-delay: .08s; }
.rs-motion-js .rs-hero-motion .carousel-item .text-content > :nth-child(3) { transition-delay: .16s; }
.rs-motion-js .rs-hero-motion .carousel-item:not(.rs-initial) .image-container {
    transform: translate3d(0, 24px, 0) scale(.97);
    transition-duration: .8s, .8s;
    transition-delay: .05s;
}
.rs-motion-js .rs-hero-motion .carousel-item.rs-in .text-content > *,
.rs-motion-js .rs-hero-motion .carousel-item.rs-in .image-container {
    opacity: 1;
    transform: none;
}
/* outgoing slide: quick lift-and-fade while Bootstrap slides it away */
.rs-motion-js .rs-hero-motion .carousel-item.rs-out .text-content > *,
.rs-motion-js .rs-hero-motion .carousel-item.rs-out .image-container {
    opacity: 0;
    transform: translate3d(0, -16px, 0);
    transition-duration: .4s, .4s;
    transition-delay: 0s;
    transition-timing-function: ease-in, ease-in;
}

/* ---------- Slide 1: "49 YEARS" (overlay "flow49", assets/js/rs-hero49.js) ----------
   .rs-hero-49 is only a placeholder: the WebGL scene measures it and draws the 3D
   figures exactly over it. The inline SVG inside is the same artwork as a static
   fallback; it hands over to the 3D version once the scene has drawn. When the
   overlay cannot run (.rs-overlay-off: no WebGL2) slide 1 keeps its own still. */
.rs-hero-49 {
    width: 100%;
    max-width: 560px;
    aspect-ratio: 624 / 428;
    margin-right: auto;
}
.rs-hero-49 svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    transition: opacity .3s ease;
}
#heroCarouselSection.rs-abstract--ready:not(.rs-overlay-off) .rs-hero-49 svg {
    opacity: 0;
}
#heroCarouselSection.rs-overlay-off .rs-hero-slide-49 .background-pattern {
    opacity: 1;
}
/* the other slides get their height from the photo in this column (1000 × 1240):
   give slide 1 the same box so its copy sits at the same height as theirs */
#heroCarouselSection .rs-hero-slide-49 .image-container {
    aspect-ratio: 1000 / 1240;
    height: auto;
}
/* the copy lies over the brightest part of the artwork */
#heroCarouselSection .rs-hero-slide-49 .text-content {
    text-shadow: 0 1px 18px rgba(0, 22, 120, .55);
}
@media (max-width: 991px) {
    #heroCarouselSection .rs-hero-slide-49 .image-container {
        aspect-ratio: auto;
    }
    .rs-hero-49 {
        max-width: 380px;
        margin: 28px auto 0;
    }
}
@media (max-width: 767px) {
    /* phones hide the hero's image column; slide 1 keeps it for the figures, in the
       band the copy leaves free under the navbar */
    #heroCarouselSection .rs-hero-slide-49 .image-container {
        display: block !important;
        position: absolute;
        top: 104px;
        right: 0;
        left: 0;
        height: auto;
        pointer-events: none;
    }
    .rs-hero-49 {
        width: min(62vw, 250px);
        margin: 0 auto;
    }
}

/* ---------- Reduced motion: everything static ---------- */
@media (prefers-reduced-motion: reduce) {
    .rs-motion-js [data-rs-reveal] { opacity: 1; transform: none; transition: none; }
    .rs-motion-js .rs-hero-motion .carousel-item .text-content > *,
    .rs-motion-js .rs-hero-motion .carousel-item .image-container { opacity: 1 !important; transform: none !important; transition: none !important; }
    .rs-tilt { transform: none !important; }
    .rs-hero > :not(.rs-abstract__canvas) { translate: none !important; }
}

/* ---------- 5. Scroll-linked text fill ([data-rs-scrolltext]) ----------
   rs-motion.js wraps every word in .rs-st-w and adds .is-lit as the block
   travels up the viewport. Without JS (or with reduced motion) the text is
   never split, so it simply keeps its normal colour. */
.rs-scrolltext .rs-st-w {
    color: var(--rs-st-dim, rgba(20, 25, 63, .22));
    transition: color .5s ease;
}
.rs-scrolltext .rs-st-w.is-lit {
    color: var(--rs-st-lit, inherit);
}
