/* The narrative page: layout, notes, and the effects in DESIGN.md, "Effects and
   interactivity". Everything reads without JavaScript or motion; the effects at the end
   are layered on only where the browser supports them and the reader allows motion. */

/* ---------------------------------------------------------------------------------------
   Layout. Narrow: one column. Wide: date-and-place margin, text, notes margin.
   --------------------------------------------------------------------------------------- */
.flow {
	display: grid;
	grid-template-columns: [full-start] var(--gutter) [text-start] minmax(0, 1fr) [text-end] var(--gutter) [full-end];
}
.flow > *,
.episode > *,
.night > * {
	grid-column: text-start / text-end;
}
.episode,
.night {
	grid-column: full-start / full-end;
	display: grid;
	grid-template-columns: subgrid;
	position: relative;
}
/* Wide: normal block flow, as in Tufte CSS, so a sidenote floated into the notes margin
   overflows its paragraph instead of stretching it (a grid item would grow to contain it).
   The episodes and plates run full width; only the text is set in from the edges. */
@media (min-width: 64rem) {
	.flow,
	.episode {
		display: block;
	}
	/* The night holds its own notes, so none spill past the black band of the fallback. */
	.night {
		display: flow-root;
	}
	/* A long note never runs into the plate or the band below it. */
	.plate,
	.night,
	.coda {
		clear: right;
	}
	.episode > p,
	.night > p,
	.n-nav {
		/* The date margin (10.5rem) after a centring lead; the notes margin (16rem) and a
		   gutter after the text. The text column takes what is left, up to the measure. */
		margin-left: calc(max(1rem, (100% - 62.5rem) / 2) + 10.5rem);
		margin-right: calc(16rem + var(--gutter));
		max-width: var(--measure);
	}
}

/* The narrative opens on the cover alone. */
html.narrative-page .site-header {
	display: none;
}

.episode > p,
.night > p {
	position: relative;
	margin-block: 0 1.15em;
	hyphens: manual;
}

/* Paragraph links, for citation. */
.pilcrow {
	position: absolute;
	left: -1.35rem;
	top: 0.05em;
	color: var(--muted);
	text-decoration: none;
	font-size: 0.85em;
	opacity: 0;
	transition: opacity 0.15s;
}
@media (max-width: 63.99rem) {
	.pilcrow {
		left: -0.9rem;
	}
}
p:hover > .pilcrow,
.pilcrow:focus-visible {
	opacity: 1;
}
p:target {
	animation: target-flash 2.4s ease-out;
}
@keyframes target-flash {
	from {
		background: color-mix(in srgb, var(--blue) 22%, transparent);
	}
}

/* ---------------------------------------------------------------------------------------
   Notes (effect 6). Wide: in the margin, lit up while the reader points at the number.
   Narrow: the number opens the note inline. No JavaScript either way.
   --------------------------------------------------------------------------------------- */
.note-ref {
	cursor: pointer;
}
.note-ref sup,
.tipnote sup {
	font: 700 0.62em/0 var(--sans);
	color: var(--blue);
	padding: 0 0.08em 0 0.05em;
}
.note-toggle {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}
.note:has(.note-toggle:focus-visible) .note-ref {
	outline: 2px solid var(--blue);
	outline-offset: 2px;
}
.sidenote {
	display: none;
	font: 400 0.84rem/1.45 var(--serif);
	font-style: normal;
	color: var(--fg);
}
.sidenote-n {
	font: 700 0.78em/1 var(--sans);
	color: var(--blue);
	margin-right: 0.2em;
}
.note-toggle:checked + .sidenote {
	display: block;
	margin: 0.4rem 0 0.8rem;
	padding: 0.15rem 0 0.15rem 0.8rem;
	border-left: 2px solid var(--blue);
}
@media (min-width: 64rem) {
	.note-toggle {
		display: none;
	}
	.note-ref {
		cursor: default;
	}
	.sidenote,
	.note-toggle:checked + .sidenote {
		display: block;
		float: right;
		clear: right;
		width: 13.5rem;
		margin: 0.3rem -16rem 0.9rem 0;
		padding: 0 0 0 0.75rem;
		border-left: 2px solid transparent;
		color: var(--muted);
		transition:
			color 0.2s,
			border-color 0.2s;
	}
	.note:hover .sidenote,
	.note:focus-within .sidenote {
		color: var(--fg);
		border-left-color: var(--blue);
	}
}

