/* ============================================================
   Rhino Boxing — Hero Slider widget
   ------------------------------------------------------------
   This sheet adds ONLY what a slider needs on top of the theme's
   site-wide concept-1 hero styles (main.css lines ~126-199):
   the stacking context, the transition, the dots, the arrows and
   the progress bar.

   Everything else — the scrim gradients, the `.hero--left` …
   `.hero--bottom-right` content-position variants, the button
   styles and the `body.locale-vi` line-height bumps — is
   inherited, because each slide renders the same `.hero` markup
   the single `rhino_hero` widget does.
   ============================================================ */

/* ---------- Box model -------------------------------------------- */

/* Declared here rather than assumed. `inc/enqueue.php` never enqueues the
   theme's style.css, which is where the universal `box-sizing: border-box` lives
   — the theme's own article.css has a comment recording the same discovery. So on
   this site elements compute as CONTENT-BOX, and a full-width element with
   horizontal padding overflows its parent by exactly the padding.
   The slider sets its own box model over its own subtree so it behaves the same
   whether or not that reset ever starts loading. A widget must not depend on a
   reset that ships in a different package. */
.rhino-hslider,
.rhino-hslider *,
.rhino-hslider *::before,
.rhino-hslider *::after {
    box-sizing: border-box;
}

/* ---------- Root -------------------------------------------------- */

.rhino-hslider {
    position: relative;
    overflow: hidden;
    background: var(--atmo0, #000);

    /* Written by the Slider Height control. `svh` (small viewport height) is
       deliberate: `vh` is the LARGE viewport height on iOS/Android, so a 100vh
       slide is taller than what you can actually see and the buttons sit under
       the browser chrome. `dvh` would fix the height but re-lays-out the whole
       slide every time the toolbars hide, which reads as a jump mid-scroll.
       `svh` is stable AND fully visible. The `vh` line is the fallback for
       browsers without svh support. */
    --rhino-hs-h: 100vh;
    height: var(--rhino-hs-h);

    /* Extra text inset, on top of the container's own 24px gutter. DECLARED as a
       real value at each breakpoint rather than left to a `var(…, fallback)`,
       because a fallback has to be repeated at every use site and the copies
       drift: one rule said 40px and another 4px, so a 390px screen inherited a
       64px inset and the headline lost a third of its width.
       The Text Inset control overrides these — Elementor's generated selector is
       more specific and it uses these same two breakpoints. */
    --rhino-hs-inset: 40px;
}

@media (max-width: 1024px) {
    .rhino-hslider { --rhino-hs-inset: 16px; }
}

@media (max-width: 767px) {
    .rhino-hslider { --rhino-hs-inset: 4px; }
}

@supports (height: 100svh) {
    .rhino-hslider {
        height: min(var(--rhino-hs-h), 100svh);
    }
}

.rhino-hslider__viewport {
    position: relative;
    height: 100%;
    overflow: hidden;
}

.rhino-hslider__track {
    position: relative;
    height: 100%;
}

/* ---------- Slides ------------------------------------------------ */

/* `.hero` ships `position: relative; min-height: 88vh; display: flex`. Inside a
   slider every slide has to occupy the SAME box, so it is pinned absolute and
   the min-height is released — otherwise each slide would claim 88vh of layout
   and the container would grow to 3x the viewport. */
.rhino-hslider__slide.hero {
    position: absolute;
    inset: 0;
    min-height: 0;
    height: 100%;
    width: 100%;
}

/* Fade (default) */
.rhino-hslider--fade .rhino-hslider__slide {
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-slower, 600ms) var(--ease-out, ease),
                visibility var(--dur-slower, 600ms) var(--ease-out, ease);
    pointer-events: none;
}

.rhino-hslider--fade .rhino-hslider__slide.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}

/* Slide (horizontal). Off-screen slides are translated rather than hidden, so
   the movement is visible; `visibility` still flips so an inactive slide's
   links are not reachable by keyboard. */
.rhino-hslider--slide .rhino-hslider__slide {
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--dur-slower, 600ms) var(--ease-out, ease),
                visibility var(--dur-slower, 600ms) var(--ease-out, ease);
    pointer-events: none;
}

.rhino-hslider--slide .rhino-hslider__slide.is-active {
    transform: translateX(0);
    visibility: visible;
    pointer-events: auto;
}

