/* Site styles. Mobile first; section styles are added per homepage section.
   Colours and fonts come from theme.json presets only. */

:root {
	--header-h: 56px;
	--gutter: 16px;
	--focus-ring: var(--wp--preset--color--teal);
}

@media (min-width: 561px) {
	:root { --gutter: 32px; }
}

/* ---------- base ---------- */

body {
	overflow-x: clip; /* clip, not hidden, so position: sticky keeps working */
}

html {
	scroll-padding-top: var(--header-h);
}

@media (prefers-reduced-motion: no-preference) {
	html { scroll-behavior: smooth; }
}

/* Header, main and footer sit flush; sections set their own spacing. */
.wp-site-blocks > * + * {
	margin-block-start: 0;
}

/* Dark surfaces switch the focus ring to Sky for contrast. */
.site-header,
.site-footer,
.has-navy-background-color,
.has-deep-blue-background-color,
.has-teal-background-color {
	--focus-ring: var(--wp--preset--color--sky);
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 3px;
}

/* Wide container matching the mockup's .wrap: 1160px including side gutters. */
.site-header__bar,
.site-footer > * {
	box-sizing: border-box;
	padding-inline: var(--gutter);
}

/* ---------- buttons ---------- */

.wp-element-button,
.wp-block-button__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	isolation: isolate;
	transition: transform 0.3s ease;
}

/* Hover glow is a pre-rendered shadow faded in with opacity. */
.wp-element-button::after,
.wp-block-button__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	box-shadow: 0 0 26px rgba(43, 184, 235, 0.65);
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
}

.wp-element-button:hover,
.wp-block-button__link:hover {
	transform: translateY(-2px);
}

.wp-element-button:hover::after,
.wp-block-button__link:hover::after {
	opacity: 1;
}

.wp-block-button.is-style-compact .wp-block-button__link {
	padding: 6px 18px;
	font-size: 0.82rem;
}

/* Ghost button style: Cyan outline, no fill or glow. */
.wp-block-button.is-style-ghost .wp-block-button__link {
	background: none;
	box-shadow: none;
	color: var(--wp--preset--color--deep-blue);
}

.wp-block-button.is-style-ghost .wp-block-button__link::after {
	display: none;
}

/* ---------- header ---------- */

.site-header {
	position: fixed;
	top: var(--wp-admin--admin-bar--height, 0px);
	left: 0;
	right: 0;
	z-index: 50;
	color: var(--wp--preset--color--white);
}

/* Solid backdrop fades in on scroll (JS adds .is-solid); always on for inner pages. */
.site-header::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba(7, 26, 43, 0.85); /* Midnight Navy */
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
	opacity: 0;
	transition: opacity 0.4s ease;
}

.site-header.is-solid::before,
body:not(.home) .site-header::before {
	opacity: 1;
}

.site-header__bar {
	height: var(--header-h);
	align-items: center;
}

.site-header__logo {
	flex-shrink: 0;
}

.site-header__logo img {
	display: block;
	width: auto;
	height: 17px;
}

.site-header__nav {
	gap: 28px;
	align-items: center;
}

/* Up to 960px (where the mockup hides its nav links) the menu collapses into the
   Navigation block's overlay; Contact us stays visible, hamburger sits after it.
   Core switches the overlay off at 600px, so re-enable it up to 960px. */
@media (max-width: 960px) {
	.site-header__nav {
		gap: 12px;
	}

	.site-header .site-nav {
		order: 2;
	}
}

@media (min-width: 600px) and (max-width: 960px) {
	.site-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}

	.site-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}
}

/* Small phones: logo, button and hamburger must share one row. */
@media (max-width: 479px) {
	.site-header__logo img {
		height: 14px;
	}

	.site-header__cta .wp-block-button.is-style-compact .wp-block-button__link {
		padding-inline: 14px;
		white-space: nowrap;
	}
}

.site-header .wp-block-navigation__responsive-container-open,
.site-header .wp-block-navigation__responsive-container-close {
	color: var(--wp--preset--color--white);
}

/* Open overlay */
.site-header .wp-block-navigation__responsive-container.is-menu-open {
	padding: 20px var(--gutter) 40px;
}

.site-header .is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: calc(var(--header-h) + 8px);
	gap: 20px;
}

.site-header .is-menu-open .wp-block-navigation__submenu-container {
	padding: 12px 0 0 16px !important;
	margin-top: 12px !important;
	gap: 12px;
	border: 0 !important;
	border-left: 1px solid var(--wp--preset--color--teal) !important;
	border-radius: 0;
	background: transparent !important;
	box-shadow: none;
	font-size: 0.95rem;
}

.site-header .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 0 !important;
	font-size: 0.95rem;
	opacity: 0.75;
}

.site-header .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--manrope);
	font-size: 1.15rem;
	font-weight: 600;
}

/* ---------- navigation (header and footer) ---------- */

.site-nav {
	gap: 28px;
	font-size: 0.88rem;
}

.site-nav .wp-block-navigation-item__content {
	color: var(--wp--preset--color--white);
	text-decoration: none;
	opacity: 0.9;
}

.site-nav a[href].wp-block-navigation-item__content:hover,
.site-nav .wp-block-navigation-submenu__toggle:hover {
	color: var(--wp--preset--color--cyan);
	opacity: 1;
}

/* Unbuilt destinations: plain text, no link affordance. */
.site-nav span.wp-block-navigation-item__content {
	cursor: default;
}

.site-nav .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--white);
	opacity: 0.9;
}

.site-nav .wp-block-navigation__submenu-container {
	padding: 8px 0;
	border: 1px solid var(--wp--preset--color--teal) !important;
	border-radius: 10px;
	background: var(--wp--preset--color--deep-blue) !important;
	color: var(--wp--preset--color--white) !important;
	box-shadow: 0 12px 32px rgba(7, 26, 43, 0.5);
}

.site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 8px 18px;
	white-space: nowrap;
}

/* ---------- footer ---------- */

.site-footer {
	padding-block: 120px 48px;
	text-align: center;
}

.site-footer__logo img {
	width: 485px; /* 38px high; scales down, never stretched, on narrow screens */
	max-width: 100%;
	height: auto;
	margin-inline: auto;
	opacity: 0.85;
}

.site-footer__nav {
	margin-block: 22px 12px;
}

.site-footer__social .wp-social-link {
	opacity: 0.85; /* as the logo above */
	transition: opacity 0.2s ease;
}

.site-footer__social .wp-social-link:hover {
	opacity: 1;
}

/* Arrow button style: small UI arrow after the label, nudges right on hover. */
.wp-block-button.is-style-arrow .wp-block-button__link::before {
	content: "→" / "";
	order: 1;
	transition: transform 0.3s ease;
}

.wp-block-button.is-style-arrow .wp-block-button__link:hover::before {
	transform: translateX(4px);
}

/* Chip and tag lists: one wrapping row, no bullets; each list sets its own
   margin, and its gap when not 8px. */
.gov-section .csa-chips,
.svc-hero__chips,
.hia-chips-dark,
.se-tags,
.uc-stack,
.fl-platforms,
.fl-detail__pf,
.service__tags,
.so-hero__trust,
.aif-chips,
.caps,
.so-vapt__does {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	padding: 0;
	list-style: none;
}

/* ---------- 1 hero ---------- */

/* Navy zone with a faint grid; the customer logo band will sit inside it too. */
.hero-zone {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	margin: 0;
	padding: 0;
	background: radial-gradient(ellipse at 75% 45%, var(--wp--preset--color--deep-blue) 0%, var(--wp--preset--color--navy) 60%);
	color: var(--wp--preset--color--white);
	--focus-ring: var(--wp--preset--color--sky);
	--grid-line: rgba(43, 184, 235, 0.05);
	/* The logo band is the zone's last band, below the first screen. Without
	   the loop (no JS, reduced motion, editor) the Gallery shows every logo
	   in centred rows. */
	border-bottom: 1px solid rgba(43, 184, 235, 0.12);
}

/* Faint 48px grid behind the heroes (homepage, service pages, Security
   Operations); each hero sets --grid-line and, if it differs, --grid-fade. */