/* Glosses: period words that show their meaning on hover or tap. */
.gloss {
	position: relative;
	cursor: help;
	text-decoration: underline dotted color-mix(in srgb, var(--fg) 50%, transparent);
	text-decoration-thickness: 1.5px;
	text-underline-offset: 0.22em;
}
.tipnote {
	text-decoration: none;
	cursor: pointer;
}
.gloss-tip {
	position: absolute;
	left: 50%;
	bottom: calc(100% + 0.5rem);
	translate: -50% 0;
	z-index: 6;
	width: max-content;
	max-width: min(17rem, 80vw);
	padding: 0.45rem 0.75rem;
	background: var(--fg);
	color: var(--bg);
	font: italic 400 0.85rem/1.4 var(--serif);
	text-align: left;
	text-indent: 0;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition:
		opacity 0.15s,
		visibility 0.15s;
}
.gloss:hover .gloss-tip,
.gloss:focus .gloss-tip {
	opacity: 1;
	visibility: visible;
}

/* ---------------------------------------------------------------------------------------
   Running date and place (effect 5). Narrow: a bar that holds at the top of the screen
   while its episode is in view. Wide: the same, in the left margin. Each opens its
   timeline entry, with what the wider war was doing meanwhile.
   --------------------------------------------------------------------------------------- */
.dateline-rail {
	grid-column: full-start / full-end;
	position: sticky;
	top: 9px;
	z-index: 4;
	margin: -0.35rem 0 0.7rem;
	padding: 0.25rem var(--gutter);
	background: var(--bg);
	border-bottom: 1px solid color-mix(in srgb, var(--fg) 12%, transparent);
}
.dateline {
	all: unset;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 0.6rem;
	cursor: pointer;
}
.dateline:focus-visible {
	outline: 2px solid var(--blue);
	outline-offset: 3px;
}
.dateline .when {
	font: 700 0.78rem/1.35 var(--sans);
}
.dateline .where {
	font: italic 400 0.92rem/1.35 var(--serif);
	color: var(--muted);
}
.dateline:hover .when,
.dateline:focus-visible .when {
	color: var(--blue);
}
@media (min-width: 64rem) {
	.dateline-rail {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		width: calc(max(1rem, (100% - 62.5rem) / 2) + 8.5rem);
		grid-column: auto;
		margin: 0;
		padding: 0;
		background: none;
		border: 0;
		z-index: 3;
		pointer-events: none;
	}
	.dateline {
		position: sticky;
		top: 42vh;
		display: flex;
		flex-direction: column;
		align-items: flex-end;
		gap: 0.15rem;
		width: max-content;
		max-width: 11rem;
		margin-left: auto;
		text-align: right;
		pointer-events: auto;
	}
}

.tl-pop {
	margin: auto;
	max-width: min(26rem, 88vw);
	padding: 1.6rem 1.8rem 1.3rem;
	border: 1px solid var(--ink);
	background: var(--paper);
	color: var(--ink);
	font: 400 1rem/1.45 var(--serif);
}
.tl-pop::backdrop {
	background: rgb(25 26 24 / 0.3);
}
.tl-pop .tl-when {
	margin: 0 0 0.3rem;
	font: 700 0.8rem/1.3 var(--sans);
}
.tl-pop .tl-event {
	margin: 0 0 1.1rem;
	font-size: 1.15rem;
	line-height: 1.35;
}
.tl-pop h3 {
	margin: 0 0 0.4rem;
	font: 700 0.75rem/1.3 var(--sans);
	color: var(--quiet);
}
.tl-pop ul {
	margin: 0 0 1.1rem;
	padding: 0;
	list-style: none;
	font-size: 0.92rem;
	color: var(--quiet);
}
.tl-pop li + li {
	margin-top: 0.3rem;
}
.tl-pop .tl-link {
	font: 400 0.9rem var(--sans);
}
.tl-close {
	all: unset;
	position: absolute;
	top: 0.45rem;
	right: 0.7rem;
	font: 400 1.4rem/1 var(--sans);
	color: var(--quiet);
	cursor: pointer;
}
.tl-close:focus-visible {
	outline: 2px solid var(--blue);
}

/* ---------------------------------------------------------------------------------------
   Plates (effect 2). Each holds the full screen while the reader scrolls past it.
   --------------------------------------------------------------------------------------- */
