/**
 * Animated gradient hero (pattern: kindling/hero-animated-gradient).
 *
 * The gradient follows the designer's Figma Make handoff
 * (matchbox-animation-handoff, src/index.css), using the theme's color
 * presets, which carry the same values as the handoff's palette.
 *
 * Layers, bottom to top:
 * 1. Panel background: the static "Gradient-08" preset (theme.json), fitted
 *    to the still (reduced-motion) frame below. Shows in the editor, and on
 *    the front end until the canvas paints.
 * 2. .matchbox-gradient-hero__canvas (handoff: .gradient-field): dark green
 *    base, plus two oversized, blurred color layers (::before, ::after) that
 *    drift on alternating loops. Front end only, added by
 *    includes/gradient-hero.php.
 * 3. Panel ::after (handoff: .gradient-demo::after): a light dark-green tint
 *    and "living" grain.
 * 4. Content (header, headline, lede), with a soft halo behind the text block
 *    so the lede meets WCAG AA (4.5:1) throughout the animation, and a
 *    pause/play button (WCAG 2.2.2) shown by matchbox-gradient-hero.js.
 */

.matchbox-gradient-hero {
	/* Layout. */
	--mgh-pad-x: clamp(1.25rem, 0.5rem + 3vw, 2.5rem);
	--mgh-pad-bottom: clamp(2rem, 1.25rem + 2.5vw, 3rem);
	/* 90% of the viewport, so the next section peeks above the fold. */
	--mgh-min-height: max(34rem, calc(90svh - var(--wp-admin--admin-bar--height, 0px)));

	/* Animation (handoff values). */
	--mgh-duration: 1; /* Multiplier for both loop durations. Higher is slower. */
	--mgh-blur-a: 54px;
	--mgh-blur-b: 68px;
	--mgh-saturate-a: 100%;

	/* Readability halo behind the text block (the handoff's dark green tint). */
	--mgh-text-scrim: rgb(14 35 36 / 0.2);

	box-sizing: border-box;
	max-width: 100%;
}

.matchbox-gradient-hero__panel {
	position: relative;
	box-sizing: border-box;
	min-height: var(--mgh-min-height);
	padding: 0 var(--mgh-pad-x) var(--mgh-pad-bottom);
	/* Text sits at the bottom; a header, when present, keeps the top (see below). */
	justify-content: flex-end;
	/*
	 * Keep the text halo inside the hero so it can't shade the next section.
	 * clip (not hidden) doesn't affect fixed-position children such as the
	 * mobile menu overlay.
	 */
	overflow: clip;
	/* Fallback if the preset is ever removed from the block. */
	background-color: var(--wp--preset--color--theme-04);
}

/* Content sits above the canvas and grain. Header and text share the wide width. */
.matchbox-gradient-hero__panel > :not(.matchbox-gradient-hero__canvas) {
	position: relative;
	z-index: 1;
}

/*
 * Header inside the hero: pinned to the top by its auto bottom margin, and
 * layered above the text so the mobile menu overlay covers the hero content.
 */
.matchbox-gradient-hero__panel > .wp-block-template-part {
	z-index: 2;
	margin-bottom: auto;
}

/* The panel already pads the header, so drop the header's own root padding. */
.matchbox-gradient-hero__panel > .wp-block-template-part > .has-global-padding {
	padding-inline: 0;
}

/*
 * Two classes to beat core's `body .is-layout-flex > * { margin: 0 }`. Only the
 * inline margins are set here, so a top margin chosen in the editor still
 * applies, as the minimum gap below the header.
 */
.matchbox-gradient-hero__panel > .matchbox-gradient-hero__content {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1280px);
	margin-inline: auto;
}

/*
 * Halo behind the text, so the lede keeps 4.5:1 wherever the layers drift.
 * closest-side makes it fade out fully inside its own box, so it never shows
 * a hard edge.
 */
.matchbox-gradient-hero__content::before {
	content: '';
	position: absolute;
	inset: -45% -30% -45% -25%;
	z-index: -1;
	background: radial-gradient(closest-side, var(--mgh-text-scrim) 0%, color-mix(in srgb, var(--mgh-text-scrim) 70%, transparent) 55%, rgb(14 35 36 / 0) 100%);
	pointer-events: none;
}

/* Typography. */
.matchbox-gradient-hero .matchbox-gradient-hero__title {
	max-width: 9.5em;
	margin: 0;
	font-size: clamp(2.75rem, 1.6rem + 5.6vw, 7.5rem);
	font-weight: 600;
	letter-spacing: -0.035em;
	line-height: 0.98;
	text-wrap: balance;
	/* Handoff: soft dark shadow that keeps the headline legible over the bright fields. */
	text-shadow:
		0 2px 24px rgb(14 35 36 / 22%),
		0 1px 2px rgb(14 35 36 / 18%);
}