.hero-zone::before,
.svc-hero::before,
.so-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image:
		linear-gradient(var(--grid-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
	background-size: 48px 48px;
	-webkit-mask-image: var(--grid-fade, radial-gradient(ellipse 60% 60% at 72% 45%, #000, transparent));
	mask-image: var(--grid-fade, radial-gradient(ellipse 60% 60% at 72% 45%, #000, transparent));
	pointer-events: none;
}

.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 100vh;
	margin: 0;
	padding: 120px 0 80px;
	overflow: hidden;
}

/* Shade behind the headline keeps text readable over the network. */
.hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(ellipse 55% 45% at 22% 48%, rgba(7, 26, 43, 0.75) 0%, rgba(7, 26, 43, 0.4) 55%, rgba(7, 26, 43, 0) 100%);
	pointer-events: none;
}

.hero__content {
	position: relative;
	z-index: 2;
	box-sizing: border-box;
	width: 100%;
	max-width: var(--wp--style--global--wide-size);
	margin: 0 auto !important;
	padding-inline: var(--gutter);
	pointer-events: none; /* let the network below receive hover */
}

.hero__content > * {
	pointer-events: auto;
}

.hero__title {
	width: fit-content; /* don't cover the network's left nodes */
	max-width: 760px;
	margin: 0;
	color: var(--wp--preset--color--white);
	font-size: clamp(2.6rem, 5.4vw, 4.875rem); /* 78px at 1440 (owner, 3 Oct 2026) */
	line-height: 1.04;
}

.hero__title .ln {
	display: block;
}

.hero__title mark {
	background: none;
}

.hero__lead {
	max-width: 460px;
	margin: 20px 0 30px !important;
	color: var(--wp--preset--color--mist);
	font-size: var(--wp--preset--font-size--lead);
}

.hero__cta {
	margin: 0 !important;
}

/* Network: the List and Image blocks are shown as-is in the editor. On the site,
   inc/hero-network.php adds .is-rendered and draws the SVG; the list becomes
   the SVG labels and the image is placed over the hub. */
.hero-network.is-rendered {
	position: absolute;
	top: 50%;
	right: 4%;
	z-index: 1;
	width: min(50vw, 760px);
	aspect-ratio: 800 / 660;
	margin: 0 !important;
	transform: translateY(-50%);
	color: var(--wp--preset--color--cyan);
	container-type: inline-size; /* labels size against the network's width */
}

/* Node labels: the List items, placed beside their nodes by inc/hero-network.php.
   1.5cqw matches the drawing's 12-unit text; never below 11px. */
.hero-network.is-rendered > .hero-network__labels {
	position: absolute;
	inset: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	pointer-events: none;
}

.hero-network__labels .lbl {
	position: absolute;
	top: var(--y);
	left: var(--x);
	margin: 0;
	color: var(--wp--preset--color--sky);
	width: min-content; /* one word per line */
	font: 500 max(11px, 1.5cqw) / 1.2 var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.06em;
	text-align: center;
	opacity: 0;
	transform: translate(-50%, -100%);
	transition: opacity 0.6s;
	pointer-events: auto;
}

.hero-network__labels .lbl--extra {
	display: none;
}

.hero-network.is-named .lbl {
	opacity: 0.85;
}

.hero-network__labels .lbl a {
	color: inherit;
	text-decoration: none;
}

.hero-network .lbl.is-hot {
	color: var(--wp--preset--color--white);
	opacity: 1;
}

.hero-network__svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

.hero-network.is-rendered .hero-network__hub {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 11%;
	margin: 0;
	transform: translate(-50%, -50%);
	pointer-events: none;
}

.hero-network__hub img {
	display: block;
	width: 100%;
	height: auto;
}

.hero-network line {
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 1.3;
	stroke-opacity: 0.45;
	transition: stroke-opacity 0.6s;
}

.hero-network line.hot {
	stroke-opacity: 0.8;
	filter: drop-shadow(0 0 3px rgba(43, 184, 235, 0.8));
}

.hero-network .dot {
	fill: var(--wp--preset--color--mist);
	filter: drop-shadow(0 0 4px var(--wp--preset--color--cyan));
}

.hero-network .ring {
	fill: var(--wp--preset--color--deep-blue);
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 1.6;
	filter: drop-shadow(0 0 6px rgba(43, 184, 235, 0.6));
	transition: stroke 0.4s, fill 0.4s;
}

.hero-network .ic {
	fill: none;
	stroke: var(--wp--preset--color--sky);
	stroke-width: 1.6;
	stroke-linecap: round;
	stroke-linejoin: round;
	transition: stroke 0.4s;
}

.hero-network .risk .ring {
	fill: color-mix(in srgb, var(--wp--preset--color--orange) 16%, var(--wp--preset--color--navy));
	stroke: var(--wp--preset--color--orange);
	filter: drop-shadow(0 0 8px rgba(255, 144, 37, 0.7));
}

.hero-network .risk .ic {
	stroke: var(--wp--preset--color--orange);
}

.hero-network .blink .ring {
	fill: color-mix(in srgb, var(--wp--preset--color--orange) 32%, var(--wp--preset--color--navy));
}

.hero-network .n-node.s:hover .ring,
.hero-network .n-node.s.is-hot .ring {
	fill: var(--wp--preset--color--teal);
	stroke: var(--wp--preset--color--mist);
}

.hero-network .has-link {
	cursor: pointer;
}

.hero-network .hub-ring {
	fill: var(--wp--preset--color--navy);
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 2;
}

.hero-network .pulse {
	fill: var(--wp--preset--color--white);
	filter: drop-shadow(0 0 6px var(--wp--preset--color--cyan));
}

/* Shield "armed" (site.js adds .is-armed once the shield has formed): a flash
   and shockwave, then a radar sweep, light running round the outline, service
   nodes pinging in turn and threats breaking on the shield. Without the class
   (no JS, reduced motion, replay) none of it shows. */
.hero-network .n-fx,
.hero-network .ping {
	opacity: 0;
}

.hero-network .n-shield-fill {
	fill: url(#heroNetFill);
}

.hero-network .n-sweep {
	fill: currentColor;
	transform-box: view-box;
	transform-origin: 400px 330px;
}

.hero-network .n-sweep line {
	stroke: var(--wp--preset--color--mist);
	stroke-width: 1.4;
	stroke-opacity: 0.7;
}

.hero-network .n-shock {
	fill: none;
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 2;
	opacity: 0;
	transform-box: fill-box;
	transform-origin: center;
}

.hero-network .n-shield-trace {
	fill: none;
	stroke: var(--wp--preset--color--mist);
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-dasharray: 1 0;
	filter: drop-shadow(0 0 5px var(--wp--preset--color--cyan));
}

.hero-network .n-shield-trace--2 {
	stroke-dasharray: 0.08 0.42; /* two lights, opposite each other */
}

.hero-network .ping {
	fill: none;
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 1.5;
	transform-box: fill-box;
	transform-origin: center;
}

.hero-network .threat-head {
	fill: var(--wp--preset--color--white);
	stroke: var(--wp--preset--color--orange);
	stroke-width: 2.5;
	filter: drop-shadow(0 0 7px var(--wp--preset--color--orange));
}

.hero-network .threat-tail {
	fill: var(--wp--preset--color--orange);
	opacity: 0.6;
}

.hero-network .spark {
	fill: color-mix(in srgb, var(--wp--preset--color--cyan) 25%, transparent);
	stroke: var(--wp--preset--color--mist);
	stroke-width: 2.5;
	filter: drop-shadow(0 0 6px var(--wp--preset--color--cyan));
}

.hero-network .n-shield-hit {
	fill: none;
	stroke: var(--wp--preset--color--white);
	stroke-width: 3.5;
	stroke-linecap: round;
	stroke-dasharray: 0.07 0.93;
	filter: drop-shadow(0 0 8px var(--wp--preset--color--cyan));
}

.hero-network.is-armed .n-fx {
	opacity: 1;
}

.hero-network.is-armed .n-shield-fill {
	animation: net-flash 1.4s ease-out both, net-breathe 4s ease-in-out 1.4s infinite;
}

.hero-network.is-armed .n-sweep {
	animation: spin 5s linear infinite;
}

.hero-network.is-armed .n-shock {
	animation: net-shock 1.3s cubic-bezier(0.2, 0.6, 0.3, 1) both, net-shock 2.4s cubic-bezier(0.2, 0.6, 0.3, 1) 4s infinite;
}

.hero-network.is-armed .n-shock--2 {
	animation-delay: 0.25s, 4.4s;
}

.hero-network.is-armed .n-shield-trace {
	animation: net-trace-in 1s ease-out both, net-settle 1.2s ease-out 1s forwards;
}

.hero-network.is-armed .n-shield-trace--2 {
	animation: hero-fade-in 0.4s ease-out 1s backwards, net-trace 6s linear 1s infinite;
}

.hero-network.is-armed .ping {
	animation: net-ping 4.8s ease-out calc(1.2s + var(--k, 0) * 0.8s) infinite;
}

.hero-network .n-node.s[data-k="1"] { --k: 1; }
.hero-network .n-node.s[data-k="2"] { --k: 2; }
.hero-network .n-node.s[data-k="3"] { --k: 3; }
.hero-network .n-node.s[data-k="4"] { --k: 4; }
.hero-network .n-node.s[data-k="5"] { --k: 5; }

.hero-network.is-paused * {
	animation-play-state: paused !important;
}

@keyframes net-flash {
	0% { opacity: 0; }
	18% { opacity: 1; }
	100% { opacity: 0.7; }
}

@keyframes net-breathe {
	0%, 100% { opacity: 0.7; }
	50% { opacity: 1; }
}

@keyframes spin {
	to { transform: rotate(360deg); }
}

@keyframes net-shock {
	0% { opacity: 0.9; transform: scale(0.4); }
	70% { opacity: 0.15; }
	100% { opacity: 0; transform: scale(2.5); }
}

/* The outline draws once at full brightness and settles to a soft glow while
   two lights run round it. */
@keyframes net-trace-in {
	from { stroke-dasharray: 0 1; stroke-dashoffset: 0; }
	to { stroke-dasharray: 1 0; stroke-dashoffset: 0; }
}

@keyframes net-trace {
	from { stroke-dashoffset: 0; }
	to { stroke-dashoffset: -1; }
}

@keyframes net-settle {
	to { opacity: 0.35; }
}

@keyframes net-ping {
	0% { opacity: 0.9; transform: scale(1); }
	16% { opacity: 0; transform: scale(2.6); }
	100% { opacity: 0; transform: scale(2.6); }
}

@media (max-width: 960px) {
	/* Below 960px the hero stacks (a deliberate improvement on the mockup, which
	   overlaps here): text from the top, then the network in its own row below
	   the CTA, never behind the text. */
	.hero {
		display: block;
		min-height: 0;
		padding: 110px 0 56px;
	}

	.hero::before {
		content: none;
	}

	.hero-network.is-rendered {
		position: relative;
		top: auto;
		right: auto;
		width: calc(100% - 2 * var(--gutter));
		max-width: 520px;
		margin: 32px auto 0 !important;
		transform: none;
	}

	.hero-network__svg {
		overflow: hidden; /* scattered nodes can never reach the CTA above */
	}

	/* Larger hub so the logo's wordmark is readable. */
	.hero-network .hub-ring { r: 81px; }
	.hero-network .hub-halo { r: 125px; }

	.hero-network.is-rendered .hero-network__hub {
		width: 15.4%;
	}
}

/* Phones: 11px labels would run into the shield, so show icons only. The
   labels stay in the page (visually hidden) and are still read out. */
@media (max-width: 479px) {
	.hero-network__labels .lbl {
		clip-path: inset(50%);
		width: 1px;
		height: 1px;
		overflow: hidden;
	}
}

/* Editor: show the network's List and Image blocks plainly so they can be edited. */
.editor-styles-wrapper .hero-network {
	position: relative;
	z-index: 2;
	max-width: 420px;
	margin: 40px var(--gutter) 0 auto;
	padding: 16px 20px;
	border: 1px dashed var(--wp--preset--color--teal);
	border-radius: 10px;
	font-family: var(--wp--preset--font-family--plex-mono);
	font-size: 0.8rem;
}

.editor-styles-wrapper .hero-network .hero-network__hub {
	max-width: 88px;
}

/* Hero entrance. Hidden states apply only with JavaScript and motion allowed;
   .is-playing (site.js) starts the sequence in step with the network. */
@media (prefers-reduced-motion: no-preference) {
	.js .hero__title .ln,
	.js .hero__lead,
	.js .hero__cta,
	.js .hero-network.is-rendered:not(.is-live) .hero-network__svg,
	.js .hero-network.is-rendered:not(.is-live) .hero-network__hub,
	.js .hero-network.is-rendered:not(.is-live) .lbl {
		opacity: 0;
	}

	.hero.is-playing .ln--1 { animation: hero-rise 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) 0.4s both; }
	.hero.is-playing .ln--2 { animation: hero-rise 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) 0.85s both; }

	/* "Is your security?" about 2 s later, sharpening from a blurred copy. */
	.hero.is-playing .ln--q {
		position: relative;
		--rise: 30px;
		animation: hero-rise 1.1s cubic-bezier(0.215, 0.61, 0.355, 1) 3.75s both;
	}

	.hero.is-playing .ln--q .ln__txt {
		animation: hero-fade-in 1.1s ease-out 3.75s both;
	}

	.hero.is-playing .ln--q::before {
		content: attr(data-text) / "";
		position: absolute;
		inset: 0;
		color: var(--ln-color, currentColor);
		filter: blur(8px);
		pointer-events: none;
		animation: hero-fade-out 1.1s ease-out 3.75s both;
	}

	.hero.is-playing .hero__lead { --rise: 24px; animation: hero-rise 0.8s cubic-bezier(0.215, 0.61, 0.355, 1) 6.35s both; }
	.hero.is-playing .hero__cta { --rise: 24px; animation: hero-rise 0.8s cubic-bezier(0.215, 0.61, 0.355, 1) 6.85s both; }
}

@keyframes hero-rise {
	from { opacity: 0; transform: translateY(var(--rise, 40px)); }
	to { opacity: 1; transform: none; }
}

@keyframes hero-fade-in {
	from { opacity: 0; }
	to { opacity: 1; }
}

@keyframes hero-fade-out {
	from { opacity: 1; }
	to { opacity: 0; }
}

/* ---------- customer logo band (1b) ---------- */

.logo-band {
	box-sizing: border-box;
	max-width: var(--wp--style--global--wide-size);
	margin: 0 auto !important;
	padding: 34px var(--gutter) 40px;
}

/* "Client we serve": the eyebrow style, left-aligned above the track. */
.logo-band .logo-band__title {
	margin: 0 0 24px;
	font-weight: 500;
	line-height: 1.2;
}

.logo-band__track.wp-block-gallery.has-nested-images {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 28px 60px;
	margin: 0;
}

.logo-band__track.wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
	display: block;
	flex: none;
	width: auto;
	margin: 0;
}

.logo-band__track.wp-block-gallery figure.wp-block-image img {
	display: block;
	width: auto;
	max-width: 150px !important; /* core gallery sets max-width: 100% !important */
	height: 34px;
	object-fit: contain;
	filter: brightness(0) invert(1); /* all marks white; pre-rendered white copies are unchanged */
	opacity: 0.8;
	transition: opacity 0.3s;
}

.logo-band__track.wp-block-gallery figure.is-tall img {
	height: 42px;
}

.logo-band__track.wp-block-gallery figure.wp-block-image img:hover {
	opacity: 1;
}

.logo-band__track figcaption {
	display: none;
}

/* Continuous track (site.js adds .is-looping after appending a hidden copy of
   the logos): one row moving left by half its width, faded at both ends.
   A solid first mask layer keeps the heading row (above the logos) unfaded. */
.logo-band.is-looping {
	overflow: hidden;
	-webkit-mask-image: linear-gradient(#000 0 0), linear-gradient(90deg, transparent var(--gutter), #000 calc(var(--gutter) + 90px), #000 calc(100% - var(--gutter) - 90px), transparent calc(100% - var(--gutter)));
	mask-image: linear-gradient(#000 0 0), linear-gradient(90deg, transparent var(--gutter), #000 calc(var(--gutter) + 90px), #000 calc(100% - var(--gutter) - 90px), transparent calc(100% - var(--gutter)));
	-webkit-mask-size: 100% 64px, 100% 100%;
	mask-size: 100% 64px, 100% 100%;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

.logo-band.is-looping .logo-band__track.wp-block-gallery.has-nested-images {
	flex-wrap: nowrap;
	justify-content: flex-start;
	width: max-content;
	padding-inline-end: 60px; /* one gap after the last logo so -50% lands exactly on the copy */
	animation: logo-loop 60s linear infinite;
}

/* Paused while hovered, while focused from the keyboard (the band is in the
   tab order while looping) or after a tap; a second tap resumes. Hover and
   plain focus are left out on touch, where a tap would leave both behind. */
.logo-band.is-looping:is(:focus-visible, .is-paused) .logo-band__track.wp-block-gallery.has-nested-images {
	animation-play-state: paused;
}

@media (hover: hover) {
	.logo-band.is-looping:hover .logo-band__track.wp-block-gallery.has-nested-images {
		animation-play-state: paused;
	}
}

/* The edge fade would hide the focus ring, so drop it while focused. */
.logo-band.is-looping:focus-visible {
	outline-offset: -2px;
	-webkit-mask-image: none;
	mask-image: none;
}

@keyframes logo-loop {
	to { transform: translateX(-50%); }
}

/* ---------- 2 trust facts and credentials ---------- */

/* White band below the hero zone: four facts in a row, then the credentials. */
.trust {
	margin: 0;
	padding: 76px 0 64px;
	background: var(--wp--preset--color--white);
}

.trust > * {
	box-sizing: border-box;
	max-width: var(--wp--style--global--wide-size);
	margin-inline: auto !important;
	padding-inline: var(--gutter);
}

.trust-facts.wp-block-columns {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0;
	margin-block: 0;
}

.trust-facts > .wp-block-column {
	padding: 0 18px;
	border-right: 1px solid color-mix(in srgb, var(--wp--preset--color--slate) 13%, var(--wp--preset--color--mist));
	text-align: center;
}

.trust-facts > .wp-block-column:last-child {
	border-right: 0;
}

.trust-facts__figure {
	margin: 0 0 8px;
	font-size: clamp(1.6rem, 2.6vw, 2.2rem);
	white-space: nowrap;
}

/* "Since" and "-based": the Highlight format (Teal text) shown as small type. */
.trust-facts__figure mark {
	margin: 0 0.12em;
	background: none;
	font-size: 0.5em;
	font-weight: 600;
	letter-spacing: 0;
}

.trust-facts__figure + p {
	margin: 0;
	color: var(--wp--preset--color--slate);
	font-size: 0.92rem;
	line-height: calc(var(--wp--preset--font-size--body) * 1.6); /* body line box, as in the mockup */
}

.credentials {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 40px;
	width: calc(100% - 2 * var(--gutter));
	max-width: calc(var(--wp--style--global--wide-size) - 2 * var(--gutter));
	margin-top: 52px !important;
	padding: 36px 0 0;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--slate) 6%, var(--wp--preset--color--mist));
}

.credentials > * {
	margin: 0 !important;
}

.credentials .wp-block-image img {
	display: block;
	width: auto;
	height: 64px;
	object-fit: contain;
}

.credentials > .wp-block-image.is-tall img {
	height: 85px;
}

/* CSRO mark beside its two licence numbers. */
.credentials__csro {
	display: flex;
	align-items: center;
	gap: 14px;
}

.credentials__csro > * {
	margin: 0 !important;
}

.credentials__csro .wp-block-image img {
	height: 72px;
}

.credentials__csro p {
	max-width: 250px;
	color: var(--wp--preset--color--slate);
	font-size: 0.7rem;
	line-height: 1.35;
}

.credentials__csro strong {
	color: var(--wp--preset--color--navy);
	font: 600 0.68rem var(--wp--preset--font-family--plex-mono);
}

/* Row 2: the team's certifications, labelled below. */
.credentials__team {
	display: flex;
	flex-basis: 100%;
	flex-direction: column;
	align-items: center;
	gap: 10px;
}

.credentials__team > * {
	margin: 0 !important;
}

.credentials__logos.wp-block-gallery.has-nested-images {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 24px;
	max-width: 1080px;
	margin: 0;
}

.credentials__logos.wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
	flex: none;
	width: auto;
	margin: 0;
}

.credentials__logos.wp-block-gallery figure.wp-block-image img {
	width: auto;
	max-width: none !important; /* core gallery sets max-width: 100% !important */
	height: 46px;
}

.credentials__logos.wp-block-gallery figure.is-ring img {
	width: 44px;
	height: 44px;
}

/* CDPSE's artwork has a wider margin; scale it to match CISM optically. */
.credentials__logos.wp-block-gallery figure.is-trim img {
	transform: scale(1.29);
}

.credentials__logos.wp-block-gallery figure.is-short img {
	height: 40px;
}

.credentials__logos figcaption {
	display: none;
}

.credentials__label {
	color: var(--wp--preset--color--slate);
	font-size: 0.68rem;
}

@media (max-width: 960px) {
	.trust-facts.wp-block-columns {
		grid-template-columns: 1fr 1fr;
		row-gap: 36px;
	}

	.trust-facts > .wp-block-column:nth-child(2) {
		border-right: 0;
	}
}

@media (max-width: 560px) {
	.trust {
		padding-block: 72px;
	}

	.trust-facts.wp-block-columns {
		grid-template-columns: 1fr;
	}

	.trust-facts > .wp-block-column {
		border-right: 0;
	}
}

/* Entrance: facts, then credentials, rise in one after another (site.js adds
   .is-in). Hidden states apply only with JavaScript and motion allowed. */
@media (prefers-reduced-motion: no-preference) {
	.js .trust-facts > *,
	.js .credentials > * {
		opacity: 0;
		transform: translateY(26px);
	}

	/* Counting figure: an aria-hidden copy counts over the final number,
	   which keeps its width and stays readable to screen readers. Both share
	   one grid cell on the text's baseline. */
	.count {
		display: inline-grid;
		align-items: baseline;
	}

	.count > * {
		grid-area: 1 / 1;
	}

	.count__run {
		justify-self: end; /* hugs the text after the number, as the final value does */
	}

	.count.is-counting > :first-child {
		opacity: 0;
	}

	.count:not(.is-counting) .count__run {
		display: none;
	}

	.js .trust-facts.is-in > *,
	.js .credentials.is-in > * {
		opacity: 1;
		transform: none;
		transition: opacity 0.7s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 80ms), transform 0.7s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 80ms);
	}
}