.flow .plate,
.episode > .plate,
.night > .plate {
	grid-column: full-start / full-end;
}
.plate {
	height: 210svh;
}
.fx-night {
	height: 165svh;
	margin-block: 0.5rem;
}
.fx-hand,
.fx-stars,
.fx-shot {
	height: 260svh;
}
.fx-stake,
.fx-arms {
	height: 300svh;
}
.cover-stage {
	height: 380svh;
}
.fx-map {
	height: 560svh;
}
.plate figure {
	position: sticky;
	top: 0;
	height: 100svh;
	margin: 0;
	padding: 1.5rem var(--gutter);
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1rem;
}
.plate-art,
.cover-art {
	position: relative;
	height: min(76svh, calc((100vw - 2 * var(--gutter)) * var(--hw)));
}
.cover-art {
	height: min(88svh, calc((100vw - 2 * var(--gutter)) * var(--hw)));
}
.layer {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
}
.cover-stage {
	margin-block: 0 2rem;
}

/* Layer styles: the complete picture, which the effects below take apart. */
.leg {
	fill: none;
	stroke: var(--blue);
	stroke-width: 7;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-dasharray: 1 1;
	stroke-dashoffset: 0;
}
/* Map lettering: the places the route adds match the map's own, measured from MAP.psd and the
   master (in the map's pixels): ITC Giovanni Book at 24.5px, tracked +40, in black, italic
   for water; markers a black ring (outer radius 10.75) round a dot (radius 5.25). */
.route-stop {
	fill: var(--plate);
}
.route-stop .ring {
	fill: none;
	stroke: var(--plate);
	stroke-width: 2.5;
}
.route-label {
	fill: var(--plate);
	font: 400 24.5px var(--serif);
	letter-spacing: 0.04em;
}
.route-label.water {
	font-style: italic;
}
/* Captions belong to the animation; the still map shows the whole journey without one. Set
   in the map's Giovanni, larger so they read. */
.leg-caption {
	opacity: 0;
}
.leg-when {
	fill: #fff;
	font: 700 34px var(--serif);
}
.leg-what {
	fill: #fff;
	font: italic 400 40px var(--serif);
}
.stars circle {
	fill: #fff;
}
.shot-line,
.cstroke {
	fill: none;
	stroke-dasharray: 1 1;
	stroke-dashoffset: 0;
}
.shot-line {
	stroke: #000;
	stroke-linecap: butt;
}
.cstroke {
	stroke: #000;
	stroke-width: 30;
	stroke-linecap: round;
}
.shot-mark {
	transform-box: view-box;
}
.cover-title {
	z-index: 1;
}
.plate-art picture,
.plate-art img {
	width: 100%;
	height: 100%;
}
.plate figcaption {
	max-width: 28rem;
	text-align: center;
	font: italic 700 1rem/1.4 var(--serif);
	text-wrap: balance;
}
.plate .credit {
	display: block;
	margin-top: 0.35rem;
	font: 400 0.75rem/1.3 var(--sans);
	color: var(--muted);
}

/* The tattoo (effect 3): the ladder layer, revealed through six stroke masks. */
.tattoo .stroke {
	fill: none;
	stroke: #fff;
	stroke-width: 28;
	stroke-linecap: round;
	stroke-dasharray: 1 1;
	stroke-dashoffset: 0;
}

/* ---------------------------------------------------------------------------------------
   Nightfall (effect 1). Without the effect, the night is a black band.
   --------------------------------------------------------------------------------------- */
.night {
	--bg: #000000;
	--fg: #e9e7e1;
	--muted: #a3a097;
	background: var(--bg);
	color: var(--fg);
	padding-bottom: 2rem;
}

/* ---------------------------------------------------------------------------------------
   Coda (effect 8): the closing lines, alone on the page.
   --------------------------------------------------------------------------------------- */
.flow .coda {
	grid-column: full-start / full-end;
	height: 320svh;
}
.coda-stage {
	position: sticky;
	top: 0;
	height: 100svh;
	box-sizing: border-box;
	padding: 0 var(--gutter);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
}
.coda-psalm {
	margin: 0 0 2.6rem;
	font-size: 1.3rem;
	line-height: 1.75;
}
.coda-line {
	display: block;
}
.coda-blessing {
	margin: 0 0 2.6rem;
	font-style: italic;
}
.coda-finis {
	margin: 0;
	font: 900 1.6rem/1 var(--sans);
	letter-spacing: 0.04em;
}

.n-nav {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	margin-block: 2rem 0;
	font: 400 0.95rem/1.3 var(--sans);
}
.n-nav a {
	color: inherit;
	text-decoration: none;
}
.n-nav a:hover {
	color: var(--blue);
}

