/*
 * Ken Burns for Elementor.
 *
 * The effect needs a layer it can scale, because you cannot transform an
 * element's own background without transforming its content too. The layer is
 * injected as a real child element (see ken-burns.js) rather than a pseudo
 * element, because on a container `::before` is already Elementor's background
 * overlay and `::after` is used by the Shimmer FX plugin.
 *
 * `background: inherit` copies the host's background verbatim - image, size,
 * position, repeat - so the layer is a faithful duplicate with no need to know
 * the image URL, and it follows Elementor's responsive background settings for
 * free.
 *
 * Nothing here affects the host's layout: the layer is absolutely positioned,
 * and it clips the zoom inside itself so the host never needs `overflow`.
 */

:root {
	--ekb-play-state: running;
}

@media ( prefers-reduced-motion: reduce ) {
	:root {
		--ekb-play-state: paused;
	}
}

/*
 * The layer is absolutely positioned, so the host needs to be a containing
 * block. Containers and sections already are. `:where()` keeps this at zero
 * specificity so it can never override Elementor's Position control - see the
 * Shimmer FX plugin, where a higher-specificity version of this exact rule
 * broke every element set to Absolute or Fixed.
 */
:where( .ekb-yes ) {
	position: relative;
}

/* Confines the layer's negative z-index to the host, so it lands above the
 * host's own background and below its content. No layout effect. */
.ekb-yes {
	isolation: isolate;
}

/* The clipping frame. Keeps the zoom inside the host and follows its corners,
 * which is why the host itself never needs `overflow: hidden`. */
.ekb-yes > .ekb-layer {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	overflow: hidden;
	border-radius: inherit;
	pointer-events: none;
	z-index: -1;
	background: inherit;
}

/* The thing that actually moves. */
.ekb-yes > .ekb-layer > .ekb-img {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background: inherit;
	transform-origin: var( --ekb-origin, center center );
	animation-name: ekb-zoom;
	animation-duration: var( --ekb-duration, 20s );
	animation-timing-function: var( --ekb-ease, ease-in-out );
	animation-direction: var( --ekb-direction, alternate );
	animation-iteration-count: infinite;
	animation-play-state: var( --ekb-play-state, running );
	will-change: transform;
}

@keyframes ekb-zoom {
	from { transform: scale( 1 ); }
	to   { transform: scale( var( --ekb-scale, 1.2 ) ); }
}

/*
 * "Pause When Off-Screen" (`ekb-io-yes`). The front-end script adds
 * `ekb-out-of-view` while its IntersectionObserver reports the element is not
 * visible. This selector has four classes (specificity 0,4,0) against the base
 * rule's three (0,3,0), so it wins outright with a plain value - no
 * `!important`, and no interference with the reduced-motion variable above:
 * that rule already forces `paused` its own way, this one forces it for a
 * different reason, and either being true is enough to stop the animation.
 */
.ekb-yes.ekb-out-of-view > .ekb-layer > .ekb-img {
	animation-play-state: paused;
}
