/**
 * Upnuvo theme presentation layer.
 *
 * Design tokens come from theme.json as CSS custom properties. This file only
 * holds component and utility styles that block supports cannot express.
 *
 * 1.  Base and accessibility
 * 2.  Brand mark
 * 3.  Site header
 * 4.  Site footer
 * 5.  Eyebrow labels and section headings
 * 6.  Hero
 * 7.  Cards, pillars and numbered steps
 * 8.  Stats
 * 9.  Logo strip
 * 10. Testimonials
 * 11. FAQ
 * 12. Dark panel and CTA
 * 13. Forms
 * 14. Buttons
 * 15. Long-form and legal pages
 * 16. Scroll reveal and motion
 */

/* ---------------------------------------------------------------- 1. Base  */

:root {
	--u-ring: 0 0 0 3px rgba(31, 94, 255, 0.32);
	--u-header-height: 72px;
}

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

/*
 * No overflow-x clipping on the root elements: it silently breaks the sticky
 * header. Sections that paint decorative bleed clip themselves instead.
 */
body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	font-synthesis-weight: none;
}

/* Anchor links must not disappear behind the sticky header. */
:where([id]) {
	scroll-margin-top: calc(var(--u-header-height) + 1.5rem);
}

/*
 * Header, main and footer each carry their own padding, so the default block
 * gap between them only produces a pale stripe between dark sections. Making
 * the wrapper a column flexbox also keeps the footer at the bottom on pages
 * too short to fill the viewport.
 */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.wp-site-blocks > * {
	margin-block-start: 0;
}

.wp-site-blocks > main {
	flex: 1 0 auto;
}

/* Restyle the skip link that WordPress outputs for block themes. */
.skip-link.screen-reader-text:focus {
	z-index: 999;
	top: 1rem;
	left: 1rem;
	padding: 0.75rem 1.25rem;
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--ink);
	color: #fff;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
	box-shadow: none;
}

:where(a, button, summary, input, textarea, select, .wp-block-button__link):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
	border-radius: 4px;
}

::selection {
	background: var(--wp--preset--color--accent);
	color: #fff;
}

/* Balance short headings across lines without manual breaks. */
h1,
h2,
.u-balance {
	text-wrap: balance;
}

p,
li {
	text-wrap: pretty;
}

/* ---------------------------------------------------------- 2. Brand mark  */

.u-brand {
	margin: 0;
}

.u-brand a,
.u-brand > span {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	letter-spacing: -0.035em;
	font-weight: 700;
}

.u-brand a:hover {
	text-decoration: none;
	color: var(--wp--preset--color--ink);
}

.u-brand a::before,
.u-brand > span::before {
	content: "";
	flex: 0 0 auto;
	width: 1.15em;
	height: 1.15em;
	background-color: var(--wp--preset--color--accent);
	-webkit-mask-image: var(--u-mark);
	mask-image: var(--u-mark);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	transition: transform var(--wp--custom--transition);
}

.u-brand a:hover::before {
	transform: translateY(-2px);
}

/* Ascending bars: the "up" in Upnuvo. */
:root {
	--u-mark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect x="3" y="19" width="6" height="10" rx="3"/><rect x="13" y="12" width="6" height="17" rx="3"/><rect x="23" y="3" width="6" height="26" rx="3"/></svg>');
}

/* On dark backgrounds the mark and wordmark both follow the text colour. */
.u-brand--invert a,
.u-brand--invert > span {
	color: #fff;
}

.u-brand--invert a::before,
.u-brand--invert > span::before {
	background-color: #fff;
}

/* -------------------------------------------------------- 3. Site header  */

.u-header {
	position: sticky;
	top: 0;
	z-index: 100;
	border-bottom: 1px solid transparent;
	transition: border-color var(--wp--custom--transition),
		box-shadow var(--wp--custom--transition);
}

/*
 * The frosted pane is a pseudo-element rather than the header itself: an element
 * with backdrop-filter becomes the containing block for fixed-position
 * descendants, which would trap the navigation block's mobile overlay inside the
 * header's box instead of letting it cover the viewport. The negative z-index
 * keeps the pane behind the header's own content while still sampling the page
 * scrolling underneath.
 */
.u-header::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba(255, 255, 255, 0.82);
	backdrop-filter: saturate(180%) blur(14px);
	-webkit-backdrop-filter: saturate(180%) blur(14px);
}

.u-header.is-stuck {
	border-bottom-color: var(--wp--preset--color--border);
	box-shadow: 0 1px 20px rgba(11, 21, 36, 0.05);
}