/* ---------------------------------------------------------------------------------------
   Reading progress (effect 4): the line itself is in site.css; it follows the narrative.
   --------------------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
	.narrative {
		view-timeline: --article block;
	}
	html.narrative-page {
		timeline-scope: --article;
	}
}

/* ---------------------------------------------------------------------------------------
   The scroll-driven effects, for readers who allow motion.
   --------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	@supports (animation-timeline: view()) {
		/* 1. Nightfall: the whole page darkens across the night, and day returns. */
		html.narrative-page {
			timeline-scope: --night, --article;
			animation: nightfall linear both;
			animation-timeline: --night;
			animation-range: entry 0% exit 100%;
		}
		.night {
			view-timeline: --night block;
			--bg: inherit;
			--fg: inherit;
			--muted: inherit;
			background: transparent;
			color: inherit;
			padding-bottom: 0;
		}

		/* 2. Plates rise into place, then hold. The cover is already in place. */
		.plate {
			view-timeline: --plate block;
		}
		.plate:not(.cover-stage) .plate-art {
			animation: plate-rise linear both;
			animation-timeline: --plate;
			animation-range: entry 0% entry 100%;
		}
		.plate figcaption {
			animation: caption-in linear both;
			animation-timeline: --plate;
			animation-range: entry 75% contain 6%;
		}

		/* 3. The tattoo draws itself, stroke by stroke, while the hand holds: the rails, then
		   the rungs, each from its own layer so no rung shows early. */
		.tattoo .stroke {
			animation: ink-stroke linear both;
			animation-timeline: --plate;
		}
		.tattoo .s1 { animation-range: contain 3% contain 17%; }
		.tattoo .s2 { animation-range: contain 17% contain 31%; }
		.tattoo .s3 { animation-range: contain 33% contain 43%; }
		.tattoo .s4 { animation-range: contain 45% contain 55%; }
		.tattoo .s5 { animation-range: contain 57% contain 67%; }
		.tattoo .s6 { animation-range: contain 69% contain 79%; }

		/* The cover: the title's two blocks together, then opening apart; the hand rises
		   between them; the ladder is pricked into it. */
		.cover-title {
			animation: title-open ease-in-out both;
			animation-timeline: --plate;
			animation-range: contain 6% contain 26%;
		}
		.cover-hand {
			animation: hand-rise linear both;
			animation-timeline: --plate;
			animation-range: contain 28% contain 50%;
		}
		.cstroke {
			animation: ink-stroke linear both;
			animation-timeline: --plate;
		}
		.c1 { animation-range: contain 54% contain 61%; }
		.c2 { animation-range: contain 61% contain 68%; }
		.c3 { animation-range: contain 70% contain 75%; }
		.c4 { animation-range: contain 76% contain 81%; }
		.c5 { animation-range: contain 82% contain 87%; }
		.c6 { animation-range: contain 88% contain 93%; }

		/* Map: the bare map, then the names, then Brown's journey leg by leg. Each leg dims
		   when the next begins; its caption shows in the sea while it draws. */
		.map-names {
			animation: fade-in linear both;
			animation-timeline: --plate;
			animation-range: contain 2% contain 8%;
		}
		.leg {
			animation-name: ink-stroke, dim;
			animation-timing-function: linear;
			animation-fill-mode: both;
			animation-timeline: --plate;
		}
		.leg-last {
			animation-name: ink-stroke;
		}
		.route-stop,
		.route-label {
			animation: fade-in linear both;
			animation-timeline: --plate;
		}
		.leg-caption {
			animation: caption-span linear both;
			animation-timeline: --plate;
		}
		.leg-caption-last {
			animation-name: fade-in;
		}

		/* The night: firelight finds the figures. */
		.fx-night .plate-art > picture {
			mask-image: radial-gradient(circle at var(--fx) var(--fy), #000 var(--glow), transparent calc(var(--glow) + 16%));
			animation: glow linear both;
			animation-timeline: --plate;
			animation-range: entry 60% contain 60%;
		}

		/* The head and pole are raised into the fixed frame; the merchant comes into it from
		   the right. */
		.framed-picture {
			animation: raise ease-out both;
			animation-timeline: --plate;
			animation-range: contain 0% contain 45%;
		}
		.fx-arrive .framed-picture {
			animation-name: arrive;
		}

		/* The stake: the man, then each burning skewer in turn. */
		.skewer {
			animation: appear steps(1, jump-start) both;
			animation-timeline: --plate;
		}
		.skewer-1 { animation-range: contain 14% contain 26%; }
		.skewer-2 { animation-range: contain 32% contain 44%; }
		.skewer-3 { animation-range: contain 50% contain 62%; }
		.skewer-4 { animation-range: contain 68% contain 80%; }

		/* The gauntlet: the arms rise one at a time, left to right. */
		.arm {
			animation: arm-in ease-out both;
			animation-timeline: --plate;
		}
		.arm-1 { animation-range: contain 6% contain 22%; }
		.arm-2 { animation-range: contain 26% contain 42%; }
		.arm-3 { animation-range: contain 46% contain 62%; }
		.arm-4 { animation-range: contain 66% contain 82%; }

		/* The stars come out one at a time over the street. */
		.stars circle {
			animation: fade-in linear both;
			animation-timeline: --plate;
		}

		/* The field rises around the man at work. */
		.fx-grass .plate-art > picture {
			mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 200' preserveAspectRatio='none'%3E%3Cpath d='M0 200L0.0 99.5L0.5 87.5L0.9 98.4L1.3 90.3L1.6 98.5L1.9 93.6L2.3 99.8L2.8 93.1L3.3 97.5L3.8 92.8L4.3 98.1L4.7 84.5L5.1 98.8L5.7 84.2L6.3 97.4L6.6 91.1L7.0 99.6L7.3 90.9L7.7 99.5L8.4 88.2L9.1 98.9L9.7 88.5L10.4 99.8L10.7 91.9L11.0 98.7L11.7 90.9L12.3 98.6L12.9 91.0L13.5 97.9L14.2 91.6L14.9 98.4L15.5 85.2L16.1 99.1L16.7 84.2L17.4 98.7L17.7 86.4L18.1 98.5L18.5 93.6L18.9 97.7L19.5 88.3L20.1 99.1L20.9 87.0L21.6 98.3L22.2 89.4L22.8 97.2L23.5 89.3L24.2 99.8L24.9 87.0L25.5 97.0L26.1 85.8L26.7 98.8L27.2 87.3L27.6 98.6L27.9 92.3L28.3 99.8L28.6 86.3L29.0 99.3L29.3 90.1L29.7 99.8L30.4 89.5L31.2 97.3L31.7 85.8L32.3 99.2L33.1 89.8L33.8 97.3L34.3 84.4L34.7 99.5L35.1 91.7L35.5 98.5L35.9 88.1L36.3 100.0L36.8 89.8L37.2 98.3L37.7 84.5L38.2 98.5L38.8 87.8L39.4 99.8L40.1 85.0L40.7 97.4L41.4 86.0L42.1 98.8L42.6 93.0L43.1 99.8L43.7 93.3L44.3 99.5L44.7 90.6L45.1 100.0L45.5 92.5L45.8 98.9L46.1 93.7L46.5 98.2L47.2 92.5L48.0 99.0L48.4 90.4L48.8 97.5L49.2 84.1L49.5 98.5L50.1 93.1L50.6 99.0L51.0 91.4L51.3 99.5L52.0 93.8L52.7 98.4L53.5 92.5L54.3 99.9L54.9 88.7L55.4 97.4L56.2 87.0L57.0 98.9L57.4 92.3L57.9 98.4L58.6 86.2L59.2 99.3L59.7 85.9L60.2 97.4L61.0 85.9L61.8 97.8L62.5 91.7L63.2 98.9L63.7 93.7L64.3 99.2L64.6 91.4L64.9 97.1L65.6 89.5L66.2 97.0L67.0 84.4L67.8 99.3L68.2 91.7L68.7 99.4L69.1 87.8L69.5 97.5L70.3 89.2L71.0 97.6L71.6 93.2L72.3 97.3L72.9 86.2L73.5 98.6L74.2 92.2L74.9 99.0L75.6 86.0L76.3 98.8L77.1 90.0L77.8 97.8L78.6 92.3L79.4 99.5L79.8 85.0L80.1 99.6L80.8 85.7L81.5 98.0L82.3 90.5L83.1 99.6L83.7 93.9L84.3 98.1L85.0 88.7L85.8 98.7L86.6 85.3L87.4 99.4L88.1 91.5L88.8 99.3L89.2 88.1L89.7 98.7L90.1 92.7L90.5 98.9L91.3 89.4L92.0 97.3L92.6 89.8L93.2 98.5L94.0 88.7L94.7 99.9L95.3 89.6L95.9 100.0L96.3 86.0L96.7 98.6L97.0 86.7L97.4 99.0L98.0 88.8L98.6 97.6L99.2 92.9L99.7 99.3L100.3 91.2L100 98L100 200Z'/%3E%3C/svg%3E");
			mask-size: 100% 200%;
			mask-repeat: no-repeat;
			animation: grass-rise linear both;
			animation-timeline: --plate;
			animation-range: entry 70% contain 60%;
		}

		/* The partridge: the drawn line is the aim; the shot draws over it in heavier ink,
		   and the mark appears where it strikes. */
		.shot-line {
			animation: ink-stroke linear both;
			animation-timeline: --plate;
		}
		.shot-mark {
			animation: pop linear both;
			animation-timeline: --plate;
		}

		/* 8. The coda arrives a line at a time. */
		.coda {
			view-timeline: --coda block;
		}
		.coda-line,
		.coda-blessing,
		.coda-finis {
			animation: coda-in linear both;
			animation-timeline: --coda;
		}
		.coda-line:nth-child(1) {
			animation-range: contain 0% contain 10%;
		}
		.coda-line:nth-child(2) {
			animation-range: contain 12% contain 22%;
		}
		.coda-line:nth-child(3) {
			animation-range: contain 24% contain 34%;
		}
		.coda-line:nth-child(4) {
			animation-range: contain 36% contain 46%;
		}
		.coda-blessing {
			animation-range: contain 52% contain 64%;
		}
		.coda-finis {
			animation-range: contain 72% contain 86%;
		}
	}
}

