/*
 * Finora Vista motion system.
 *
 * Every rule is gated on `html.fv-motion`, which the head snippet in
 * functions.php only adds when JS is running and the visitor has not asked for
 * reduced motion. Without the gate the page renders static and fully visible.
 * Only opacity / transform / clip-path / translate are animated (compositor
 * friendly). Reveal targets are tagged by fv-motion.js; this file only
 * defines their hidden and revealed states (hidden from first paint via the
 * selector map below, then keyed on [data-fv-reveal] once the script is ready).
 */

:root {
	--fv-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
	--fv-ease-wipe: cubic-bezier(0.65, 0, 0.35, 1);
}

/* Hero: logo -> photo -> nav (CSS only, done by ~1.9s) ------------------ */
.fv-hero.wp-block-cover {
	background-color: var(--color-brand, #4b2a27);
}

@keyframes fv-fade-in {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

/* The hero photo is the LCP element: starting at 0 opacity hides it from LCP until the fade begins. */
@keyframes fv-fade-in-lcp {
	from {
		opacity: var(--fv-hero-bg-start-opacity, 0.3);
	}

	to {
		opacity: 1;
	}
}

html.fv-motion .fv-hero .fv-hero__logo {
	animation: fv-fade-in 0.6s ease-out 0s backwards;
}

html.fv-motion .fv-hero .wp-block-cover__image-background {
	animation: fv-fade-in-lcp 0.9s ease-out 0.6s backwards;
}

html.fv-motion body:has(.fv-hero) .fv-nav {
	animation: fv-fade-in 0.8s ease-out 1.1s backwards;
}

/* Not gated: layout must not change if the motion gate is removed. !important is needed
   because the cover block carries an inline min-height (same reason as the mobile rule in _finora.scss). */
@media (min-width: 768px) {
	.fv-hero.wp-block-cover {
		min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px)) !important;
	}
}

/* Pre-paint hidden states ------------------------------------------------- */
/*
 * Same selector map as TARGETS in fv-motion.js (keep both in sync). These hide
 * targets from first paint; once the script tags them it adds `.fv-ready` and
 * the [data-fv-reveal] rules below take over with identical values. The head
 * snippet drops `.fv-motion` if `.fv-ready` never arrives, so a broken script
 * cannot leave content hidden.
 */
html.fv-motion:not(.fv-ready) :is(
	.fv-community .fv-eyebrow,
	.fv-community .fv-display,
	.fv-gallery__copy,
	.fv-amenities__copy .fv-eyebrow,
	.fv-amenities__copy .studio-accordion,
	.fv-cards__head .fv-eyebrow,
	.fv-cards__head .fv-h2,
	.fv-contact .wp-block-column:first-child > *,
	.fv-contact .wp-block-column:last-child > *
) {
	opacity: 0;
	transform: translate3d(0, 40px, 0);
}

html.fv-motion:not(.fv-ready) :is(.fv-amenities__media, .fv-cards .studio-slider) {
	opacity: 0;
	transform: translate3d(0, 56px, 0) scale(0.97);
}

html.fv-motion:not(.fv-ready) .fv-gallery .wp-block-image {
	opacity: 0;
	overflow: hidden;
	transform: translate3d(0, 40px, 0);
}

html.fv-motion:not(.fv-ready) .fv-gallery .wp-block-image img {
	clip-path: inset(100% 0 0 0);
	transform: scale(1.2);
}

/* Gallery parallax ---------------------------------------------------------- */
/*
 * The theme's scroll-driven float (fv-float in _finora.scss) animates the same
 * frames' transform: it would override the reveal rise and stack with the image
 * drift below. With motion on, the image drift is the only parallax.
 */
html.fv-motion .fv-gallery .wp-block-columns .wp-block-image,
html.fv-motion .fv-gallery .wp-block-columns .fv-gallery__offset .wp-block-image {
	animation: none;
}

/* Reveal start states ---------------------------------------------------- */
html.fv-motion [data-fv-reveal] {
	opacity: 0;
	transition:
		opacity 1.2s var(--fv-ease-out) var(--fv-delay, 0ms),
		transform 1.2s var(--fv-ease-out) var(--fv-delay, 0ms);
}

html.fv-motion [data-fv-reveal="text"] {
	transform: translate3d(0, 40px, 0);
}

html.fv-motion [data-fv-reveal="block"] {
	transform: translate3d(0, 56px, 0) scale(0.97);
	transition-duration: 1.4s;
}

html.fv-motion [data-fv-reveal="curtain"] {
	overflow: hidden;
	transform: translate3d(0, 40px, 0);
	transition:
		opacity 0.8s ease var(--fv-delay, 0ms),
		transform 1.6s var(--fv-ease-out) var(--fv-delay, 0ms);
}

html.fv-motion [data-fv-reveal="curtain"] img {
	clip-path: inset(100% 0 0 0);
	transform: scale(1.2);
	transition:
		clip-path 1.6s var(--fv-ease-wipe) var(--fv-delay, 0ms),
		transform 2.2s var(--fv-ease-out) var(--fv-delay, 0ms);
	/* Scroll drift is applied via the separate `translate` property so it never fights the scale transition. */
	translate: 0 var(--fv-drift, 0px);
}

/* Revealed ---------------------------------------------------------------- */
html.fv-motion [data-fv-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

html.fv-motion [data-fv-reveal="curtain"].is-revealed img {
	clip-path: inset(0);
	transform: scale(1.1);
}
