/**
 * 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 on a class, and the gate is 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
 * `.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. Without it every block simply renders where it belongs, which is
 * also what browsers get with JavaScript off.
 *
 * Deliberately not gated on prefers-reduced-motion: gating made the site's
 * motion look broken on every machine with system animations off (Windows'
 * "Animation effects", macOS' "Reduce motion").
 *
 * 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. */

.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; they stay apart because that one plays in the editor on request,
 * without the ready class.
 */
.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. 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;
	}
}
