/* =============================================================================
   Sustainable Ply — Motion
   Source: 02-UI-SPEC.md §Motion Contract (lines 462-560).
   "Still page, alive controls" — section-level scroll fade-in, section-only.
   The IntersectionObserver in assets/js/scroll-animate.js applies `.is-visible`.
   D2-15 / LCH-03 prep: every animation/transition rule lives inside a
   prefers-reduced-motion: no-preference wrapper, with a companion reduce block
   that snaps the element to its final visible state.
   ============================================================================= */

/* --------------------------------------------------------------------------- */
/* On-scroll fade-in — applied to section/pattern wrappers                      */
/* --------------------------------------------------------------------------- */

/* Default state — VISIBLE. Sections only get hidden when the JS observer
   is actually about to run (it adds `.sp-anim-active` to <html>). This means:
   - No-JS users see content immediately
   - JS that bails (no IntersectionObserver, reduced-motion) leaves content visible
   - Headless tools / Lighthouse / pre-paint screenshots get the visible state
   The hidden-then-fade-in state is a progressive enhancement, not a default. */

/* Pre-reveal state — only when JS has opted in. */
html.sp-anim-active .sp-animate {
	opacity: 0;
	transform: translateY(12px);
}

/* In-view state — added by IntersectionObserver callback.                     */
@media (prefers-reduced-motion: no-preference) {
	html.sp-anim-active .sp-animate.is-visible {
		opacity: 1;
		transform: translateY(0);
		transition:
			opacity 300ms ease-out,
			transform 300ms ease-out;
	}
}

/* Reduced motion fallback: even if html.sp-anim-active is set (shouldn't be
   per the JS guard, but defensive), force visible.                            */
@media (prefers-reduced-motion: reduce) {
	html.sp-anim-active .sp-animate {
		opacity: 1;
		transform: none;
	}
}

/* --------------------------------------------------------------------------- */
/* Generic motion safety net — block any animation/transition for users who    */
/* opt into reduce-motion at the OS level. This is a final guard rail; each    */
/* component CSS file already scopes its own motion rules to no-preference.    */
/* --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}
