/*
 * Reveal animations, triggered when a block first comes into view.
 *
 * This replaced a scroll-driven implementation that tied each block's progress
 * to a view() timeline. That version was elegant — no JavaScript at all — and
 * wrong on two counts, both measured against the running site:
 *
 *   Firefox does not implement it. Firefox 154 answers no to
 *   animation-timeline: view(), animation-timeline: scroll() and
 *   animation-range-start, so every Firefox reader got no reveal whatsoever.
 *   Chromium and Safari were the only engines the effect existed in.
 *
 *   Where it did run, it ran off the bottom of the screen. A view() `entry`
 *   range ends the moment the block is fully inside the scrollport, so the
 *   whole animation played out in the lowest part of the viewport and was over
 *   before the reader's eye arrived: measured at 73% down the screen for a
 *   508px team card. Worse for short blocks, because an `entry` range is only
 *   as long as the block is tall — a 64px sponsor logo animated over 64px of
 *   scroll, so its entire six-step stagger finished inside 3% of the viewport
 *   and read as a blink.
 *
 * A viewport trigger has neither problem. It works in every browser that has
 * IntersectionObserver, and the animation runs on its own clock once, at a
 * duration a reader can actually see, wherever the block happens to be.
 *
 * What is given up, and it is a real loss: the reveal no longer runs backwards
 * when the reader scrolls up, and it no longer tracks the scroll exactly. It
 * plays once, forwards.
 *
 * Two block styles, registered in inc/animations.php, switch it on:
 *
 *   is-style-reveal            the block itself rises into place
 *   is-style-reveal-children   its direct children rise in, one after another
 *
 * This is a stylesheet of its own rather than part of style.css because
 * style.css is also handed to the editor canvas by add_editor_style(). A block
 * that stays transparent until it is scrolled into view reads well and edits
 * badly, so this one is enqueued on the front end only — see inc/animations.php.
 */

:root {
	/* How far a block travels on its way in. */
	--dicken--reveal-distance: 2rem;

	/*
	 * How long one reveal takes, and how far apart two consecutive ones start.
	 * Real time now, not a share of a scroll range, which is the whole point of
	 * the change: a 64px logo and a 508px card take exactly as long as each
	 * other, where under the scroll timeline the logo got a twentieth of the
	 * card's range and vanished.
	 *
	 * Four steps of stagger add 270ms to the last child, which stays under the
	 * reveal's own duration so a row still reads as one gesture rather than as
	 * four separate ones.
	 */
	--dicken--reveal-duration: 640ms;
	--dicken--reveal-stagger: 90ms;

	/* Decelerating, no overshoot — the same curve as the theme's motion tokens. */
	--dicken--reveal-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/*
 * Nothing below hides anything outside these two guards, which is the point of
 * them.
 *
 * `.dicken-reveal-ready` is put on <html> by the script in inc/animations.php,
 * and only once that script has confirmed IntersectionObserver exists. So a
 * browser without it, a reader with JavaScript off, and anything that stops the
 * script running at all, are all served the finished article rather than a page
 * of permanently invisible content. That guard is doing the job the @supports
 * gate did for the scroll-driven version, and it has to stay for the same
 * reason.
 *
 * `screen` also keeps print out, where nothing scrolls into view.
 */
@media screen and (prefers-reduced-motion: no-preference) {
	.dicken-reveal-ready .is-style-reveal,
	.dicken-reveal-ready .is-style-reveal-children > * {
		opacity: 0;
		translate: 0 var(--dicken--reveal-distance);
		transition:
			opacity var(--dicken--reveal-duration) var(--dicken--reveal-ease) var(--dicken--reveal-delay, 0ms),
			translate var(--dicken--reveal-duration) var(--dicken--reveal-ease) var(--dicken--reveal-delay, 0ms);
	}

	/*
	 * translate rather than transform, so a reveal composes with the hover
	 * transforms in style.css instead of overwriting them: a card whose photo
	 * scales on hover and whose wrapper rises on reveal are two different
	 * properties, and both survive.
	 */
	.dicken-reveal-ready .is-revealed {
		opacity: 1;
		translate: 0;
	}

	/*
	 * Children of one row come into view together, so their order has to come
	 * from a delay rather than from when each is seen — the observer watches the
	 * row, not the children, and reveals all of them at once.
	 *
	 * The offset repeats every fourth child instead of growing with the list:
	 * nothing should have to wait through twenty steps, and past the fourth
	 * child a vertical list is separated by the scroll itself anyway. That cap
	 * is also why this is :nth-child() rather than a sibling-index() ramp, which
	 * would need the same cap written on top.
	 */
	.dicken-reveal-ready .is-style-reveal-children > :nth-child(4n + 2) {
		--dicken--reveal-delay: var(--dicken--reveal-stagger);
	}

	.dicken-reveal-ready .is-style-reveal-children > :nth-child(4n + 3) {
		--dicken--reveal-delay: calc(2 * var(--dicken--reveal-stagger));
	}

	.dicken-reveal-ready .is-style-reveal-children > :nth-child(4n + 4) {
		--dicken--reveal-delay: calc(3 * var(--dicken--reveal-stagger));
	}
}
