/**
 * Shared scroll-reveal recipe.
 *
 * Mark a section root with data-actabl-reveal and each element that should
 * animate with data-actabl-reveal-item. The JS adds data-actabl-reveal-init on
 * load and is-visible when the section scrolls in, so a JS failure leaves every
 * section fully visible rather than blank.
 *
 * The .actabl-reveal / .actabl-reveal-item classes do the same job and exist for
 * sections built from Beaver Builder rows, whose settings only expose a CSS
 * Class field and cannot set a data attribute.
 *
 * WHAT THE HERO DOES, AND WHY IT IS THE REFERENCE
 *
 * The hero lifts six content blocks — logo, eyebrow, heading, media,
 * description, button — 24px each, 80ms apart, in reading order, over a
 * background that never moves. Opacity runs on `ease` while transform runs on
 * an expo-out curve, so each block becomes readable slightly before it stops
 * moving: it arrives and lands rather than sliding into place. The last block
 * starts 320ms after the first and everything settles around 1.02s.
 *
 * What sells it is the number of beats, not the distance. Six staggered blocks
 * read as one wave travelling down the section. A section that lifts a single
 * block the same 24px reads as a plain fade, which is why the flatter sections
 * felt too subtle even at identical timing values.
 *
 * THE RULE
 *
 * The unit of reveal is a top-level content block of the section: the heading
 * is the first beat, then each card, media object or button that follows.
 * Never animate inside a block — a card lifts as one object and its title,
 * number and copy ride along with it. Containers that merely hold content (a
 * section background, the CTA's white card) stay still and let their contents
 * cascade over them, exactly as the hero's background does.
 *
 * USAGE
 *
 * Children stagger 80ms apart by position within their own parent. Because
 * those positions restart in each container, a heading and the first card of a
 * grid beneath it would otherwise both fire at 0. Set --actabl-reveal-offset on
 * the container to push its whole run back by a beat and keep the cascade
 * continuous across the section.
 *
 * Three knobs, all inheritable so they can be set on a container:
 *   --actabl-reveal-step    gap between consecutive items, default 80ms. Widen
 *                           it where items are small and alike, such as a list
 *                           of FAQ rows, which otherwise all overlap and read
 *                           as one block rather than a sequence.
 *   --actabl-reveal-offset  flat head start for a whole container.
 *   --actabl-reveal-index   position in the run; set it directly to move a
 *                           single element out of source order.
 *
 * WHEN IT FIRES
 *
 * A section reveals once its top edge is about two thirds of the way up the
 * window. A section taller than the window is handled per item instead, since
 * firing the whole thing off its top edge would reveal the lower rows while
 * they were still well below the fold. Both rules live in actabl-reveal.js.
 */

[data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item) {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
	transition-delay: calc(var(--actabl-reveal-offset, 0s) + var(--actabl-reveal-index, 0) * var(--actabl-reveal-step, 0.08s));
}

/* Two ways an item becomes visible: the whole section fired at once, or — in a
   section taller than the window — the item scrolled into view on its own. */
[data-actabl-reveal-init].is-visible :is([data-actabl-reveal-item], .actabl-reveal-item),
[data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item).is-visible {
	opacity: 1;
	transform: translateY(0);
}

/* Position in the run, wrapped in :where() so it carries zero specificity and
   any module rule wins without a specificity fight. Positions count within each
   item's own parent, so a heading and the first card of a grid below it both
   start at 0. The index is multiplied by --actabl-reveal-step, so a module can
   widen its own rhythm without restating every delay. */
:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(2)) {
	--actabl-reveal-index: 1;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(3)) {
	--actabl-reveal-index: 2;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(4)) {
	--actabl-reveal-index: 3;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(5)) {
	--actabl-reveal-index: 4;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(6)) {
	--actabl-reveal-index: 5;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(7)) {
	--actabl-reveal-index: 6;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(8)) {
	--actabl-reveal-index: 7;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(9)) {
	--actabl-reveal-index: 8;
}

:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(10)) {
	--actabl-reveal-index: 9;
}

/* Capped so a very long list does not drag on for seconds. */
:where([data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item):nth-child(n + 11)) {
	--actabl-reveal-index: 10;
}

@media (prefers-reduced-motion: reduce) {
	[data-actabl-reveal-init] :is([data-actabl-reveal-item], .actabl-reveal-item) {
		opacity: 1;
		transform: none;
		transition: none;
	}
}
