/**
 * Swup page transitions.
 *
 * This file is not decoration -- it is load-bearing. Swup's `animationSelector`
 * looks for these elements and WAITS for a real CSS transition to finish before
 * swapping content. A theme that puts `transition-fade` in its markup but never
 * defines the class gets no animation at all and, worse, makes Swup sit through
 * its internal timeout on every single navigation. Markup and CSS have to ship
 * together.
 *
 * How the handshake works:
 *   1. Swup adds `.is-animating` to <html> and waits for the out-transition.
 *   2. It swaps the container contents.
 *   3. It removes `.is-animating` and the in-transition plays.
 */

.transition-fade {
	opacity: 1;
	transition: opacity 200ms ease-out;
}

html.is-animating .transition-fade {
	opacity: 0;
}

/**
 * A slightly richer variant -- fade plus a small lift. Put `transition-slide`
 * on the container instead of `transition-fade` to use it.
 *
 * Note the direction is written in logical properties (translate on the block
 * axis), so it behaves the same in LTR and RTL. Hardcoding translateX here is
 * a common way to end up with a transition that slides the wrong way on an
 * Arabic or Hebrew site.
 */
.transition-slide {
	opacity: 1;
	transform: translateY( 0 );
	transition: opacity 220ms ease-out, transform 220ms ease-out;
}

html.is-animating .transition-slide {
	opacity: 0;
	transform: translateY( 12px );
}

/**
 * Loading affordance.
 *
 * On a fast connection the swap is imperceptible and needs no spinner. On a
 * slow one, a click with no feedback reads as a broken link, so show the
 * browser's own "busy" cursor while a visit is in flight.
 */
html.is-navigating,
html.is-navigating a {
	cursor: progress;
}

/**
 * A thin progress bar along the top edge. Purely CSS -- it is driven by the
 * `is-navigating` class the init script toggles, so there is no JS timer to
 * keep in sync.
 */
html.is-navigating::after {
	content: "";
	position: fixed;
	inset-block-start: 0;
	inset-inline-start: 0;
	z-index: 99999;
	block-size: 3px;
	inline-size: 100%;
	background: currentColor;
	opacity: 0.85;
	/* transform-origin only takes physical keywords, so the RTL case needs its
	   own rule -- a progress bar that grows away from the reading edge looks
	   backwards. */
	transform-origin: left center;
	animation: swup-progress 1.6s ease-out forwards;
	pointer-events: none;
}

html[dir="rtl"].is-navigating::after {
	transform-origin: right center;
}

@keyframes swup-progress {
	0%   { transform: scaleX( 0 ); }
	60%  { transform: scaleX( 0.75 ); }
	100% { transform: scaleX( 0.95 ); }
}

/**
 * Respect the user's motion preference.
 *
 * Vestibular disorders make movement genuinely unpleasant, and this preference
 * is how people tell us so. Collapsing the duration to near-zero rather than
 * removing the transition keeps Swup's completion event firing, so navigation
 * still works -- setting `transition: none` here would leave Swup waiting.
 */
@media ( prefers-reduced-motion: reduce ) {
	.transition-fade,
	.transition-slide {
		transition-duration: 1ms;
		transform: none;
	}

	html.is-animating .transition-slide {
		transform: none;
	}

	html.is-navigating::after {
		animation: none;
	}
}

/**
 * Removes the focus ring that would otherwise appear on the content container
 * when the init script moves focus there after a navigation. The focus move is
 * for screen readers; a visible outline around the whole page is not useful.
 */
[tabindex="-1"]:focus {
	outline: 0;
}

/**
 * The live region the init script creates to announce each navigation.
 *
 * It must stay in the accessibility tree, so `display: none` and
 * `visibility: hidden` are both wrong -- they would remove it and announce
 * nothing. This clips it to a single pixel instead, which is the standard
 * visually-hidden technique.
 *
 * If your project already ships an equivalent (WordPress themes have
 * `.screen-reader-text`, Bootstrap has `.visually-hidden`, Tailwind has
 * `sr-only`), point the init script at that class instead of duplicating it.
 */
.swup-visually-hidden {
	position: absolute !important;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset( 50% );
	white-space: nowrap;
	border: 0;
}
