/* ==========================================================================
   Brand fonts - self-hosted.
   Elementor's Google Fonts loader is disabled in inc/elementor-support.php
   because it is render blocking and pulls weights this site never uses.
   Variable files: one request covers every weight in the range.
   Regenerate with the download step documented in docs/BRAND.md.
   ========================================================================== */

@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('../fonts/inter-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'Outfit';
	font-style: normal;
	font-weight: 400 800;
	font-display: swap;
	src: url('../fonts/outfit-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Outfit';
	font-style: normal;
	font-weight: 400 800;
	font-display: swap;
	src: url('../fonts/outfit-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ==========================================================================
   AI FOR AI - Design System
   Sampled from the live mobile app + logo. Do NOT invent new colours here;
   add a token instead so Elementor Globals and CSS stay in sync.
   ========================================================================== */

:root {
	/* Brand */
	--ai-violet:        #690DAC;
	--ai-violet-deep:   #3F0151;
	--ai-magenta:       #B3208C;
	--ai-orange:        #F26522;
	--ai-amber:         #F5821F;
	--ai-cream:         #FFF2DF;
	--ai-ink:           #14111F;
	--ai-slate:         #5B5570;
	--ai-mist:          #F7F5FA;
	--ai-white:         #FFFFFF;
	--ai-line:          #E7E2EF;

	/* State colours, used only where "before vs after" has to read at a
	   glance. Deliberately outside the brand ramp: the gradient means "us", so
	   painting the problem column with it would say the problem is ours too. */
	--ai-pos:           #1F9D6B;
	--ai-neg:           #D6417E;
	/* The same two as RGB triples, so tints can be mixed with rgba().
	   color-mix() would be tidier, but it is too new to hang a whole
	   section's background on. */
	--ai-pos-rgb:       31, 157, 107;
	--ai-neg-rgb:       214, 65, 126;

	/* Gradients */
	--grad-brand: linear-gradient(100deg, #3F0151 0%, #690DAC 35%, #B3208C 65%, #F26522 100%);
	--grad-cta:   linear-gradient(100deg, #690DAC 0%, #F26522 100%);
	--grad-dark:  linear-gradient(160deg, #14111F 0%, #3F0151 100%);

	/* Type */
	--font-display: "Outfit", "Segoe UI", system-ui, sans-serif;
	--font-body:    "Inter", "Segoe UI", system-ui, sans-serif;

	/* Spacing scale */
	--sp-1: .5rem;  --sp-2: 1rem;   --sp-3: 1.5rem;
	--sp-4: 2rem;   --sp-5: 3rem;   --sp-6: 4rem;
	--sp-7: 6rem;   --sp-8: 8rem;

	/* Radius + elevation */
	--r-sm: 10px; --r-md: 16px; --r-lg: 20px; --r-xl: 28px; --r-pill: 999px;
	--shadow-card:  0 4px 24px rgba(105, 13, 172, .08);
	--shadow-lift:  0 18px 48px rgba(105, 13, 172, .18);
	--shadow-glow:  0 12px 40px rgba(242, 101, 34, .28);

	--ease: cubic-bezier(.2, .8, .2, 1);
	--container: 1240px;

	/* The header's own height, shared with the mobile sheet that hangs off it
	   and with scroll-padding, so the three can never disagree. */
	--ai-header-h: 76px;
}

/* --- Base ---------------------------------------------------------------- */
html {
	scroll-behavior: smooth;
	/* Sticky header height plus a little air, so in-page anchors do not land
	   underneath it. */
	scroll-padding-top: calc(var(--ai-header-h) + 20px);
	/* Grey flash on tap is the browser's stand-in for feedback we now provide
	   ourselves, and it lands on the wrong box on rounded cards. */
	-webkit-tap-highlight-color: transparent;
}

body {
	font-family: var(--font-body);
	font-size: 17px;
	line-height: 1.7;
	color: var(--ai-slate);
	background: var(--ai-white);
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-display);
	color: var(--ai-ink);
	line-height: 1.12;
	letter-spacing: -0.02em;
}

h1 { font-size: clamp(2.5rem, 5.2vw, 4.5rem); font-weight: 800; }
h2 { font-size: clamp(2rem, 3.6vw, 3rem);     font-weight: 700; }
h3 { font-size: clamp(1.35rem, 2vw, 1.875rem); font-weight: 600; }

a { color: var(--ai-violet); text-decoration: none; transition: color .2s var(--ease); }

@media (hover: hover) {
	a:hover { color: var(--ai-orange); }
}

/* --- Utility: gradient text (used for stat numbers + hero keyword) -------- */
.ai-grad-text {
	background: var(--grad-cta);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

/* --- Eyebrow label ------------------------------------------------------- */
.ai-eyebrow {
	font-family: var(--font-body);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--ai-violet);
	display: inline-flex;
	align-items: center;
	gap: .5rem;
}
.ai-eyebrow::before {
	content: "";
	width: 22px; height: 2px;
	background: var(--grad-cta);
	border-radius: 2px;
}

/* --- Buttons ------------------------------------------------------------- */
.ai-btn,
.elementor-button.ai-btn {
	position: relative;
	/* Clips the shine sweep below. An element's own outline and box-shadow are
	   painted outside its border box and are not clipped by this, so the
	   focus ring survives intact. */
	overflow: hidden;
	display: inline-flex; align-items: center; gap: .6rem;
	font-family: var(--font-body);
	font-weight: 600; font-size: 16px;
	padding: .95rem 1.9rem;
	border-radius: var(--r-pill);
	border: 0; cursor: pointer;
	transition: transform .24s var(--ease), box-shadow .24s var(--ease), background .24s var(--ease);
}
.ai-btn--primary { background: var(--grad-cta); color: #fff; box-shadow: var(--shadow-card); }

@media (hover: hover) {
	.ai-btn--primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-glow); color: #fff; }
}

/* Light sweeping across the fill on hover. */
.ai-btn--primary::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(110deg, transparent 32%, rgba(255, 255, 255, .38) 50%, transparent 68%);
	transform: translateX(-130%);
	transition: transform .8s var(--ease);
	pointer-events: none;
}

@media (hover: hover) {
	.ai-btn--primary:hover::after { transform: translateX(130%); }
}

.ai-btn--ghost { background: transparent; color: var(--ai-violet); box-shadow: inset 0 0 0 2px var(--ai-line); }

@media (hover: hover) {
	.ai-btn--ghost:hover { box-shadow: inset 0 0 0 2px var(--ai-violet); color: var(--ai-violet); }
}

/* --- Cards --------------------------------------------------------------- */
.ai-card {
	background: var(--ai-white);
	border: 1px solid var(--ai-line);
	border-radius: var(--r-lg);
	padding: var(--sp-4);
	box-shadow: var(--shadow-card);
	transition: transform .24s var(--ease), box-shadow .24s var(--ease);
}

@media (hover: hover) {
	.ai-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lift); }
}

/* Icon bubble motif - repeats before every feature heading */
.ai-icon-bubble {
	width: 48px; height: 48px;
	display: grid; place-items: center;
	border-radius: var(--r-md);
	background: rgba(105, 13, 172, .08);
	color: var(--ai-violet);
	margin-bottom: var(--sp-2);
}

/* --- Stat block ---------------------------------------------------------- */
.ai-stat__num {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(3rem, 6vw, 5.5rem);
	line-height: 1;
	background: var(--grad-cta);
	-webkit-background-clip: text; background-clip: text;
	color: transparent; -webkit-text-fill-color: transparent;
}
.ai-stat__label {
	font-size: 14px; font-weight: 600;
	letter-spacing: .04em; text-transform: uppercase;
	color: var(--ai-slate);
}

/* --- Dark section -------------------------------------------------------- */
.ai-section--dark { background: var(--grad-dark); color: rgba(255,255,255,.82); }
.ai-section--dark h1,
.ai-section--dark h2,
.ai-section--dark h3 { color: #fff; }
.ai-section--dark .ai-eyebrow { color: var(--ai-orange); }

/* --- Notice block (mirrors the app's cream TDS panel) -------------------- */
.ai-notice {
	background: var(--ai-cream);
	border-radius: var(--r-md);
	padding: var(--sp-3);
	color: #8A4B0A;
}

/* --- Scroll reveal -------------------------------------------------------
   Hidden ONLY under .js-reveal, which functions.php adds from an inline head
   script. Without JS the content simply renders — never blank.

   The entrance uses `translate` and `scale`, not `transform`. Written as
   `transform: none`, the revealed state outranked every component's own
   `:hover { transform: translateY(...) }` — .js-reveal .ai-reveal.is-visible
   is three classes to their two — so the card lift, the stat lift and the step
   lift all silently did nothing once an element had been revealed, which is
   every element a visitor can reach. The individual transform properties
   compose with `transform` instead of replacing it, so both now apply. */
.js-reveal .ai-reveal { opacity: 0; translate: 0 28px; scale: .985; }

.js-reveal .ai-reveal.is-visible {
	opacity: 1;
	translate: none;
	scale: none;
	transition:
		opacity .7s var(--ease),
		translate .7s var(--ease),
		scale .7s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: .01ms !important;
		transition-duration: .01ms !important;
	}
	.js-reveal .ai-reveal { opacity: 1; translate: none; scale: none; }
	html { scroll-behavior: auto; }
}

/* --- Accessibility -------------------------------------------------------
   Hello Elementor's reset already styles :focus-visible on links, buttons and
   form controls with a black-and-white double ring that survives any
   background. This is only a catch-all for focusable elements outside that
   selector list, and it intentionally mirrors the same shape. */
:focus-visible {
	outline: 2px solid #000;
	outline-offset: 2px;
	box-shadow: 0 0 0 4px #fff;
}

.skip-link:focus { left: 1rem; top: 1rem; z-index: 9999; }

/* ==========================================================================
   Site header
   Sticky, on every page. The bar itself is light because the homepage hero is
   the dark surface directly below it — two dark blocks stacked would lose the
   edge between them entirely.
   ========================================================================== */
.ai-header {
	position: sticky;
	top: 0;
	z-index: 200;
	background: rgba(255, 255, 255, .9);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--ai-line);
	transition: box-shadow .24s var(--ease), background .24s var(--ease);
}

/* The admin bar is fixed above 600px and static below it. */
.admin-bar .ai-header { top: 32px; }
@media screen and (max-width: 782px) {
	.admin-bar .ai-header { top: 46px; }
	/* The sheet is measured from the viewport, so the bar above the header
	   has to come out of its height as well. */
	.admin-bar .ai-nav { height: calc(100svh - var(--ai-header-h) - 46px); }
}
@media screen and (max-width: 600px) { .admin-bar .ai-header { top: 0; } }

/* Set from JS once the page has scrolled past the first 24px. */
.ai-header.is-stuck {
	background: rgba(255, 255, 255, .96);
	box-shadow: var(--shadow-card);
}

.ai-header__inner {
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: max(clamp(1.25rem, 4vw, 2.5rem), env(safe-area-inset-left));
	min-height: var(--ai-header-h);
	display: flex;
	align-items: center;
	gap: var(--sp-3);
}

/* align-items rather than a bare inline-flex: the mark is shorter than the
   bar, and the link should be the full height of the row it sits in so the
   tap target matches what looks tappable. */
.ai-logo {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	min-height: 44px;
}
/* The mark is a wide 3.6:1 lockup whose weight is a thin car outline, so it
   needs more height than a compact logotype to carry the same presence. */
.ai-logo img { height: 40px; width: auto; display: block; }

.ai-header__actions {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin-inline-start: auto;
}

.ai-header__cta { padding: .7rem 1.4rem; font-size: 15px; }

/* --- Primary navigation -------------------------------------------------- */
.ai-nav { margin-inline: auto; }

.ai-nav__list {
	display: flex;
	align-items: center;
	gap: clamp(.75rem, 2vw, 1.75rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

.ai-nav__list > li { position: relative; }

.ai-nav__list a {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	padding: .5rem 0;
	font-family: var(--font-body);
	font-size: 15.5px;
	font-weight: 600;
	color: var(--ai-ink);
}

@media (hover: hover) {
	.ai-nav__list a:hover { color: var(--ai-violet); }
}

/* Gradient underline on hover and for the current branch. */
.ai-nav__list > li > a::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px;
	background: var(--grad-cta);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .24s var(--ease);
}.ai-nav__list > li:focus-within > a::after,
.ai-nav__list > li.current-menu-item > a::after,
.ai-nav__list > li.current-menu-ancestor > a::after,
.ai-nav__list > li.current_page_item > a::after { transform: scaleX(1); }
@media (hover: hover) {
	.ai-nav__list > li:hover > a::after { transform: scaleX(1); }
}

/* Caret on items with children. `order` moves it after the label — the anchor
   is a flex container, so no extra markup (and no nav walker) is needed. */
.ai-nav__list .menu-item-has-children > a::before {
	content: "";
	order: 2;
	width: .4em;
	height: .4em;
	margin-top: -.2em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform .24s var(--ease);
}
.ai-nav__list > li:focus-within > a::before { transform: rotate(225deg) translate(-.1em, -.1em); }
@media (hover: hover) {
	.ai-nav__list > li:hover > a::before { transform: rotate(225deg) translate(-.1em, -.1em); }
}

.ai-nav .sub-menu {
	position: absolute;
	top: 100%;
	left: 50%;
	translate: -50% 10px;
	min-width: 268px;
	margin: 0;
	padding: .5rem;
	list-style: none;
	background: var(--ai-white);
	border: 1px solid var(--ai-line);
	border-radius: var(--r-md);
	box-shadow: var(--shadow-lift);
	opacity: 0;
	visibility: hidden;
	transition: opacity .2s var(--ease), translate .2s var(--ease), visibility .2s;
}

/* Bridges the gap between the trigger and the panel so the pointer can cross
   it without the dropdown closing underneath it. */
.ai-nav .sub-menu::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	top: -12px;
	height: 12px;
}
.ai-nav__list > li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	translate: -50% 0;
}
@media (hover: hover) {
	.ai-nav__list > li:hover > .sub-menu {
		opacity: 1;
		visibility: visible;
		translate: -50% 0;
	}
}