/* ---------- shared text styles ---------- */

/* Small mono label above a section heading. */
.eyebrow {
	margin: 0 0 14px;
	color: var(--wp--preset--color--cyan);
	font-family: var(--wp--preset--font-family--plex-mono);
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* Orange closing line under a section's body text (sections 3 and 4). */
.is-orange {
	color: var(--wp--preset--color--orange);
	font: 600 1rem var(--wp--preset--font-family--manrope);
}

/* ---------- 3 protection gap ---------- */

/* Navy section, text beside the decay card. The section's own background is the
   gradient's end colour, so the space the pinned inner travels through
   (the spacer added while pinned) matches it. */
.problem {
	--problem-end: color-mix(in srgb, var(--wp--preset--color--deep-blue) 33%, var(--wp--preset--color--navy));
	margin: 0;
	padding: 0;
	background: var(--problem-end);
	color: var(--wp--preset--color--white);
	--focus-ring: var(--wp--preset--color--sky);
}

.problem__inner {
	display: grid;
	grid-template-columns: 1fr 1.05fr;
	gap: 64px;
	align-items: center;
	box-sizing: border-box;
	margin: 0 !important;
	padding: 96px max(var(--gutter), (100% - var(--wp--style--global--wide-size)) / 2 + var(--gutter)) 56px;
	background: linear-gradient(180deg, var(--wp--preset--color--navy), var(--problem-end));
}

.problem__text > * {
	margin: 0;
}

.problem__text > .eyebrow {
	margin-bottom: 14px;
}

.problem__text h2 {
	color: var(--wp--preset--color--white);
}

.problem__text mark {
	background: none;
}

.problem__lead {
	margin: 20px 0 !important;
	color: color-mix(in srgb, var(--wp--preset--color--sky) 30%, var(--wp--preset--color--mist));
	font-size: var(--wp--preset--font-size--lead);
}

/* Pinned on desktop (site.js adds .is-pinned): the inner sticks to the top
   while a spacer after it scrolls past, scrubbing the card from day 1 to 365.
   (A sticky box only travels within its parent's content box, so padding
   would not work.) */
.problem.is-pinned::after {
	content: "";
	display: block;
	height: var(--pin-distance, 1200px);
}

.problem.is-pinned .problem__inner {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0px);
	padding-top: var(--pin-pad-top);
	padding-bottom: var(--pin-pad-bottom);
}