.u-header .wp-block-navigation {
	gap: clamp(1rem, 2vw, 2rem);
}

.u-header .wp-block-navigation-item__content {
	color: var(--wp--preset--color--body);
	padding-block: 0.35rem;
	transition: color var(--wp--custom--transition);
}

.u-header .wp-block-navigation-item__content:hover,
.u-header .current-menu-item > .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

/* Underline that grows from the left on hover. */
.u-header .wp-block-navigation-item:not(.has-child) .wp-block-navigation-item__content {
	position: relative;
}

.u-header .wp-block-navigation-item:not(.has-child) .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px;
	background: var(--wp--preset--color--accent);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--wp--custom--transition);
}

.u-header .wp-block-navigation-item:not(.has-child) .wp-block-navigation-item__content:hover::after {
	transform: scaleX(1);
}

/*
 * Mobile overlay menu.
 *
 * Core ships a complete layout for the open overlay, so the selectors below
 * repeat its chain where they have to outweigh it. Where core exposes a custom
 * property for a decision, setting that is preferred:
 * --navigation-layout-justification-setting is what pushes the items to the
 * right in the header bar, and would do the same here. Core copies the nav's
 * classes onto the list as well, so the list redeclares that property and has
 * to be given the overlay value too.
 *
 * The top padding lines the close button up with the menu button it replaces.
 */
.u-header .wp-block-navigation__responsive-container.is-menu-open,
.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	--navigation-layout-justification-setting: stretch;
}

.u-header .wp-block-navigation__responsive-container.is-menu-open {
	gap: 0.25rem;
	padding: 0.85rem clamp(1.25rem, 5vw, 3rem) var(--wp--preset--spacing--40);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
}

/*
 * Every wrapper between the overlay and the list has to stretch, otherwise the
 * list cannot fill the screen and the pair at its foot has nothing to sit on.
 */
.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close,
.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
}

.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	flex: 1 1 auto;
	width: 100%;
	padding-top: 3.5rem;
}

.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	flex: 1 1 auto;
	width: 100%;
}

.u-header .wp-block-navigation__responsive-container-close {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	/* Pulls the 44px tap target out so the icon itself sits on the gutter. */
	right: -10px;
	border-radius: var(--wp--custom--radius--sm);
	color: var(--wp--preset--color--ink);
	transition: background-color var(--wp--custom--transition);
}

.u-header .wp-block-navigation__responsive-container-close:hover {
	background: var(--wp--preset--color--surface);
}

.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	min-height: 44px;
	padding-block: 0.5rem;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 600;
	letter-spacing: -0.02em;
}

.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--accent);
}

/* The underline is a pointer affordance; it has no place on a touch menu. */
.u-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:not(.has-child) .wp-block-navigation-item__content::after {
	content: none;
}

/*
 * Contact and the call to action are in the menu for the overlay's benefit
 * only — the header bar shows them in its own right at desktop widths, where
 * the menu is inline. The buttons block is wrapped in a list item by core, so
 * that wrapper has to be hidden along with it or it leaves a gap behind.
 */
.wp-block-navigation-item.u-nav-overlay-only,
.wp-block-navigation-item:has( > .u-nav-overlay-only ),
.wp-block-buttons.u-nav-overlay-only {
	display: none;
}

.is-menu-open .wp-block-navigation-item.u-nav-overlay-only,
.is-menu-open .wp-block-navigation-item:has( > .u-nav-overlay-only ),
.is-menu-open .wp-block-buttons.u-nav-overlay-only {
	display: flex;
}

/* Both sit at the foot of the screen, away from the section links. */
.is-menu-open .wp-block-navigation-item.u-nav-overlay-only {
	margin-top: auto;
	padding-top: 1.1rem;
	border-top: 1px solid var(--wp--preset--color--border);
}

.u-header .wp-block-navigation__responsive-container.is-menu-open .u-nav-overlay-only .wp-block-navigation-item__content {
	color: var(--wp--preset--color--body);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 550;
}

.is-menu-open .wp-block-buttons.u-nav-overlay-only {
	width: 100%;
	margin-top: 0.9rem;
}

.is-menu-open .u-nav-overlay-only .wp-block-button,
.is-menu-open .u-nav-overlay-only .wp-block-button__link {
	width: 100%;
}

/*
 * The shared focus ring rounds its corners to 4px, which would square off a
 * pill button. Keep the ring, keep the shape.
 */
.is-menu-open .u-nav-overlay-only .wp-block-button__link:focus-visible {
	border-radius: var(--wp--custom--radius--pill);
}

/* -------------------------------------------------------- 4. Site footer  */

