/*
 * ---------------------------------------------------------------------------------------------------------------------
 * Motion — css/motion.css
 *
 * The scroll-reveal system. Enqueued globally by functions.php after
 * global.css, because reveals are used by several blocks and each block's
 * own style.css only loads on pages where that block appears.
 *
 * How it works
 * ------------
 * Mark anything that should reveal with data-reveal="rise|left|right" in a
 * block's render.php. js/theme.js watches it and adds .is-inview once when
 * it first scrolls into view. Nothing animates back out — content that
 * re-hides itself on the way up is the thing that makes a site feel like a
 * showreel rather than a page.
 *
 * Three guards keep it safe:
 *
 *   1. The hidden state only applies under .js-reveal, a class the inline
 *      snippet in functions.php puts on <html>. No JS, no hiding — the
 *      page renders normally.
 *   2. Everything sits inside prefers-reduced-motion: no-preference, so a
 *      visitor who has asked for less motion gets the final state outright.
 *   3. The same snippet drops .js-reveal after 2.5s if theme.js has not
 *      reported in, so a failed script request cannot leave a page blank.
 *
 * Depends on tokens from css/global.css.
 * =====================================================================================================================
 */

:root {
	/* Deliberately small. A reveal you consciously notice is a reveal that
	   will irritate on the fifth visit — this is 24px of travel, not 100. */
	--reveal-rise     : 1.5rem;   /* 24px ÷ 16 — vertical travel */
	--reveal-slide    : 2.5rem;   /* 40px ÷ 16 — horizontal travel for split rows */
	--reveal-duration : var(--motion-slow);
}


@media (prefers-reduced-motion: no-preference) {

	.js-reveal [data-reveal] {
		opacity: 0;
	}

	.js-reveal [data-reveal="rise"] {
		transform: translate3d(0, var(--reveal-rise), 0);
	}

	.js-reveal [data-reveal="left"] {
		transform: translate3d(calc(var(--reveal-slide) * -1), 0, 0);
	}

	.js-reveal [data-reveal="right"] {
		transform: translate3d(var(--reveal-slide), 0, 0);
	}

	/*
	 * The transition lives on the revealed state, not the resting one, so
	 * the element snaps to its start position without animating into it.
	 *
	 * --reveal-index is set inline per item by render.php. It staggers a
	 * row of columns by one --motion-stagger each, which reads as the row
	 * arriving together rather than as three separate events.
	 */
	.js-reveal [data-reveal].is-inview {
		opacity: 1;
		transform: none;
		transition:
			opacity var(--reveal-duration) var(--ease-out-soft),
			transform var(--reveal-duration) var(--ease-out-soft);
		transition-delay: calc(var(--reveal-index, 0) * var(--motion-stagger));
	}

}


/*
 * Horizontal travel is dropped below 768px
 * ---------------------------------------------------------------------------------------------------------------------
 * A split row is stacked by then, so sliding the halves in from opposite
 * sides no longer describes the layout — and off-canvas transforms on a
 * narrow screen risk a horizontal scrollbar. Both fall back to the rise.
 */

@media only screen and (max-width: 48em) {

	.js-reveal [data-reveal="left"],
	.js-reveal [data-reveal="right"] {
		transform: translate3d(0, var(--reveal-rise), 0);
	}

}