.ai-nav .sub-menu a {
	display: block;
	padding: .6rem .8rem;
	border-radius: var(--r-sm);
	font-weight: 500;
	color: var(--ai-slate);
}
.ai-nav .sub-menu .current-menu-item > a {
	background: var(--ai-mist);
	color: var(--ai-violet);
}
@media (hover: hover) {
	.ai-nav .sub-menu a:hover {
		background: var(--ai-mist);
		color: var(--ai-violet);
	}
}

/* --- Mobile toggle -------------------------------------------------------
   Three bars in a fixed 22x16 box. The middle one fades while the outer two
   travel to the centre and cross, so the hamburger and the X share a centre
   point and the morph does not appear to jump sideways. */
.ai-nav-toggle {
	display: none;
	width: 46px;
	height: 46px;
	padding: 0;
	align-items: center;
	justify-content: center;
	background: transparent;
	color: var(--ai-ink);
	border: 1px solid var(--ai-line);
	border-radius: var(--r-sm);
	cursor: pointer;
	transition: background .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease);
}

.ai-nav-toggle:active { transform: scale(.92); }

.ai-nav-toggle__bars {
	position: relative;
	display: block;
	width: 22px;
	height: 16px;
}

.ai-nav-toggle__bars::before,
.ai-nav-toggle__bars::after {
	content: "";
	position: absolute;
	left: 0;
	width: 22px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transition: top .22s var(--ease), transform .28s var(--ease) .04s;
}
.ai-nav-toggle__bars::before { top: 2px; }
.ai-nav-toggle__bars::after  { top: 12px; }

