/**
 * Motion primitives — native CSS only, no JavaScript, no libraries.
 *
 * WHY NO GSAP / ScrollTrigger / Lenis / AOS
 * -----------------------------------------
 * The usual way to make a site "feel expensive" is to bolt on a scroll library.
 * That trade is bad here. This theme currently ships 16 asset requests against
 * a competitor's 53, and that lead is the reason the site feels quick. A scroll
 * library spends the lead on the main thread, and on a mid-range Android on
 * Thai mobile data a janky reveal reads far cheaper than no reveal at all.
 *
 * Everything below runs on the compositor via scroll-driven animations, and
 * costs zero bytes of JavaScript.
 *
 * SUPPORT (checked 2026-08-16, caniuse: ~85% global)
 *   Chrome / Edge 115+ ..... yes
 *   Safari 26+ ............. yes
 *   Firefox 156+ ........... yes
 * Older Safari and Firefox — still a real share of iPhones in Thailand — get
 * no animation at all. That is the intended fallback: every rule here is inside
 * @supports, and the page is designed to look finished without motion. The
 * layout carries the quality; motion is the enhancement, never the substance.
 */

/* -------------------------------------------------------------------------
 * Smooth scrolling — the native property, not a hijacked scroll container.
 * A JS smooth-scroll library overrides trackpad and touch momentum, which
 * feels wrong to anyone sensitive to it and breaks scroll-anchoring.
 * ---------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* Anchored sections should not land under the sticky header. */
:target {
	scroll-margin-top: 96px;
}

/* -------------------------------------------------------------------------
 * Cross-document view transitions.
 * Removes the white flash when moving between shop pages, which is most of
 * what makes a multi-page WooCommerce site feel like a website rather than an
 * app. One rule, no JS. Browsers without support simply navigate as before.
 * ---------------------------------------------------------------------- */
@view-transition {
	navigation: auto;
}

@media (prefers-reduced-motion: no-preference) {
	::view-transition-old(root) {
		animation: cp-fade-out 90ms cubic-bezier(0.4, 0, 1, 1) both;
	}
	::view-transition-new(root) {
		animation: cp-fade-in 210ms cubic-bezier(0, 0, 0.2, 1) both;
	}
}

@keyframes cp-fade-out { to { opacity: 0; } }
@keyframes cp-fade-in { from { opacity: 0; } }

/* -------------------------------------------------------------------------
 * Reveal on scroll.
 *
 * `view()` ties the animation to the element's own progress through the
 * viewport, so there is no observer, no scroll listener and no layout read.
 *
 * 🔴 THE RANGE MUST END INSIDE `entry`, NOT IN `cover`.
 * These first read `entry 0% cover 40%`, which looks right and is a trap: the
 * `cover` range only completes once an element has travelled most of the way
 * across the viewport, and the last screenful of a document can never scroll
 * that far. Everything below the fold at the bottom of the page — the legal
 * copy, the effect tiles, the final heading — stuck permanently part-faded.
 * Measured by scrolling to the document end and reading computed opacity:
 * 0.11 to 0.47 on desktop, 0.21 to 0.34 on mobile.
 *
 * `entry 100%` means "the element is fully inside the viewport", which is
 * always reachable, so ending at `entry 70%` always completes. Verified the
 * same way afterwards: nothing in view below 95% opacity on either viewport.
 * ---------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {

		.cp-reveal {
			animation: cp-reveal linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 70%;
		}

		/* Children stagger by sharing one timeline but different ranges, so a
		   row of cards resolves left to right instead of snapping as a block. */
		.cp-reveal-group > * {
			animation: cp-reveal linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 65%;
		}
		.cp-reveal-group > :nth-child(2) { animation-range: entry 5% entry 72%; }
		.cp-reveal-group > :nth-child(3) { animation-range: entry 10% entry 79%; }
		.cp-reveal-group > :nth-child(4) { animation-range: entry 15% entry 86%; }

		/* A quieter variant for large type, which looks wrong if it travels far. */
		.cp-reveal-soft {
			animation: cp-reveal-soft linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 60%;
		}

		/* Progress bar for the reading position — ties to the document scroll. */
		.cp-scroll-progress {
			animation: cp-progress linear both;
			animation-timeline: scroll(root block);
			transform-origin: 0 50%;
		}
	}
}

@keyframes cp-reveal {
	from { opacity: 0; transform: translateY(24px); }
	to   { opacity: 1; transform: translateY(0); }
}

@keyframes cp-reveal-soft {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: translateY(0); }
}

@keyframes cp-progress {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

/* -------------------------------------------------------------------------
 * Hover and focus motion. Cheap, universally supported, and does more for
 * perceived quality than any scroll effect.
 * ---------------------------------------------------------------------- */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
	.cp-lift {
		transition: transform 260ms cubic-bezier(0.2, 0, 0, 1),
					box-shadow 260ms cubic-bezier(0.2, 0, 0, 1);
	}
	.cp-lift:hover {
		transform: translateY(-4px);
	}
	.cp-lift:hover .cp-pcard__media img {
		transform: scale(1.04);
	}
	.cp-pcard__media img {
		transition: transform 600ms cubic-bezier(0.2, 0, 0, 1);
	}
}
