/*
 * Motion — site-wide micro-interactions and scroll reveal.
 * Spec: "Прибытие" — single vertical axis, photo slower than its frame.
 * Only `transform` / `opacity` animate (composited, zero CLS by construction).
 *
 * Values intentionally mirror the scoped --sc-* tokens in specialist-cards.css:
 * one visual language, different scopes.
 */

:root {
	--al-ease: cubic-bezier(.4, 0, .2, 1);
	--al-ease-pop: cubic-bezier(.34, 1.56, .64, 1);

	--al-t-inst: .08s;
	--al-t-fast: .15s;
	--al-t-med: .28s;
	--al-t-slow: .5s;
	--al-t-rv: .55s;

	--al-rise: 16px;
	--al-lift: 6px;
	--al-lift-btn: 2px;

	--al-sh-rest: 0 2px 10px rgba(30, 20, 60, .05);
	--al-sh-hover: 0 14px 40px rgba(60, 40, 110, .10);
	--al-sh-btn: 0 8px 22px rgba(90, 61, 142, .30);
	--al-sh-btn-o: 0 8px 22px rgba(242, 140, 0, .28);
}

/* ============================================================
   1. Scroll reveal
   Hiding rule applies only once JS confirmed it runs (html.al-js),
   so a failed/disabled JS leaves content visible — never the reverse.
   ============================================================ */

html.al-js .al-rv {
	opacity: 0;
	transform: translateY(var(--al-rise));
	transition: opacity var(--al-t-rv) var(--al-ease), transform var(--al-t-rv) var(--al-ease);
}

html.al-js .al-rv.is-in {
	opacity: 1;
	transform: none;
}

/* Cards in a grid ride their container's reveal, each a beat behind the last.
   Capped at 5 slots: a linear cascade over 9+ cards outruns the scroll and
   reads as lag rather than choreography. */
html.al-js .al-rv-stagger > * {
	opacity: 0;
	transform: translateY(var(--al-rise));
	transition: opacity var(--al-t-rv) var(--al-ease), transform var(--al-t-rv) var(--al-ease);
}

/* The grid either reveals on its own (archives, where it is the target) or
   rides its section's reveal (home, where the section is).
   `transform` is deliberately not reset here: this selector outranks
   `.ova-product:hover`, so pinning it would kill the card lift for good. The
   revealed state is restored by dropping .al-rv-stagger once it has played
   (motion.js), which returns the cards to their untouched styling. */
html.al-js .al-rv-stagger.is-in > *,
html.al-js .al-rv.is-in .al-rv-stagger > * {
	opacity: 1;
	transform: translateY(0);
}

html.al-js .al-rv-stagger > *:nth-child(1) { transition-delay: 0ms; }
html.al-js .al-rv-stagger > *:nth-child(2) { transition-delay: 60ms; }
html.al-js .al-rv-stagger > *:nth-child(3) { transition-delay: 120ms; }
html.al-js .al-rv-stagger > *:nth-child(4) { transition-delay: 180ms; }
html.al-js .al-rv-stagger > *:nth-child(5) { transition-delay: 240ms; }
html.al-js .al-rv-stagger > *:nth-child(n+6) { transition-delay: 300ms; }

/* ============================================================
   2. Product cards
   ============================================================ */

/* The lift and its shadow need room to escape the card box; the zoom is
   clipped one level down, on the photo wrapper, not here. */
.ova-product {
	overflow: visible;
	box-shadow: var(--al-sh-rest);
	transition: transform var(--al-t-med) var(--al-ease), box-shadow var(--al-t-med) var(--al-ease);
}

.ova-product .ova_head_product {
	overflow: hidden;
}

.ova-product .ova-product-thumbnail img {
	display: block;
	width: 100%;
	transition: transform var(--al-t-slow) var(--al-ease);
}

.ova-product .ova-product-title,
.ova-product .ova-product-title a {
	transition: color var(--al-t-med) var(--al-ease);
}

/* Owl clips overflow on .owl-stage-outer, so a card lift/shadow gets cut
   square at the track edge. Padding buys the room, the negative margin keeps
   slide widths and positions untouched. */
.ova-product-slider .owl-stage-outer {
	padding-block: 14px;
	margin-block: -14px;
}

/* Wishlist heart: dimmed at rest so it never competes with the photo, but
   never hidden — on touch there is no hover to reveal it. */
.ova-product .ova-product-wishlist {
	opacity: .82;
	transition: opacity var(--al-t-med) var(--al-ease), transform var(--al-t-fast) var(--al-ease);
}

.ova-product .ova-product-wishlist:hover,
.ova-product .ova-product-wishlist:focus-within {
	opacity: 1;
	transform: scale(1.12);
}

.ova-product .ova-product-wishlist:active {
	animation: al-pop var(--al-t-med) var(--al-ease-pop);
}

@keyframes al-pop {
	0% { transform: scale(.82); }
	60% { transform: scale(1.12); }
	100% { transform: scale(1); }
}

/* Hover effects only where a real pointer exists — on touch `:hover` sticks
   after a tap and leaves the card lifted until the user taps elsewhere. */
@media (hover: hover) and (pointer: fine) {
	.ova-product:hover {
		transform: translateY(calc(var(--al-lift) * -1));
		box-shadow: var(--al-sh-hover);
	}

	.ova-product:hover .ova-product-thumbnail img {
		transform: scale(1.06);
	}

	.ova-product:hover .ova-product-title,
	.ova-product:hover .ova-product-title a {
		color: #5A3D8E;
	}

	/* The button wakes with the whole card, so the card reads as clickable
	   before the pointer reaches the button itself. */
	.ova-product:hover .product-btn-book-now {
		transform: translateY(-1px);
		box-shadow: var(--al-sh-btn);
	}
}

@media not all and (hover: hover) {
	.ova-product .ova-product-wishlist {
		opacity: 1;
	}
}

/* ============================================================
   3. Buttons
   ============================================================ */

.product-btn-book-now,
.ova-product .btn {
	transition:
		transform var(--al-t-fast) var(--al-ease),
		box-shadow var(--al-t-med) var(--al-ease),
		filter var(--al-t-fast) var(--al-ease);
}

@media (hover: hover) and (pointer: fine) {
	.product-btn-book-now:hover,
	.ova-product .btn:hover {
		transform: translateY(calc(var(--al-lift-btn) * -1));
		/* Darken, never lighten: lightening #F28C00 drifts into yellow. */
		filter: brightness(.94);
		box-shadow: var(--al-sh-btn-o);
	}
}

/* Press feedback is the one micro-interaction that matters on touch. */
.product-btn-book-now:active,
.ova-product .btn:active {
	transform: translateY(0) scale(.985);
	transition-duration: var(--al-t-inst);
}

.product-btn-book-now:focus-visible,
.ova-product .btn:focus-visible {
	outline: 2px solid #5A3D8E;
	outline-offset: 2px;
	/* No transition on focus — keyboard navigation needs instant feedback. */
	transition: none;
}

/* ============================================================
   4. Reduced motion
   ============================================================ */

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

	/* Resetting the start state is what actually matters: killing the
	   transition alone would strand these at opacity 0 forever. */
	html.al-js .al-rv,
	html.al-js .al-rv-stagger > * {
		opacity: 1 !important;
		transform: none !important;
	}
}