/*
 * The footer sets its own text colour rather than inheriting the light-theme
 * body colour, which would be almost unreadable on the dark background.
 */
.u-footer {
	color: rgba(255, 255, 255, 0.72);
}

.u-footer a {
	color: rgba(255, 255, 255, 0.72);
}

.u-footer a:hover {
	color: #fff;
	text-decoration: none;
}

.u-footer .wp-block-heading {
	color: rgba(255, 255, 255, 0.5);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.u-footer-nav {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.7rem;
}

.u-footer-legal {
	border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* --------------------------------------------- 5. Eyebrows and headings  */

/*
 * Block rather than flex, so that when the label wraps on a narrow screen the
 * leading rule stays attached to the first line instead of floating beside it.
 */
.u-eyebrow {
	display: block;
	margin: 0 0 0.4rem;
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 650;
	letter-spacing: 0.11em;
	line-height: 1.5;
	text-transform: uppercase;
}

.u-eyebrow::before {
	content: "";
	display: inline-block;
	width: 1.75rem;
	height: 2px;
	margin-right: 0.6rem;
	vertical-align: middle;
	border-radius: 2px;
	background: currentColor;
	opacity: 0.65;
}

.u-eyebrow--center {
	text-align: center;
}

.u-eyebrow--invert {
	color: #7ea3ff;
}

/* Lead paragraph under a section heading. */
.u-lead {
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.6;
	color: var(--wp--preset--color--body);
}

.u-measure {
	max-width: 62ch;
}

.u-measure--narrow {
	max-width: 48ch;
}

/*
 * Headings need their own measure: ch units scale with font size, so the value
 * that reads well for body copy is far too wide at display sizes.
 */
.u-measure-h {
	max-width: 22ch;
}

.u-center-measure {
	max-width: 62ch;
	margin-inline: auto;
	text-align: center;
}

/* Accent underline on a single word inside a heading. */
.u-mark-accent {
	color: var(--wp--preset--color--accent);
}

/*
 * A real text decoration rather than a positioned bar: the browser places it
 * against the baseline, which stays correct at every heading size and when the
 * line height is tighter than the font's own.
 */
.u-underline {
	text-decoration: underline;
	text-decoration-color: rgba(31, 94, 255, 0.34);
	text-decoration-thickness: 0.13em;
	text-underline-offset: 0.1em;
	text-decoration-skip-ink: none;
}

/* -------------------------------------------- 5b. Vertical rhythm  */

/*
 * Landing-page sections carry their own generous top and bottom padding, so
 * the default gap between them would only ever show up as a stripe of page
 * background between two coloured sections.
 */
.u-sections > * {
	margin-block-start: 0;
}

/*
 * The intro stack that opens every section: eyebrow, heading, lead paragraph,
 * then an optional list or button. The eyebrow labels the heading, so it sits
 * close to it; the lead is a separate thought and needs the room to read as
 * one. Kept here rather than as per-block spacing in the patterns so that the
 * rhythm stays identical across sections.
 */
.u-intro > * + * {
	margin-block-start: 1.5rem;
}

.u-intro > .u-eyebrow + * {
	margin-block-start: 0.85rem;
}

.u-intro > .wp-block-buttons,
.u-intro > .wp-block-list {
	margin-block-start: 2.25rem;
}

/* ------------------------------------------------------------- 6. Hero  */

.u-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

/* Looser than a section intro: the type is larger and it stands alone. */
.u-hero > * + * {
	margin-block-start: 1.75rem;
}

.u-hero > .u-eyebrow + * {
	margin-block-start: 1rem;
}

.u-hero > .wp-block-buttons {
	margin-block-start: 2.5rem;
}

.u-hero > .u-hero__meta {
	margin-block-start: 2rem;
}

/* Soft radial glows plus a faint grid, all drawn in CSS. */
.u-hero::before {
	content: "";
	position: absolute;
	inset: -20% -10% auto -10%;
	height: 130%;
	z-index: -2;
	background:
		radial-gradient(38rem 26rem at 72% 12%, rgba(31, 94, 255, 0.13), transparent 65%),
		radial-gradient(30rem 22rem at 12% 6%, rgba(10, 168, 143, 0.09), transparent 62%);
	pointer-events: none;
}

.u-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image:
		linear-gradient(to right, rgba(11, 21, 36, 0.045) 1px, transparent 1px),
		linear-gradient(to bottom, rgba(11, 21, 36, 0.045) 1px, transparent 1px);
	background-size: 68px 68px;
	mask-image: radial-gradient(72% 60% at 50% 22%, #000 30%, transparent 100%);
	-webkit-mask-image: radial-gradient(72% 60% at 50% 22%, #000 30%, transparent 100%);
	pointer-events: none;
}

.u-hero__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.85rem;
}

/* Small trust line below the hero buttons. Its top margin comes from the hero
   rhythm above, so only the other sides are reset here. */
.u-hero__meta {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.4rem 1.5rem;
	margin-block-end: 0;
	margin-inline: 0;
	padding: 0;
	list-style: none;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

.u-hero__meta li {
	display: flex;
	align-items: center;
	gap: 0.45rem;
}

.u-hero__meta li::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--wp--preset--color--teal);
	flex: 0 0 auto;
}

/* --------------------------------------------------------- 7. Cards etc  */

.u-grid {
	display: grid;
	gap: clamp(1rem, 2vw, 1.5rem);
}

/*
 * Pairs, used inside a half-width column rather than across the full page, so
 * the track minimum has to stay well under half of ~560px to hold two columns.
 */
.u-grid--2 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.u-grid--3 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}

