/* ======================================================================================================================================================
REVEAL TEXT

Shared by every element that can animate its text in - Special Heading and Text Block today.

avia-snippet-text-reveal.js splits the text into words or letters, and each unit carries its
own index. Everything below turns that index into a delay, so the timing of the animation
lives here rather than in javascript.

Until the split has happened the text stays invisible, else the whole of it would flash into
view before animating in. The failsafe animation is what makes that safe: if the script never
arrives, the text appears anyway, unanimated.
====================================================================================================================================================== */
.av-reveal{
	/*
	 * How far up the screen the text has to travel before it animates, as a percentage of
	 * the window height. 20 is the same point the theme's other fade in animations use -
	 * their "almost visible" trigger fires at an offset of 80%, which is the same line
	 * measured from the other end. Overwrite it in Quick CSS to move the trigger.
	 */
	--av-reveal-start: 20;

	--av-reveal-stagger: 0.06s;
	--av-reveal-duration: 1s;
	--av-reveal-ease: cubic-bezier( 0.25, 1, 0.5, 1 );
	--av-reveal-distance: 120%;
	--av-reveal-bleed: 0.12em;
}

.av-reveal-speed-slow{
	--av-reveal-stagger: 0.09s;
	--av-reveal-duration: 1.4s;
}

.av-reveal-speed-fast{
	--av-reveal-stagger: 0.03s;
	--av-reveal-duration: 0.6s;
}

/*
 * Words need a wider gap than letters. The delays above are per unit, and a heading has a
 * handful of words where it has dozens of letters - at the same spacing the words arrive
 * almost together and the effect reads as one block fading in rather than a sequence.
 *
 * After the speed rules on purpose: these carry the same weight and have to win.
 */
.av-reveal-word{
	--av-reveal-stagger: 0.1s;
}

.av-reveal-word.av-reveal-speed-slow{
	--av-reveal-stagger: 0.15s;
}

.av-reveal-word.av-reveal-speed-fast{
	--av-reveal-stagger: 0.05s;
}

html.js_active .av-reveal .av-reveal-target{
	visibility: hidden;
	animation: av-reveal-show 1ms linear 2s forwards;
}

html.js_active .av-reveal[data-av-reveal-ready] .av-reveal-target{
	visibility: visible;
	animation: none;
}

@keyframes av-reveal-show{
	to{ visibility: visible; }
}

/*
 * The text a screen reader announces in place of the split units below, which are hidden
 * from it. Not the theme's .screen-reader-text class - that one is set to display:none
 * elsewhere, which would hide this from screen readers too.
 */
.av-reveal-sr-text{
	position: absolute;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	clip-path: inset( 50% );
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	white-space: nowrap;
}

/* one group per word, so a word is never broken across two lines */
.av-reveal .av-reveal-group,
.av-reveal .av-reveal-unit{
	display: inline-flex;
	line-height: inherit;
}

.av-reveal .av-reveal-unit > span{
	display: inline-flex;
	line-height: inherit;
	transition-delay: calc( var(--av-reveal-i, 0) * var(--av-reveal-stagger) );
	transition-duration: var(--av-reveal-duration);
	transition-timing-function: var(--av-reveal-ease);
}

.av-reveal-fade .av-reveal-unit > span{
	opacity: 0;
	transition-property: opacity;
}

.av-reveal-fade.av-reveal-active .av-reveal-unit > span{
	opacity: 1;
}

/*
 * The unit clips, the text inside it slides up into place.
 *
 * Clipped along the bottom only. The text never moves sideways or above the line, so
 * those edges need no clip - and clipping them is what shaves the top off a "G" on a
 * heading with a tight line height, or the overhang off an italic "f".
 *
 * Even the bottom edge is given a little room: a tight line height pushes descenders
 * below the line box, and a clip flush with the box would cut them off. The travel
 * distance above covers that extra room, so nothing peeks before it animates.
 *
 * A clip costs no layout, so a heading fitted to the exact width of its container
 * keeps its measurements.
 */
.av-reveal-rise .av-reveal-unit{
	clip-path: inset( -0.5em -0.25em calc( var(--av-reveal-bleed) * -1 ) -0.25em );
}

.av-reveal-rise .av-reveal-unit > span{
	transform: translateY( var(--av-reveal-distance) );
	transition-property: transform;
	will-change: transform;
}

.av-reveal-rise.av-reveal-active .av-reveal-unit > span{
	transform: translateY( 0 );
}

/*
 * The script does not split at all when reduced motion is asked for, so this only catches a
 * heading that was already split when the setting changed mid-visit.
 */
@media (prefers-reduced-motion: reduce){
	.av-reveal .av-reveal-unit > span{
		opacity: 1;
		transform: none;
		transition: none;
	}
}