.rhino-hslider--slide .rhino-hslider__slide.is-prev {
    transform: translateX(-100%);
}

/* Single slide: no chrome, no transition cost. */
.rhino-hslider--single .rhino-hslider__slide {
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
}

/* ---------- Photo + scrim ---------------------------------------- */

.rhino-hslider__slide .hero-bg img {
    /* Framed by the per-slide focal-point sliders, which write these two custom
       properties. The fallbacks keep the photo centred if either is cleared. */
    object-position: var(--rhino-bg-x, 50%) var(--rhino-bg-y, 50%);
    object-fit: cover;
    width: 100%;
    height: 100%;
}

/* The "Dark overlay strength" control writes --rhino-hs-scrim on `.hero-bg`;
   the pseudo-element inherits it. Default 1 = the theme's gradient at full
   strength, which is the current homepage look. */
.rhino-hslider__slide .hero-bg::after {
    opacity: var(--rhino-hs-scrim, 1);
}

/* Slow photo drift on the active slide, from the Slow Photo Zoom switch. The
   duration is derived from the autoplay dwell time rather than hardcoded, so the
   movement finishes as the slide changes instead of stopping dead halfway or
   still accelerating when it leaves. Purely decorative — switched off entirely
   under prefers-reduced-motion below. */
.rhino-hslider--kenburns .rhino-hslider__slide .hero-bg img {
    transform: scale(1.07);
    transition: transform calc(var(--rhino-hs-delay, 7000ms) * 1.5) linear;
    transform-origin: 50% 45%;
}

.rhino-hslider--kenburns .rhino-hslider__slide.is-active .hero-bg img {
    transform: scale(1);
}

/* ---------- Copy -------------------------------------------------- */

/* `.hero-content` also carries the theme's `.container`
   (`max-width: 1280px; margin: 0 auto; padding: 0 24px`), which is what lines
   the headline up with the header logo and nav. NOTHING here may override its
   max-width or its auto margins — the per-slide width control caps the inner
   `.rhino-hslider__copy` for exactly that reason. Overriding it here put the
   headline at the bare 24px screen edge, underneath the previous-slide arrow. */
/* THREE SELECTOR CLASSES, ON PURPOSE — this needs to beat `.hero--left
   .hero-content` (two classes) in main.css, which sets `margin-left: 0`. Between
   that and `.hero-content { max-width: 625px }` also in main.css, the container's
   centred 1280px column was gone: the copy was pinned to the bare gutter at the
   screen edge no matter how wide the viewport got. Measured at 1440px it sat 9px
   to the LEFT of the header logo. Restoring the column here is what makes the
   headline line up with the nav.

   Note the box model. `inc/enqueue.php` never enqueues the theme's style.css,
   where the universal `box-sizing: border-box` lives — there is a comment saying
   so in the theme's own article.css — so this computes as CONTENT-BOX. The
   1280px is the content column and the padding sits outside it, which is exactly
   how `.container` and `.header-inner` already behave. That is why the copy ends
   up on the same vertical line as the logo on a wide screen, and inset by the
   Text Inset value once the viewport is narrower than the column. */
.rhino-hslider .rhino-hslider__slide .hero-content {
    /* `width: 100%` is REQUIRED, not defensive. `.hero-content` is a flex item of
       `.hero`, so `width: auto` means shrink-to-fit — and `margin-inline: auto`
       then centres that SHRUNK box rather than a 1280px column. Measured at
       1920px the copy landed 320px right of the header logo. With `width: 100%`
       the item fills the line, `max-width` caps it at the column, and the auto
       margins centre the column itself. */
    box-sizing: border-box;
    width: 100%;
    max-width: 1280px;
    margin-left: auto;
    margin-right: auto;

    /* Room for the bottom control row and the progress bar, so a long lead
       paragraph never sits under the chrome. */
    padding-top: 96px;
    padding-bottom: 120px;

    /* Extra inset ON TOP of the container's 24px gutter, from the Text Inset
       control. A full-height hero needs more than a normal section: at 24px the
       headline reads as falling off the edge of the screen. */
    padding-left: calc(24px + var(--rhino-hs-inset));
    padding-right: calc(24px + var(--rhino-hs-inset));
}

