/* ═══════════════════════════════════════════════════════════════════
   SCROLL REVEAL — PRIMITIVES

   A vocabulary of verbs. This file names no component, so it ports
   between builds unchanged. Every rule is scoped to html.wr-reveal,
   which an inline <head> script adds only when IntersectionObserver
   exists and motion is not reduced - so if that script never runs,
   nothing is ever hidden.

   Structural invariant: every resting rule requires an ancestor
   [data-reveal]; every entered rule requires that ancestor with
   .is-in-view. A verb outside a container is therefore never hidden.

   Markup API
     data-reveal               trigger, on a section container
     data-reveal-item="verb"   one element's move
     data-reveal-seq="verb"    stagger this element's children (JS sets --i)
     data-reveal-text          word-by-word reveal on a heading
     data-reveal-lead="420"    ms before it starts, ADDED to --sr-lead
     data-reveal-step="120"    ms between children
   ═══════════════════════════════════════════════════════════════════ */

:root {
	/* ── TUNING ─────────────────────────────────────────────────
	   If the ask is "start them sooner / later", "faster / slower" or
	   "less movement", the answer is in this block and nowhere else. */

	/* How far down the screen a section must be before it fires, as a
	   fraction of the viewport height. HIGHER = SOONER. Read by
	   js/reveal.js off :root, so the trigger is not split across two
	   files and two languages. */
	--sr-trigger: .78;

	/* The pause after firing, before anything moves. */
	--sr-lead: 260ms;

	/* Multiplies every duration. >1 slower, <1 snappier. Touches only
	   durations - "starts later" and "moves slower" are separate dials. */
	--sr-speed: 1;

	/* The gap between one staggered child (or word) and the next. */
	--sr-step: 175ms;
	--sr-word-step: 62ms;
	--sr-word-cap: 14;   /* word index past which the ripple stops growing */

	/* Multiplies how far every verb travels. 0 keeps the fades and drops
	   the movement. */
	--sr-distance: 1;

	--sr-ease: cubic-bezier(.16, 1, .3, 1);

	/* ── Derived. Verbs reference these, never a literal. ─────── */
	--sr-t-move: calc(1.55s * var(--sr-speed));
	--sr-t-wipe: calc(2s    * var(--sr-speed));
	--sr-t-fade: calc(1.35s * var(--sr-speed));

	--sr-d-up:       calc(30px * var(--sr-distance));
	--sr-d-glide:    calc(56px * var(--sr-distance));
	--sr-d-cascade:  calc(34px * var(--sr-distance));
	--sr-d-converge: calc(44px * var(--sr-distance));
	--sr-s-settle:   calc(1 - .04 * var(--sr-distance));
}

/* Shared delay: lead + index * step. */
html.wr-reveal [data-reveal] [data-reveal-item],
html.wr-reveal [data-reveal] [data-reveal-seq] > *,
html.wr-reveal [data-reveal][data-reveal-item] {
	--sr-delay: calc(var(--sr-lead) + var(--lead, 0ms) + var(--i, 0) * var(--step, var(--sr-step)));
}

/* ── up — one block rises ─────────────────────────────────────── */
html.wr-reveal [data-reveal] [data-reveal-item="up"] {
	opacity: 0;
	transform: translateY(var(--sr-d-up));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="up"] { opacity: 1; transform: none; }

/* ── glide — a larger object rises as a whole ─────────────────── */
html.wr-reveal [data-reveal] [data-reveal-item="glide"] {
	opacity: 0;
	transform: translateY(var(--sr-d-glide));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="glide"] { opacity: 1; transform: none; }

/* ── dissolve — opacity only, for anything a script transforms ── */
html.wr-reveal [data-reveal] [data-reveal-item="dissolve"] {
	opacity: 0;
	transition: opacity var(--sr-t-fade) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="dissolve"] { opacity: 1; }

