/**
 * Block Motion
 *
 * Timing is shared by every effect, so a site moves in one consistent way.
 * Themes can tune it by overriding these properties.
 */
:root {
	--block-motion-duration: 1200ms;
	--block-motion-ease: cubic-bezier(0.33, 1, 0.68, 1);
	--block-motion-distance: 1.5rem;
	--block-motion-stagger: 200ms;
	/* Parallax travel each way, as a fraction of the image height */
	--block-motion-parallax: 0.1;
}

/*
 * Starting state. Only under `.block-motion-js` (set in the <head> when
 * JavaScript runs and reduced motion is off), so content is never hidden
 * otherwise. Staggered blocks hide their children instead of themselves;
 * each child gets `is-motion-in` as it comes into view.
 */
.block-motion-js :is([data-motion="fade-up"], [data-motion="fade-in"]):not([data-motion-stagger], .is-motion-in),
.block-motion-js [data-motion-stagger] > :not(.is-motion-in) {
	opacity: 0;
}

.block-motion-js [data-motion="reveal"]:not(.is-motion-in) {
	clip-path: inset(0 100% 0 0);
}

.block-motion-js [data-motion="reveal"]:not(.is-motion-in):dir(rtl) {
	clip-path: inset(0 0 0 100%);
}

/*
 * Revealed. `backwards` holds the first frame during a delay, then hands
 * back to the block's own styles, so hover transitions keep working.
 */
[data-motion="fade-up"]:not([data-motion-stagger]).is-motion-in,
[data-motion="fade-up"][data-motion-stagger] > .is-motion-in {
	animation: block-motion-fade-up var(--block-motion-duration) var(--block-motion-ease) backwards;
}

[data-motion="fade-in"]:not([data-motion-stagger]).is-motion-in,
[data-motion="fade-in"][data-motion-stagger] > .is-motion-in {
	animation: block-motion-fade-in var(--block-motion-duration) var(--block-motion-ease) backwards;
}

/* As specific as the rules above and after them, so their `animation`
   shorthand doesn't reset the delay to 0 */
[data-motion][data-motion-stagger] > .is-motion-in {
	animation-delay: calc(var(--block-motion-index, 0) * var(--block-motion-stagger));
}

[data-motion="reveal"].is-motion-in {
	animation: block-motion-reveal calc(var(--block-motion-duration) * 1.25) var(--block-motion-ease) backwards;
}

[data-motion="reveal"].is-motion-in:dir(rtl) {
	animation-name: block-motion-reveal-rtl;
}

@keyframes block-motion-fade-up {
	from {
		opacity: 0;
		translate: 0 var(--block-motion-distance);
	}
}

@keyframes block-motion-fade-in {
	from {
		opacity: 0;
	}
}

/* Explicit end shape: `inset()` to `none` can't interpolate and would jump */
@keyframes block-motion-reveal {
	from {
		clip-path: inset(0 100% 0 0);
	}
	to {
		clip-path: inset(0);
	}
}

@keyframes block-motion-reveal-rtl {
	from {
		clip-path: inset(0 0 0 100%);
	}
	to {
		clip-path: inset(0);
	}
}

/*
 * Parallax: the image or video moves slightly slower than the page. A
 * scroll-driven animation, so no script; browsers without support (or with
 * reduced motion) show the block as it is.
 */
@media (prefers-reduced-motion: no-preference) {
	@supports (animation-timeline: view()) {
		[data-motion="parallax"] {
			overflow: clip;
		}

		[data-motion="parallax"] > :is(img, video).wp-block-cover__image-background:not(.has-parallax),
		[data-motion="parallax"] > video.wp-block-cover__video-background,
		.wp-block-image[data-motion="parallax"] img {
			/* Just enough zoom to keep the edges hidden at full travel */
			scale: calc(1 + var(--block-motion-parallax) * 2.2);
			animation: block-motion-parallax linear both;
			animation-timeline: view();
		}
	}
}

@keyframes block-motion-parallax {
	from {
		translate: 0 calc(var(--block-motion-parallax) * -100%);
	}
	to {
		translate: 0 calc(var(--block-motion-parallax) * 100%);
	}
}
