/**
 * Scroll reveal — a gentle fade + rise as blocks enter the viewport.
 *
 * Everything here is gated on the `geba-anim` class, which reveal.js only puts on <html>
 * when IntersectionObserver exists and the visitor hasn't asked for reduced motion. So if
 * JS fails, is blocked, or the browser is old, no element is ever hidden — the page just
 * renders normally. Nothing is hidden by CSS alone.
 *
 * @package astra-child
 */

.geba-anim .geba-reveal {
	opacity: 0;
	transform: translate3d(0, 16px, 0);
	will-change: opacity, transform;
}

.geba-anim .geba-reveal.is-in {
	opacity: 1;
	transform: translate3d(0, 0, 0);
	/* soft ease-out; 600ms reads as "settled" without feeling slow */
	transition: opacity 600ms cubic-bezier(.22, .61, .36, 1), transform 600ms cubic-bezier(.22, .61, .36, 1);
	transition-delay: var(--geba-reveal-delay, 0ms);
}

/* once it has played, drop the compositing hint */
.geba-anim .geba-reveal.is-done { will-change: auto; }

/* Belt and braces: if anything ever leaves an element stuck hidden, this makes it
   visible for anyone who prefers reduced motion regardless of JS state. */
@media (prefers-reduced-motion: reduce) {
	.geba-anim .geba-reveal,
	.geba-anim .geba-reveal.is-in {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* --- Hero entrance ---
   PURE CSS on purpose. reveal.js is a footer script, so anything it hides has already
   painted — which made the hero flash at full opacity and then fade, looking broken.
   A keyframe animation declared in the stylesheet applies at first paint instead, needs
   no JS, and always runs to completion, so the hero can never be left invisible.

   Two beats: the photo settles, then the title arrives just behind it. */
@keyframes geba-hero-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@keyframes geba-hero-rise {
	from { opacity: 0; transform: translate3d(0, 14px, 0); }
	to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@media (prefers-reduced-motion: no-preference) {
	.geba-hero,
	.geba-projhero {
		animation: geba-hero-in 900ms ease both;
	}
	.geba-hero .geba-hero__inner,
	.geba-projhero .geba-projhero__panel {
		animation: geba-hero-rise 800ms cubic-bezier(.22, .61, .36, 1) 220ms both;
	}
}

/* --- Cross-page transitions ---
   Native View Transitions: the browser cross-fades the outgoing page into the incoming
   one, so navigation feels continuous instead of a hard white flash. No JavaScript, and
   crucially no interception of link clicks — browsers without support (currently Firefox)
   just navigate normally, and nothing can ever block a navigation.

   Kept short (260ms) so it reads as a soft hand-off and doesn't fight the hero settle
   that plays immediately after on the new page. */
@view-transition {
	navigation: auto;
}

::view-transition-old(root) {
	animation: geba-vt-out 200ms cubic-bezier(.4, 0, 1, 1) both;
}
::view-transition-new(root) {
	animation: geba-vt-in 260ms cubic-bezier(0, 0, .2, 1) both;
}
@keyframes geba-vt-out {
	from { opacity: 1; }
	to   { opacity: 0; }
}
@keyframes geba-vt-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	/* still cross-document, just without the fade */
	::view-transition-old(root),
	::view-transition-new(root) { animation: none; }
}