.u-grid--4 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.u-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	padding: clamp(1.5rem, 2.4vw, 2rem);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	transition: transform var(--wp--custom--transition),
		box-shadow var(--wp--custom--transition),
		border-color var(--wp--custom--transition);
	height: 100%;
}

.u-card:hover {
	transform: translateY(-3px);
	border-color: rgba(31, 94, 255, 0.28);
	box-shadow: var(--wp--preset--shadow--lifted);
}

.u-card > :first-child {
	margin-top: 0;
}

.u-card > :last-child {
	margin-bottom: 0;
}

.u-card__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	font-weight: 650;
	letter-spacing: -0.018em;
	color: var(--wp--preset--color--ink);
}

.u-card__text {
	margin: 0;
	color: var(--wp--preset--color--body);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.65;
}

/* Icon tile at the top of a card, drawn with a CSS mask. */
.u-card__icon {
	width: 2.75rem;
	height: 2.75rem;
	display: grid;
	place-items: center;
	margin-bottom: 0.35rem;
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--accent-soft);
	color: var(--wp--preset--color--accent);
	font-size: 1.05rem;
	font-weight: 700;
	flex: 0 0 auto;
}

/*
 * Icons are stroke-only SVGs applied as CSS masks, so they inherit the tile's
 * colour and cost no extra requests. Add a new one by defining --u-icon.
 */