/* The pinned view must fit the window at any height. Everything in the
   section except the card's stage is about 440px high (96px + 56px padding,
   288px of card around the stage), so the stage takes what is left, up to
   the mockup's 290px. Short windows also get tighter padding (72px clears
   the 56px header) and a smaller day figure and check rows. */
.problem.is-pinned {
	--pin-pad-top: 96px;
	--pin-pad-bottom: 56px;
	--pin-card: 288px;
}

.problem.is-pinned .decay__stage {
	max-height: clamp(140px, 100vh - var(--wp-admin--admin-bar--height, 0px) - var(--pin-pad-top) - var(--pin-pad-bottom) - var(--pin-card), 290px);
}

@media (max-height: 740px) {
	.problem.is-pinned {
		--pin-pad-top: 72px;
		--pin-pad-bottom: 24px;
	}
}

@media (max-height: 600px) {
	.problem.is-pinned {
		--pin-card: 250px;
	}

	.problem.is-pinned .decay {
		padding-block: 18px 16px;
	}

	.problem.is-pinned .decay__day {
		font-size: 1.6rem;
	}

	.problem.is-pinned .decay__checks li {
		padding-block: 6px;
	}
}

/* Decay card: day and status on top, the stage (shield, ring, attackers), then
   the checks and the scroll hint. */
.decay {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: baseline;
	position: relative;
	margin: 0 !important;
	padding: 26px 28px 24px;
	border: 1px solid rgba(43, 184, 235, 0.25);
	border-radius: 20px;
	background: linear-gradient(160deg, rgba(16, 45, 64, 0.9), rgba(7, 26, 43, 0.9));
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}

.decay > * {
	margin: 0 !important;
}

.decay > :not(.decay__day, .decay__status) {
	grid-column: 1 / -1;
}

.decay__day {
	color: var(--wp--preset--color--white);
	font: 800 1.9rem/normal var(--wp--preset--font-family--manrope);
	letter-spacing: -0.02em;
}