/* ── curtain — vertical clip wipe. The verb for a photograph. ─── */
html.wr-reveal [data-reveal] [data-reveal-item="curtain"] {
	clip-path: inset(0 0 100% 0);
	transition: clip-path var(--sr-t-wipe) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="curtain"] { clip-path: inset(0 0 0 0); }

/* ── unveil — horizontal clip wipe ────────────────────────────── */
html.wr-reveal [data-reveal] [data-reveal-item="unveil"] {
	clip-path: inset(0 100% 0 0);
	transition: clip-path var(--sr-t-wipe) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="unveil"] { clip-path: inset(0 0 0 0); }

/* ── settle — scales up ───────────────────────────────────────── */
html.wr-reveal [data-reveal] [data-reveal-item="settle"] {
	opacity: 0;
	transform: scale(var(--sr-s-settle));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="settle"] { opacity: 1; transform: none; }

/* ── converge — two halves meeting from opposite sides ────────── */
html.wr-reveal [data-reveal] [data-reveal-item="converge-l"] {
	opacity: 0;
	transform: translateX(calc(-1 * var(--sr-d-converge)));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal] [data-reveal-item="converge-r"] {
	opacity: 0;
	transform: translateX(var(--sr-d-converge));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="converge-l"],
html.wr-reveal [data-reveal].is-in-view [data-reveal-item="converge-r"] { opacity: 1; transform: none; }

@media (max-width: 899px) {
	/* Stacked columns have no sides to converge from. */
	html.wr-reveal [data-reveal] [data-reveal-item="converge-l"],
	html.wr-reveal [data-reveal] [data-reveal-item="converge-r"] { transform: translateY(var(--sr-d-up)); }
}

/* ── cascade — staggered rise of a parent's children ──────────── */
html.wr-reveal [data-reveal] [data-reveal-seq="cascade"] > * {
	opacity: 0;
	transform: translateY(var(--sr-d-cascade));
	transition: opacity var(--sr-t-move) var(--sr-ease) var(--sr-delay),
	            transform var(--sr-t-move) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-seq="cascade"] > * { opacity: 1; transform: none; }

/* ── drift — staggered children, opacity only ─────────────────── */
html.wr-reveal [data-reveal] [data-reveal-seq="drift"] > * {
	opacity: 0;
	transition: opacity var(--sr-t-fade) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-seq="drift"] > * { opacity: 1; }

/* ── riser — staggered children, clip wipe ────────────────────── */
html.wr-reveal [data-reveal] [data-reveal-seq="riser"] > * {
	clip-path: inset(0 0 100% 0);
	transition: clip-path var(--sr-t-wipe) var(--sr-ease) var(--sr-delay);
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-seq="riser"] > * { clip-path: inset(0 0 0 0); }

/* ── read-in — per-word mask ──────────────────────────────────── */
.wr-w {
	display: inline-block;
	overflow: hidden;
	vertical-align: bottom;
	/* Descenders hang below the baseline and the mask would slice them off;
	   the padding gives them room and the negative margin takes that height
	   back out of the line box. */
	padding-bottom: .16em;
	margin-bottom: -.16em;
}

html.wr-reveal [data-reveal] [data-reveal-text] .wr-w__i {
	display: inline-block;
	transform: translateY(105%);
	transition: transform var(--sr-t-move) var(--sr-ease)
	            calc(var(--sr-lead) + var(--lead, 0ms) + var(--i, 0) * var(--step, var(--sr-word-step)));
}
html.wr-reveal [data-reveal].is-in-view [data-reveal-text] .wr-w__i { transform: none; }

/* ── Reduced motion, for a mid-session change ─────────────────── */
@media (prefers-reduced-motion: reduce) {
	html.wr-reveal [data-reveal] [data-reveal-item],
	html.wr-reveal [data-reveal] [data-reveal-seq] > *,
	html.wr-reveal [data-reveal] [data-reveal-text] .wr-w__i {
		clip-path: none !important;
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}