.u-card__icon::before {
	content: "";
	width: 1.4rem;
	height: 1.4rem;
	background-color: currentColor;
	-webkit-mask-image: var(--u-icon, none);
	mask-image: var(--u-icon, none);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.u-icon--strategy {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4"/><path d="M12 3v3M12 18v3M3 12h3M18 12h3"/></svg>');
}

.u-icon--design {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7.5 12 3l8 4.5-8 4.5z"/><path d="m4 12.5 8 4.5 8-4.5"/><path d="m4 17 8 4.5 8-4.5"/></svg>');
}

.u-icon--engineering {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m8 7-5 5 5 5"/><path d="m16 7 5 5-5 5"/><path d="m13.5 4-3 16"/></svg>');
}

.u-icon--ai {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3c.9 3.9 2.2 5.2 6 6-3.8.8-5.1 2.1-6 6-.9-3.9-2.2-5.2-6-6 3.8-.8 5.1-2.1 6-6z"/><path d="M18.5 15.5c.4 1.6.9 2.1 2.5 2.5-1.6.4-2.1.9-2.5 2.5-.4-1.6-.9-2.1-2.5-2.5 1.6-.4 2.1-.9 2.5-2.5z"/></svg>');
}

.u-icon--launch {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20V6"/><path d="m6 12 6-6 6 6"/><path d="M5 21h14"/></svg>');
}

.u-icon--team {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="8" r="3.2"/><path d="M3 20c0-3.3 2.7-5.5 6-5.5s6 2.2 6 5.5"/><path d="M16 5.2a3.2 3.2 0 0 1 0 6.1"/><path d="M18 14.9c2 .8 3 2.5 3 5.1"/></svg>');
}

.u-icon--sprint {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5V12l3.2 2.2"/></svg>');
}

.u-icon--price {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="18" height="12" rx="2.5"/><circle cx="12" cy="12" r="2.4"/><path d="M6.5 12h.01M17.5 12h.01"/></svg>');
}

.u-icon--focus {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8V5a2 2 0 0 1 2-2h3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M8 21H5a2 2 0 0 1-2-2v-3"/><circle cx="12" cy="12" r="2.6"/></svg>');
}

.u-icon--own {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7.5 3v5.5c0 4.4-3 8.1-7.5 9.5-4.5-1.4-7.5-5.1-7.5-9.5V6z"/><path d="m8.8 12 2.2 2.2 4.2-4.4"/></svg>');
}

.u-icon--docs {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M9 13h6M9 17h4"/></svg>');
}

.u-icon--agent {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="8" width="16" height="12" rx="3.2"/><path d="M12 4.5V8"/><circle cx="12" cy="3.2" r="1.2"/><path d="M9.5 13h.01M14.5 13h.01"/><path d="M9.8 16.6h4.4"/></svg>');
}

.u-icon--architecture {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="18" height="5" rx="1.6"/><rect x="3" y="15.5" width="18" height="5" rx="1.6"/><path d="M8 8.5v7M16 8.5v7"/></svg>');
}

.u-icon--eval {
	--u-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4v16h16"/><path d="m7.5 15.5 3.2-3.8 2.8 2.2 4.2-5.4"/></svg>');
}

.u-card--flat {
	background: var(--wp--preset--color--surface);
	border-color: transparent;
}

/*
 * A full-width card that closes a section: text on the left, one action on the
 * right. Overrides the column direction cards use by default, and wraps to a
 * stack once the two halves no longer fit side by side.
 */
.u-prompt {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.25rem 2.5rem;
}

.u-prompt__body {
	flex: 1 1 34rem;
	display: grid;
	gap: 0.5rem;
	max-width: 68ch;
}

.u-prompt .wp-block-buttons {
	flex: 0 0 auto;
}

.u-card--flat:hover {
	background: var(--wp--preset--color--base);
	border-color: var(--wp--preset--color--border);
}

/* Numbered process steps. */
.u-step {
	position: relative;
	padding-top: 1.4rem;
	border-top: 2px solid var(--wp--preset--color--border);
	transition: border-color var(--wp--custom--transition);
}

.u-step:hover {
	border-top-color: var(--wp--preset--color--accent);
}

.u-step__num {
	display: block;
	margin-bottom: 0.55rem;
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	letter-spacing: 0.08em;
}

/* Simple checked list used in prose columns. */
.u-checks {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.8rem;
}

.u-checks li {
	position: relative;
	padding-left: 2rem;
	color: var(--wp--preset--color--body);
}

.u-checks li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.15em;
	width: 1.25rem;
	height: 1.25rem;
	border-radius: 50%;
	background: var(--wp--preset--color--accent-soft);
}

.u-checks li::after {
	content: "";
	position: absolute;
	left: 0.4rem;
	top: 0.48em;
	width: 0.45rem;
	height: 0.25rem;
	border-left: 2px solid var(--wp--preset--color--accent);
	border-bottom: 2px solid var(--wp--preset--color--accent);
	transform: rotate(-45deg);
}

/* Tag pills for the capability list. */
.u-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.u-tags li {
	padding: 0.45rem 0.9rem;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--body);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 550;
	transition: color var(--wp--custom--transition),
		border-color var(--wp--custom--transition);
}

.u-tags li:hover {
	color: var(--wp--preset--color--accent);
	border-color: rgba(31, 94, 255, 0.35);
}

/* ------------------------------------------------------------- 8. Stats  */

