/**
 * Entry animations for blocks.
 *
 * Hand-written rather than built from src/animation/, for the same reason the
 * carousel's motion.css is: it has to reach the editor canvas, and the only
 * reliable way a plugin does that is add_editor_style() with an absolute URL.
 * A stylesheet enqueued on enqueue_block_editor_assets lands in the admin
 * document instead, and the block editor only copies such a sheet into the
 * iframe when one of its selectors mentions `.editor-styles-wrapper` or
 * `.wp-block` — a heuristic nothing here would satisfy.
 *
 * Three things live here, in the order they appear:
 *
 *   1. The presets. Each one says only where a block starts from; the state it
 *      ends in is always the block's own. They are plain custom properties, set
 *      unconditionally, and none of them can hide anything by itself.
 *   2. The front-end transition, which is what actually hides a block until it
 *      is seen. Gated twice over, and the gates are the point of the file.
 *   3. The editor's on-demand preview, driven by keyframes instead.
 *
 * Why the hiding is gated on a class the page has to earn: a block waiting to
 * animate is a block at opacity 0, and if the script that reveals it never
 * arrives that is a permanently blank page. So the rule needs BOTH
 * `.campweb-animation-ready` on the root element — added by a small inline
 * script in the head, which cannot 404 the way a built file can, and removed
 * again after five seconds if the view module never boots to clear that
 * deadline — AND a visitor who has not asked for reduced motion. Miss either
 * and every block simply renders where it belongs, which is also what browsers
 * get with JavaScript off.
 *
 * Deliberately no fade-in-from-left/right presets. A horizontal translate
 * extends the page's scrollable area sideways, so every block below the fold
 * still waiting its turn would put a horizontal scrollbar on the page — and the
 * only fix from here, clipping overflow on the body, is far too blunt a thing
 * for a plugin to impose on a theme. Vertical shifts have the same effect on
 * the bottom of a page that already scrolls, where 2rem goes unnoticed.
 */

/* 1. Presets. */

.campweb-animation--fade {
	--campweb-animation-from-opacity: 0;
}

.campweb-animation--fade-up {
	--campweb-animation-from-opacity: 0;
	--campweb-animation-from-transform: translateY(2rem);
}

.campweb-animation--fade-down {
	--campweb-animation-from-opacity: 0;
	--campweb-animation-from-transform: translateY(-2rem);
}

.campweb-animation--zoom-in {
	--campweb-animation-from-opacity: 0;
	--campweb-animation-from-transform: scale(0.92);
}

/* 2. The front end. */

@media (prefers-reduced-motion: no-preference) {
	.campweb-animation-ready .campweb-animation {
		opacity: var(--campweb-animation-from-opacity, 1);
		transform: var(--campweb-animation-from-transform, none);
		transition-property: opacity, transform;
		transition-duration: var(--campweb-animation-duration, 600ms);
		transition-timing-function: var(--campweb-animation-easing, cubic-bezier(0.22, 0.61, 0.36, 1));
		transition-delay: var(--campweb-animation-delay, 0ms);
	}

	/*
	 * Added once, by the view module, and never taken away again: an entry
	 * animation that replayed every time the block scrolled back past would be
	 * a different feature, and a tiring one.
	 *
	 * `transform: none` rather than restoring whatever the block had, because
	 * the starting transform replaced it wholesale. A block that carries a
	 * transform of its own therefore cannot also carry one of these presets —
	 * worth knowing, though nothing in the editor offers both.
	 */
	.campweb-animation-ready .campweb-animation.is-animation-visible {
		opacity: 1;
		transform: none;
	}

	/*
	 * A second showing, for a block that was revealed somewhere the viewport
	 * could not speak for — a fading carousel's slides all arrive at once, so
	 * the one brought forward later has to be told to play again. See the
	 * replay event in src/animation/view.js.
	 *
	 * Keyframes rather than the transition above, and the block keeps its
	 * resting state throughout. Taking `is-animation-visible` off and putting
	 * it back would look like the obvious way to do this and does nothing at
	 * all: the rule it falls back to is transitioned too, so the block starts
	 * travelling towards its hidden state, and restoring the class a moment
	 * later just sends it back to where it already was. An animation plays
	 * over a resting block instead of moving it away first, which is also what
	 * keeps a block from being left hidden if a replay is interrupted.
	 *
	 * Same declarations as the editor's preview rule at the bottom of this
	 * file, for the same reason; they stay apart because that one is meant to
	 * play for someone who asked for it, reduced motion or not.
	 */
	.campweb-animation-ready .campweb-animation.is-animation-replaying {
		animation-name: campweb-animation-enter;
		animation-duration: var(--campweb-animation-duration, 600ms);
		animation-timing-function: var(--campweb-animation-easing, cubic-bezier(0.22, 0.61, 0.36, 1));
		animation-delay: var(--campweb-animation-delay, 0ms);
		animation-fill-mode: both;
	}
}

/* 3. The editor's preview button. */

/*
 * Keyframes, not the transition above, so the effect can be replayed from a
 * resting block without anything having to move it back first.
 *
 * Not gated on prefers-reduced-motion, unlike everything else here. That
 * setting is about motion nobody asked for; this plays only when an editor
 * presses a button asking to see it.
 */
.campweb-animation.is-animation-preview {
	animation-name: campweb-animation-enter;
	animation-duration: var(--campweb-animation-duration, 600ms);
	animation-timing-function: var(--campweb-animation-easing, cubic-bezier(0.22, 0.61, 0.36, 1));
	animation-delay: var(--campweb-animation-delay, 0ms);
	animation-fill-mode: both;
}

@keyframes campweb-animation-enter {
	from {
		opacity: var(--campweb-animation-from-opacity, 1);
		transform: var(--campweb-animation-from-transform, none);
	}

	to {
		opacity: 1;
		transform: none;
	}
}