/* The middle bar is the element's own background, drawn as a third line. */
.ai-nav-toggle__bars {
	background:
		linear-gradient(currentColor, currentColor) 0 7px / 22px 2px no-repeat;
	transition: background-size .18s var(--ease), opacity .18s var(--ease);
}

.ai-header.is-open .ai-nav-toggle {
	background: rgba(105, 13, 172, .07);
	border-color: rgba(105, 13, 172, .28);
}

/* Bars first slide to the middle, then rotate — the delay on transform is
   what makes it read as one gesture instead of two shapes swapping. */
.ai-header.is-open .ai-nav-toggle__bars { background-size: 0 2px; }
.ai-header.is-open .ai-nav-toggle__bars::before { top: 7px; transform: rotate(45deg); }
.ai-header.is-open .ai-nav-toggle__bars::after  { top: 7px; transform: rotate(-45deg); }

/* CTA is duplicated inside the mobile panel; only one of the two ever shows. */
.ai-nav__cta { display: none; }

/* --- The mobile sheet ----------------------------------------------------
   Below the breakpoint the navigation is not a dropdown, it is a place. A
   dropdown that covered two thirds of the screen left the hero showing
   underneath it, which read as a rendering fault rather than as a menu, and
   the page went on scrolling behind it.

   The sheet borrows the site's own dark surface and its engineering-drawing
   grid rather than inventing a third treatment, so opening the menu feels
   like moving to another part of the same site. */