.u-stats {
	display: grid;
	gap: clamp(1.25rem, 3vw, 2.5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}

.u-stat__value {
	display: block;
	font-size: clamp(2.25rem, 4.5vw, 3.25rem);
	font-weight: 680;
	line-height: 1;
	letter-spacing: -0.04em;
	color: var(--wp--preset--color--ink);
}

.u-stat__label {
	display: block;
	margin-top: 0.55rem;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45;
}

.u-panel .u-stat__value {
	color: #fff;
}

.u-panel .u-stat__label {
	color: rgba(255, 255, 255, 0.62);
}

/* -------------------------------------------------------- 9. Logo strip  */

.u-logos {
	--u-logo-height: 1.7rem;

	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.u-logos li {
	display: flex;
	align-items: center;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 650;
	letter-spacing: -0.02em;
	opacity: 0.55;
	filter: grayscale(1);
	transition: opacity var(--wp--custom--transition);
}

.u-logos li:hover {
	opacity: 0.85;
}

/*
 * Where we have a client's logo it stands in for their name. The logo is a
 * background rather than an image in the markup: the list stays a plain list
 * anyone can edit, and the marquee can measure its width before any file has
 * loaded.
 *
 * The name stays in the document as the item's only text alternative and is
 * pushed out of the clipped box instead. It has to be hidden from the list
 * item itself: the name is a bare text node, and wrapping it in an element to
 * carry a class would make the block invalid. The indent also takes the text
 * out of the item's intrinsic width, so the item measures as exactly the
 * logo and the marquee's spacing stays even.
 */
.u-logo:not([data-block]) {
	overflow: hidden;
	text-indent: -100em;
	white-space: nowrap;
}

/*
 * data-block is on the editor's copy of the item only. There the name has to
 * stay visible and clear of the logo, or the list becomes something you have
 * to edit blind.
 */
.u-logo[data-block] {
	gap: 0.6rem;
}

/*
 * Each logo needs its own rule because the proportions differ. The box is one
 * logo height multiplied by that logo's aspect ratio, so every mark comes out
 * the same height without being stretched.
 */
.u-logo::before {
	content: "";
	flex: 0 0 auto;
	height: var(--u-logo-height);
	width: calc(var(--u-logo-height) * var(--u-logo-ratio));
	background: var(--u-logo) center / contain no-repeat;
}

.u-logo--pllay {
	--u-logo: url("../images/clients/pllay.png");
	--u-logo-ratio: 3.38;
}

.u-logo--hcn {
	--u-logo: url("../images/clients/hcn.png");
	--u-logo-ratio: 7.75;
}

.u-logo--simera {
	--u-logo: url("../images/clients/simera.svg");
	--u-logo-ratio: 4.52;
}

.u-logo--winegrower {
	--u-logo: url("../images/clients/winegrower.png");
	--u-logo-ratio: 1;
}

.u-logo--savvly {
	--u-logo: url("../images/clients/savvly.svg");
	--u-logo-ratio: 5;
}

.u-logo--piop {
	--u-logo: url("../images/clients/piop.svg");
	--u-logo-ratio: 6.47;
}

.u-logo--granicus {
	--u-logo: url("../images/clients/granicus.svg");
	--u-logo-ratio: 4.86;
}

/*
 * The names scroll only once JavaScript has built the track and measured how
 * far one full set travels, because the distance depends on the rendered text
 * width. Until then — and whenever motion is reduced — the list above stays a
 * centred row that wraps, which is why none of the movement is styled on
 * .u-logos itself.
 */
.u-marquee.is-scrolling {
	overflow: hidden;
	/* Fades the names out at both edges instead of cutting them off. */
	mask-image: linear-gradient(
		to right,
		transparent,
		#000 8%,
		#000 92%,
		transparent
	);
}

.u-marquee__track {
	display: flex;
	align-items: center;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	width: max-content;
	animation: u-marquee var(--u-marquee-duration, 40s) linear infinite;
}

/* Let people read a name they recognise, and stop for keyboard users. */
.u-marquee:hover .u-marquee__track,
.u-marquee:focus-within .u-marquee__track {
	animation-play-state: paused;
}

.u-marquee__track .u-logos {
	flex: 0 0 auto;
	flex-wrap: nowrap;
	gap: clamp(1.5rem, 4vw, 3.5rem);
}

.u-marquee__track li {
	white-space: nowrap;
}

@keyframes u-marquee {
	to {
		transform: translateX(var(--u-marquee-shift, -50%));
	}
}

@media (prefers-reduced-motion: reduce) {
	.u-marquee__track {
		animation: none;
	}
}

/* ---------------------------------------------------- 10. Testimonials  */

.u-quotes {
	display: grid;
	gap: clamp(1rem, 2vw, 1.5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
	align-items: start;
}

.u-quote {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
	padding: clamp(1.5rem, 2.4vw, 2rem);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	height: 100%;
}

.u-quote__text {
	margin: 0;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.6;
}

.u-quote__text::before {
	content: "";
	display: block;
	width: 1.6rem;
	height: 1.6rem;
	margin-bottom: 0.85rem;
	background-color: var(--wp--preset--color--accent);
	opacity: 0.9;
	-webkit-mask-image: var(--u-quote-glyph);
	mask-image: var(--u-quote-glyph);
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

:root {
	--u-quote-glyph: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6.5C6.7 8 5 10.4 5 13.4c0 2.5 1.5 4.1 3.6 4.1 2 0 3.4-1.4 3.4-3.3 0-1.8-1.2-3.1-3-3.1-.3 0-.6 0-.8.1.4-1.4 1.5-2.6 3.2-3.5l-1.4-1.2zm9 0C15.7 8 14 10.4 14 13.4c0 2.5 1.5 4.1 3.6 4.1 2 0 3.4-1.4 3.4-3.3 0-1.8-1.2-3.1-3-3.1-.3 0-.6 0-.8.1.4-1.4 1.5-2.6 3.2-3.5l-1.4-1.2z"/></svg>');
}

.u-quote__author {
	margin: 0;
	margin-top: auto;
	padding-top: 0.35rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45;
	color: var(--wp--preset--color--muted);
}

.u-quote__author strong {
	display: block;
	color: var(--wp--preset--color--ink);
	font-weight: 620;
}

/* -------------------------------------------------------------- 11. FAQ  */

.u-faq {
	display: grid;
	gap: 0;
	border-top: 1px solid var(--wp--preset--color--border);
}

.u-faq__item {
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.u-faq__item summary {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1.5rem;
	padding: 1.35rem 0;
	cursor: pointer;
	list-style: none;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 600;
	letter-spacing: -0.015em;
	transition: color var(--wp--custom--transition);
}

.u-faq__item summary::-webkit-details-marker {
	display: none;
}

.u-faq__item summary:hover {
	color: var(--wp--preset--color--accent);
}

/* Plus sign that rotates into a minus when open. */
.u-faq__item summary::after {
	content: "";
	flex: 0 0 auto;
	width: 1.5rem;
	height: 1.5rem;
	margin-top: 0.15rem;
	border-radius: 50%;
	background: var(--wp--preset--color--accent-soft);
	background-image:
		linear-gradient(var(--wp--preset--color--accent), var(--wp--preset--color--accent)),
		linear-gradient(var(--wp--preset--color--accent), var(--wp--preset--color--accent));
	background-repeat: no-repeat;
	background-position: center;
	background-size: 0.7rem 2px, 2px 0.7rem;
	transition: transform var(--wp--custom--transition);
}

.u-faq__item[open] summary::after {
	transform: rotate(90deg);
	background-size: 0.7rem 2px, 0 0.7rem;
}

.u-faq__answer,
.u-faq__item > :not(summary) {
	margin: 0;
	padding: 0 0 1.5rem;
	max-width: 68ch;
	color: var(--wp--preset--color--body);
}

/* The details block ships with its own spacing that fights the row layout. */
.u-faq__item.wp-block-details {
	margin: 0;
}

/* --------------------------------------------------- 12. Dark panel/CTA  */

.u-panel {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--preset--color--contrast);
	color: rgba(255, 255, 255, 0.76);
}

.u-panel::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		radial-gradient(34rem 22rem at 88% 8%, rgba(31, 94, 255, 0.42), transparent 62%),
		radial-gradient(26rem 20rem at 6% 96%, rgba(10, 168, 143, 0.22), transparent 60%);
	pointer-events: none;
}

.u-panel :where(h1, h2, h3, h4, h5, h6) {
	color: #fff;
}

/* Accent blue does not have the contrast to be a link colour on dark navy. */
.u-panel a:not(.wp-block-button__link) {
	color: #fff;
	text-decoration: none;
}

.u-panel a:not(.wp-block-button__link):hover {
	color: #fff;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.u-panel--full {
	border-radius: 0;
}

.u-panel .u-lead {
	color: rgba(255, 255, 255, 0.74);
}

/* Contact rows in the closing CTA. */
.u-contact-list {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
	margin: 0;
	padding: 0;
	list-style: none;
}

.u-contact-list dt,
.u-contact-list__label {
	margin: 0 0 0.3rem;
	color: rgba(255, 255, 255, 0.5);
	font-size: var(--wp--preset--font-size--xx-small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.u-contact-list dd,
.u-contact-list__value {
	margin: 0;
	color: #fff;
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 550;
}

/* ------------------------------------------------------------ 13. Forms  */

.u-form {
	display: grid;
	gap: 1.1rem;
}

.u-field {
	display: grid;
	gap: 0.4rem;
}

.u-field > span,
.u-field > label {
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

/*
 * border-box is essential here, not cosmetic: inputs and textareas default to
 * content-box, so width:100% plus the padding and border would make every
 * control wider than its grid column and overlap the field beside it.
 */
.u-field input,
.u-field textarea,
.u-field select {
	box-sizing: border-box;
	width: 100%;
	padding: 0.85rem 1rem;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	transition: border-color var(--wp--custom--transition),
		box-shadow var(--wp--custom--transition);
}

.u-field input::placeholder,
.u-field textarea::placeholder {
	color: var(--wp--preset--color--muted);
}

.u-field input:focus,
.u-field textarea:focus,
.u-field select:focus {
	outline: none;
	border-color: var(--wp--preset--color--accent);
	box-shadow: var(--u-ring);
}

.u-field textarea {
	min-height: 9rem;
	resize: vertical;
}

.u-form__row {
	display: grid;
	gap: 1.1rem;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.u-form__note {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.55;
}

/* Consent checkbox sits inline rather than stacked. */
.u-field--check {
	grid-template-columns: auto 1fr;
	align-items: start;
	gap: 0.7rem;
}

.u-field--check input {
	width: 1.15rem;
	height: 1.15rem;
	margin-top: 0.15rem;
	accent-color: var(--wp--preset--color--accent);
}

.u-field--check span {
	font-weight: 400;
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.55;
	color: var(--wp--preset--color--body);
}

.u-field abbr {
	color: var(--wp--preset--color--accent);
	text-decoration: none;
	border: 0;
}

/* Kept in the layout for bots, removed from the accessibility tree. */
.u-honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.u-notice {
	margin: 0 0 1.25rem;
	padding: 1rem 1.15rem;
	border-radius: var(--wp--custom--radius--md);
	border: 1px solid transparent;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.55;
}

.u-notice:focus {
	outline: none;
}

.u-notice--ok {
	background: #e7f7f2;
	border-color: #a9e2d3;
	color: #0a5f4d;
}

.u-notice--error {
	background: #fdecec;
	border-color: #f5c2c2;
	color: #8c2020;
}

/* ---------------------------------------------------------- 14. Buttons  */

.wp-block-button__link {
	transition: background-color var(--wp--custom--transition),
		color var(--wp--custom--transition),
		border-color var(--wp--custom--transition),
		transform var(--wp--custom--transition);
}

.wp-block-button__link:hover {
	transform: translateY(-1px);
}

/* Outline style, registered in functions.php. */
.wp-block-button.is-style-u-outline .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border: 1px solid var(--wp--preset--color--border);
	box-shadow: none;
}

.wp-block-button.is-style-u-outline .wp-block-button__link:hover {
	background: var(--wp--preset--color--base);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--ink);
}

.u-panel .wp-block-button.is-style-u-outline .wp-block-button__link {
	color: #fff;
	border-color: rgba(255, 255, 255, 0.28);
}

.u-panel .wp-block-button.is-style-u-outline .wp-block-button__link:hover {
	background: rgba(255, 255, 255, 0.1);
	border-color: rgba(255, 255, 255, 0.6);
	color: #fff;
}

/* Text link with an arrow that nudges on hover. */
.wp-block-button.is-style-u-link .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--accent);
	padding: 0.5rem 0;
	border-radius: 4px;
}

.wp-block-button.is-style-u-link .wp-block-button__link::after {
	content: " \2192";
	display: inline-block;
	transition: transform var(--wp--custom--transition);
}

.wp-block-button.is-style-u-link .wp-block-button__link:hover {
	background: transparent;
	color: var(--wp--preset--color--accent-deep);
	transform: none;
}

.wp-block-button.is-style-u-link .wp-block-button__link:hover::after {
	transform: translateX(4px);
}

.u-panel .wp-block-button.is-style-u-link .wp-block-button__link {
	color: #8fb0ff;
}

/* --------------------------------------------- 15. Long-form and legal  */

.u-prose > * + * {
	margin-top: 1.1em;
}

.u-prose :where(h2) {
	margin-top: 2.5em;
	font-size: var(--wp--preset--font-size--xx-large);
}

.u-prose :where(h3) {
	margin-top: 1.8em;
}

.u-prose :where(ul, ol) {
	display: grid;
	gap: 0.5rem;
}

.u-prose :where(a) {
	text-decoration: underline;
	text-underline-offset: 2px;
}

.u-legal-meta {
	padding: 1rem 1.25rem;
	border-left: 3px solid var(--wp--preset--color--accent);
	background: var(--wp--preset--color--surface);
	border-radius: 0 var(--wp--custom--radius--sm) var(--wp--custom--radius--sm) 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

/* ------------------------------------------------- 16. Scroll reveal  */

/*
 * Reveal styles are scoped to the u-js class, which is set by an inline head
 * script and removed again by a failsafe timer. If scripts never finish, the
 * class disappears and every section is simply visible.
 */
.u-js .u-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 620ms cubic-bezier(0.2, 0.7, 0.3, 1),
		transform 620ms cubic-bezier(0.2, 0.7, 0.3, 1);
	will-change: opacity, transform;
}

.u-js .u-reveal.is-visible {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	.u-js .u-reveal {
		opacity: 1;
		transform: none;
	}
}

@media print {
	.u-header,
	.u-footer,
	.wp-block-button {
		display: none !important;
	}

	.u-panel {
		background: none;
		color: #000;
	}
}
