/**
 * Shared effects - scroll reveal, 3D glossy hover, depth shadows.
 *
 * Used by the About, Blog and Our Science pages so the motion language stays
 * consistent and is defined once.
 */

/* -------------------------------------------------------------------------
 * Scroll reveal
 *
 * The hidden state is scoped to .ml-reveal-ready, which reveal.js adds to
 * <html> only once it is running. Without JavaScript nothing is ever hidden.
 * ---------------------------------------------------------------------- */

.ml-reveal-ready [data-ml-reveal] {
	opacity: 0;
	transform: translateY(22px);
	transition:
		opacity 0.6s var(--ml-e-enter),
		transform 0.6s var(--ml-e-enter);
	transition-delay: calc(var(--ml-reveal-i, 0) * 80ms);
	will-change: opacity, transform;
}

.ml-reveal-ready [data-ml-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

/* -------------------------------------------------------------------------
 * 3D glossy card
 *
 * The lift is a real perspective transform, not a flat translate, so the card
 * tips slightly towards the viewer. A sheen sweeps across on hover.
 * ---------------------------------------------------------------------- */

.ml-glass {
	position: relative;
	isolation: isolate;
	background: var(--ml-white);
	border: 1px solid var(--ml-line);
	border-radius: 14px;
	overflow: hidden;
	transform-style: preserve-3d;
	transition:
		transform var(--ml-t-enter) var(--ml-e-enter),
		box-shadow var(--ml-t-enter) var(--ml-e-enter),
		border-color var(--ml-t-enter) var(--ml-e-standard);
	box-shadow: 0 10px 26px -20px rgba(10, 37, 64, 0.55);
}

.ml-glass:hover,
.ml-glass:focus-within {
	transform: perspective(900px) rotateX(2.4deg) rotateY(-2.4deg) translateY(-6px);
	border-color: #cde7f7;
	box-shadow:
		0 30px 50px -28px rgba(10, 37, 64, 0.65),
		0 8px 18px -12px rgba(0, 175, 240, 0.35);
}

/* The sheen. Sits above the card's own background but below its content. */
.ml-glass::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(
		115deg,
		rgba(255, 255, 255, 0) 32%,
		rgba(255, 255, 255, 0.55) 48%,
		rgba(213, 240, 255, 0.35) 56%,
		rgba(255, 255, 255, 0) 72%
	);
	transform: translateX(-120%);
	opacity: 0;
	transition: transform 0.85s var(--ml-e-enter), opacity 0.3s var(--ml-e-standard);
	pointer-events: none;
}

.ml-glass:hover::after,
.ml-glass:focus-within::after {
	transform: translateX(120%);
	opacity: 1;
}

/* Darker variant, for cards on navy. */
.ml-glass--dark {
	background: rgba(255, 255, 255, 0.05);
	border-color: rgba(255, 255, 255, 0.16);
	box-shadow: none;
}

.ml-glass--dark:hover,
.ml-glass--dark:focus-within {
	border-color: rgba(0, 175, 240, 0.55);
	box-shadow: 0 26px 44px -26px rgba(0, 0, 0, 0.75);
}

/* -------------------------------------------------------------------------
 * Reduced motion
 * ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.ml-reveal-ready [data-ml-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
		transition-delay: 0s;
	}

	.ml-glass,
	.ml-glass::after {
		transition: none;
	}

	.ml-glass:hover,
	.ml-glass:focus-within {
		transform: none;
	}

	/* No sweep; keep a plain border/shadow change as the hover cue. */
	.ml-glass:hover::after,
	.ml-glass:focus-within::after {
		transform: translateX(-120%);
		opacity: 0;
	}
}