.decay__day mark {
	margin-right: 8px;
	background: none;
	font: 500 0.7rem var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* Status pill: one item shown at a time (.is-current; the last without JS). */
.decay__status {
	padding: 0;
	list-style: none;
}

.decay__status li {
	padding: 5px 10px;
	border: 1px solid currentColor;
	border-radius: 999px;
	color: var(--wp--preset--color--orange);
	font: 600 0.78rem/normal var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.decay__status li:first-child {
	color: var(--wp--preset--color--cyan);
}

.decay.is-rendered .decay__status li:not(.is-current) {
	display: none;
}

/* Stage: the SVG fills it (viewBox 420 × 300, max 290 px high, centred as in
   the mockup); .decay__field matches the viewBox so attackers can be placed
   in viewBox units (1cqw = 4.2 units). Attackers outside the stage are clipped. */
.decay__stage {
	position: relative;
	width: 100%;
	max-height: 290px;
	aspect-ratio: 420 / 300;
	margin: 6px 0 10px !important;
	overflow: hidden;
}

.decay__svg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	color: var(--wp--preset--color--cyan);
}

.decay__warm { stop-color: var(--wp--preset--color--orange); }

.decay__ring path { fill: var(--wp--preset--color--cyan); }
.decay__ring path.is-off { fill: var(--wp--preset--color--orange); opacity: 0.18; }

.decay__shield {
	fill: var(--wp--preset--color--deep-blue);
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 2.5;
}

.decay.is-breached .decay__shield,
.decay.is-rendered:not(.is-live) .decay__shield {
	stroke: var(--wp--preset--color--orange);
}

.decay__tick,
.decay__crack {
	fill: none;
	stroke-linecap: round;
}

.decay__tick {
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 4;
	stroke-linejoin: round;
}

.decay__crack {
	stroke: var(--wp--preset--color--orange);
	stroke-width: 2.5;
}

.decay__field {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	aspect-ratio: 420 / 300;
	transform: translateX(-50%);
	container-type: inline-size;
}

/* Attackers: the Image block, plus hidden copies made by site.js. Without JS
   the one image sits top left of the ring. */
.decay__field .decay__threat {
	position: absolute;
	top: 0;
	left: 0;
	width: 6.667cqw; /* 28 viewBox units */
	margin: 0;
	transform: translate(calc(var(--x, 21) * 1cqw - 50%), calc(var(--y, 13) * 1cqw - 50%)) scale(var(--s, 1));
}

.decay__field .decay__threat img {
	display: block;
	width: 100%;
	height: auto;
	filter: drop-shadow(0 0 6px rgba(255, 144, 37, 0.6));
}

/* Checks: ✓ / ✕, what was done, and what became of it. */
.decay__checks {
	display: grid;
	gap: 8px;
	padding: 0;
	list-style: none;
}

.decay__checks li {
	display: grid;
	grid-template-columns: 22px 1fr auto;
	gap: 10px;
	align-items: center;
	padding: 10px 12px;
	border: 1px solid rgba(255, 255, 255, 0.06);
	border-radius: 10px;
	background: rgba(255, 255, 255, 0.04);
	font-size: 0.9rem;
}

.decay__checks li::before {
	content: "✓" / "";
	display: grid;
	place-items: center;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: rgba(43, 184, 235, 0.18);
	color: var(--wp--preset--color--cyan);
	font-size: 0.75rem;
}

.decay__was {
	color: var(--wp--preset--color--white);
}

.decay__now {
	color: var(--wp--preset--color--cyan);
	font: 500 0.72rem var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.06em;
	text-align: right;
	text-transform: uppercase;
}

.decay__checks li.is-off::before {
	content: "✕" / "";
	background: rgba(255, 144, 37, 0.18);
	color: var(--wp--preset--color--orange);
}

.decay__checks li.is-off .decay__now {
	color: var(--wp--preset--color--orange);
}

.decay__checks li.is-off .decay__was {
	color: color-mix(in srgb, var(--wp--preset--color--slate) 50%, var(--wp--preset--color--mist));
	text-decoration: line-through;
	text-decoration-color: rgba(255, 144, 37, 0.6);
}

/* Scroll hint: only while the section is pinned; fades out at day 365. */
.decay__hint {
	margin-top: 10px !important;
	color: color-mix(in srgb, var(--wp--preset--color--slate) 50%, var(--wp--preset--color--sky));
	font-size: 0.68rem;
	text-align: right;
	transition: opacity 0.4s ease;
}

.decay.is-rendered .decay__hint {
	display: none;
}

.problem.is-pinned .decay__hint {
	display: block;
}

.problem.is-pinned .decay.is-done .decay__hint {
	opacity: 0;
}

/* Editor: lists and image shown plainly inside the card. */
.editor-styles-wrapper .decay .wp-block-image {
	max-width: 28px;
}

@media (max-width: 960px) {
	.problem__inner {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 560px) {
	.problem__inner {
		padding-block: 72px;
	}

	.decay {
		padding: 22px 18px 20px;
	}

	.decay__day {
		font-size: 1.6rem;
	}

	.decay__checks li {
		font-size: 0.85rem;
	}
}

/* Homepage entrances (sections 2–8): text rises in, headings word by word
   (site.js splits the problem, solution, journey and enquiry headings into
   .w spans and marks them .is-split). Hidden states apply only with
   JavaScript and motion allowed; site.js adds .is-in on entry. */
@media (prefers-reduced-motion: no-preference) {
	.js .problem__text > :not(h2),
	.js .problem .decay.is-rendered,
	.js .solution__text > :not(h2),
	.js .solution > .is-orange,
	.js .services__inner > h2,
	.js .testimonial > :not(.testimonial__quotes),
	.js .testimonial__quotes > *,
	.js .journey__lead,
	.js .contact__lead {
		opacity: 0;
		transform: translateY(32px);
	}

	.js .problem__text > .is-in,
	.js .problem .decay.is-rendered.is-in,
	.js .solution__text > .is-in,
	.js .solution > .is-orange.is-in,
	.js .services__inner > h2.is-in,
	.js .testimonial > .is-in,
	.js .journey__lead.is-in,
	.js .contact__lead.is-in {
		opacity: 1;
		transform: none;
		transition: opacity 0.9s cubic-bezier(0.215, 0.61, 0.355, 1), transform 0.9s cubic-bezier(0.215, 0.61, 0.355, 1);
	}

	h2.is-split .w {
		display: inline-block;
		overflow: hidden;
		vertical-align: top;
	}

	h2.is-split .w > span {
		display: inline-block;
	}

	.js h2.is-split:not(.is-in) .w > span {
		transform: translateY(110%);
	}

	.js h2.is-split.is-in .w > span {
		transition: transform 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 50ms);
	}
}

/* ---------- 4 solution ---------- */

/* Navy section, centred text above the "Connect" infographic and the orange
   closing line. Mockup tints are mixed from the brand palette. */
.solution {
	--connect-line: color-mix(in srgb, var(--wp--preset--color--sky) 50%, var(--wp--preset--color--cyan));
	--connect-glint: color-mix(in srgb, var(--wp--preset--color--white) 75%, var(--wp--preset--color--sky));
	--connect-soft: color-mix(in srgb, var(--wp--preset--color--white) 50%, var(--wp--preset--color--sky));
	--connect-state: color-mix(in srgb, color-mix(in srgb, var(--wp--preset--color--sky), var(--wp--preset--color--mist)) 80%, var(--wp--preset--color--slate));
	--connect-circle: color-mix(in srgb, var(--wp--preset--color--navy) 50%, var(--wp--preset--color--deep-blue));
	--connect-lit: color-mix(in srgb, var(--wp--preset--color--teal) 90%, var(--wp--preset--color--cyan));
	--connect-word: color-mix(in srgb, var(--wp--preset--color--orange) 70%, var(--wp--preset--color--navy));
	margin: 0;
	padding: 72px var(--gutter) 96px;
	overflow: hidden;
	background: var(--wp--preset--color--navy);
	color: var(--wp--preset--color--white);
	text-align: center;
	--focus-ring: var(--wp--preset--color--sky);
}

.solution > *,
.solution__text > * {
	margin: 0 !important;
}

.solution__text {
	max-width: 760px;
	margin: 0 auto 36px !important;
}

.solution__text > .eyebrow {
	margin-bottom: 14px !important;
}

.solution__text h2 {
	color: var(--wp--preset--color--white);
}

.solution__text mark {
	background: none;
}

.solution__lead {
	max-width: 640px;
	margin: 16px auto 0 !important;
	color: var(--wp--preset--color--mist);
	font-size: var(--wp--preset--font-size--lead);
}

.solution > .is-orange {
	max-width: 680px;
	margin: 28px auto 0 !important;
}

.connect {
	max-width: 810px;
	margin: 0 auto !important;
}

.connect__svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/* Hidden on screen, still read out: blocks a drawing shows instead (the
   Connect infographic here; the CSA marks, HIA tabs and price captions and
   the SO escalation list on their pages). */
.connect.is-rendered > :not(.connect__stage),
.csa-marks.is-ready .csa-marks__name,
.hia-tabs.is-tabbed .hia-tabs__label,
.hia-price.is-ready .hia-price__table figcaption,
.so-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.connect.is-rendered > :not(.connect__stage) {
	margin: 0;
}

.connect .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

.connect__stop-sky { stop-color: var(--wp--preset--color--sky); }
.connect__stop-cyan { stop-color: var(--wp--preset--color--cyan); }
.connect__stop-mid { stop-color: color-mix(in srgb, var(--wp--preset--color--cyan) 60%, var(--wp--preset--color--teal)); }
.connect__stop-navy { stop-color: var(--wp--preset--color--navy); }
.connect__head { fill: var(--connect-line); }

.connect__ic {
	fill: var(--wp--preset--color--navy);
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 2;
	filter: drop-shadow(0 0 8px rgba(43, 184, 235, 0.5));
}

.connect__gl {
	fill: none;
	stroke: var(--connect-line);
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.connect__gl--bars { stroke-width: 4; }

.connect__t {
	fill: var(--wp--preset--color--white);
	font: 600 19px var(--wp--preset--font-family--manrope);
}

.connect__s {
	fill: var(--connect-state);
	font: 400 15px var(--wp--preset--font-family--inter);
}

.connect__feed {
	fill: none;
	stroke: var(--wp--preset--color--cyan);
	stroke-width: 2.2;
	filter: drop-shadow(0 0 5px rgba(43, 184, 235, 0.8));
}

.connect__pulses circle {
	fill: var(--connect-glint);
}

.connect__sw { fill: none; }
.connect__sw--1 { stroke: var(--wp--preset--color--sky); stroke-opacity: 0.55; stroke-width: 3; }
.connect__sw--2 { stroke: var(--wp--preset--color--cyan); stroke-opacity: 0.5; stroke-width: 6; }
.connect__sw--3 { stroke: var(--connect-glint); stroke-opacity: 0.5; stroke-width: 2; }

.connect__orb-rim {
	fill: none;
	stroke: var(--wp--preset--color--sky);
	stroke-width: 2.5;
}

.connect__orbt {
	fill: var(--wp--preset--color--white);
	font: 700 19px var(--wp--preset--font-family--manrope);
	letter-spacing: 0.3em;
	text-anchor: middle;
}

.connect__rb {
	fill: none;
	stroke-linecap: round;
}

.connect__rb--glow { stroke: var(--wp--preset--color--cyan); opacity: 0.45; }
.connect__rb--body { stroke: url(#connectBeam); opacity: 0.8; }
.connect__rb--thin { opacity: 0.6; }

.connect__rb--flow {
	stroke: var(--connect-glint);
	stroke-dasharray: 26 70;
}

.connect__rb--soft { stroke: var(--connect-soft); }

.connect__arrows {
	fill: none;
	stroke: var(--connect-line);
	stroke-width: 5;
	stroke-linecap: round;
}

.connect__cc {
	fill: var(--connect-circle);
	stroke: var(--connect-line);
	stroke-width: 2.5;
	filter: drop-shadow(0 0 10px rgba(43, 184, 235, 0.55));
	transition: fill 0.5s ease, stroke 0.5s ease;
}

.connect__svc.is-lit .connect__cc {
	fill: var(--connect-lit);
	stroke: var(--connect-glint);
}

.connect__ct {
	fill: var(--wp--preset--color--white);
	font: 600 15px var(--wp--preset--font-family--manrope);
	text-anchor: middle;
}

/* Cycle words: regular when idle, bold orange while their service is lit. */
.connect__rw {
	fill: var(--connect-word);
	font: 400 21px var(--wp--preset--font-family--inter);
	text-anchor: middle;
	transition: fill 0.5s ease;
}

.connect__rw.is-lit {
	fill: var(--wp--preset--color--orange);
	font-weight: 700;
}

/* Editor: the blocks shown plainly. */
.editor-styles-wrapper .connect > * {
	margin-block: 12px;
}

.editor-styles-wrapper .connect ul {
	padding: 0;
	list-style: none;
}

/* Phones: the drawing is cropped to the orb and the cycle (larger labels),
   and the inputs show as a list above it. */
@media (max-width: 560px) {
	.solution {
		padding-block: 72px;
	}

	.connect.is-rendered {
		display: flex;
		flex-direction: column;
	}

	.connect__stage {
		order: 2;
		overflow: hidden;
	}

	/* Shows viewBox x 380–1010: the orb, ribbons and cycle with a margin. */
	.connect__svg {
		width: 158.73%;
		margin-left: -60.32%;
	}

	.connect__ct { font-size: 19px; }

	.connect.is-rendered > .connect__inputs {
		position: static;
		display: grid;
		gap: 8px;
		width: auto;
		height: auto;
		margin: 0 0 8px;
		padding: 0;
		overflow: visible;
		clip-path: none;
		list-style: none;
		white-space: normal;
		text-align: left;
	}

	.connect__inputs li {
		padding: 10px 14px;
		border-left: 2px solid var(--wp--preset--color--cyan);
		border-radius: 0 10px 10px 0;
		background: rgba(255, 255, 255, 0.04);
	}

	.connect__title {
		display: block;
		font: 600 1rem var(--wp--preset--font-family--manrope);
	}

	.connect__state {
		color: var(--connect-state);
		font-size: 0.9rem;
	}
}

/* Entrance and idle motion. Hidden states apply only with JavaScript and
   motion allowed; site.js adds .is-in on entry and .is-visible while the
   infographic is on screen (idle loops pause off screen). */
@media (prefers-reduced-motion: no-preference) {
	.connect__orb-art,
	.connect__halo,
	.connect__swirl {
		transform-box: view-box;
		transform-origin: 500px 185px;
	}

	.connect__svc {
		transform-box: fill-box;
		transform-origin: center;
	}

	.js .connect.is-rendered:not(.is-in) .connect__input { opacity: 0; transform: translateX(-24px); }
	.js .connect.is-rendered:not(.is-in) .connect__feed,
	.js .connect.is-rendered:not(.is-in) .connect__arw { stroke-dasharray: 1; stroke-dashoffset: 1; }
	.js .connect.is-rendered:not(.is-in) .connect__orb-art { opacity: 0; transform: scale(0.4); }
	.js .connect.is-rendered:not(.is-in) .connect__ribbons,
	.js .connect.is-rendered:not(.is-in) .connect__arrows { opacity: 0; }
	.js .connect.is-rendered:not(.is-in) .connect__svc { opacity: 0; transform: scale(0.6); }
	.js .connect.is-rendered:not(.is-in) .connect__rw { opacity: 0; transform: translateY(8px); }

	.js .connect.is-in .connect__input {
		transition: opacity 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i) * 0.18s), transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i) * 0.18s);
	}

	.js .connect.is-in .connect__feed {
		stroke-dasharray: 1;
		transition: stroke-dashoffset 0.8s cubic-bezier(0.455, 0.03, 0.515, 0.955) calc(0.76s + var(--i) * 0.12s);
	}

	.js .connect.is-in .connect__orb-art {
		transition: opacity 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) 1.5s, transform 0.9s cubic-bezier(0.34, 1.6, 0.64, 1) 1.5s;
	}

	.js .connect.is-in .connect__ribbons {
		transition: opacity 0.8s ease 2.2s;
	}

	.js .connect.is-in .connect__svc {
		transition: opacity 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) calc(2.8s + var(--i) * 0.14s), transform 0.6s cubic-bezier(0.34, 1.6, 0.64, 1) calc(2.8s + var(--i) * 0.14s);
	}

	.js .connect.is-in .connect__arrows {
		transition: opacity 0.3s ease 3.38s;
	}

	.js .connect.is-in .connect__arw {
		stroke-dasharray: 1;
		transition: stroke-dashoffset 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) calc(3.38s + var(--i) * 0.12s);
	}

	.js .connect.is-in .connect__rw {
		transition: fill 0.5s ease, opacity 0.4s ease calc(4.02s + var(--i) * 0.15s), transform 0.4s ease calc(4.02s + var(--i) * 0.15s);
	}

	/* Idle loops */
	.connect__rb--flow { animation: connect-flow 2.2s linear infinite; }
	.connect__rb--soft { animation-duration: 2.8s; }
	.connect__swirl { animation: spin 14s linear infinite; }
	.connect__halo { animation: connect-halo 2.2s ease-in-out infinite alternate; }
	.connect__rb--glow { animation: connect-glow 1.8s ease-in-out calc(var(--i) * 0.5s) infinite alternate; }
	.connect__rb--body { animation: connect-bob 2.4s ease-in-out calc(var(--i) * 0.4s) infinite alternate; }
	.connect__arw { animation: connect-dim 1.5s ease-in-out infinite alternate; }

	.connect:not(.is-visible) :is(.connect__rb, .connect__swirl, .connect__halo, .connect__arw) {
		animation-play-state: paused;
	}
}