@media (max-width: 1024px) {
	.ai-nav-toggle { display: inline-flex; }
	.ai-header__cta { display: none; }

	/* Absolute against the header, not fixed to the viewport: the header
	   carries a backdrop-filter, and that makes it the containing block for
	   any fixed descendant — the sheet ended up 76px tall inside its own
	   parent. Anchoring it to the header instead gives the same result and
	   keeps the admin bar's offset handled for free. */
	.ai-nav {
		position: absolute;
		inset: 100% 0 auto;
		height: calc(100vh - var(--ai-header-h));
		height: calc(100svh - var(--ai-header-h));
		z-index: 190;
		margin: 0;
		padding:
			var(--sp-3)
			max(clamp(1.25rem, 4vw, 2.5rem), env(safe-area-inset-right))
			max(var(--sp-4), env(safe-area-inset-bottom))
			max(clamp(1.25rem, 4vw, 2.5rem), env(safe-area-inset-left));
		display: flex;
		flex-direction: column;
		background: var(--grad-dark);
		color: #fff;
		overflow-y: auto;
		overscroll-behavior: contain;

		/* Closed state. visibility is what keeps the links out of the tab
		   order while the sheet is shut — opacity alone would leave them
		   focusable and invisible. */
		opacity: 0;
		visibility: hidden;
		translate: 0 -12px;
		transition:
			opacity .28s var(--ease),
			translate .28s var(--ease),
			visibility .28s;
	}

	/* Same grid as the hero, masked so it fades out before the CTA. */
	.ai-nav::before {
		content: "";
		position: absolute;
		inset: 0;
		background-image:
			linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
			linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
		background-size: 56px 56px;
		-webkit-mask-image: linear-gradient(#000, transparent 62%);
		mask-image: linear-gradient(#000, transparent 62%);
		pointer-events: none;
	}

	.ai-nav > * { position: relative; }

	.ai-header.is-open .ai-nav {
		opacity: 1;
		visibility: visible;
		translate: none;
	}

	.ai-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		flex: 1 1 auto;
	}

	.ai-nav__list > li + li { border-top: 1px solid rgba(255, 255, 255, .1); }

	/* Each row rises in behind the one above it. --i is set on the markup so
	   the delay follows the menu the client actually built, however many
	   items that turns out to be. */
	.ai-header.is-open .ai-nav__list > li {
		animation: ai-nav-in .42s var(--ease) backwards;
		animation-delay: calc(60ms + var(--i, 0) * 45ms);
	}

	.ai-nav__list > li > a {
		/* 56px, not the 44px floor: this is the primary way around the site on
		   a phone, and a thumb reaching the top of a tall screen is not
		   precise. */
		min-height: 56px;
		padding: .55rem 0 .55rem 1rem;
		font-family: var(--font-display);
		font-size: 1.25rem;
		font-weight: 600;
		color: #fff;
	}

	/* The brand's orange rule, turned vertical for a stacked menu — it marks
	   where you are, which is the one thing a menu on a small screen has to
	   answer. */
	.ai-nav__list > li > a::after {
		inset: .55rem auto .55rem 0;
		width: 3px;
		height: auto;
		transform: scaleY(0);
		transform-origin: top;
		transition: transform .28s var(--ease);
	}
	.ai-nav__list > li.current-menu-item > a::after,
	.ai-nav__list > li.current-menu-ancestor > a::after,
	.ai-nav__list > li.current_page_item > a::after,
	.ai-nav__list > li > a:active::after { transform: scaleY(1); }

	.ai-nav__list .menu-item-has-children > a::before { display: none; }

	/* Sub-menus sit open inline on mobile: no second tap, no extra JS, and
	   nothing hidden behind a control a screen reader has to discover. */
	.ai-nav .sub-menu {
		position: static;
		min-width: 0;
		margin: 0 0 .6rem;
		padding: 0 0 0 1rem;
		translate: none;
		opacity: 1;
		visibility: visible;
		background: transparent;
		border: 0;
		box-shadow: none;
	}
	.ai-nav .sub-menu::before { display: none; }

	.ai-nav .sub-menu a {
		display: flex;
		align-items: center;
		min-height: 44px;
		padding: .3rem .75rem;
		border-radius: var(--r-sm);
		font-size: 1rem;
		color: rgba(255, 255, 255, .78);
	}
	.ai-nav .sub-menu a:active,
	.ai-nav .sub-menu .current-menu-item > a {
		background: rgba(255, 255, 255, .08);
		color: #fff;
	}

	.ai-nav__cta {
		display: block;
		margin-top: var(--sp-4);
		padding-top: var(--sp-3);
		border-top: 1px solid rgba(255, 255, 255, .12);
	}
	.ai-nav__cta .ai-btn { width: 100%; justify-content: center; padding-block: 1.05rem; }

	.ai-nav__cta-note {
		margin: 0 0 .85rem;
		font-size: 13px;
		font-weight: 600;
		letter-spacing: .06em;
		text-transform: uppercase;
		color: rgba(255, 255, 255, .62);
	}

	/* The page must not scroll under an open sheet. Set from JS, which also
	   holds the scroll position so closing the menu returns you to where you
	   were rather than to the top. */
	html.is-nav-locked,
	html.is-nav-locked body { overflow: hidden; }
}

@keyframes ai-nav-in {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Site footer
   ========================================================================== */
.ai-footer {
	background: var(--grad-dark);
	color: rgba(255, 255, 255, .74);
	font-size: 15.5px;
}

.ai-footer a { color: rgba(255, 255, 255, .74); }

@media (hover: hover) {
	.ai-footer a:hover { color: var(--ai-orange); }
}

.ai-footer__inner {
	max-width: var(--container);
	margin-inline: auto;
	padding: clamp(3rem, 6vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) var(--sp-5);
	display: grid;
	grid-template-columns: minmax(0, 1.3fr) minmax(0, 2fr);
	gap: clamp(2rem, 5vw, 4.5rem);
}

.ai-footer__brand .ai-logo img { height: 48px; }

.ai-footer__blurb {
	margin: var(--sp-3) 0 0;
	max-width: 42ch;
	line-height: 1.7;
}

.ai-footer__contact,
.ai-footer__social {
	list-style: none;
	margin: var(--sp-3) 0 0;
	padding: 0;
}

/* The sitemap columns and the social row share the second grid cell, stacked.
   The row used to sit under the brand blurb, where it competed with the
   contact details immediately above it. */
.ai-footer__menus {
	display: grid;
	align-content: start;
	gap: var(--sp-4);
}

.ai-footer__follow-label {
	margin: 0;
	font-family: var(--font-display);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, .55);
}

.ai-footer__follow .ai-footer__social { margin-top: var(--sp-2); }

.ai-footer__contact li {
	display: flex;
	align-items: flex-start;
	gap: .65rem;
	margin-top: .6rem;
}
.ai-footer__contact svg { flex: 0 0 auto; margin-top: .2rem; color: var(--ai-orange); }

.ai-footer__social { display: flex; gap: .6rem; }
.ai-footer__social a {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: var(--r-sm);
	background: rgba(255, 255, 255, .08);
	transition: background .24s var(--ease), transform .24s var(--ease);
}

@media (hover: hover) {
	.ai-footer__social a:hover { background: rgba(255, 255, 255, .16); transform: translateY(-2px); }
}

/* A profile the client has not created yet: same shape as its siblings so the
   row still reads as a set, dimmed and inert so it does not invite a click. */
.ai-footer__social .is-soon {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: var(--r-sm);
	background: rgba(255, 255, 255, .04);
	color: rgba(255, 255, 255, .3);
	cursor: default;
}

.ai-footer__contact address {
	font-style: normal;
	max-width: 34ch;
}

/* --- Sitemap columns ----------------------------------------------------- */
.ai-footer__cols {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: var(--sp-4) var(--sp-3);
}

/* Top-level items are column headings; their children are the column. */
.ai-footer__cols > li > a {
	font-family: var(--font-display);
	font-size: 15px;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--ai-white);
}

