/* ==========================================================================
   Motion — reveal states and hero entrance.
   Only transform and opacity are animated. Durations/easings are tokens, and
   the tokens themselves collapse under prefers-reduced-motion, so nothing here
   needs its own opt-out.
   ========================================================================== */

.js [data-reveal] {
	opacity: 0;
	transition:
		opacity var(--dur-reveal) var(--ease-out),
		transform var(--dur-reveal) var(--ease-out);
	transition-delay: calc(var(--reveal-i, 0) * var(--stagger));
	will-change: transform, opacity;
}
.js [data-reveal="up"]    { transform: translate3d(0, 26px, 0); }
.js [data-reveal="fade"]  { transform: none; }
.js [data-reveal="scale"] { transform: scale(0.97); }
.js [data-reveal="left"]  { transform: translate3d(-24px, 0, 0); }
.js [data-reveal="right"] { transform: translate3d(24px, 0, 0); }

/* Below the two-column breakpoint a sideways offset would stick out past the
   viewport before the element reveals, so it becomes a vertical one. */
@media (max-width: 899px) {
	.js [data-reveal="left"], .js [data-reveal="right"] { transform: translate3d(0, 26px, 0); }
}

.js [data-reveal].is-revealed {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/* Non-JS and reduced-motion users get the finished state, never a blank page. */
@media (prefers-reduced-motion: reduce) {
	.js [data-reveal] { opacity: 1; transform: none; transition: none; }
}
/* Without the .js flag nothing is hidden in the first place. */

/* ---------- Hero entrance ---------------------------------------------------- */

.js .hero [data-hero-item] {
	opacity: 0;
	transform: translate3d(0, 20px, 0);
	transition:
		opacity var(--dur-reveal) var(--ease-out),
		transform var(--dur-reveal) var(--ease-out);
	transition-delay: calc(var(--hero-delay) + var(--hero-i, 0) * var(--hero-stagger));
}
.hero.is-entered [data-hero-item] { opacity: 1; transform: none; }

.hero__card { transition: transform var(--dur-slow) var(--ease-out); }
.hero.is-entered .hero__card { transform: none; }
.js .hero:not(.is-entered) .hero__card { transform: translate3d(0, 28px, 0) scale(0.98); }

.hero__lattice { transform: translate3d(0, 0, 0); }

/* ---------- Section-level micro-motion ---------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	.cat-card, .card--lift, .product-card { will-change: auto; }
}
