/* ============================================================================
   BENIS SHOES — MOTION
   ----------------------------------------------------------------------------
   The reveal states and the hero entry choreography. Loaded last so a reveal
   can override a component's resting transform without !important.

   Two hard rules:

   1. Only transform and opacity are animated. Anything that animates width,
      height, top or margin forces layout on every frame and will not hold 60fps
      on a mid-range Android phone, which is most of this store's traffic.

   2. Content is never hidden by motion alone. Every hidden state below is
      inside `.js-motion`, a class benis-ui.js puts on <html> at boot, and is
      cancelled wholesale by prefers-reduced-motion. If the JS never runs, the
      page renders fully visible and static.
   ========================================================================== */

/* ── Reveal ──────────────────────────────────────────────────────────────── */

/* The resting (pre-reveal) state only exists when JS is present to undo it. */
.js-motion [data-reveal],
.js-motion [data-reveal-group] > * {
	opacity: 0;
	transform: translate3d(0, 1.25rem, 0);
	transition:
		opacity 620ms var(--ease-out),
		transform 620ms var(--ease-out);
	will-change: transform, opacity;
}

.js-motion [data-reveal].is-revealed,
.js-motion [data-reveal-group] > .is-revealed {
	opacity: 1;
	transform: none;
	/* Dropped once the element has arrived — a permanent will-change on every
	   card keeps a compositor layer alive for the life of the page. */
	will-change: auto;
}

/* Directional variants, for elements whose entrance should read as coming from
   the side of the composition they belong to. */
.js-motion [data-reveal="start"]  { transform: translate3d(1.5rem, 0, 0); }
.js-motion [data-reveal="end"]    { transform: translate3d(-1.5rem, 0, 0); }
.js-motion [data-reveal="scale"]  { transform: scale(0.96); }
.js-motion [data-reveal="fade"]   { transform: none; }

html[dir="ltr"] .js-motion [data-reveal="start"] { transform: translate3d(-1.5rem, 0, 0); }
html[dir="ltr"] .js-motion [data-reveal="end"]   { transform: translate3d(1.5rem, 0, 0); }

/* ── Hero entry ──────────────────────────────────────────────────────────────
   Only the copy animates in now, and only on the ACTIVE slide.

   The old version also wiped `.hero__media` open with a clip-path and settled
   its image back from an overscale. That cannot survive the slider: the media
   now belongs to every slide, so the entry animation would replay the wipe on
   frames that are cross-fading, and clip-path on a slide that is also animating
   opacity and scale is three composited properties fighting over one element.
   The cross-fade IS the media transition; the entry is the copy arriving over
   the first frame.

   `.hero__arc` and `.hero__proof` rules were deleted with the elements they
   animated — the portrait split-hero they belonged to no longer exists. */

.js-motion .hero__slide.is-active .hero__kicker,
.js-motion .hero__slide.is-active .hero__title,
.js-motion .hero__slide.is-active .hero__text,
.js-motion .hero__slide.is-active .hero__actions {
	opacity: 0;
	transform: translate3d(0, 1rem, 0);
	transition:
		opacity 700ms var(--ease-out),
		transform 700ms var(--ease-out);
}

.js-motion .hero.is-entered .hero__slide.is-active .hero__kicker,
.js-motion .hero.is-entered .hero__slide.is-active .hero__title,
.js-motion .hero.is-entered .hero__slide.is-active .hero__text,
.js-motion .hero.is-entered .hero__slide.is-active .hero__actions {
	opacity: 1;
	transform: none;
}

.js-motion .hero.is-entered .hero__slide.is-active .hero__kicker  { transition-delay: 160ms; }
.js-motion .hero.is-entered .hero__slide.is-active .hero__title   { transition-delay: 240ms; }
.js-motion .hero.is-entered .hero__slide.is-active .hero__text    { transition-delay: 340ms; }
.js-motion .hero.is-entered .hero__slide.is-active .hero__actions { transition-delay: 440ms; }

/* ── Parallax layers ─────────────────────────────────────────────────────── */

/* The JS writes transform on these directly, so they must not carry a
   transition or the easing would fight the rAF loop. */
[data-parallax-depth] {
	will-change: transform;
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */

/* Everything off. Note this resets the hidden states too, not just the
   transitions — animating nothing is useless if the content stays at
   opacity 0. */
@media (prefers-reduced-motion: reduce) {
	.js-motion [data-reveal],
	.js-motion [data-reveal-group] > *,
	.js-motion .hero__kicker,
	.js-motion .hero__title,
	.js-motion .hero__text,
	.js-motion .hero__actions,
	.js-motion .hero__media,
	.js-motion .hero__media img {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
		transition: none !important;
		will-change: auto !important;
	}

	/* The slide is deliberately NOT in the list above. Its opacity is which
	   slide you are looking at, not an animation — forcing it to 1 would stack
	   every banner on top of the others. Only the transition is removed, so the
	   slider still works and simply cuts between frames. */
	.js-motion .hero__slide {
		transition: none !important;
		scale: 1 !important;
	}
}