@media (hover: hover) {
	.ai-footer__cols > li > a:hover { color: var(--ai-orange); }
}

/* The sitemap was the one place on the site where a link did nothing but
   change colour. The marker sits on the list item and the label steps aside
   from it — the same orange rule the navigation uses, at the size a footer
   wants. Transforms, not padding, so hovering a column cannot reflow it. */
.ai-footer__cols .sub-menu li { position: relative; }

.ai-footer__cols .sub-menu li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	width: 9px;
	height: 2px;
	margin-top: -1px;
	border-radius: 2px;
	background: var(--ai-orange);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .26s var(--ease);
}

.ai-footer__cols .sub-menu a {
	display: inline-block;
	transition: color .26s var(--ease), transform .26s var(--ease);
}

@media (hover: hover) {
	.ai-footer__cols .sub-menu li:hover::before { transform: scaleX(1); }
	.ai-footer__cols .sub-menu li:hover > a { transform: translateX(17px); color: #fff; }
	.ai-footer__legal-list a:hover { color: #fff; }
}

.ai-footer__cols .sub-menu {
	list-style: none;
	margin: var(--sp-2) 0 0;
	padding: 0;
}
.ai-footer__cols .sub-menu li + li { margin-top: .55rem; }

/* --- Legal bar ----------------------------------------------------------- */
.ai-footer__bar { border-top: 1px solid rgba(255, 255, 255, .12); }

.ai-footer__bar-inner {
	max-width: var(--container);
	margin-inline: auto;
	padding: var(--sp-3) clamp(1.25rem, 4vw, 2.5rem);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2) var(--sp-4);
	font-size: 14px;
	color: rgba(255, 255, 255, .6);
}

.ai-footer__copy { margin: 0; }

.ai-footer__legal-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
}


