/*
 * True Marketing motion system.
 *
 * The Figma file defines no motion, so this sets one house style for the whole site:
 * quiet and quick, things settle into place rather than bounce. Only opacity and
 * transform animate (GPU-composited, no layout shift), and everything switches off
 * under prefers-reduced-motion. Rules and how to use the classes: design-system.md.
 *
 * Marker classes (Elementor global classes; behaviour lives here and in motion.js):
 *   m-reveal       fade and rise into place when scrolled into view
 *   m-reveal-fade  fade only (large images, full-bleed blocks)
 *   m-stagger      its direct children reveal one after another
 *   m-hero         its image settles from a slight zoom on page load
 *   m-card         image zooms inside its frame and arrow nudges on hover
 *   m-count        a number counts up when scrolled into view
 *   m-parallax     on an image frame: its photo drifts slower than the page as it scrolls
 *                  (-soft and -strong set the travel)
 *   m-wipe         an image opens from its bottom edge while the photo settles
 *                  (-from-left, -from-right and -centre open from elsewhere)
 *
 * Hidden-before-reveal states only apply under html.m-js, which an inline script in
 * <head> sets (and removes again if motion.js never starts), so content never stays
 * hidden without JavaScript. Nothing is hidden in the Elementor editor.
 */

:root {
	/* Durations */
	--m-dur-xs: 120ms;  /* colour and border changes */
	--m-dur-s: 200ms;   /* hover, arrow nudge */
	--m-dur-m: 320ms;   /* panels, drawer, accordion */
	--m-dur-l: 700ms;   /* scroll reveals, card image zoom */
	--m-dur-xl: 1400ms; /* hero image settle */
	--m-dur-wipe: 1100ms; /* image wipe */

	/* Easing */
	--m-ease-out: cubic-bezier(.22, 1, .36, 1);   /* settle: entrances, reveals */
	--m-ease-std: cubic-bezier(.2, 0, 0, 1);      /* state changes: hover, colour */
	--m-ease-in-out: cubic-bezier(.65, 0, .35, 1); /* moves between two places */

	/* Distance and sequence */
	--m-rise: 24px;
	--m-step: 80ms;
	--m-par: .08; /* parallax travel, as a share of the frame height each way */

	interpolate-size: allow-keywords;
}

/* ── Scroll reveals ───────────────────────────────────────────────────────── */
.m-js body:not(.elementor-editor-active) .m-reveal:not(.is-in),
.m-js body:not(.elementor-editor-active) .m-stagger:not(.is-in) > * {
	opacity: 0;
	transform: translate3d(0, var(--m-rise), 0);
}
.m-js body:not(.elementor-editor-active) .m-reveal-fade:not(.is-in) {
	opacity: 0;
}
.m-js body:not(.elementor-editor-active) .m-reveal,
.m-js body:not(.elementor-editor-active) .m-reveal-fade,
.m-js body:not(.elementor-editor-active) .m-stagger > * {
	transition:
		opacity var(--m-dur-l) var(--m-ease-out),
		transform var(--m-dur-l) var(--m-ease-out);
}
.m-js body:not(.elementor-editor-active) .m-stagger > * {
	transition-delay: calc(var(--m-i, 0) * var(--m-step));
}

/* ── Hero: the photograph settles from a slight zoom on load ──────────────── */
@keyframes m-settle {
	from { transform: scale(1.06); }
}
.m-js body:not(.elementor-editor-active) .m-hero > img {
	animation: m-settle var(--m-dur-xl) var(--m-ease-out) both;
}

/* ── Parallax: the photo drifts inside its frame ──────────────────────────── *
 * Put m-parallax on the frame; its direct child image is enlarged just enough
 * to never show an edge, and motion.js moves it with the separate translate
 * property, so it stacks with the hero settle (transform) rather than fighting. */
.m-parallax { overflow: clip; }
.m-parallax-soft { --m-par: .05; }
.m-parallax-strong { --m-par: .12; }
.m-js body:not(.elementor-editor-active) :is(.m-parallax, .m-parallax-soft, .m-parallax-strong) > img {
	scale: calc(1 + 2 * var(--m-par));
	will-change: translate;
}

/* ── Wipe: the image opens from an edge while the photo settles ───────────── *
 * Put it on the image itself. Plays once when scrolled into view. The photo
 * starts at scale 1.08 and the clip starts inset by (1 - 1/1.08) / 2 = 3.7% on
 * the other sides, so it never spills past its own box. The animation does not
 * fill forwards, so card hover zoom takes over cleanly afterwards. */
