/* ==========================================================================
   Beam motion, after Roar Folio.
   Loaded only when animations are on. Every rule waits for .beam-motion, which an
   inline script in <head> adds to <html> unless the visitor prefers reduced motion,
   so without it the page is simply still. assets/js/motion.js drives the rest.
   ========================================================================== */

:root {
	--beam-header-h: 76px;
	--beam-stick: calc(var(--wp-admin--admin-bar--height, 0px) + var(--beam-header-h));
}

@keyframes beam-rise {
	from {
		opacity: 0;
		transform: translateY(28px);
	}

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

@keyframes beam-fade-in {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

@keyframes beam-drift {
	from {
		background-position: 0% 0%, 100% 100%, 50% 50%, 0 0;
	}

	to {
		background-position: 18% 12%, 82% 88%, 40% 62%, 0 0;
	}
}

@keyframes beam-cue {
	from {
		background-position: 0 -24px, 0 0;
	}

	to {
		background-position: 0 56px, 0 0;
	}
}

@keyframes beam-marquee {
	to {
		transform: translateX(-50%);
	}
}

/* ------------------------------------------------ Entrances on load */

.beam-motion :is(.beam-hero__text, .beam-intro) > *,
.beam-motion .beam-hero__media > *,
.beam-motion .beam-intro-media > * {
	animation: beam-rise 1.1s var(--beam-ease) backwards;
	animation-delay: calc(var(--beam-d, 0) * 110ms + 120ms);
}

.beam-motion :is(.beam-hero__text, .beam-intro) > :nth-child(2) {
	--beam-d: 1;
}

.beam-motion :is(.beam-hero__text, .beam-intro) > :nth-child(3) {
	--beam-d: 2;
}

.beam-motion :is(.beam-hero__text, .beam-intro) > :nth-child(4) {
	--beam-d: 3;
}

.beam-motion :is(.beam-hero__text, .beam-intro) > :nth-child(5) {
	--beam-d: 4;
}

.beam-motion :is(.beam-hero__text, .beam-intro) > :nth-child(n + 6) {
	--beam-d: 5;
}

.beam-motion :is(.beam-hero__media, .beam-intro-media) > * {
	--beam-d: 2;
	animation-duration: 1.4s;
}

/* Intro headlines wait for the script to split them into words, and fade in by
   themselves if it never arrives. */
.beam-motion :is(.beam-hero__text, .beam-intro) :is(h1, h2) {
	animation: beam-fade-in 0.6s ease 1.4s backwards;
}

.beam-motion :is(.beam-hero__text, .beam-intro) :is(h1, h2).is-split {
	animation: none;
}

/* ------------------------------------------------ Words rise from a mask */

.beam-w {
	display: inline-block;
	overflow: hidden;
	vertical-align: top;
	margin: 0 -0.06em -0.18em;
	padding: 0 0.06em 0.18em;
}

.beam-w__i {
	display: inline-block;
	transition: transform 1.1s var(--beam-ease);
	transition-delay: calc(var(--w, 0) * 45ms);
}

.beam-motion .beam-split:not(.is-in) .beam-w__i {
	transform: translateY(110%);
}

/* Then the highlighter swipes across the emphasised word. */
.beam-motion .beam-split em {
	background-repeat: no-repeat;
	background-size: 100% 100%;
	transition: background-size 0.9s var(--beam-ease) 0.6s;
}

.beam-motion .beam-split:not(.is-in) em {
	background-size: 0% 100%;
}

/* ------------------------------------------------ Fade up on entering */

.beam-motion .beam-reveal {
	opacity: 0;
	transform: translateY(36px);
	transition: opacity 1s var(--beam-ease), transform 1.1s var(--beam-ease);
	transition-delay: calc(var(--i, 0) * 90ms);
}

.beam-motion .beam-reveal.is-in {
	opacity: 1;
	transform: none;
}

/* ------------------------------------------------ Statement lights up */

.beam-scrub-w {
	transition: opacity 0.35s linear;
}

.beam-motion .beam-scrub .beam-scrub-w {
	opacity: 0.18;
}

.beam-motion .beam-scrub .beam-scrub-w.is-lit {
	opacity: 1;
}

/* ------------------------------------------------ Count up */

.beam-motion .beam-stat .beam-display {
	font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------ Images unclip from a frame */

.beam-motion .beam-frame {
	--f: 1;
	overflow: hidden;
	clip-path: inset(calc((1 - var(--f)) * 6%) round var(--beam-radius-m));
}

.beam-motion .beam-frame img {
	transform: scale(calc(1.1 - var(--f) * 0.1));
	transform-origin: center 45%;
}

/* ------------------------------------------------ Colour sections open out */

.beam-motion .beam-unfold {
	--f: 1;
	clip-path: inset(calc((1 - var(--f)) * 3.5vw) round calc((1 - var(--f)) * 56px));
}

/* ------------------------------------------------ Gentle parallax */

.beam-motion .wp-block-image.is-style-arch::after {
	translate: 0 calc(var(--py, 0) * 56px);
}

.beam-motion .beam-sparkles::before {
	translate: 0 calc(var(--py, 0) * -70px);
}

.beam-motion .beam-sparkles::after {
	translate: 0 calc(var(--py, 0) * 50px);
}

/* ------------------------------------------------ Hero background drifts */

.beam-motion .beam-hero__inner::before {
	background-size: 140% 140%, 140% 140%, 120% 120%, auto;
	animation: beam-drift 18s ease-in-out infinite alternate;
}

/* ------------------------------------------------ The hero folds into a window */

@media (min-width: 900px) and (min-height: 680px) {
	.beam-motion .beam-hero--fold {
		--p: 0;
		height: calc(100vh - var(--beam-stick) + 70vh);
		height: calc(100svh - var(--beam-stick) + 70vh);
	}

	.beam-motion .beam-hero--fold .beam-hero__inner {
		position: sticky;
		top: var(--beam-stick);
		display: flex;
		flex-direction: column;
		justify-content: center;
		height: calc(100vh - var(--beam-stick));
		height: calc(100svh - var(--beam-stick));
		padding-top: var(--wp--preset--spacing--40) !important;
		padding-bottom: var(--wp--preset--spacing--50) !important;
		overflow: hidden;
	}

	.beam-motion .beam-hero--fold .beam-hero__inner > .wp-block-columns {
		width: 100%;
		margin-block: 0;
	}

	.beam-motion .beam-hero--fold .beam-hero__inner::before {
		clip-path: inset(calc(var(--p) * 7svh) calc(var(--p) * 5vw) calc(var(--p) * 9svh) round calc(var(--p) * var(--beam-radius-l) * 1.6));
		will-change: clip-path;
	}

	/* Keep the portrait inside the screen. */
	.beam-motion .beam-hero--fold .beam-hero__media .wp-block-image {
		width: fit-content;
		max-width: 100%;
		margin-inline: auto;
	}

	.beam-motion .beam-hero--fold .beam-hero__media .wp-block-image img {
		width: auto;
		max-width: 100%;
		height: min(calc(100svh - var(--beam-stick) - 10rem), 52vw);
	}

	.beam-motion .beam-hero--fold .beam-hero__text {
		opacity: clamp(0, calc(1 - var(--p) * 2.2), 1);
		transform: translateY(calc(var(--p) * -12vh)) scale(calc(1 - var(--p) * 0.05));
		transform-origin: left center;
	}

	.beam-motion .beam-hero--fold .beam-hero__media {
		position: relative;
		z-index: 1;
		transform: translateX(calc(var(--p) * var(--beam-hero-shift, 0px))) scale(calc(1 - var(--p) * 0.1));
	}

	/* A caption follows the bottom edge of the folded window. */
	.beam-motion .beam-hero--fold .beam-hero__caption {
		position: absolute;
		left: calc(var(--p) * 5vw);
		right: calc(var(--p) * 5vw);
		bottom: calc(var(--p) * 9svh);
		z-index: 2;
		display: flex;
		max-width: none;
		margin: 0;
		padding: 1.1rem 1.75rem;
		opacity: clamp(0, calc(var(--p) * 2.4 - 1.2), 1);
		color: var(--wp--preset--color--contrast);
		font-size: var(--wp--preset--font-size--x-small);
		font-weight: 600;
		letter-spacing: 0.12em;
		text-transform: uppercase;
	}

	.beam-motion .beam-hero--fold .beam-hero__caption p {
		margin: 0;
	}

	/* Scroll cue. */
	.beam-motion .beam-hero--fold .beam-hero__inner::after {
		content: "";
		position: absolute;
		bottom: 1.25rem;
		left: 50%;
		width: 1px;
		height: 56px;
		background:
			linear-gradient(currentColor, currentColor) 0 -24px / 100% 24px no-repeat,
			color-mix(in srgb, currentColor 22%, transparent);
		opacity: clamp(0, calc(1 - var(--p) * 5), 1);
		animation: beam-cue 2.2s cubic-bezier(0.65, 0, 0.35, 1) infinite;
	}
}

/* ------------------------------------------------ Header turns into floating pills */

.beam-motion .wp-site-blocks > header.wp-block-template-part::before {
	transition: opacity 0.45s var(--beam-ease);
}

.beam-motion .wp-site-blocks > header.wp-block-template-part.is-scrolled {
	border-bottom-color: transparent;
	animation: none;
}

.beam-motion .wp-site-blocks > header.wp-block-template-part.is-scrolled::before {
	opacity: 0;
}

.beam-motion .beam-header-bar > .wp-block-site-title,
.beam-motion .beam-header-actions {
	position: relative;
	isolation: isolate;
}

/* The pill backgrounds live on pseudo-elements so the mobile menu can still cover the screen. */
.beam-motion .beam-header-bar > .wp-block-site-title::after,
.beam-motion .beam-header-actions::before {
	content: "";
	position: absolute;
	z-index: -1;
	border-radius: var(--beam-radius-pill);
	background: color-mix(in srgb, var(--wp--preset--color--base) 82%, transparent);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--wp--preset--color--contrast) 8%, transparent),
		0 10px 30px -12px rgba(28, 27, 25, 0.28);
	-webkit-backdrop-filter: blur(16px) saturate(1.5);
	backdrop-filter: blur(16px) saturate(1.5);
	opacity: 0;
	transform: scale(0.94);
	transition: opacity 0.4s var(--beam-ease), transform 0.5s var(--beam-ease);
	pointer-events: none;
}

.beam-motion .beam-header-bar > .wp-block-site-title::after {
	inset: -0.5rem -1.1rem -0.5rem -0.7rem;
}

.beam-motion .beam-header-actions::before {
	inset: -0.45rem -0.5rem -0.45rem -1.25rem;
}

.beam-motion .is-scrolled .beam-header-bar > .wp-block-site-title::after,
.beam-motion .is-scrolled .beam-header-actions::before {
	opacity: 1;
	transform: none;
}

/* ------------------------------------------------ Client-name reel */

.beam-motion .beam-marquee.is-running {
	flex-wrap: nowrap !important;
	justify-content: flex-start !important;
	gap: 0 !important;
	min-width: 0;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
	mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}

.beam-marquee__track {
	display: flex;
	flex: none;
	align-items: center;
	animation: beam-marquee var(--beam-marquee-duration, 30s) linear infinite;
}

.beam-marquee__track > .beam-marquee__item {
	flex: none;
	margin: 0 var(--beam-marquee-gap, 40px) 0 0 !important;
	white-space: nowrap;
}

.beam-marquee.is-paused .beam-marquee__track,
.beam-marquee:hover .beam-marquee__track {
	animation-play-state: paused;
}

.beam-marquee__toggle {
	display: inline-grid;
	flex: none;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 50%;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	transition: background-color 0.2s, border-color 0.2s;
}

.beam-marquee__toggle:hover {
	border-color: var(--wp--preset--color--contrast);
}

.beam-marquee__toggle svg {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.beam-marquee__toggle .beam-icon-play {
	display: none;
	fill: currentColor;
	stroke: none;
}

.beam-marquee__toggle[aria-pressed="true"] .beam-icon-pause {
	display: none;
}

.beam-marquee__toggle[aria-pressed="true"] .beam-icon-play {
	display: inline;
}

/* ------------------------------------------------ Accordions */

.beam-motion .wp-block-details > .beam-details__body {
	margin-top: 0;
	padding-top: 0.75rem;
	overflow: hidden;
}

.beam-motion .wp-block-details.is-closing summary::after {
	transform: none;
	background: var(--wp--preset--color--base-2);
}

/* ------------------------------------------------ Steps light up in turn */

.beam-motion .beam-steps--motion .beam-step-number {
	position: relative;
	z-index: 1;
	opacity: 0.5;
	transform: scale(0.82);
	transition: transform 0.6s var(--beam-ease), opacity 0.4s, box-shadow 0.6s var(--beam-ease);
}

.beam-motion .beam-steps--motion :is(.is-active, .is-done) .beam-step-number {
	opacity: 1;
	transform: none;
}

.beam-motion .beam-steps--motion .is-active .beam-step-number {
	box-shadow: 0 0 0 7px color-mix(in srgb, var(--wp--preset--color--accent) 32%, transparent);
}

.beam-motion .beam-steps--motion.is-row {
	position: relative;
}

.beam-motion .beam-steps--motion.is-row::before {
	content: "";
	position: absolute;
	top: calc(var(--steps-y, 1.375rem) - 1px);
	left: var(--steps-x, 1.375rem);
	width: var(--steps-w, 0px);
	height: 2px;
	border-radius: 2px;
	background: linear-gradient(to right, var(--wp--preset--color--accent) calc(var(--sp, 0) * 100%), var(--wp--preset--color--line) 0);
	transition: background 0.4s;
}
