/**
 * Cross-document View Transitions.
 *
 * Only when the visitor allows motion: with `prefers-reduced-motion: reduce`
 * nothing below applies and navigation is a normal page load.
 */
@media (prefers-reduced-motion: no-preference) {
	@view-transition {
		navigation: auto;
	}
}

/**
 * Persistent chrome gets its own name, so it stays put instead of cross-fading
 * with the root snapshot: the menu must not blink, the to-top button must not
 * jump. One element per page — a duplicated view-transition-name silently
 * disables the transition for both.
 */
#masthead {
	view-transition-name: site-header;
}

.origin-totop {
	view-transition-name: origin-to-top;
}

/**
 * Third-party floating widgets live in the same layer as the chrome. The chat
 * launcher is fixed to the viewport, and without a name of its own the root
 * cross-fade drags it across the screen on every navigation. The same one line
 * covers any other fixed-position widget a site adds.
 */
#wp-chatbot-ball {
	view-transition-name: origin-chatbot-ball;
}

/**
 * The launcher is positioned by the widget's own script, so its snapshot
 * differs between pages: the outgoing page has it where the script left it,
 * the incoming one is captured before the script has moved it. The group's
 * default animation interpolates that difference and reads as the ball flying
 * across the screen, so the group is not animated at all: the incoming
 * position simply applies, exactly as on a normal page load.
 */
::view-transition-group(origin-chatbot-ball) {
	animation: none;
}

::view-transition-old(origin-chatbot-ball),
::view-transition-new(origin-chatbot-ball) {
	animation: none;
	mix-blend-mode: normal;
}

/**
 * The region that actually changes. `main#primary` is the id used by index,
 * page, archive, 404, single and the post templates; full-width uses
 * `main#content`.
 */
main#primary,
main#content {
	view-transition-name: page-content;
}

/**
 * Content motion, forward (the default): the current page lifts away upwards and
 * the next one arrives from below. Only opacity + translate — no scale, which
 * would rasterise the snapshot and soften the text for the whole animation.
 */
::view-transition-old(page-content) {
	animation: origin-vt-out-forward 180ms cubic-bezier(0.4, 0, 1, 1) both;
}

::view-transition-new(page-content) {
	animation: origin-vt-in-forward 260ms cubic-bezier(0, 0, 0.2, 1) 40ms both;
}

/**
 * Going back (browser back/forward) plays the same motion reversed. The marker
 * attribute is set by view.js from the navigation type, on the outgoing page and
 * again on the incoming one; without JavaScript the forward direction stands.
 */
html[data-origin-nav="back"]::view-transition-old(page-content) {
	animation-name: origin-vt-out-back;
}

html[data-origin-nav="back"]::view-transition-new(page-content) {
	animation-name: origin-vt-in-back;
}

@keyframes origin-vt-out-forward {
	to {
		opacity: 0;
		transform: translateY(-10px);
	}
}

@keyframes origin-vt-in-forward {
	from {
		opacity: 0;
		transform: translateY(14px);
	}
}

@keyframes origin-vt-out-back {
	to {
		opacity: 0;
		transform: translateY(10px);
	}
}

@keyframes origin-vt-in-back {
	from {
		opacity: 0;
		transform: translateY(-14px);
	}
}

/**
 * Belt and braces for the explicit opt-out: no names, no transition at all.
 */
@media (prefers-reduced-motion: reduce) {
	#masthead,
	.origin-totop,
	#wp-chatbot-ball,
	main#primary,
	main#content {
		view-transition-name: none;
	}
}
