/*
Theme Name: Engine Base
Theme URI: https://github.com/engine/engine-base
Author: Engine
Author URI: https://github.com/engine
Description: Shared parent block theme for the Engine WordPress site factory. Structure only — every colour, font and brand value comes from the per-site child theme generated from tokens.json. Do not put brand values in this theme.
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 8.1
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: engine-base
Tags: block-patterns, full-site-editing, blog, e-commerce, one-column, wide-blocks
*/

/*
 * Engine Base ships almost no CSS on purpose.
 *
 * All presentation lives in theme.json (structure, here) and in the child
 * theme's generated theme.json (brand tokens). Anything below is mechanical:
 * it must never introduce a colour, a font family, or an absolute font size.
 */

/* --- Media ---------------------------------------------------------------- */

img,
video,
svg {
	max-width: 100%;
	height: auto;
}

/* --- Accessibility -------------------------------------------------------- */

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.screen-reader-text:focus {
	position: static !important;
	width: auto;
	height: auto;
	margin: 0;
	overflow: visible;
	clip: auto;
	white-space: normal;
}

.skip-link:focus {
	z-index: 100000;
}

/* --- Motion --------------------------------------------------------------- */

/*
 * A colourway switch changes the role custom properties in one step. While
 * palette.js holds `is-palette-switching` on <html> (under a second), every
 * colour-bearing property transitions, so the page glides to the new ambiance
 * instead of snapping. Opacity is listed so fading layers keep their fade.
 */
html.is-palette-switching *,
html.is-palette-switching *::before,
html.is-palette-switching *::after {
	transition-property: background-color, color, border-color, outline-color, fill, stroke, box-shadow, opacity;
	transition-duration: 700ms;
	transition-timing-function: ease;
}

/*
 * The header, the content and the footer touch. WordPress puts its block gap
 * between the top-level template parts and <main>; no design draws a strip of
 * canvas under its header, so the gap is removed here for every site.
 */
.wp-site-blocks > main,
.wp-site-blocks > footer {
	margin-block-start: 0;
}

/*
 * A sticky header sticks. The header pattern sits inside the template-part
 * wrapper, which is exactly as tall as the header, so `position: sticky` on
 * the pattern alone has nowhere to move; the wrapper carries it instead.
 */
.wp-site-blocks > header:has(> .engine-site-header.is-sticky) {
	position: sticky;
	/* A masthead pins only its index row: interact.js measures the rows above
	   it into --engine-masthead-offset and the wrapper sticks that far above
	   the viewport. Every other header measures 0 and sticks at the top. */
	inset-block-start: calc(-1 * var(--engine-masthead-offset, 0px));
	z-index: var(--wp--custom--layer--sticky, 40);
}

/*
 * Scroll motion (opt-in per site: <html data-scroll-motion="depth">).
 *
 * Scroll-driven CSS animations, so the compositor does the work and the page
 * never listens to scroll events. A pattern sets --engine-scroll-y (a
 * percentage of the element's own height) on what drifts and picks one of the
 * keyframes below; they animate `translate` (and `scale` stays free for a
 * pattern's own use), never `transform`, so a pattern's hover transforms are
 * untouched. Everything sits under prefers-reduced-motion: no-preference.
 * Browsers without animation-timeline run assets/js/scroll-motion.js, which
 * reads the same properties.
 *
 *   .engine-reveal   rises into view as it enters (--engine-scroll-rise, 4rem)
 *
 * Nothing in the flow drifts against its own section: a card that glides
 * relative to the heading above it ends up under that heading. What drifts
 * is what has room to: hero planes, decorative motifs, and photographs
 * inside their frames.
 */
@property --engine-scroll-y { syntax: '<length-percentage>'; inherits: false; initial-value: 0%; }
@property --engine-scroll-fade { syntax: '<number>'; inherits: false; initial-value: 1; }

@keyframes engine-scroll-shift {
	from { translate: 0 0; }
	to   { translate: 0 var(--engine-scroll-y, 0%); }
}
@keyframes engine-scroll-shift-fade {
	from { translate: 0 0; opacity: 1; }
	to   { translate: 0 var(--engine-scroll-y, 0%); opacity: var(--engine-scroll-fade, 1); }
}
@keyframes engine-scroll-drift {
	from { translate: 0 var(--engine-scroll-y, 0%); }
	to   { translate: 0 calc(-1 * var(--engine-scroll-y, 0%)); }
}
@keyframes engine-scroll-rise {
	from { translate: 0 var(--engine-scroll-rise, 4rem); rotate: var(--engine-scroll-rotate, 0deg); opacity: 0; }
	to   { translate: 0 0; rotate: 0deg; opacity: 1; }
}

/*
 * Small loops and one-shots a pattern can borrow (all under a reduced-motion
 * guard where they are used): a hover-free float, a pop, a pulsing ring, a
 * gradient that drifts, a print that steps in.
 */
@keyframes engine-float {
	from, to { translate: 0 0; }
	50%      { translate: 0 -0.45rem; }
}
@keyframes engine-pop {
	from { scale: 0.6; opacity: 0; }
	60%  { scale: 1.12; opacity: 1; }
	to   { scale: 1; opacity: 1; }
}
@keyframes engine-pulse {
	0%   { box-shadow: 0 0 0 0 var(--engine-pulse-color, currentColor); }
	55%  { box-shadow: 0 0 0 0.9em transparent; }
	100% { box-shadow: 0 0 0 0.9em transparent; }
}
@keyframes engine-gradient-drift {
	from { background-position: 0% 50%; }
	to   { background-position: 100% 50%; }
}
@keyframes engine-step-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@media (prefers-reduced-motion: no-preference) {
	@supports (animation-timeline: view()) {
		html[data-scroll-motion] .engine-reveal {
			animation: engine-scroll-rise cubic-bezier(0.2, 0.7, 0.2, 1) both;
			animation-timeline: view();
			animation-range: entry 0% entry 65%;
		}
		html[data-scroll-motion] .engine-reveal:nth-child(2) { animation-range: entry 10% entry 75%; }
		html[data-scroll-motion] .engine-reveal:nth-child(3) { animation-range: entry 20% entry 85%; }
		html[data-scroll-motion] .engine-reveal:nth-child(n + 4) { animation-range: entry 30% entry 95%; }
	}

	/* The script's path: it marks html once it runs, so nothing is hidden
	   unless it is there to reveal it. */
	html[data-scroll-motion].has-scroll-motion-js .engine-reveal {
		opacity: 0;
		translate: 0 var(--engine-scroll-rise, 4rem);
		rotate: var(--engine-scroll-rotate, 0deg);
		transition: opacity 0.8s ease, translate 0.8s cubic-bezier(0.2, 0.7, 0.2, 1), rotate 0.8s cubic-bezier(0.2, 0.7, 0.2, 1);
	}
	html[data-scroll-motion].has-scroll-motion-js .engine-reveal:nth-child(2) { transition-delay: 0.08s; }
	html[data-scroll-motion].has-scroll-motion-js .engine-reveal:nth-child(3) { transition-delay: 0.16s; }
	html[data-scroll-motion].has-scroll-motion-js .engine-reveal:nth-child(n + 4) { transition-delay: 0.24s; }
	html[data-scroll-motion].has-scroll-motion-js .engine-reveal.is-inview {
		opacity: 1;
		translate: 0 0;
		rotate: 0deg;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}