@keyframes connect-flow { to { stroke-dashoffset: -96; } }
@keyframes connect-halo { to { transform: scale(1.12); opacity: 0.6; } }
@keyframes connect-glow { from { opacity: 0.45; } to { opacity: 0.2; } }
@keyframes connect-bob { to { transform: translateY(3px); } }
@keyframes connect-dim { to { opacity: 0.7; } }

/* ---------- unbuilt destinations ---------- */

/* A Button with no link is a destination that does not exist yet: it shows
   as plain text and gains the button look once a link is added. */
a.wp-block-button__link:not([href]) {
	padding: 0;
	border: 0;
	background: none;
	box-shadow: none;
	color: var(--wp--preset--color--teal);
	cursor: default;
}

/* (.wp-block-button outranks the Arrow style's arrow.) */
.wp-block-button a.wp-block-button__link:not([href])::before,
.wp-block-button a.wp-block-button__link:not([href])::after {
	display: none;
}

a.wp-block-button__link:not([href]):hover {
	transform: none;
}

/* ---------- 5 how we can help ---------- */

/* Cloud band. Without JS every service shows, illustration beside text.
   site.js adds .is-tabbed (a step list built from the H3s, one service shown)
   and on desktop .is-pinned (the inner sticks while the steps scroll past). */
.services {
	--services-line: color-mix(in srgb, var(--wp--preset--color--mist) 88%, var(--wp--preset--color--slate));
	--services-idle: var(--wp--preset--color--slate); /* the mockup's paler grey fails contrast (2.6:1) */
	--services-chip: color-mix(in srgb, var(--wp--preset--color--mist) 85%, var(--wp--preset--color--teal));
	margin: 0;
	padding: 0;
	background: var(--wp--preset--color--cloud);
}

.services__inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	align-content: center;
	box-sizing: border-box;
	margin: 0 !important;
	padding: 96px max(var(--gutter), (100% - var(--wp--style--global--wide-size)) / 2 + var(--gutter));
}

.services__inner > * {
	margin: 0 !important;
}

.services__inner > h2 {
	margin-bottom: 40px !important;
}

/* Illustration in the first column; the text blocks in the second, centred
   beside it (each block on its own row between two flexible rows). */
.service {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-template-rows: 1fr repeat(6, auto) 1fr;
	column-gap: 44px;
}

.services:not(.is-tabbed) .service + .service {
	margin-top: 64px !important;
}

.service > * {
	grid-column: 2;
	margin: 0;
}

.service > :nth-child(2) { grid-row: 2; }
.service > :nth-child(3) { grid-row: 3; }
.service > :nth-child(4) { grid-row: 4; }
.service > :nth-child(5) { grid-row: 5; }
.service > :nth-child(6) { grid-row: 6; }
.service > :nth-child(7) { grid-row: 7; }

.service > h3 {
	margin-bottom: 12px;
	font-size: 1.8rem;
}

.service > p {
	margin-bottom: 14px;
	color: var(--wp--preset--color--slate);
}

.service__art {
	grid-column: 1;
	grid-row: 1 / -1;
	align-self: center;
	margin: 0 !important;
}

.service__art img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1.1;
	object-fit: contain;
}

/* Photo art (image class "is-photo"): framed screenshot photo instead of an
   isometric drawing; keeps its own proportions. */
.service__art.is-photo img,
.services.is-pinned .service__art.is-photo img {
	max-height: none;
	aspect-ratio: 1080 / 750;
	object-fit: cover;
	border-radius: 16px;
	box-shadow: 0 24px 60px -24px rgba(7, 26, 43, 0.55);
}

.service__tags {
	margin: 0 0 26px; /* the mockup's 4px top margin collapses into the text's 14px */
}

.service__tags li {
	padding: 6px 12px;
	border: 1px solid var(--services-chip);
	border-radius: 999px;
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--teal);
	font: 500 0.8rem/normal var(--wp--preset--font-family--inter);
}

/* Step list (built by site.js from the H3s). */
.services.is-tabbed .services__inner {
	min-height: 100vh;
	grid-template-columns: 200px minmax(0, 1fr);
	column-gap: 44px;
	align-items: center;
}

.services.is-tabbed .services__inner > h2 {
	grid-column: 1 / -1;
}

.services__tabs {
	position: relative;
	display: flex;
	flex-direction: column;
}

.services__tab {
	appearance: none;
	margin: 0;
	padding: 18px 0 18px 18px;
	border: 0;
	border-bottom: 1px solid var(--services-line);
	background: none;
	color: var(--services-idle);
	font: 500 1rem/normal var(--wp--preset--font-family--inter);
	text-align: left;
	cursor: pointer;
	transition: color 0.3s ease;
}

.services__tab small {
	display: block;
	margin-bottom: 4px;
	font: 500 0.66rem/normal var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.1em;
	color: inherit;
}

.services__tab[aria-selected="true"] {
	color: var(--wp--preset--color--teal);
	font-weight: 600;
}

.services__tab[aria-selected="true"] small {
	color: var(--wp--preset--color--navy);
}

.services__tab:focus-visible {
	outline-color: var(--wp--preset--color--cyan);
	outline-offset: 4px;
}

.services__track {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 2px;
	border-radius: 2px;
	background: var(--services-line);
}

.services__track i {
	position: absolute;
	inset: 0;
	border-radius: 2px;
	background: var(--wp--preset--color--cyan);
	transform: scaleY(var(--progress, 0));
	transform-origin: top;
}

.services.is-tabbed .service {
	grid-column: 2;
	grid-row: 2;
}

.services.is-tabbed .service[hidden] {
	display: none;
}

/* Pinned on desktop: the inner fills the window and sticks while the spacer
   scrolls past (as in section 3). */
.services.is-pinned::after {
	content: "";
	display: block;
	height: var(--pin-distance, 200vh);
}

.services.is-pinned .services__inner {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0px);
	min-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px));
}

.services.is-pinned .service__art img {
	max-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px) - 290px);
}

@media (max-height: 760px) {
	.services.is-pinned .services__inner {
		padding-block: 72px 24px;
	}

	.services.is-pinned .service__art img {
		max-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px) - 190px);
	}
}

@media (max-width: 960px) {
	.service,
	.services.is-tabbed .services__inner {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: none;
	}

	.service > *,
	.service > h3,
	.service__art,
	.services.is-tabbed .service {
		grid-column: 1;
		grid-row: auto;
	}

	.service__art {
		width: min(100%, 440px);
		justify-self: center;
		margin-bottom: 16px !important;
	}

	.services.is-tabbed .services__inner > h2 {
		margin-bottom: 24px !important;
	}

	/* Plain tabs: a scrolling row, the current tab underlined. */
	.services__tabs {
		flex-direction: row;
		gap: 22px;
		margin-bottom: 16px !important;
		overflow-x: auto;
		scrollbar-width: none;
	}

	.services__tab {
		flex-shrink: 0;
		padding: 12px 0;
		border-bottom: 3px solid transparent;
	}

	.services__tab[aria-selected="true"] {
		border-bottom-color: var(--wp--preset--color--cyan);
	}

	.services__track {
		display: none;
	}
}

@media (max-width: 560px) {
	.services__inner {
		padding-block: 72px;
	}

	.service > h3 {
		font-size: 1.5rem;
	}
}

/* Editor: the services shown one after another. */
.editor-styles-wrapper .service + .service {
	margin-top: 48px;
}

/* ---------- 6 testimonial ---------- */

.testimonial {
	--testimonial-line: color-mix(in srgb, var(--wp--preset--color--mist) 88%, var(--wp--preset--color--slate));
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
	gap: 16px 52px; /* rows: quotes, dots, note */
	align-items: center;
	box-sizing: border-box;
	margin: 0;
	padding: 80px max(var(--gutter), (100% - var(--wp--style--global--wide-size)) / 2 + var(--gutter));
	background: var(--wp--preset--color--white);
}

.testimonial > * {
	margin: 0 !important;
}

.testimonial h2 {
	padding-right: 36px;
	border-right: 1px solid var(--testimonial-line);
}

.testimonial .wp-block-quote {
	position: relative;
	padding: 0 0 0 76px;
	border: 0;
	color: var(--wp--preset--color--teal);
	font-size: 1.2rem;
	font-style: italic;
}

.testimonial .wp-block-quote::before {
	content: "\201C" / "";
	position: absolute;
	top: -24px;
	left: 0;
	color: var(--wp--preset--color--sky);
	font: 800 5.5rem/1.6 var(--wp--preset--font-family--manrope);
	opacity: 0.6;
}

.testimonial .wp-block-quote p {
	margin: 0;
}

