/* Motion system.
   Reveal targets carry .k2p-reveal / .k2p-reveal-up; they start hidden ONLY when
   JS is active (html.js) and GSAP is available (html.gsap-ready). Otherwise visible. */

html.js.gsap-ready .k2p-reveal,
html.js.gsap-ready .k2p-reveal-up { opacity: 0; }

html.js.gsap-ready [data-stagger] > * { will-change: transform, opacity; }
html.js.gsap-ready .hero-image-wrap,
html.js.gsap-ready .range-card,
html.js.gsap-ready .service-card,
html.js.gsap-ready .gallery-item { will-change: transform; }

/* When GSAP is driving, it writes transform inline; a CSS transition on the same
   property would re-interpolate every tick and smear the motion. */
html.js.gsap-ready .range-card,
html.js.gsap-ready .service-card,
html.js.gsap-ready .gallery-item { transition: background-color 0.3s ease; }
html.js.gsap-ready .range-card:hover,
html.js.gsap-ready .service-card:hover,
html.js.gsap-ready .gallery-item:hover { transform: none; }

/* Words split out of a heading by k2pMotion.splitWords() for scrubbed reveals.
   inline-block is what makes transform apply at all; the splitter leaves the
   whitespace text nodes and any <br> in place so the line breaks still hold. */
.k2p-word { display: inline-block; will-change: opacity; }

@media (prefers-reduced-motion: reduce) {
	html.js.gsap-ready .k2p-reveal,
	html.js.gsap-ready .k2p-reveal-up { opacity: 1; }
	html.js.gsap-ready .hero-image-wrap,
	html.js.gsap-ready .range-card,
	html.js.gsap-ready .service-card,
	html.js.gsap-ready .gallery-item { will-change: auto; }
	.k2p-word { opacity: 1 !important; will-change: auto; }
	*, *::before, *::after { animation-duration: 0.001s !important; transition-duration: 0.001s !important; }
}
