/* ==========================================================================
   Site reveal
   ==========================================================================
   The homepage's entrance, everywhere else: text arrives with a fade and a
   short lift, one element after another, as it scrolls into view. Global,
   plain CSS, loaded from includes/scripts-and-styles.php on every page but
   the front page, which carries its own (assets/css/home.css, [data-reveal]).

   What it reaches. Headings, paragraphs, list items, quotes, figures, tables
   and forms inside <main>, and a few card-like blocks, chosen so a page needs
   no markup to take part. An element inside another candidate is left alone
   (the outer one carries it), as is anything under [data-reveal] (a page's
   own entrance, run by its own script) or a .no-reveal wrapper. Media is left
   alone on purpose: a hero image is often the largest paint on the page and
   should not wait.

   Why it is safe for search and for readers without scripting. The hidden
   state exists only under html.js, which the head script sets synchronously,
   so a crawler or a reader without JavaScript gets the finished page in the
   HTML itself. With scripting, assets/js/site-reveal.js reveals each element
   as it enters the viewport, and marks the root tcw-revealing to say it is on
   duty. If that script never runs (it failed to load, or the browser cannot
   observe intersections), the safety animation below makes everything
   visible 2.6s after the styles load instead. The text is always in the DOM,
   at its place, in full.

   Motion is a courtesy, not a requirement: a reduced-motion preference and
   print both get the finished state at once.
   ========================================================================== */

:root {
	--tcw-reveal-t: 640ms;
	--tcw-reveal-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--tcw-reveal-step: 70ms;
	--tcw-reveal-lift: 14px;
}

/*
 * translate rather than transform, so a page's own transform on the same element (a positioned
 * diagram node, a rotated card) is never touched. :where() keeps the candidate list at zero
 * specificity, so the state rules below win by their prefix alone.
 */
/* One line on purpose: a line break between the :where() parts would be a descendant combinator. */
html.js body:not(.home) #main :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, figure, table, form, .svc-tier-card, .svc-tier-matrix-row):where(:not(:is(li, blockquote, figure, table, form, .svc-tier-card, .svc-tier-matrix-row, [data-reveal], .no-reveal, svg) *)):where(:not([data-reveal], .no-reveal)) {
	opacity: 0;
	translate: 0 var(--tcw-reveal-lift);
	transition:
		opacity var(--tcw-reveal-t) var(--tcw-reveal-ease),
		translate var(--tcw-reveal-t) var(--tcw-reveal-ease);
	transition-delay: calc(var(--tcw-reveal-i, 0) * var(--tcw-reveal-step));
	animation: tcw-reveal-safety 1ms linear 2600ms forwards;
}

html.js body:not(.home) #main .is-in:where(h1, h2, h3, h4, h5, h6, p, li, blockquote, figure, table, form, .svc-tier-card, .svc-tier-matrix-row) {
	opacity: 1;
	translate: none;
}

/* The script is on duty: the reveal is scroll-driven, so the safety stands down. */
html.js.tcw-revealing body:not(.home) #main :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, figure, table, form, .svc-tier-card, .svc-tier-matrix-row) {
	animation: none;
}

@keyframes tcw-reveal-safety {
	to {
		opacity: 1;
		translate: none;
	}
}

@media (prefers-reduced-motion: reduce), print {

	html.js body:not(.home) #main :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, figure, table, form, .svc-tier-card, .svc-tier-matrix-row) {
		opacity: 1;
		translate: none;
		transition: none;
		animation: none;
	}
}
