/*
 * Layer: motion, the top theme layer. Animations and their timing read
 * --wp--custom--ease / --ease-spring and --duration--fast / --base / --slow.
 * Every animation is guarded (plan §7): keyframed motion only runs under no-preference, and
 * reduced motion stops transitions and hover transforms too, kit misses included.
 */
@layer motion {

	@keyframes nd-fade-in {

		from {
			opacity: 0;
		}

		to {
			opacity: 1;
		}
	}

	@keyframes nd-slide-in {

		from {
			transform: translateX(100%);
		}

		to {
			transform: translateX(0);
		}
	}

	@keyframes nd-rise {

		from {
			opacity: 0;
			transform: translateY(18px);
		}

		to {
			opacity: 1;
			transform: none;
		}
	}

	/* Scroll-out fades with no "from": they start at whatever the entrance left (underlying value). */
	@keyframes nd-fade-away {

		to {
			opacity: 0;
			transform: translateY(-70px);
		}
	}

	@keyframes nd-fade-away-glass {

		to {
			border-color: transparent;
			background-color: transparent;
			color: transparent;
			transform: translateY(-70px);
			-webkit-backdrop-filter: blur(0) saturate(1);
			backdrop-filter: blur(0) saturate(1);
		}
	}

	/*
	 * nd-rise for a glass button: fading opacity would show the sharp art through a half-faded
	 * blur, so the fill, label, edge and blur radius grow in instead (ends at its own values).
	 */
	@keyframes nd-rise-glass {

		from {
			border-color: transparent;
			background-color: transparent;
			color: transparent;
			transform: translateY(18px);
			-webkit-backdrop-filter: blur(0) saturate(1);
			backdrop-filter: blur(0) saturate(1);
		}
	}

	@keyframes nd-draw {

		from {
			stroke-dashoffset: 1;
		}

		to {
			stroke-dashoffset: 0;
		}
	}

	@keyframes nd-sweep {

		from {
			clip-path: inset(0 100% 0 0);
		}

		to {
			clip-path: inset(0 0 0 0);
		}
	}

	@keyframes nd-spark {

		0% {
			opacity: 0;
			transform: translate(0, 0) scale(0.3) rotate(0deg);
		}

		25% {
			opacity: 1;
		}

		100% {
			opacity: 0;
			transform: translate(var(--dx, 14px), var(--dy, -22px)) scale(1) rotate(90deg);
		}
	}

	@keyframes nd-sun {

		0%,
		100% {
			opacity: 0.88;
			transform: scale(1);
		}

		50% {
			opacity: 1;
			transform: scale(1.14);
		}
	}

	@keyframes nd-brush {

		from {
			-webkit-mask-position: 100% 0;
			mask-position: 100% 0;
		}

		to {
			-webkit-mask-position: 0 0;
			mask-position: 0 0;
		}
	}

	@keyframes nd-drift {

		0%,
		100% {
			transform: translateX(-3%);
		}

		50% {
			transform: translateX(3%);
		}
	}

	@keyframes nd-shimmer {

		0% {
			background-position: 150% 0;
		}

		60%,
		100% {
			background-position: -50% 0;
		}
	}

	/*
	 * M15: with menu.js running (html.nd-menu-js), one progress value drives the overlay instead of
	 * the keyframes below: the script writes the panel's translate and the page's scale/opacity, and
	 * --nd-menu-p (0–1) here scales the scrim. The script itself honours reduced motion (instant, no
	 * scale). Without the script, core's overlay keeps the keyframed entrance.
	 */
	html.nd-menu-js .wp-block-navigation__responsive-container.disable-default-overlay.is-menu-open {
		animation: none;
		background-color: color-mix(in srgb, var(--wp--preset--color--cobalt) calc(35% * var(--nd-menu-p, 1)), transparent);
		-webkit-backdrop-filter: blur(calc(4px * var(--nd-menu-p, 1)));
		backdrop-filter: blur(calc(4px * var(--nd-menu-p, 1)));
	}

	html.nd-menu-js .is-menu-open .nd-menu {
		animation: none;
	}

	html.nd-menu-active .wp-site-blocks {
		will-change: scale, opacity;
	}

	/* The page keeps vertical panning and pinch-zoom; sideways swipes reach menu.js (burger widths only). */
	@media (max-width: 1100px) {

		html.nd-menu-js :is(.wp-site-blocks, .wp-block-navigation__responsive-container.is-menu-open) {
			touch-action: pan-y pinch-zoom;
		}
	}

	@media (prefers-reduced-motion: no-preference) {

		/* Overlay menu: scrim fades, panel slides in, ornament draws, links rise in turn. */
		.wp-block-navigation__responsive-container.disable-default-overlay.is-menu-open {
			animation: nd-fade-in 0.4s ease both;
		}

		.is-menu-open .nd-menu {
			animation: nd-slide-in 0.55s var(--wp--custom--ease) both;
		}

		.is-menu-open .nd-menu__ornament :is(path, circle) {
			stroke-dasharray: 1;
			animation: nd-draw 1.4s ease-out 0.3s both;
		}

		/* The filled band can't stroke-draw: a left-to-right clip sweep on the lines' exact timing. */
		.is-menu-open .nd-menu__ornament .nd-menu__band {
			animation: nd-sweep 1.4s ease-out 0.3s both;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item {
			animation: nd-rise 0.7s var(--d, 0.2s) var(--wp--custom--ease) both;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(2) {
			--d: 0.26s;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(3) {
			--d: 0.32s;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(4) {
			--d: 0.38s;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(5) {
			--d: 0.44s;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(6) {
			--d: 0.5s;
		}

		.is-menu-open .nd-menu__nav .wp-block-navigation-item:nth-child(n + 7) {
			--d: 0.56s;
		}

		/* Overlay account actions rise after the links (kit .nd-menu__actions). */
		/*
		 * Each action rises itself, never the wrapper (L110): an animating (or forwards-filled)
		 * ancestor is a backdrop root, so Sign in's glass would blur nothing until it ended. An
		 * element's own animation doesn't cut off its own backdrop. Backwards fill only (L70).
		 */
		.is-menu-open .nd-account--menu > * {
			animation: nd-rise 0.8s 0.75s var(--wp--custom--ease) backwards;
		}

		.is-menu-open .nd-account--menu > .nd-account__secondary {
			animation-name: nd-rise-glass;
		}

		/* Footer support button: sparks fly up and right while hovered. */
		.nd-support:is(:hover, :focus-visible) .nd-support__spark {
			animation: nd-spark 1.1s ease-out var(--d, 0s) infinite;
		}

		/* Front-page hero (kit .nd-rise, .nd-brush): copy rises in, the headline is brushed on. */
		.nd-hero__eyebrow {
			animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) both;
		}

		.nd-hero__title {
			-webkit-mask-image: linear-gradient(100deg, black 45%, transparent 55%);
			mask-image: linear-gradient(100deg, black 45%, transparent 55%);
			-webkit-mask-size: 260% 100%;
			mask-size: 260% 100%;
			animation: nd-brush 1.8s cubic-bezier(0.6, 0.05, 0.3, 1) 0.2s both;
		}

		.nd-hero__lead {
			animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) 1.2s both;
		}

		/*
		 * The buttons rise themselves, never their row: "Browse courses" is glass, and an animated
		 * ancestor is a backdrop root (L110). The glass one grows in instead of fading.
		 */
		.nd-hero__actions .wp-block-button__link {
			animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) 1.5s backwards;
		}

		.nd-hero__actions .is-style-glass .wp-block-button__link {
			animation-name: nd-rise-glass;
		}

		/*
		 * The copy lifts away as the hero scrolls out (kit .nd-hero-fade); no fallback where
		 * unsupported. The copy only names the timeline (animating it would gate the glass, even
		 * before the range starts); each piece fades itself on top of its entrance.
		 */
		@supports (animation-timeline: view()) {

			.nd-hero__copy {
				view-timeline-name: --nd-hero;
			}

			.nd-hero__eyebrow {
				animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) both, nd-fade-away linear both;
			}

			.nd-hero__title {
				animation: nd-brush 1.8s cubic-bezier(0.6, 0.05, 0.3, 1) 0.2s both, nd-fade-away linear both;
			}

			.nd-hero__lead {
				animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) 1.2s both, nd-fade-away linear both;
			}

			.nd-hero__actions .wp-block-button__link {
				animation: nd-rise var(--wp--custom--duration--slow) var(--wp--custom--ease) 1.5s backwards, nd-fade-away linear both;
			}

			.nd-hero__actions .is-style-glass .wp-block-button__link {
				animation-name: nd-rise-glass, nd-fade-away-glass;
			}

			:is(.nd-hero__eyebrow, .nd-hero__title, .nd-hero__lead, .nd-hero__actions .wp-block-button__link) {
				animation-timeline: auto, --nd-hero;
				animation-range: normal, cover 58% cover 100%;
			}
		}

		.wp-block-cover.is-style-living::after {
			animation: nd-drift 26s ease-in-out infinite;
		}

		.wp-block-cover.is-style-living .nd-living {
			transition: opacity 0.8s ease;
		}

		/* Backwards fill only: a forwards fill would pin transform:none over the hover lift. */
		.nd-islands > .is-style-glass-island {
			animation: nd-rise 1s var(--wp--custom--ease) 1.9s backwards;
		}

		.nd-islands > .is-style-glass-island:nth-child(2) {
			animation-delay: 2.1s;
		}

		.nd-islands > .is-style-glass-island:nth-child(3) {
			animation-delay: 2.3s;
		}

		/* The red dot breathes (kit .nd-dot--breathe). */
		.nd-period--breathe::after,
		.nd-testimonial::before {
			animation: nd-sun var(--wp--custom--breath) ease-in-out infinite;
		}

		/* Slow shimmer across the glass panel and the light button. */
		:is(.is-style-glass-panel, .nd-news)::before {
			animation: nd-shimmer 6s ease-in-out infinite;
		}

		:is(.wp-block-button.is-style-light .wp-block-button__link, .nd-news .nd-news__submit)::before {
			animation: nd-shimmer 3.5s ease-in-out infinite;
		}

		.wp-block-image.is-style-plate-round:hover {
			transform: rotate(4deg);
		}

		/* Ornaments draw in (assets/js/ornament.js marks the ones still below the fold as pending). */
		.nd-ornament :is(path, circle) {
			stroke-dasharray: 1;
			stroke-dashoffset: 0;
			transition: stroke-dashoffset 1.6s ease-out;
		}

		.nd-ornament path + path {
			transition-delay: 0.2s;
		}

		.nd-ornament circle {
			transition-duration: 1s;
			transition-delay: 0.9s;
		}

		.nd-ornament.nd-draw-pending :is(path, circle) {
			stroke-dashoffset: 1;
		}

		.wp-block-separator.is-style-ornament-wave {
			clip-path: inset(0);
			transition: clip-path 1.6s ease-out;
		}

		.wp-block-separator.is-style-ornament-wave.nd-draw-pending {
			clip-path: inset(0 100% 0 0);
		}
	}

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

		*,
		::before,
		::after {
			animation: none;
			transition: none;
		}

		:where(.wp-element-button, .wp-block-button__link, .pmpro_btn:not(.pmpro_btn-plain), #loginform [type="submit"], .wpcf7-submit):is(:hover, :active),
		.wp-block-navigation__responsive-container-open:hover,
		.nd-menu .wp-block-navigation-overlay-close:hover,
		.nd-support:hover,
		.is-style-glass-island:is(:hover, :focus-within),
		.nd-island__label:hover,
		.is-style-glass-island .wp-block-button__link:focus-visible .nd-island__label,
		.wp-block-button.is-style-text-link .wp-block-button__link:is(:hover, :focus-visible),
		.nd-arrow {
			transform: none;
		}
	}
}