@keyframes nightfall {
	0% {
		--bg: #ffffff;
		--fg: #191a18;
		--muted: #6b6b66;
	}
	14%,
	86% {
		--bg: #000000;
		--fg: #e9e7e1;
		--muted: #a3a097;
	}
	100% {
		--bg: #ffffff;
		--fg: #191a18;
		--muted: #6b6b66;
	}
}
@property --wipe {
	syntax: '<percentage>';
	inherits: false;
	initial-value: 112%;
}
@property --glow {
	syntax: '<percentage>';
	inherits: false;
	initial-value: 120%;
}
@property --rise {
	syntax: '<percentage>';
	inherits: false;
	initial-value: 100%;
}
@keyframes wipe {
	from {
		--wipe: -18%;
	}
	to {
		--wipe: 112%;
	}
}
@keyframes glow {
	from {
		--glow: 0%;
	}
	to {
		--glow: 120%;
	}
}
@keyframes grass-rise {
	from {
		mask-position: 0 0%;
	}
	to {
		mask-position: 0 100%;
	}
}
@keyframes fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
@keyframes pop {
	from {
		opacity: 0;
		scale: 2.2;
	}
	to {
		opacity: 1;
		scale: 1;
	}
}
@keyframes title-open {
	from {
		translate: var(--tx) var(--ty);
	}
	to {
		translate: 0 0;
	}
}
@keyframes dim {
	to {
		opacity: 0.3;
		stroke-width: 4;
	}
}
@keyframes caption-span {
	0% {
		opacity: 0;
	}
	12%,
	88% {
		opacity: 1;
	}
	100% {
		opacity: 0;
	}
}
@keyframes appear {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
@keyframes raise {
	from {
		translate: 0 80%;
	}
	to {
		translate: 0 0;
	}
}
@keyframes arrive {
	from {
		translate: 85% 0;
	}
	to {
		translate: 0 0;
	}
}
@keyframes arm-in {
	from {
		opacity: 0;
		translate: 0 6%;
	}
	to {
		opacity: 1;
		translate: 0 0;
	}
}
@keyframes hand-rise {
	from {
		opacity: 0;
		translate: -6% 22%;
	}
	to {
		opacity: 1;
		translate: 0 0;
	}
}
@keyframes plate-rise {
	from {
		opacity: 0;
		scale: 0.88;
	}
	to {
		opacity: 1;
		scale: 1;
	}
}
@keyframes caption-in {
	from {
		opacity: 0;
		translate: 0 0.6rem;
	}
	to {
		opacity: 1;
		translate: 0 0;
	}
}
@keyframes ink-stroke {
	from {
		stroke-dashoffset: 1;
	}
	to {
		stroke-dashoffset: 0;
	}
}
@keyframes coda-in {
	from {
		opacity: 0;
		translate: 0 0.8rem;
	}
	to {
		opacity: 1;
		translate: 0 0;
	}
}