/* The width-capped text column. Separate from `.hero-content` so capping it
   cannot disturb the container that positions it. */
.rhino-hslider__copy {
    max-width: 640px;
}

/* Content-position variants act on the COPY inside the container, not on the
   container itself — again so the container keeps centring and the copy stays
   inside the same column the header uses. */
.rhino-hslider__slide.hero--center .rhino-hslider__copy { margin-inline: auto; }
.rhino-hslider__slide.hero--right .rhino-hslider__copy,
.rhino-hslider__slide.hero--bottom-right .rhino-hslider__copy { margin-left: auto; margin-right: 0; }

/* The bottom-anchored positions drop the top padding in main.css. That rule and
   the one above have EQUAL specificity, so which wins comes down to stylesheet
   order — which is not guaranteed for a widget sheet Elementor enqueues. Restated
   here with the slider class added so it wins outright and the bottom variants
   keep sitting on the floor of the slide. */
.rhino-hslider .rhino-hslider__slide.hero--bottom-left .hero-content,
.rhino-hslider .rhino-hslider__slide.hero--bottom-right .hero-content {
    padding-top: 0;
    padding-bottom: 120px;
}

/* Slides 2..n render an <h2> instead of a third <h1> (one <h1> per page). The
   theme only styles `.hero-content h1`, so reproduce it for the <h2> here —
   otherwise slide 2 renders at the global h2 size and the deck looks broken. */
.rhino-hslider__slide .hero-content h2 {
    font-family: var(--font-display, 'Anton', sans-serif);
    font-size: clamp(38px, 6vw, 72px);
    line-height: 1.05;
    text-transform: uppercase;
    letter-spacing: var(--tracking-tight, 0.01em);
    margin: 0 0 20px;
    color: #fff;
}

body.locale-vi .rhino-hslider__slide .hero-content h2 {
    line-height: 1.2;
}

.rhino-hslider__slide .hero-content h2 .text-brand {
    display: block;
    color: var(--brand, #E59744);
}

/* ---------- Entrance animation ----------------------------------- */

/* THE DIRECTION OF THIS MATTERS.
   The animated-away state is scoped to `:not(.is-active)`, and PHP already puts
   `is-active` on slide 1. So the resting state of the visible slide is "fully
   shown" and the animation is what the OTHER slides are waiting in. Inverting it
   — hiding everything by default and revealing with a class — means anything that
   stops the CSS or the JS leaves a full-height slide of blank ink.

   Every variant animates only `opacity`, `transform` and `clip-path`, all of
   which the compositor can handle without re-laying-out the page. */

.rhino-hslider__el {
    /* Shared timing. `--d` is the per-element stagger. */
    transition:
        opacity 800ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) var(--d, 0ms),
        transform 900ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) var(--d, 0ms),
        clip-path 900ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) var(--d, 0ms);
    will-change: opacity, transform;
}

/* The stagger. Set on the element, so each variant below inherits it. */
.rhino-hslider__slide .overline          { --d: 80ms; }
.rhino-hslider__slide .hero-content h1,
.rhino-hslider__slide .hero-content h2   { --d: 200ms; }
.rhino-hslider__slide .hero-content .lead { --d: 380ms; }
.rhino-hslider__slide .hero-actions      { --d: 520ms; }

/* --- fade-up ----------------------------------------------------- */

.rhino-hslider--anim-fade-up .rhino-hslider__slide:not(.is-active) .rhino-hslider__el {
    opacity: 0;
    transform: translateY(22px);
}

/* --- wipe (default) ---------------------------------------------- */

/* The headline sweeps in behind an edge instead of fading. On an ALL-CAPS Anton
   headline that reads like a title card, which suits the brand better than a
   generic fade — and it is a single `clip-path` on one element, not a per-letter
   span structure that would wreck the copy for a screen reader. */
.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .hero-content h1,
.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .hero-content h2 {
    clip-path: inset(0 100% 0 0);
    transform: translateY(8px);
}

.rhino-hslider--anim-wipe .rhino-hslider__slide .hero-content h1,
.rhino-hslider--anim-wipe .rhino-hslider__slide .hero-content h2 {
    /* The resting state has to be declared too. Without it the property has no
       start value to animate FROM on the very first transition and the headline
       simply appears. */
    clip-path: inset(0 -8% 0 0);
}