@keyframes m-wipe-up {
	from { clip-path: inset(100% 3.7% 3.7% 3.7%); scale: 1.08; }
	to { clip-path: inset(0); scale: 1; }
}
@keyframes m-wipe-from-left {
	from { clip-path: inset(3.7% 100% 3.7% 3.7%); scale: 1.08; }
	to { clip-path: inset(0); scale: 1; }
}
@keyframes m-wipe-from-right {
	from { clip-path: inset(3.7% 3.7% 3.7% 100%); scale: 1.08; }
	to { clip-path: inset(0); scale: 1; }
}
@keyframes m-wipe-centre {
	from { clip-path: inset(50% 3.7% 50% 3.7%); scale: 1.08; }
	to { clip-path: inset(0); scale: 1; }
}
.m-js body:not(.elementor-editor-active) .m-wipe:not(.is-in) { clip-path: inset(100% 0 0 0); }
.m-js body:not(.elementor-editor-active) .m-wipe-from-left:not(.is-in) { clip-path: inset(0 100% 0 0); }
.m-js body:not(.elementor-editor-active) .m-wipe-from-right:not(.is-in) { clip-path: inset(0 0 0 100%); }
.m-js body:not(.elementor-editor-active) .m-wipe-centre:not(.is-in) { clip-path: inset(50% 0 50% 0); }
.m-js body:not(.elementor-editor-active) :is(.m-wipe, .m-wipe-from-left, .m-wipe-from-right, .m-wipe-centre).is-in {
	animation: m-wipe-up var(--m-dur-wipe) var(--m-ease-in-out) backwards;
	animation-delay: calc(var(--m-i, 0) * var(--m-step));
}
.m-js body:not(.elementor-editor-active) .m-wipe-from-left.is-in { animation-name: m-wipe-from-left; }
.m-js body:not(.elementor-editor-active) .m-wipe-from-right.is-in { animation-name: m-wipe-from-right; }
.m-js body:not(.elementor-editor-active) .m-wipe-centre.is-in { animation-name: m-wipe-centre; }

/* ── Cards: image zooms inside its own frame, arrow nudges ────────────────── *
 * The clip-path grows with the scale so the image never spills over the text
 * under it: inset = (1 - 1/1.04) / 2 = 1.923%. No wrapper or overflow needed. */
.elementor .m-card > img {
	clip-path: inset(0);
	transition:
		transform var(--m-dur-l) var(--m-ease-out),
		clip-path var(--m-dur-l) var(--m-ease-out);
}
.elementor .m-card svg,
.elementor .link-arrow svg {
	transition: transform var(--m-dur-s) var(--m-ease-std);
}
@media (hover: hover) {
	.elementor .m-card:hover > img {
		transform: scale(1.04);
		clip-path: inset(1.923%);
	}
	.elementor .m-card:hover svg,
	.elementor .link-arrow:hover svg {
		transform: translateX(4px);
	}
}
.elementor .card-outline {
	transition: border-color var(--m-dur-s) var(--m-ease-std);
}
.elementor .card-outline.m-card:hover {
	border-color: var(--border-light, #C9C9CE);
}

/* ── Buttons and links: colour changes ease instead of snapping ───────────── */
.elementor .btn-primary,
.elementor .btn-secondary,
.elementor .btn-quiet,
.elementor .footer-link,
.elementor .chip,
.elementor .mm-trigger,
.elementor .mm-tab {
	transition:
		color var(--m-dur-s) var(--m-ease-std),
		background-color var(--m-dur-s) var(--m-ease-std),
		border-color var(--m-dur-s) var(--m-ease-std),
		box-shadow var(--m-dur-s) var(--m-ease-std);
}

/* ── Mega menu, scrim and drawer: entrances ───────────────────────────────── *
 * The panels switch with display, so they animate in with keyframes; closing
 * stays instant, which keeps Escape and outside clicks feeling immediate. */
@keyframes m-drop {
	from { opacity: 0; transform: translate3d(0, -8px, 0); }
}
@keyframes m-fade {
	from { opacity: 0; }
}
@keyframes m-slide-in {
	from { transform: translate3d(100%, 0, 0); }
}
@keyframes m-step-in {
	from { opacity: 0; transform: translate3d(16px, 0, 0); }
}
body:not(.elementor-editor-active) .elementor .mm-panel.is-open {
	animation: m-drop var(--m-dur-m) var(--m-ease-out);
}
.mm-scrim:not([hidden]) {
	animation: m-fade var(--m-dur-m) var(--m-ease-out);
}
body:not(.elementor-editor-active) .elementor-location-header .mm-drawer.is-open {
	animation: m-slide-in var(--m-dur-m) var(--m-ease-out);
}
body:not(.elementor-editor-active) .elementor .mm-drawer.is-drilled .mm-view.is-active {
	animation: m-step-in var(--m-dur-m) var(--m-ease-out);
}
body .elementor .mm-trigger svg {
	transition: transform var(--m-dur-m) var(--m-ease-out);
}

/* ── FAQ accordion: open and close by height (Chrome/Edge; elsewhere instant) */
.faq details::details-content {
	block-size: 0;
	overflow: clip;
	transition:
		block-size var(--m-dur-m) var(--m-ease-out),
		content-visibility var(--m-dur-m) allow-discrete;
}
.faq details[open]::details-content {
	block-size: auto;
}

/* ── Carousel dots ─────────────────────────────────────────────────────────── */
.carousel-dots span {
	transition:
		width var(--m-dur-m) var(--m-ease-out),
		background-color var(--m-dur-m) var(--m-ease-std);
}

/* ── Reduced motion: everything shown, nothing moves ──────────────────────── */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after,
	*::details-content {
		animation-duration: 1ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 1ms !important;
		transition-delay: 0ms !important;
		scroll-behavior: auto !important;
	}
	.elementor .m-card:hover > img {
		transform: none;
		clip-path: inset(0);
	}
}

@media print {
	.m-reveal,
	.m-reveal-fade,
	.m-stagger > * {
		opacity: 1 !important;
		transform: none !important;
	}
	.m-wipe,
	.m-wipe-from-left,
	.m-wipe-from-right,
	.m-wipe-centre {
		clip-path: none !important;
	}
}