.testimonial .wp-block-quote cite {
	display: block;
	margin-top: 10px;
	color: var(--wp--preset--color--slate);
	font-size: 0.85rem;
	font-style: normal;
}

/* Several testimonials (Quote blocks in the Group "testimonial__quotes"):
   all shown, two per row beside the heading, with the quote mark above each
   one's text; the note sits under them. They rise in one after another. */
.testimonial:has(.testimonial__quotes) > h2 {
	grid-row: span 2;
}

.testimonial__quotes {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 44px 48px;
}

.testimonial__quotes > .wp-block-quote {
	margin: 0;
	padding: 34px 0 0;
	font-size: 1.05rem;
}

.testimonial__quotes > .wp-block-quote::before {
	top: -36px;
	font-size: 4.5rem;
	transform-origin: 0 60%;
}

.testimonial__note {
	margin: 12px 0 0 !important;
	color: var(--wp--preset--color--slate);
	font-size: 0.75rem;
}

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

	.testimonial:has(.testimonial__quotes) > h2 {
		grid-row: auto;
	}

	.testimonial > h2 {
		margin-bottom: 36px !important; /* 52px above the quotes */
	}

	.testimonial h2 {
		padding: 0;
		border: 0;
	}
}

@media (max-width: 760px) {
	.testimonial__quotes {
		grid-template-columns: minmax(0, 1fr);
		gap: 36px;
	}
}

@media (max-width: 560px) {
	.testimonial .wp-block-quote {
		padding: 44px 0 0;
	}

	.testimonial .wp-block-quote::before {
		top: -18px;
	}
}

/* ---------- 7 cyber journey ---------- */

/* Mist band, four stage cards on a path. site.js adds the path line and the
   runner dot, inlines each stage icon (an SVG from the Media Library) so its
   strokes can draw in, and cycles .is-on through the cards on desktop. */
.journey {
	--journey-border: color-mix(in srgb, var(--wp--preset--color--mist) 88%, var(--wp--preset--color--teal));
	box-sizing: border-box;
	margin: 0;
	padding: 96px max(var(--gutter), (100% - var(--wp--style--global--wide-size)) / 2 + var(--gutter));
	background: var(--wp--preset--color--mist);
}

.journey > * {
	margin: 0 !important;
}

.journey__lead {
	margin: 10px 0 62px !important;
	color: var(--wp--preset--color--teal);
	font-size: var(--wp--preset--font-size--lead);
}

.journey__stages {
	position: relative;
	display: grid !important;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 24px !important;
}

.journey__stage {
	position: relative;
	box-sizing: border-box;
	padding: 22px 20px 24px;
	border: 1px solid var(--journey-border);
	border-radius: 14px;
	background: var(--wp--preset--color--white);
	transition: transform 0.3s ease;
}

/* Lift, shadow and cyan border while hovered or highlighted (the shadow and
   border are layers faded in with opacity). */
.journey__stage::before,
.journey__stage::after {
	content: "";
	position: absolute;
	inset: -1px;
	border-radius: inherit;
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
}

.journey__stage::before {
	z-index: -1;
	box-shadow: 0 18px 40px rgba(16, 45, 64, 0.12);
}

.journey__stage::after {
	border: 1px solid var(--wp--preset--color--cyan);
}

.journey__stage.is-on,
.journey__stage:hover {
	transform: translateY(-6px);
}

.journey__stage.is-on::before,
.journey__stage.is-on::after,
.journey__stage:hover::before,
.journey__stage:hover::after {
	opacity: 1;
}

.journey__stage > * {
	margin: 0;
}

.journey__icon {
	position: relative;
	display: grid;
	place-items: center;
	box-sizing: border-box;
	width: 58px;
	height: 58px;
	margin: -52px 0 16px !important;
	border: 1px solid var(--wp--preset--color--teal);
	border-radius: 14px;
	background: var(--wp--preset--color--deep-blue);
}

.journey__icon img,
.journey__icon svg {
	position: relative;
	z-index: 1;
	display: block;
	width: 28px;
	height: 28px;
}

/* Highlight: the tile turns teal and glows, with a ring pulsing out. */
.journey__icon::before,
.journey__icon::after {
	content: "";
	position: absolute;
	inset: -1px;
	border-radius: 14px;
	opacity: 0;
	pointer-events: none;
}

.journey__icon::before {
	background: var(--wp--preset--color--teal);
	box-shadow: 0 0 0 6px rgba(43, 184, 235, 0.15), 0 0 24px rgba(43, 184, 235, 0.55);
	transition: opacity 0.4s ease;
}

.journey__icon::after {
	border: 2px solid var(--wp--preset--color--cyan);
}

.journey__stage.is-on .journey__icon::before {
	opacity: 1;
}

