/**
 * cf-behaviours.css — the CSS half of the data-cf behaviour contract.
 *
 * cf-behaviours.js attaches behaviour by a `data-cf="<name>"` opt-in. Several of
 * those behaviours need a resting state the JS then changes — reveal hides its
 * element and fades it in, so SOMETHING has to author `opacity: 0`. This file is
 * that half, keyed by the same attribute, so all three ends of a contract share
 * one grep: `data-cf="reveal"` finds the opt-in, the JS and the CSS.
 *
 * RULED 2026-08-09 (Alex). The JS half of a behaviour contract already has a
 * sanctioned single home; the CSS half has no reason to live differently. The
 * alternative was the same three lines copied onto fourteen component selectors
 * — the eyebrow disease in a behaviour's clothes.
 *
 * ⚠️ SCOPE, STRICTLY: only rules keyed to a `data-cf` attribute, plus their
 * reduced-motion blocks. Every selector in this file starts with `[data-cf=` or
 * `.js [data-cf=`. That is the whole admissions test.
 *
 * ⚠️ WHAT THIS IS NOT — and the distinction is load-bearing. The build's law
 * bans a stylesheet holding COMPONENT styling, because CSS detached from the
 * thing it styles is exactly how a second near-identical rule gets written on the
 * next page. This file holds BEHAVIOUR styling, which no component owns. The
 * moment something component-specific lands here it BECOMES the stylesheet the
 * law forbids. Concretely: cf-care's honeycomb load-path draw stays on `.cf-care`
 * where it already lives — it is that component's own art, not the reveal
 * behaviour. If a rule does not start with `[data-cf=`, it does not belong here;
 * it belongs on its component's selector.
 *
 * Values follow the page designs (newpages/*.html §7): translateY(20px), 1.1s on
 * --ease-line, reduced motion renders the final state.
 *
 * @package CausewayForge
 */

/* ── reveal ────────────────────────────────────────────────────────────────────
 * Scoped to `.js` so a visitor without JS is never left with hidden content:
 * behaviours.php adds that class in <head> (and withholds it inside the Etch
 * builder canvas, which is what keeps the canvas editable). Without `.js` the
 * resting state below never applies and everything renders settled.
 *
 * The delay is per-element, set by initReveal from the element's position within
 * its stagger group — never from IntersectionObserver callback order, which is
 * not position and collapses to zero on a slow scroll.
 */
.js [data-cf="reveal"] {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity 1.1s var(--ease-line),
		transform 1.1s var(--ease-line);
	transition-delay: var(--cf-reveal-delay, 0ms);
}

[data-cf="reveal"].is-revealed {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	/* Render the final state, and do not animate into it. initReveal also adds
	   .is-revealed immediately when reduced motion is set, so this holds whether
	   or not the module runs. */
	.js [data-cf="reveal"] {
		opacity: 1;
		transform: none;
		transition: none;
	}
}
