/*
 * Carousel Transitions.
 *
 * Fade and Short Slide are built entirely on Swiper's own always-present core
 * classes (`swiper-slide-active` / `-prev` / `-next`), not on Swiper's
 * optional effect modules (EffectFade / EffectCreative). Elementor's carousel
 * widgets are not guaranteed to load those modules, and reconfiguring or
 * reinitialising Elementor's own Swiper instance to add them would mean
 * reimplementing everything else Elementor already wired up (autoplay,
 * navigation, pagination, breakpoints...) - fragile, and liable to drift out
 * of sync with Elementor's own carousel widget updates. Building on the core
 * classes instead needs nothing but CSS plus a few lines of JS to add one
 * class - see carousel-transitions.js.
 *
 * Only ever active when a widget opts in (`mct-active`, added by the script
 * only after it confirms the carousel is one-slide-at-a-time - see the
 * `slidesPerView` note there). A carousel nobody has touched this control on
 * gets none of these rules and is completely unaffected.
 */

/*
 * Note what ISN'T here: an earlier version of this file tried to neutralise
 * Swiper's own wrapper transform with `transform: none !important`. That
 * broke Swiper itself - its internal "is a transition currently running"
 * bookkeeping waits for a real `transitionend` event on the wrapper, which
 * never fires when the transform's computed value never actually changes, so
 * every carousel command after the first got silently swallowed. The fix
 * lives in carousel-transitions.js: it sets Swiper's own `virtualTranslate`
 * option, which is Swiper's documented way of saying "I will render slide
 * position myself" - so Swiper simply never writes a transform to the
 * wrapper in the first place, and nothing here has to fight it.
 */

/*
 * Only the active slide stays part of normal layout flow - every other slide
 * is pulled out with `position: absolute`. This is what lets the carousel's
 * height keep tracking the current slide's natural height with no JS
 * measuring: a flex row's height is set by its in-flow children, and the
 * active slide is the only one left in flow.
 */
.mct-active > .swiper-wrapper > .swiper-slide {
	position: absolute;
	inset: 0;
	height: 100%;
	pointer-events: none;
	z-index: 1;
	opacity: 0;
	transform: translateX( 0 );
	transition:
		opacity var( --mct-duration, 0.5s ) ease,
		transform var( --mct-duration, 0.5s ) ease;
}

.mct-active > .swiper-wrapper > .swiper-slide-active {
	position: relative;
	pointer-events: auto;
	z-index: 2;
	opacity: 1;
	transform: translateX( 0 );
}

/*
 * Short Slide only: the outgoing/incoming neighbours travel in from a short
 * distance either side rather than sitting still and just fading. Fade has no
 * equivalent rule, so its non-active slides use the base translateX(0) above
 * and simply fade in place.
 */
.mct-short-slide > .swiper-wrapper > .swiper-slide-prev {
	transform: translateX( calc( -1 * var( --mct-distance, 20% ) ) );
}

.mct-short-slide > .swiper-wrapper > .swiper-slide-next {
	transform: translateX( var( --mct-distance, 20% ) );
}

/*
 * Used momentarily by carousel-transitions.js's FLIP fix
 * (forceCorrectStartingOffset) while it forces the incoming slide's starting
 * position - see the long comment on that function for why the fix exists at
 * all. This re-lists the SAME opacity transition as the base rule above, just
 * without transform, rather than reaching for `transition: none` on the
 * element: that would suspend the opacity crossfade too for however long this
 * class is present, turning a smooth fade into an instant jump-cut for every
 * Short Slide transition. Restricting the freeze to transform alone leaves
 * the crossfade untouched regardless of timing.
 *
 * `visibility` used to be part of both this rule and the base one above - a
 * belated switch from hidden to visible, so a fully-transparent inactive
 * slide couldn't be focused or hit by a screen reader in the moment right
 * before it's fully faded out. It caused a real, visible bug: toggling this
 * class on and straight back off resets `visibility`'s delay countdown to
 * start from the moment it's removed rather than the moment the transition
 * began, because `visibility` hadn't actually started transitioning yet at
 * that point (its own delay was still pending) - so it ended up staying
 * `hidden` for up to a full --mct-duration AFTER opacity had already reached
 * 1, on a real Swiper instance: a fully rendered, fully opaque incoming slide
 * that the browser was nonetheless not painting at all, looking exactly like
 * "blank, then the image pops in". `opacity: 0` and `pointer-events: none`
 * on inactive slides already cover the visual hiding and the click
 * prevention that actually matter; losing the belated visibility/focus
 * nicety is a far smaller cost than that bug.
 */
.mct-active.mct-instant-transform > .swiper-wrapper > .swiper-slide-active {
	transition: opacity var( --mct-duration, 0.5s ) ease;
}