/* Right-aligned copy wipes from the right, or the motion fights the reading
   direction of the text it is revealing. */
.rhino-hslider--anim-wipe .hero--right:not(.is-active) .hero-content h1,
.rhino-hslider--anim-wipe .hero--right:not(.is-active) .hero-content h2,
.rhino-hslider--anim-wipe .hero--bottom-right:not(.is-active) .hero-content h1,
.rhino-hslider--anim-wipe .hero--bottom-right:not(.is-active) .hero-content h2 {
    clip-path: inset(0 0 0 100%);
}

.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .overline,
.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .lead,
.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .hero-actions {
    opacity: 0;
    transform: translateY(18px);
}

/* The overline gets a rule that draws itself in — a small detail that makes the
   whole block feel authored rather than defaulted. */
.rhino-hslider--anim-wipe .rhino-hslider__slide .overline::after {
    content: '';
    display: block;
    width: 56px;
    height: 2px;
    margin-top: 10px;
    background: var(--brand, #E59744);
    transform-origin: left center;
    transition: transform 700ms var(--ease-out, ease) 260ms;
}

.rhino-hslider--anim-wipe .hero--center .overline::after {
    margin-inline: auto;
    transform-origin: center;
}

.rhino-hslider--anim-wipe .rhino-hslider__slide:not(.is-active) .overline::after {
    transform: scaleX(0);
}

/* --- zoom -------------------------------------------------------- */

.rhino-hslider--anim-zoom .rhino-hslider__slide:not(.is-active) .rhino-hslider__el {
    opacity: 0;
    transform: scale(0.94);
}

.rhino-hslider--anim-zoom .rhino-hslider__copy {
    /* Scale from the text's own edge so the block grows outward from where it
       sits, not from the middle of the screen. */
    transform-origin: left center;
}

.rhino-hslider--anim-zoom .hero--center .rhino-hslider__copy { transform-origin: center; }
.rhino-hslider--anim-zoom .hero--right .rhino-hslider__copy,
.rhino-hslider--anim-zoom .hero--bottom-right .rhino-hslider__copy { transform-origin: right center; }

/* --- none -------------------------------------------------------- */

.rhino-hslider--anim-none .rhino-hslider__el {
    transition: none;
}

/* --- buttons ----------------------------------------------------- */

/* A hover lift on the CTA, which the theme's `.btn` already has, plus a sweep of
   light across the primary button. Reserved for the primary CTA only: the whole
   point of the accent is that exactly one thing per slide carries it. */
.rhino-hslider__slide .hero-actions .btn-red {
    position: relative;
    overflow: hidden;
}

.rhino-hslider__slide .hero-actions .btn-red::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: -60%;
    width: 40%;
    background: linear-gradient(100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.30) 50%, rgba(255, 255, 255, 0) 100%);
    transform: skewX(-18deg);
    pointer-events: none;
}

.rhino-hslider__slide.is-active .hero-actions .btn-red::after {
    animation: rhino-hs-sheen 900ms var(--ease-out, ease) 1100ms 1 both;
}

@keyframes rhino-hs-sheen {
    from { left: -60%; }
    to   { left: 130%; }
}

/* ---------- Arrows ----------------------------------------------- */

.rhino-hslider__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 4;
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--radius-full, 50%);
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 18px;
    cursor: pointer;
    padding: 0;
    transition: background-color var(--dur-base, 250ms) ease,
                color var(--dur-base, 250ms) ease,
                border-color var(--dur-base, 250ms) ease;
}