/* Number and destination keep the body text's line height, as in the mockup. */
.journey__num {
	color: var(--wp--preset--color--slate);
	font: 400 0.66rem/calc(var(--wp--preset--font-size--body) * 1.6) var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.journey__stage h3 {
	margin: 6px 0;
	font-size: 1.1rem;
}

.journey__stage > p:not([class]) {
	margin-bottom: 18px;
	color: var(--wp--preset--color--slate);
	font-size: 0.9rem;
}

/* Destination: plain text until it has a link. */
.journey__next {
	color: var(--wp--preset--color--teal);
	font-size: 0.92rem;
	font-weight: 500;
	line-height: calc(var(--wp--preset--font-size--body) * 1.6);
}

.journey__next a {
	padding: 0 0 2px;
	border-bottom: 1px solid var(--wp--preset--color--cyan);
	color: inherit;
	text-decoration: none;
	transition: padding 0.3s ease;
}

.journey__next a::after {
	content: " →" / "";
}

/* The line runs through the top of the icon tiles, above the cards. */
.journey__line,
.journey__runner {
	position: absolute;
	top: -25px;
	left: 6%;
	width: 88%;
	pointer-events: none;
}

.journey__line {
	height: 2px;
	background: linear-gradient(90deg, var(--wp--preset--color--cyan), var(--wp--preset--color--teal));
	transform-origin: left;
}

/* The runner is as wide as the line and invisible; its dot sits at its right
   end, so moving it from -100% to 0 carries the dot along the line. */
.journey__runner {
	z-index: 3;
	top: -30px;
	height: 12px;
	opacity: 0;
}

.journey__runner::after {
	content: "";
	position: absolute;
	top: 0;
	right: -6px;
	box-sizing: border-box;
	width: 12px;
	height: 12px;
	border: 3px solid var(--wp--preset--color--cyan);
	border-radius: 50%;
	background: var(--wp--preset--color--white);
	box-shadow: 0 0 14px var(--wp--preset--color--cyan);
}

@media (max-width: 960px) {
	.journey__stages {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		row-gap: 64px !important;
	}

	.journey__line,
	.journey__runner {
		display: none;
	}
}

@media (max-width: 560px) {
	.journey {
		padding-block: 72px;
	}

	.journey__stages {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ---------- 8 enquiry ---------- */

/* Navy section: heading beside the form preview, with the ribbon artwork
   (the Image block) behind. The artwork layer runs on under the footer, which
   is transparent on this page; site.js measures the footer (--footer-h). */
.contact {
	--contact-bg: color-mix(in srgb, var(--wp--preset--color--navy) 60%, var(--wp--preset--color--deep-blue));
	--contact-field: color-mix(in srgb, var(--wp--preset--color--cyan) 45%, transparent);
	position: relative;
	isolation: isolate;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 72px;
	align-items: start;
	box-sizing: border-box;
	min-height: calc(100vh - var(--footer-h, 280px));
	margin: 0;
	padding: 120px max(var(--gutter), (100% - var(--wp--style--global--wide-size)) / 2 + var(--gutter)) 0;
	background: var(--contact-bg);
	color: var(--wp--preset--color--white);
	--focus-ring: var(--wp--preset--color--sky);
}

.contact > * {
	margin: 0 !important;
}

/* Clips the artwork layer where it runs past the footer. */
.wp-site-blocks:has(.contact) {
	overflow: clip;
}

.wp-site-blocks:has(.contact) .site-footer {
	position: relative;
	z-index: 1;
	background-color: transparent !important;
}

.contact__ribbons {
	position: absolute !important;
	z-index: -1;
	inset: 0 0 calc(-1 * var(--footer-h, 400px)); /* generous without JS; clipped at the page end */
	overflow: hidden;
	background: var(--contact-bg);
	pointer-events: none;
}

.contact__ribbons img {
	position: absolute;
	top: 16%;
	left: -3%;
	width: 106%;
	max-width: none;
	height: 88%;
	object-fit: cover;
	object-position: 50% 100%;
	scale: 0.8;
	transform-origin: 60% 100%;
	-webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 55%, transparent 100%);
	mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 55%, transparent 100%);
}

/* Light sweep, then the fade that keeps the top clear for the text. */
.contact__ribbons::before,
.contact__ribbons::after {
	content: "";
	position: absolute;
	inset: 0;
}

.contact__ribbons::before {
	z-index: 1;
	width: 250%;
	background: linear-gradient(105deg, transparent 35%, color-mix(in srgb, var(--wp--preset--color--sky) 12%, transparent) 48%, transparent 60%);
	mix-blend-mode: screen;
	transform: translateX(-72%);
}

.contact__ribbons::after {
	z-index: 2;
	background: linear-gradient(180deg,
		var(--contact-bg) 0%,
		color-mix(in srgb, var(--contact-bg) 85%, transparent) 22%,
		transparent 45%,
		transparent 80%,
		color-mix(in srgb, var(--wp--preset--color--navy) 70%, transparent) 100%);
}

/* Holds the ripple filter (site.js); takes no space. */
.contact__ripple {
	position: absolute;
	width: 0;
	height: 0;
	overflow: hidden;
}

.contact__intro > * {
	margin: 0;
}

.contact__intro h2 {
	color: var(--wp--preset--color--white);
}

.contact__intro h2,
.contact__lead {
	text-shadow: 0 2px 20px rgba(0, 0, 0, 0.45);
}

.contact__lead {
	margin-top: 16px !important;
	color: color-mix(in srgb, var(--wp--preset--color--mist) 80%, var(--wp--preset--color--sky));
	font-size: var(--wp--preset--font-size--lead);
}

/* Enquiry form (Fluent Forms block; its default skin is off, inc/enquiry.php). */
.contact__form .fluentform {
	--ff-gap: 16px;
}

.contact__form .ff-el-group {
	margin: 0 0 var(--ff-gap);
}

.contact__form .ff-el-input--label {
	display: block; /* the plugin's inline-block adds a line box */
	margin: 0 0 6px;
}

.contact__form .ff-el-input--label label {
	display: block;
	color: var(--wp--preset--color--white);
	font-size: 0.84rem;
	font-weight: 400;
}

.contact__form .ff-el-form-control {
	display: block;
	box-sizing: border-box;
	width: 100%;
	margin: 0;
	padding: 12px 14px;
	border: 1px solid var(--contact-field);
	border-radius: 8px;
	background: color-mix(in srgb, var(--wp--preset--color--deep-blue) 70%, transparent);
	color: var(--wp--preset--color--white);
	font: 0.95rem/normal var(--wp--preset--font-family--inter);
}

.contact__form .ff-el-form-control::placeholder {
	color: color-mix(in srgb, var(--wp--preset--color--white) 45%, transparent);
}

.contact__form textarea.ff-el-form-control {
	min-height: 100px;
	resize: vertical;
}

.contact__form .ff-el-form-control:focus-visible {
	outline: none;
	border-color: var(--wp--preset--color--cyan);
	box-shadow: 0 0 0 3px rgba(43, 184, 235, 0.2);
}

.contact__form .ff-el-is-error .ff-el-form-control {
	border-color: var(--wp--preset--color--orange);
}

.contact__form .error.text-danger {
	margin: 6px 0 0;
	color: var(--wp--preset--color--orange);
	font-size: 0.8rem;
}

.contact__form .contact__consent {
	margin: 4px 0 20px;
	color: color-mix(in srgb, color-mix(in srgb, var(--wp--preset--color--sky) 85%, var(--wp--preset--color--slate)) 80%, var(--wp--preset--color--white));
	font-size: 0.75rem;
}

.contact__form .contact__consent p {
	margin: 0;
}

.contact__form .contact__consent a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Submit: the theme's Button classes (Arrow style), reapplied over the
   plugin's structural .ff-btn rule. */
.contact__form .ff_submit_btn_wrapper {
	margin: 0;
}

/* The rest of the look comes from theme.json's button element; the colour
   clears Fluent Forms' own grey under the gradient. */
.contact__form .ff-btn.wp-block-button__link {
	display: inline-flex;
	background-color: transparent;
	cursor: pointer;
}

.contact__form .ff-btn.ff-working {
	opacity: 0.7;
	cursor: progress;
}

/* Shown only after a successful submit (the form is hidden then). */
.contact__form .ff-message-success {
	margin: 0;
	padding: 20px 22px;
	border: 1px solid var(--contact-field);
	border-radius: 8px;
	background: color-mix(in srgb, var(--wp--preset--color--deep-blue) 70%, transparent);
	color: var(--wp--preset--color--white);
	box-shadow: none;
}

.contact__form .ff-message-success p {
	margin: 0;
}

.contact__form .ff-errors-in-stack {
	color: var(--wp--preset--color--orange);
	font-size: 0.85rem;
}

/* Editor: the artwork shown as a normal image above the text. */
.editor-styles-wrapper .contact__ribbons {
	position: relative !important;
	inset: auto;
	grid-column: 1 / -1;
	margin-bottom: 32px !important;
}

.editor-styles-wrapper .contact__ribbons img {
	position: static;
	width: 100%;
	height: 240px;
	scale: none;
	-webkit-mask-image: none;
	mask-image: none;
	animation: none;
}

.editor-styles-wrapper .contact__ribbons::before,
.editor-styles-wrapper .contact__ribbons::after {
	display: none;
}

@media (max-width: 960px) {
	.contact {
		grid-template-columns: minmax(0, 1fr);
		row-gap: 40px;
		padding-top: 96px;
	}
}

@media (max-width: 560px) {
	.contact {
		padding-top: 72px;
	}
}

/* ---------- entrance and idle motion, sections 5–8 ---------- */

/* Text entrances are with section 2's; here the staggered ones. */
@media (prefers-reduced-motion: no-preference) {
	.js .contact__form .ff-el-group {
		opacity: 0;
		transform: translateY(26px);
	}

	/* Testimonials rise in one after another; each quote mark pops in after. */
	.js .testimonial__quotes.is-in > * {
		opacity: 1;
		transform: none;
		transition: opacity 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 180ms), transform 0.9s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 180ms);
	}

	.js .testimonial__quotes > .wp-block-quote::before {
		opacity: 0;
		transform: scale(0.5);
	}

	.js .testimonial__quotes.is-in > .wp-block-quote::before {
		opacity: 0.6;
		transform: none;
		transition: opacity 0.6s ease calc(var(--i, 0) * 180ms + 0.35s), transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) calc(var(--i, 0) * 180ms + 0.35s);
	}

	.js .contact__form.is-in .ff-el-group {
		opacity: 1;
		transform: none;
		transition: opacity 0.7s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 80ms), transform 0.7s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 80ms);
	}

	/* A service's parts rise in each time it is shown. */
	.services.is-tabbed .service > * {
		animation: services-in 0.5s cubic-bezier(0.215, 0.61, 0.355, 1) calc(var(--i, 0) * 70ms) backwards;
	}

	.services.is-tabbed .service > .service__art {
		animation: services-art 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) backwards;
	}

	/* Journey: the line draws and the runner travels it (2.2 s); each card
	   rises as the runner arrives, its icon draws, then its text follows. */
	.js .journey__stages.is-live:not(.is-in) .journey__line { transform: scaleX(0); }
	.js .journey__stages.is-live:not(.is-in) .journey__stage { opacity: 0; }
	.js .journey__stages.is-live:not(.is-in) .journey__stage > :not(.journey__icon) { opacity: 0; }

	.journey__stages.is-in .journey__line {
		animation: journey-line 2.2s linear backwards;
	}

	.journey__stages.is-in .journey__runner {
		animation: journey-run 2.5s linear;
	}

	.journey__stages.is-in .journey__stage {
		animation: journey-rise 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) calc(var(--i) * 0.55s) backwards;
	}

	.journey__stages.is-in .journey__stage > :not(.journey__icon) {
		animation: services-in 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) calc(var(--i) * 0.55s + 0.3s + var(--j, 0) * 0.06s) backwards;
	}

	.journey__stages.is-in .journey__icon svg * {
		stroke-dasharray: 1;
		animation: journey-draw 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) calc(var(--i) * 0.55s + 0.25s + var(--k, 0) * 0.08s) backwards;
	}

	.journey__stage.is-on .journey__icon::after,
	.journey__stages.is-instant .journey__stage.is-on .journey__icon::after { /* the highlight loop keeps running */
		animation: journey-ring 1.6s ease-out infinite !important;
	}

	/* Ribbons: slow drift and a light sweep, paused off screen. */
	.contact__ribbons img {
		animation: contact-drift 14s ease-in-out infinite alternate;
	}

	.contact__ribbons::before {
		animation: contact-sheen 9s linear infinite;
	}

	/* Ripple (site.js): SVG displacement filter on the artwork. */
	.contact__ribbons img.is-rippling {
		filter: url(#contact-ripple);
	}

	.contact:not(.is-visible) .contact__ribbons img,
	.contact:not(.is-visible) .contact__ribbons::before {
		animation-play-state: paused;
	}
}

@keyframes services-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes services-art { from { opacity: 0; transform: translateY(20px); } }
@keyframes journey-line { from { transform: scaleX(0); } }
@keyframes journey-run {
	0% { opacity: 0; transform: translateX(-100%); }
	8% { opacity: 1; }
	88% { opacity: 1; transform: none; }
	100% { opacity: 0; transform: none; }
}
@keyframes journey-rise { from { opacity: 0; transform: translateY(50px) scale(0.96); } }
@keyframes journey-draw { from { stroke-dashoffset: 1; } }
@keyframes journey-ring { from { opacity: 0.8; transform: scale(1); } to { opacity: 0; transform: scale(1.45); } }
@keyframes contact-drift { to { transform: translate(-40px, 14px) scale(1.03); } }
@keyframes contact-sheen { from { transform: translateX(-72%); } to { transform: translateX(72%); } }

/* Scrolled up into a section that had not played (site.js onScrollDown):
   show its final state at once. */
.is-instant,
.is-instant *,
.is-instant::before,
.is-instant *::before,
.is-instant *::after {
	transition: none !important;
	animation: none !important;
}

/* ---------- reduced motion: skip to final states ---------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		animation-delay: 0s !important;
		transition-duration: 0.01ms !important;
		transition-delay: 0s !important;
	}

	.wp-element-button:hover,
	.wp-block-button__link:hover {
		transform: none;
	}
}

/* ---------- privacy policy (and other plain text pages) ---------- */

/* A light page under the fixed header: title, date, then the policy as
   ordinary headings, paragraphs and lists in a readable column. */
.policy {
	margin: 0;
	padding: 140px var(--gutter) 96px;
	background: linear-gradient(180deg, var(--wp--preset--color--mist), var(--wp--preset--color--white) 420px);
	color: var(--wp--preset--color--navy);
}

.policy__inner {
	max-width: 760px;
	margin: 0 auto;
}

.policy__inner > * {
	margin-block: 0;
}

.policy .policy__title {
	font-size: clamp(2.2rem, 4.4vw, 3.4rem);
	line-height: 1.08;
}

.policy .policy__updated {
	margin: 14px 0 40px;
	color: var(--wp--preset--color--teal);
	font: 500 0.78rem/1.6 var(--wp--preset--font-family--plex-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.policy h2 {
	margin: 40px 0 12px;
	font-size: clamp(1.15rem, 1.6vw, 1.35rem);
}

.policy p,
.policy li {
	color: var(--wp--preset--color--slate);
	font-size: 1rem;
	line-height: 1.7;
}

.policy p + p,
.policy ul + p,
.policy p + ul {
	margin-top: 12px;
}

.policy ul {
	padding-left: 1.3em;
}

.policy li + li {
	margin-top: 4px;
}

.policy li::marker {
	color: var(--wp--preset--color--cyan);
}

.policy strong {
	color: var(--wp--preset--color--navy);
}

.policy a {
	border-bottom: 1px solid var(--wp--preset--color--cyan);
	color: var(--wp--preset--color--teal);
	text-decoration: none;
}