.matchbox-gradient-hero .matchbox-gradient-hero__lede {
	max-width: 31em;
	margin-block: clamp(1.5rem, 1rem + 2vw, 2.75rem) 0;
	font-size: clamp(1.0625rem, 0.95rem + 0.45vw, 1.375rem);
	font-weight: 400;
	line-height: 1.45;
}

/*
 * Front page only: the site header sits on the gradient there, so the logo
 * turns white and the CTA turns dark, per the design. Scoped to body.home so
 * every other template keeps the default header. The button needs !important
 * to beat the orange-button rule in style.css, which is itself !important.
 */
body.home .matchbox-gradient-hero__panel > .wp-block-template-part {
	--wp--custom--color--logo: #fff;
}

body.home .matchbox-gradient-hero__panel > .wp-block-template-part .wp-block-button__link.wp-element-button {
	background-color: var(--wp--preset--color--theme-03) !important;
	color: #fff !important;
}

body.home .matchbox-gradient-hero__panel > .wp-block-template-part .wp-block-button__link.wp-element-button:is(:hover, :focus-visible) {
	background-color: var(--wp--preset--color--theme-02) !important;
}

/* Canvas (handoff: .gradient-field): dark green base; clips the drifting layers. */
.matchbox-gradient-hero__canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	isolation: isolate;
	contain: strict;
	background:
		radial-gradient(circle at 9% 15%, var(--wp--preset--color--theme-07) 0 8%, transparent 30%),
		radial-gradient(circle at 83% 12%, var(--wp--preset--color--theme-11) 0 10%, transparent 34%),
		radial-gradient(circle at 52% 95%, var(--wp--preset--color--theme-12) 0 13%, transparent 40%),
		var(--wp--preset--color--theme-04);
	pointer-events: none;
}

/*
 * The two drifting layers are larger than the hero, so their edges never show.
 *
 * Cursor tracking: matchbox-gradient-hero.js sets --mgh-pointer-x/y (-1 to 1,
 * eased) on the canvas. The layers shift with the standalone `translate`
 * property, which composes with the keyframed `transform`, so the drift loops
 * keep running underneath. Layer B moves further than A for a little depth.
 * Without the script both values stay 0 and nothing moves.
 */
.matchbox-gradient-hero__canvas {
	--mgh-pointer-x: 0;
	--mgh-pointer-y: 0;
	--mgh-track-a: 3%;
	--mgh-track-b: 5%;
}

.matchbox-gradient-hero__canvas::before,
.matchbox-gradient-hero__canvas::after {
	content: '';
	position: absolute;
	inset: -35%;
	will-change: transform, translate;
}

/* Layer A: raspberry and green blooms over a conic sweep. */
.matchbox-gradient-hero__canvas::before {
	z-index: -3;
	background:
		radial-gradient(circle at 25% 64%, var(--wp--preset--color--theme-10) 0 9%, transparent 29%),
		radial-gradient(circle at 75% 62%, var(--wp--preset--color--theme-05) 0 13%, transparent 37%),
		radial-gradient(circle at 48% 25%, var(--wp--preset--color--theme-10) 0 6%, transparent 25%),
		conic-gradient(
			from 195deg at 50% 50%,
			var(--wp--preset--color--theme-06),
			var(--wp--preset--color--theme-10) 24%,
			var(--wp--preset--color--theme-10) 48%,
			var(--wp--preset--color--theme-11) 72%,
			var(--wp--preset--color--theme-05)
		);
	filter: blur(var(--mgh-blur-a)) saturate(var(--mgh-saturate-a));
	translate: calc(var(--mgh-pointer-x) * var(--mgh-track-a)) calc(var(--mgh-pointer-y) * var(--mgh-track-a));
	animation: mgh-drift-a calc(3s * var(--mgh-duration)) ease-in-out infinite alternate;
}

/* Layer B: orange, pink, blue and green blooms, softer and partly transparent. */
.matchbox-gradient-hero__canvas::after {
	z-index: -2;
	background:
		radial-gradient(circle at 18% 25%, var(--wp--preset--color--theme-11) 0 8%, transparent 31%),
		radial-gradient(circle at 74% 28%, var(--wp--preset--color--theme-08) 0 10%, transparent 35%),
		radial-gradient(circle at 60% 78%, var(--wp--preset--color--theme-06) 0 13%, transparent 39%),
		radial-gradient(circle at 30% 76%, var(--wp--preset--color--theme-05) 0 11%, transparent 35%);
	filter: blur(var(--mgh-blur-b)) saturate(135%);
	opacity: 0.78;
	translate: calc(var(--mgh-pointer-x) * var(--mgh-track-b)) calc(var(--mgh-pointer-y) * var(--mgh-track-b));
	animation: mgh-drift-b calc(11s * var(--mgh-duration)) ease-in-out infinite alternate;
}