.rhino-hslider__arrow:hover {
    background: var(--brand, #E59744);
    border-color: var(--brand, #E59744);
    color: #000;
}

.rhino-hslider__arrow:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(229, 151, 68, 0.55);
}

/* --- Side placement (opt-in) ------------------------------------- */

/* This is why Arrow Placement defaults to "bottom": these two are pinned to the
   left and right edges of the slider, which is exactly where left- and
   right-aligned copy lives — so the previous-slide arrow landed on the headline.
   Offsetting the arrows alone does NOT fix that: measured at 1024px the arrow's
   right edge and the headline's left edge both came out at exactly 64px, i.e.
   touching. The layout has to RESERVE the arrow's width, which is what the second
   rule below does. */
.rhino-hslider--arrows-sides .rhino-hslider__arrow--prev { left: 12px; }
.rhino-hslider--arrows-sides .rhino-hslider__arrow--next { right: 12px; }

/* Reserve a full arrow plus a gap on each side. Note this works BECAUSE the
   front end computes as content-box: `inc/enqueue.php` never enqueues the
   theme's style.css, where the universal `box-sizing: border-box` lives (there
   is a comment saying so in the theme's article.css). So this padding shifts the
   text column inward instead of narrowing it, which is what is wanted here. */
.rhino-hslider.rhino-hslider--arrows-sides .rhino-hslider__slide .hero-content {
    padding-left: calc(24px + var(--rhino-hs-inset) + 56px);
    padding-right: calc(24px + var(--rhino-hs-inset) + 56px);
}

/* --- Bottom control row (default) -------------------------------- */

/* Arrows and dots in one centred row beneath the copy. It cannot collide with
   the text at any viewport width or with any of the five content positions,
   which is the whole point of making it the default. */
.rhino-hslider__nav {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 38px;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
}

/* Inside the row the arrows are in normal flow, so the absolute positioning and
   the centring transform from the base rule have to be released. */
.rhino-hslider--arrows-bottom .rhino-hslider__nav .rhino-hslider__arrow {
    position: static;
    transform: none;
    width: 42px;
    height: 42px;
    font-size: 15px;
}

/* DOM order is prev, next, dots; the dots are pulled between the two arrows with
   `order`. Doing it in CSS keeps the document order as "buttons, then the
   tablist", which is the order that reads correctly to a screen reader. */
.rhino-hslider--arrows-bottom .rhino-hslider__nav .rhino-hslider__arrow--prev { order: 0; }
.rhino-hslider--arrows-bottom .rhino-hslider__nav .rhino-hslider__dots { order: 1; }
.rhino-hslider--arrows-bottom .rhino-hslider__nav .rhino-hslider__arrow--next { order: 2; }

/* With the arrows at the edges the row holds only the dots and needs no gap. */
.rhino-hslider--arrows-sides .rhino-hslider__nav { gap: 0; }

/* ---------- Dots ------------------------------------------------- */

/* Positioning comes from `.rhino-hslider__nav`; this is only the row of dots. */
.rhino-hslider__dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

.rhino-hslider__dot {
    width: 12px;
    height: 12px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.65);
    border-radius: var(--radius-full, 50%);
    background: transparent;
    cursor: pointer;
    transition: background-color var(--dur-base, 250ms) ease,
                border-color var(--dur-base, 250ms) ease,
                transform var(--dur-base, 250ms) ease;
}

