/* =============================================================================
   Harrison and Green - motion
   -----------------------------------------------------------------------------
   Everything here is opt-in: the reveal styles only apply once motion.js has
   added .hg-motion to <html>. With JavaScript disabled, or when the visitor has
   asked for reduced motion, the page renders fully visible and completely still.

   Only opacity, transform and clip-path are animated, so each effect stays on
   the compositor and never triggers layout.
   ========================================================================== */

:root {
	--hg-reveal-distance: 28px;
	--hg-reveal-duration: 0.9s;
	--hg-reveal-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--hg-stagger: 90ms;
}

/* ---------- Scroll reveals ----------------------------------------------- */

/*
 * Children of a section fade and rise together, each one a beat after the last.
 * Targeting existing classes rather than markup hooks means the effect survives
 * the page being edited in Gutenberg.
 */
/* The full-bleed background images are not part of the stagger. */
.hg-motion .hg-reveal > *:not(.hg-cta__media):not(.hg-hero__media) {
	opacity: 0;
	transform: translateY(var(--hg-reveal-distance));
	transition:
		opacity var(--hg-reveal-duration) var(--hg-reveal-ease),
		transform var(--hg-reveal-duration) var(--hg-reveal-ease);
	transition-delay: calc(var(--hg-index, 0) * var(--hg-stagger));
	will-change: opacity, transform;
}

.hg-motion .hg-reveal.hg-in > *:not(.hg-cta__media):not(.hg-hero__media) {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/*
 * Media travels a shorter distance than text.
 *
 * The :not() exclusions matter: .hg-cta__media and .hg-hero__media are the
 * full-bleed background photographs, positioned absolutely to fill their
 * section. Offsetting one of those uncovers a strip of the section behind it,
 * which shows up as a grey band where the scrim falls on the page background.
 * They are animated by the section rules further down instead.
 */
.hg-motion .hg-reveal > figure:not(.hg-cta__media):not(.hg-hero__media),
.hg-motion .hg-card {
	transform: translateY(calc(var(--hg-reveal-distance) * 0.6));
}

/* Belt and braces: a background figure is never offset by the reveal system. */
.hg-motion .hg-cta__media,
.hg-motion .hg-hero__media {
	transform: none !important;
	opacity: 1 !important;
}

/* ---------- Hero ---------------------------------------------------------- */

/* The photograph settles from a slow push-in as the page loads. */
.hg-motion .hg-hero__media img {
	transform: scale(1.07);
	transition: transform 2.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.hg-motion .hg-hero.hg-in .hg-hero__media img {
	transform: scale(1);
}

/* The rule under the headline draws itself out from the left. */
.hg-motion .hg-hero .hg-rule,
.hg-motion .hg-reveal .hg-rule {
	transform-origin: left center;
	transform: scaleX(0);
	transition: transform 0.9s var(--hg-reveal-ease) 0.25s, opacity 0.4s linear;
}
.hg-motion .hg-hero.hg-in .hg-rule,
.hg-motion .hg-reveal.hg-in .hg-rule {
	transform: scaleX(1);
}
.hg-motion .hg-cta .hg-rule { transform-origin: center; }

/* The rotated strap line on the right edge fades in last. */
.hg-motion .hg-hero__aside {
	opacity: 0;
	transition: opacity 1.2s var(--hg-reveal-ease) 0.8s;
}
.hg-motion .hg-hero.hg-in .hg-hero__aside { opacity: 0.85; }

/* ---------- Header ------------------------------------------------------- */

/* Header drops in once, just after first paint. */
.hg-motion .hg-header {
	opacity: 0;
	transform: translateY(-12px);
	transition: opacity 1s var(--hg-reveal-ease) 0.15s, transform 1s var(--hg-reveal-ease) 0.15s;
}
.hg-motion .hg-header.hg-in {
	opacity: 1;
	transform: none;
}

/* ---------- Split sections ----------------------------------------------- */

/*
 * The about photograph wipes open from its outer edge.
 *
 * The scale goes on the <img>, not the <figure>: scaling the figure would grow
 * its layout box and let the photograph bleed over the sections above and below,
 * since the section itself does not clip.
 */
.hg-motion .hg-about__media {
	clip-path: inset(0 0 0 12%);
	overflow: hidden;
	transition: clip-path 1.3s var(--hg-reveal-ease);
}
.hg-motion .hg-about__media img {
	transform: scale(1.04);
	transition: transform 1.6s var(--hg-reveal-ease);
}
.hg-motion .hg-about.hg-in .hg-about__media {
	clip-path: inset(0 0 0 0);
}
.hg-motion .hg-about.hg-in .hg-about__media img {
	transform: scale(1);
}

/* The botanical sprig breathes in gently. */
.hg-motion .hg-about__panel img {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 1.4s var(--hg-reveal-ease) 0.35s, transform 1.4s var(--hg-reveal-ease) 0.35s;
}
.hg-motion .hg-about.hg-in .hg-about__panel img {
	opacity: 1;
	transform: none;
}

/* ---------- Service cards ------------------------------------------------ */

.hg-motion .hg-cards .hg-card {
	opacity: 0;
	transition:
		opacity var(--hg-reveal-duration) var(--hg-reveal-ease),
		transform var(--hg-reveal-duration) var(--hg-reveal-ease);
	transition-delay: calc(var(--hg-index, 0) * var(--hg-stagger));
}
.hg-motion .hg-cards.hg-in .hg-card {
	opacity: 1;
	transform: none;
}

/* ---------- Call to action band ------------------------------------------ */

.hg-motion .hg-cta__media img {
	transform: scale(1.08);
	transition: transform 2s cubic-bezier(0.16, 1, 0.3, 1);
}
.hg-motion .hg-cta.hg-in .hg-cta__media img { transform: scale(1); }

/* ---------- Interaction polish ------------------------------------------- */

/* Links lift their arrow and warm their underline - defined in main.css - plus
   a gentle colour shift here so the whole control responds as one. */
.hg-link,
.hg-card a,
.hg-nav a,
.hg-social a,
.hg-contact a {
	transition-timing-function: var(--hg-reveal-ease);
}

.hg-card a:hover .hg-card__title { color: var(--hg-ink); }

/* Keyboard users get the same reveal, never a hidden focus target. */
.hg-motion .hg-reveal > *:focus-within {
	opacity: 1;
	transform: none;
}

/* ---------- Reduced motion ----------------------------------------------- */

/*
 * The visitor asked for less movement: show everything, move nothing. This also
 * covers the case where motion.js runs before the preference is read.
 */
@media (prefers-reduced-motion: reduce) {
	.hg-motion .hg-reveal > *,
	.hg-motion .hg-cards .hg-card,
	.hg-motion .hg-header,
	.hg-motion .hg-hero__aside,
	.hg-motion .hg-about__panel img {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}

	.hg-motion .hg-hero__media img,
	.hg-motion .hg-cta__media img,
	.hg-motion .hg-about__media img,
	.hg-motion .hg-about__media {
		transform: none !important;
		clip-path: none !important;
		transition: none !important;
	}

	.hg-motion .hg-hero .hg-rule,
	.hg-motion .hg-reveal .hg-rule {
		transform: none !important;
		transition: none !important;
	}
}
