/**
 * animations.css — Lumovex 2.0 motion & interactive components (Phase 6).
 *
 * Loads after infographics.css. Scroll-reveal, orbit/waveform motion, and the
 * interactive components introduced this phase (theater modal, sound toggle, JS-driven
 * industry switching). All motion is gated behind prefers-reduced-motion: no-preference
 * and only applies under html.lvx-js, so no-JS and reduced-motion visitors get fully
 * visible, static content. A reduced-motion override at the end is belt-and-braces.
 *
 * @package Lumovex_2
 * @since   2.0 (Phase 6)
 */

/* ---------------------------------------------------------------------------
 * Keyframes
 * ------------------------------------------------------------------------- */
@keyframes lvx-fade-up {
	from {
		opacity: 0;
		transform: translateY(18px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes lvx-pop {
	0% {
		opacity: 0;
		transform: translate(-50%, -50%) scale(0.85);
	}
	100% {
		opacity: 1;
		transform: translate(-50%, -50%) scale(1);
	}
}

@keyframes lvx-orbit-spin {
	to {
		transform: translate(-50%, -50%) rotate(360deg);
	}
}

@keyframes lvx-wave {
	0%,
	100% {
		transform: scaleY(0.7);
	}
	50% {
		transform: scaleY(1.1);
	}
}

/* ---------------------------------------------------------------------------
 * Scroll reveal (JS + motion only; content is visible otherwise)
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	html.lvx-js .lvx-scene__content {
		opacity: 0;
		transform: translateY(26px);
	}
	html.lvx-js .lvx-scene.is-visible .lvx-scene__content {
		opacity: 1;
		transform: none;
		transition: opacity 0.7s var(--lvx-ease), transform 0.7s var(--lvx-ease);
	}

	/* Card stagger: hidden until the scene reveals, then fade up in sequence */
	html.lvx-js .lvx-scene .lvx-video-card,
	html.lvx-js .lvx-scene .lvx-pipeline-station,
	html.lvx-js .lvx-scene .lvx-project-card,
	html.lvx-js .lvx-scene .lvx-industry-card,
	html.lvx-js .lvx-scene .lvx-talent-card,
	html.lvx-js .lvx-scene .lvx-rights-card,
	html.lvx-js .lvx-scene .lvx-training-card {
		opacity: 0;
	}
	html.lvx-js .lvx-scene.is-visible .lvx-video-card,
	html.lvx-js .lvx-scene.is-visible .lvx-pipeline-station,
	html.lvx-js .lvx-scene.is-visible .lvx-project-card,
	html.lvx-js .lvx-scene.is-visible .lvx-industry-card,
	html.lvx-js .lvx-scene.is-visible .lvx-talent-card,
	html.lvx-js .lvx-scene.is-visible .lvx-rights-card,
	html.lvx-js .lvx-scene.is-visible .lvx-training-card {
		animation: lvx-fade-up 0.6s var(--lvx-ease) both;
	}

	.lvx-scene.is-visible .lvx-video-card:nth-child(2),
	.lvx-scene.is-visible .lvx-pipeline-station:nth-child(2),
	.lvx-scene.is-visible .lvx-rights-card:nth-child(2) {
		animation-delay: 0.07s;
	}
	.lvx-scene.is-visible .lvx-pipeline-station:nth-child(3),
	.lvx-scene.is-visible .lvx-rights-card:nth-child(3) {
		animation-delay: 0.14s;
	}
	.lvx-scene.is-visible .lvx-pipeline-station:nth-child(4),
	.lvx-scene.is-visible .lvx-rights-card:nth-child(4) {
		animation-delay: 0.21s;
	}
	.lvx-scene.is-visible .lvx-pipeline-station:nth-child(5),
	.lvx-scene.is-visible .lvx-rights-card:nth-child(5) {
		animation-delay: 0.28s;
	}

	/* Orbit reveal + rotation */
	html.lvx-js .lvx-tool-orbit.is-animated > .lvx-tool-node {
		animation: lvx-pop 0.5s var(--lvx-ease) both;
	}
	html.lvx-js .lvx-tool-orbit.is-spinning::before {
		animation: lvx-orbit-spin 60s linear infinite;
	}

	/* Waveform pulse once the talent scene is in view */
	html.lvx-js .lvx-waveform.is-animated svg {
		transform-origin: center;
		animation: lvx-wave 1.8s ease-in-out infinite;
	}
}

/* ---------------------------------------------------------------------------
 * JS-driven industry switching (single card visible when JS is on)
 * ------------------------------------------------------------------------- */
html.lvx-js .lvx-industry-card {
	display: none;
	opacity: 1;
}
html.lvx-js .lvx-industry-card.is-active {
	display: block;
}

/* ---------------------------------------------------------------------------
 * Theater modal
 * ------------------------------------------------------------------------- */
.lvx-theater[hidden] {
	display: none;
}

.lvx-theater {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--lvx-gutter);
	opacity: 0;
	transition: opacity 0.3s var(--lvx-ease);
}

.lvx-theater.is-open {
	opacity: 1;
}

.lvx-theater__overlay {
	position: absolute;
	inset: 0;
	background: rgba(2, 3, 8, 0.86);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}

.lvx-theater__dialog {
	position: relative;
	width: min(960px, 100%);
	background: var(--lvx-ink);
	border: var(--lvx-border);
	border-radius: var(--lvx-radius);
	padding: var(--lvx-sp-30);
	box-shadow: var(--lvx-shadow);
	transform: translateY(12px);
	transition: transform 0.3s var(--lvx-ease);
	/* v2.7.0: never taller than the screen, so a portrait clip + chrome can't
	   push the native video controls off the bottom of the viewport. */
	display: flex;
	flex-direction: column;
	max-height: calc(100vh - (2 * var(--lvx-gutter)));
	max-height: calc(100dvh - (2 * var(--lvx-gutter)));
}

.lvx-theater.is-open .lvx-theater__dialog {
	transform: none;
}

/*
 * v2.7.0 — responsive theater frame.
 *
 * The frame no longer forces a 16:9 box. A hard 16:9 frame crushed the
 * vertical 9:16 micro-drama clips into a tiny letterboxed strip on phones and
 * pushed the native controls out of reach. Instead the frame centers its media
 * and lets the media size to its own aspect ratio (portrait OR landscape),
 * bounded by the viewport so the whole clip — controls included — is always on
 * screen. A min-height keeps the empty/loading/error state from collapsing.
 */
.lvx-theater__frame {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 200px;
	background: #000;
	border-radius: var(--lvx-radius-sm);
	overflow: hidden;
}

/* Shared reset for whatever media the JS injects. */
.lvx-theater__media {
	position: static;
	display: block;
	border: 0;
	max-width: 100%;
	background: #000;
}

/* Real <video>: keep its intrinsic aspect ratio (portrait or landscape) and
   scale to fit within the viewport-bounded frame — no stretching, no crop. */
video.lvx-theater__media {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 80vh; /* fallback */
	max-height: min(80dvh, calc(100dvh - 8rem));
	object-fit: contain;
}

/* Provider embeds (YouTube/Vimeo) need an explicit box; give them a full-width
   16:9 frame, still bounded so the player never runs past the screen. */
iframe.lvx-theater__media {
	width: 100%;
	aspect-ratio: 16 / 9;
	max-height: 80vh; /* fallback */
	max-height: min(80dvh, calc(100dvh - 8rem));
}

.lvx-theater__close {
	position: absolute;
	top: -14px;
	right: -14px;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	border: var(--lvx-border);
	background: var(--lvx-panel);
	color: var(--lvx-text);
	font-size: 1.3rem;
	line-height: 1;
	cursor: pointer;
	z-index: 2;
	transition: border-color var(--lvx-speed) var(--lvx-ease), color var(--lvx-speed) var(--lvx-ease);
}

.lvx-theater__close:hover {
	border-color: var(--lvx-accent);
	color: var(--lvx-white);
}

body.lvx-modal-open {
	overflow: hidden;
}

/* ---------------------------------------------------------------------------
 * Sound toggle
 * ------------------------------------------------------------------------- */
.lvx-sound-toggle {
	position: fixed;
	left: clamp(0.75rem, 2vw, 1.5rem);
	bottom: clamp(0.75rem, 2vw, 1.5rem);
	z-index: 95;
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	padding: 0.6em 1em;
	border-radius: 999px;
	border: var(--lvx-border);
	background: color-mix(in srgb, var(--lvx-void) 70%, transparent);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	color: var(--lvx-muted);
	font-family: var(--lvx-font-mono);
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	cursor: pointer;
	transition: color var(--lvx-speed) var(--lvx-ease), border-color var(--lvx-speed) var(--lvx-ease);
}

.lvx-sound-toggle:hover {
	color: var(--lvx-white);
	border-color: var(--lvx-accent);
}

.lvx-sound-toggle[aria-pressed='true'] {
	color: var(--lvx-accent);
	border-color: var(--lvx-accent);
}

@media (max-width: 680px) {
	.lvx-sound-toggle {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * Reduced-motion master override (belt-and-braces)
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	html.lvx-js .lvx-scene__content,
	html.lvx-js .lvx-scene .lvx-video-card,
	html.lvx-js .lvx-scene .lvx-pipeline-station,
	html.lvx-js .lvx-scene .lvx-project-card,
	html.lvx-js .lvx-scene .lvx-industry-card.is-active,
	html.lvx-js .lvx-scene .lvx-talent-card,
	html.lvx-js .lvx-scene .lvx-rights-card,
	html.lvx-js .lvx-scene .lvx-training-card {
		opacity: 1 !important;
		transform: none !important;
		animation: none !important;
	}
	/* Orbit nodes keep their centering transform; only the animation is removed. */
	html.lvx-js .lvx-tool-orbit > .lvx-tool-node {
		opacity: 1 !important;
		animation: none !important;
	}
	.lvx-theater,
	.lvx-theater__dialog {
		transition: none !important;
	}
}

/* ===========================================================================
 * LUMOVEX CLIENT HOME — cinematic motion layer
 * Keyframes are top-level; all stateful/hidden rules live inside the
 * prefers-reduced-motion: no-preference guard so reduced-motion users get a
 * fully static, fully visible page.
 * ======================================================================== */
@keyframes lvx-hero-breathe {
	from { transform: scale(1.02); }
	to   { transform: scale(1.09); }
}
@keyframes lvx-hero-ring {
	0%, 100% { opacity: 0.45; transform: translate(-50%, -50%) scale(1); }
	50%      { opacity: 0.85; transform: translate(-50%, -50%) scale(1.045); }
}
@keyframes lvx-play-pulse {
	0%, 100% { box-shadow: 0 0 48px -12px color-mix(in srgb, var(--lvx-accent) 70%, transparent); }
	50%      { box-shadow: 0 0 72px -6px color-mix(in srgb, var(--lvx-accent) 85%, transparent); }
}

.lvx-hero {
	--lvx-hero-scroll: 0;
	--lvx-hero-px: 0;
	--lvx-hero-py: 0;
}

@media (prefers-reduced-motion: no-preference) {
	/* --- Cinematic section reveal: scale + focus-pull "push-in" --- */
	html.lvx-js .lvx-cinematic .lvx-scene__content {
		transform: translateY(34px) scale(0.955);
		filter: blur(6px);
	}
	html.lvx-js .lvx-cinematic.is-visible .lvx-scene__content {
		transform: none;
		filter: none;
		transition: opacity 0.8s var(--lvx-ease), transform 0.95s var(--lvx-ease), filter 0.8s var(--lvx-ease);
	}

	/* --- Hero ignition: parent block stays put; children stagger in --- */
	html.lvx-js .lvx-hero .lvx-scene__content {
		opacity: 1;
		transform: none;
	}
	html.lvx-js .lvx-hero__title,
	html.lvx-js .lvx-hero__sub,
	html.lvx-js .lvx-hero__play,
	html.lvx-js .lvx-hero__playlabel {
		opacity: 0;
		transform: translateY(24px);
	}
	html.lvx-js .lvx-hero.is-visible .lvx-hero__title,
	html.lvx-js .lvx-hero.is-visible .lvx-hero__sub,
	html.lvx-js .lvx-hero.is-visible .lvx-hero__play,
	html.lvx-js .lvx-hero.is-visible .lvx-hero__playlabel {
		opacity: 1;
		transform: none;
		transition: opacity 0.85s var(--lvx-ease), transform 0.85s var(--lvx-ease);
	}
	html.lvx-js .lvx-hero.is-visible .lvx-hero__title { transition-delay: 0.08s; }
	html.lvx-js .lvx-hero.is-visible .lvx-hero__sub { transition-delay: 0.22s; }
	html.lvx-js .lvx-hero.is-visible .lvx-hero__play { transition-delay: 0.36s; }
	html.lvx-js .lvx-hero.is-visible .lvx-hero__playlabel { transition-delay: 0.46s; }

	/* --- Hero ambient: breathing zoom, ring pulse, play-circle pulse --- */
	html.lvx-js .lvx-hero .lvx-scene__bg {
		animation: lvx-hero-breathe 18s var(--lvx-ease) infinite alternate;
		transform-origin: center;
	}
	html.lvx-js .lvx-hero::before {
		animation: lvx-hero-ring 6.5s ease-in-out infinite;
	}
	html.lvx-js .lvx-hero .lvx-play-circle .wp-block-button__link {
		animation: lvx-play-pulse 3.4s ease-in-out infinite;
	}

	/* --- Hero parallax: bg lags, foreground leads (CSS vars set by JS) --- */
	html.lvx-js .lvx-hero .lvx-scene__bg img {
		transform: translate3d(calc(var(--lvx-hero-px) * -14px), calc(var(--lvx-hero-scroll) * 60px + var(--lvx-hero-py) * -10px), 0);
		transition: transform 0.2s linear;
		will-change: transform;
	}
	html.lvx-js .lvx-hero__fg {
		transform: translate3d(calc(var(--lvx-hero-px) * -30px), calc(var(--lvx-hero-scroll) * -52px + var(--lvx-hero-py) * -16px), 0);
		transition: transform 0.2s linear;
	}
}

/* ---------------------------------------------------------------------------
 * v2.6.0 — image zoom overlay (client request: expandable infographics)
 * ------------------------------------------------------------------------- */

img[data-lvx-zoom] {
	cursor: zoom-in;
}

.lvx-zoom[hidden] {
	display: none;
}

.lvx-zoom {
	position: fixed;
	inset: 0;
	z-index: 1001;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(12px, 3vw, 32px);
	opacity: 0;
	transition: opacity 0.28s var(--lvx-ease);
}

.lvx-zoom.is-open {
	opacity: 1;
}

.lvx-zoom__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(2, 3, 8, 0.9);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	cursor: zoom-out;
}

.lvx-zoom__img {
	position: relative;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	border-radius: var(--lvx-radius-sm);
	box-shadow: var(--lvx-shadow);
}

.lvx-zoom__close {
	position: absolute;
	top: 14px;
	right: 14px;
	width: 44px;
	height: 44px;
	border: 1px solid rgba(255, 255, 255, 0.25);
	border-radius: 999px;
	background: rgba(10, 10, 26, 0.85);
	color: #fff;
	font-size: 24px;
	line-height: 1;
	cursor: pointer;
}

.lvx-zoom__close:hover {
	border-color: var(--lvx-accent, #00e5ff);
	color: var(--lvx-accent, #00e5ff);
}

/* v2.6.0 — theater codec/error fallback message */
.lvx-theater__error {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	text-align: center;
	padding: 1.5rem;
	color: var(--lvx-muted, #a6abc9);
}

.lvx-theater__error a {
	color: var(--lvx-accent, #00e5ff);
}