/* Tint and living grain (handoff: .gradient-demo::after). */
.matchbox-gradient-hero__panel::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image:
		linear-gradient(rgb(14 35 36 / 10%), rgb(14 35 36 / 18%)),
		url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
	background-size: auto, 180px 180px;
	background-position: 0 0, 0 0;
	opacity: 0.28;
	pointer-events: none;
	animation: mgh-living-grain 1.8s steps(2, end) infinite;
}

/* Pause/play control (handoff: .motion-toggle), icon only. */
.matchbox-gradient-hero__panel > .matchbox-gradient-hero__toggle {
	position: absolute;
	right: var(--mgh-pad-x);
	bottom: var(--mgh-pad-bottom);
	z-index: 1;
	display: inline-flex;
	align-items: center;
	padding: 6px;
	border: 0;
	border-radius: 999px;
	color: var(--wp--preset--color--theme-01);
	background: rgb(14 35 36 / 42%);
	backdrop-filter: blur(8px);
	line-height: 1.2;
	cursor: pointer;
}

/* The label is the button's accessible name; hide it visually only. */
.matchbox-gradient-hero__toggle-label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.matchbox-gradient-hero__panel > .matchbox-gradient-hero__toggle[hidden] {
	display: none;
}

.matchbox-gradient-hero__toggle-icon {
	display: grid;
	width: 27px;
	height: 27px;
	place-items: center;
	border: 1px solid rgb(243 244 240 / 55%);
	border-radius: 50%;
	font-size: 0.62rem;
	transition: background-color 180ms ease, color 180ms ease;
}

.matchbox-gradient-hero__toggle:is(:hover, :focus-visible) .matchbox-gradient-hero__toggle-icon {
	color: var(--wp--preset--color--theme-03);
	background: var(--wp--preset--color--theme-01);
}

.matchbox-gradient-hero__toggle:focus-visible {
	outline: 2px solid var(--wp--preset--color--theme-01);
	outline-offset: 4px;
}

.matchbox-gradient-hero__panel.is-paused .matchbox-gradient-hero__canvas::before,
.matchbox-gradient-hero__panel.is-paused .matchbox-gradient-hero__canvas::after,
.matchbox-gradient-hero__panel.is-paused::after {
	animation-play-state: paused;
}

/* Alternating loops ease into each turn, so there's never a jump. */
@keyframes mgh-drift-a {
	0% {
		transform: translate3d(-8%, -4%, 0) rotate(-7deg) scale(1);
	}

	45% {
		transform: translate3d(7%, 5%, 0) rotate(8deg) scale(1.08);
	}

	100% {
		transform: translate3d(-2%, 9%, 0) rotate(-2deg) scale(1.14);
	}
}

@keyframes mgh-drift-b {
	0% {
		transform: translate3d(7%, 7%, 0) rotate(9deg) scale(1.12);
	}

	50% {
		transform: translate3d(-9%, -3%, 0) rotate(-5deg) scale(1.04);
	}

	100% {
		transform: translate3d(5%, -8%, 0) rotate(4deg) scale(1.16);
	}
}

@keyframes mgh-living-grain {
	0% {
		background-position: 0 0, 0 0;
	}

	25% {
		background-position: 0 0, 3px -2px;
	}

	50% {
		background-position: 0 0, -2px 3px;
	}

	75% {
		background-position: 0 0, 2px 2px;
	}

	100% {
		background-position: 0 0, -3px -1px;
	}
}

@media (max-width: 781px) {
	.matchbox-gradient-hero {
		--mgh-min-height: max(30rem, calc(90svh - var(--wp-admin--admin-bar--height, 0px)));
	}
}

/* Handoff: lighter blur on small screens. */
@media (max-width: 720px) {
	.matchbox-gradient-hero {
		--mgh-blur-a: 36px;
		--mgh-blur-b: 44px;
		--mgh-saturate-a: 125%;

		/* Text covers more of the hero on phones, so the halo needs a little more depth. */
		--mgh-text-scrim: rgb(14 35 36 / 0.28);
	}

	/* The lede runs full width here, so give the control its own row below it. */
	.matchbox-gradient-hero__panel:has(> .matchbox-gradient-hero__toggle:not([hidden])) {
		padding-bottom: calc(var(--mgh-pad-bottom) + 3.25rem);
	}
}

/* Portrait: full height leaves a tall empty field on phones and tablets; scale with width instead. */
@media (orientation: portrait) {
	.matchbox-gradient-hero {
		--mgh-min-height: min(calc(26rem + 50vw), calc(90svh - var(--wp-admin--admin-bar--height, 0px)));
	}
}

/* Reduced motion: freeze the layers and grain in place (handoff behavior); nothing to pause. */
@media (prefers-reduced-motion: reduce) {
	.matchbox-gradient-hero__canvas::before,
	.matchbox-gradient-hero__canvas::after,
	.matchbox-gradient-hero__panel::after {
		animation: none;
	}

	.matchbox-gradient-hero__panel > .matchbox-gradient-hero__toggle {
		display: none;
	}
}