.rhino-hslider__dot:hover { border-color: var(--brand, #E59744); }

.rhino-hslider__dot.is-active {
    background: var(--brand, #E59744);
    border-color: var(--brand, #E59744);
    transform: scale(1.25);
}

.rhino-hslider__dot:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(229, 151, 68, 0.55);
}

/* Visually hidden dot number, kept in the accessibility tree. */
.rhino-hslider .screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---------- Autoplay progress ------------------------------------ */

.rhino-hslider__progress {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    height: 3px;
    background: rgba(255, 255, 255, 0.14);
}

.rhino-hslider__progress-bar {
    display: block;
    height: 100%;
    width: 0;
    background: var(--brand, #E59744);
}

.rhino-hslider__progress-bar.is-running {
    width: 100%;
    transition: width linear var(--rhino-hs-delay, 7000ms);
}

/* ---------- Tablet / mobile -------------------------------------- */

@media (max-width: 1024px) {
    .rhino-hslider__arrow {
        width: 44px;
        height: 44px;
        font-size: 16px;
    }
}

@media (max-width: 767px) {
    /* EDGE arrows are hidden on a phone: a 44px target at the screen edge fights
       the browser's own back-swipe gesture, and that placement is the one that
       overlaps the headline. The bottom row stays — it is centred, out of the
       way, and on a phone it is the clearest signal that more slides exist. */
    .rhino-hslider--arrows-sides .rhino-hslider__arrow { display: none; }

    /* …and with them gone, give the reserved space back to the copy. A phone has
       no room to spare, and leaving 56px of padding for an invisible button is
       how a headline ends up wrapping every second word. */
    .rhino-hslider.rhino-hslider--arrows-sides .rhino-hslider__slide .hero-content {
        padding-left: calc(24px + var(--rhino-hs-inset));
        padding-right: calc(24px + var(--rhino-hs-inset));
    }

    .rhino-hslider .rhino-hslider__slide .hero-content {
        padding-top: 84px;
        padding-bottom: 104px;
    }

    /* The per-slide width control is desktop-first; on a phone the copy should
       use the full column whatever it was set to. Note this caps the COPY — the
       container's own max-width is never touched, because that is what keeps the
       text lined up with the rest of the site. */
    .rhino-hslider__copy {
        max-width: none !important;
    }

    .rhino-hslider__slide .hero-content h1,
    .rhino-hslider__slide .hero-content h2 {
        font-size: clamp(30px, 8.5vw, 44px);
    }

    .rhino-hslider__slide .hero-content .lead {
        font-size: 16px;
        margin-bottom: 24px;
    }

    /* Stacked full-width CTAs beat two half-width pills that wrap awkwardly. */
    .rhino-hslider__slide .hero-actions {
        gap: 12px;
    }
    .rhino-hslider__slide .hero-actions .btn {
        flex: 1 1 100%;
        justify-content: center;
    }

    .rhino-hslider__nav { bottom: 26px; gap: 14px; }

    /* Centre-positioned photos rarely survive a 9:16 crop with a face intact,
       so the scrim is strengthened on small screens where the text overlaps
       more of the frame. */
    .rhino-hslider__slide .hero-bg::after {
        opacity: calc(var(--rhino-hs-scrim, 1) * 1.15);
    }
}

/* ---------- Reduced motion --------------------------------------- */

/* Everything decorative is switched off — and, importantly, the animated-AWAY
   STATES are reset too, not just the transitions. Killing the transition alone
   would leave an inactive slide sitting permanently at `opacity: 0` and
   `clip-path: inset(0 100% 0 0)`, so the moment it became active it would be a
   blank hero rather than a still one. */
@media (prefers-reduced-motion: reduce) {
    .rhino-hslider__slide,
    .rhino-hslider__slide .hero-bg img,
    .rhino-hslider__el,
    .rhino-hslider__slide .overline::after,
    .rhino-hslider__progress-bar {
        transition: none !important;
        animation: none !important;
    }

    .rhino-hslider__slide .hero-bg img {
        transform: none !important;
    }

    .rhino-hslider__slide:not(.is-active) .rhino-hslider__el {
        opacity: 1;
        transform: none;
        clip-path: none;
    }

    .rhino-hslider__slide .hero-content h1,
    .rhino-hslider__slide .hero-content h2 {
        clip-path: none;
    }

    .rhino-hslider__slide .overline::after {
        transform: none;
    }

    .rhino-hslider__slide.is-active .hero-actions .btn-red::after {
        display: none;
    }
}

/* ---------- Elementor editor ------------------------------------- */

/* Elementor wraps a widget in .elementor-widget-container, which is a plain
   block with no height. That is fine for a normal section but the slider's
   slides are absolute, so the wrapper must be told to carry the height or the
   editor canvas collapses to 0 and the widget looks like it failed to render. */
.elementor-widget-rhino_hero_slider .elementor-widget-container {
    height: 100%;
}

/* ---------- Never let this hero start invisible ------------------- */

/* `.elementor-invisible { visibility: hidden }` is how Elementor's Entrance
   Animation hides an element until its scroll observer reveals it. On the first
   screen of the site that is never acceptable — and it produced a bug that looked
   perfect in the editor (which removes the class on render) and broken in public:
   the active slide still showed because `.is-active` sets `visibility: visible`,
   but the dots, arrows and progress bar inherited `hidden` and vanished.
   The root cause was a control name collision, fixed in the widget. This is the
   belt: whatever puts `elementor-invisible` on this widget — a stale saved
   setting, a future control name, someone ticking Entrance Animation in the
   Advanced tab — the hero stays visible. The widget has its own Text Animation
   control, which animates opacity and transform rather than hiding the wrapper. */
.elementor-widget-rhino_hero_slider.elementor-invisible {
    visibility: visible;
}