@media (max-width: 860px) {
	.ai-footer__inner { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Floating WhatsApp button
   The one contact route on this site that reaches a person in seconds, so it
   stays reachable from every screen rather than only from the footer.

   z-index 180 puts it under the sticky header (200) and under the open mobile
   nav sheet (190): a floating pill sitting on top of an open menu is the
   classic version of this component's one bug.
   ========================================================================== */
.ai-wa {
	position: fixed;
	z-index: 180;
	right: clamp(1rem, 3vw, 1.75rem);
	bottom: max(clamp(1rem, 3vw, 1.75rem), env(safe-area-inset-bottom));
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* A filled 56px circle — 30px glyph with 13px either side — rather than a
	   bare glyph. The bare version relied on a drop shadow to separate itself
	   from the page, and over the light lavender sections there was nothing
	   for that shadow to sit against: green marks on near-white read as
	   unfinished rather than as a button. */
	height: 56px;
	padding-inline: 13px;
	border-radius: var(--r-pill);
	background: #25D366;
	box-shadow: 0 8px 22px rgba(11, 61, 34, .28), 0 2px 6px rgba(0, 0, 0, .14);
	transition: transform .24s var(--ease), box-shadow .24s var(--ease), background .24s var(--ease);
}

/* White on WhatsApp's own green: the fill carries the brand, so the glyph and
   the label only have to stay legible on it. */
.ai-wa,
.ai-wa:hover,
.ai-wa:focus { color: #fff; }

.ai-wa svg {
	flex: 0 0 auto;
	width: 30px;
	height: 30px;
}

.ai-wa__label {
	font-family: var(--font-display);
	font-size: 15px;
	font-weight: 700;
	color: #fff;
	/* Collapsed by default: the icon carries the meaning, and a permanent label
	   the width of two words covers content on every scroll. It opens on hover
	   and on keyboard focus. */
	max-width: 0;
	overflow: hidden;
	white-space: nowrap;
	opacity: 0;
	transition: max-width .3s var(--ease), opacity .2s var(--ease), margin .3s var(--ease);
}

.ai-wa:focus-visible .ai-wa__label {
	max-width: 12rem;
	opacity: 1;
	margin-inline: .55rem .2rem;
}

@media (hover: hover) {
	.ai-wa:hover {
		transform: translateY(-2px);
		background: #1EBE5B;
		box-shadow: 0 12px 28px rgba(11, 61, 34, .34), 0 3px 8px rgba(0, 0, 0, .16);
	}

	.ai-wa:hover .ai-wa__label {
		max-width: 12rem;
		opacity: 1;
		margin-inline: .55rem .2rem;
	}
}

.ai-wa:active { transform: scale(.95); }

/* The mobile nav sheet covers the screen; a button floating over it would be
   the only thing left on top of an opaque panel. The header and this button
   are both body-level elements, so a sibling selector reaches it — no :has()
   needed, and no JS. */
.ai-header.is-open ~ .ai-wa {
	opacity: 0;
	pointer-events: none;
	transition: opacity .2s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
	.ai-wa,
	.ai-wa__label { transition: none; }
}

/* ==========================================================================
   Touch
   Every hover rule in this stylesheet is guarded by @media (hover: hover),
   because a tap on a touch screen leaves :hover latched until the next tap
   lands somewhere else — a card tapped once stayed lifted. That leaves touch
   with no feedback at all, so it gets its own: a press state, which is the
   thing a finger can actually perceive.
   ========================================================================== */
.ai-btn:active,
.elementor-button.ai-btn:active { transform: scale(.97); }

.ai-footer__social a:active { background: rgba(255, 255, 255, .18); transform: scale(.94); }

@media (hover: none) {
	/* Enough to register under a fingertip and short enough not to feel like
	   a delay before the tap opens something. */
	.ai-card:active { transform: scale(.99); }
	.ai-nav__list > li > a:active { background: rgba(255, 255, 255, .06); }
	.ai-footer__cols a:active,
	.ai-footer__legal-list a:active { color: var(--ai-orange); }
}

/* ==========================================================================
   Small screens
   The layout already stacks; what it needed was the fit and the reach — type
   that does not wrap a badge onto two lines, and targets a thumb can hit.
   ========================================================================== */
@media (max-width: 860px) {
	/* 19px was the tap height of a footer link. These are the only links on
	   the page with no card or button around them to enlarge them.

	   The height comes from padding rather than min-height alone: a label that
	   wraps to two lines has to grow past 44px, and centring a wrapped label
	   inside a fixed 44px box ran the two lines into the item below it. */
	.ai-footer__cols a,
	.ai-footer__legal-list a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
		padding-block: .5rem;
	}

	.ai-footer__cols .sub-menu li + li { margin-top: .15rem; }
	.ai-footer__cols .sub-menu { margin-top: .35rem; }
	.ai-footer__cols { gap: var(--sp-3) var(--sp-3); }

	.ai-footer__bar-inner {
		flex-direction: column;
		align-items: flex-start;
		gap: .25rem;
	}
	/* Notched phones: the bar sits over the home indicator otherwise. */
	.ai-footer__bar-inner { padding-bottom: max(var(--sp-3), env(safe-area-inset-bottom)); }
}

@media (max-width: 600px) {
	body { font-size: 16px; }

	/* auto-fit gives two ~150px columns here, and "Salesforce Automation" does
	   not fit one. Two explicit columns with the labels allowed to wrap beats
	   three-quarters of a word per line. */
	.ai-footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/* Set on the header, not on its inner: the sheet is a sibling of the
	   inner row and reads the same variable for its own height. */
	.ai-header { --ai-header-h: 68px; }
	.ai-logo img { height: 34px; }
}
