/*
 * The sharp public-site layer.
 *
 * Loads after Kadence's own styles and overrides them where the Aipxperts
 * direction differs. Consumes the custom properties defined in tokens.css.
 *
 * Scope note: the saved design system describes two radius languages. This file
 * is the sharp marketing one and applies site-wide on the public site. The soft
 * app-UI layer (8px buttons, 12px cards) is for dashboards and internal tools
 * and must never be mixed onto a marketing page.
 */

/* ---------------------------------------------------------------------------
 * 1. Shape: zero radius,
everywhere.
 * ------------------------------------------------------------------------ */

.wp-site-blocks .kb-row-layout-wrap,
.wp-site-blocks .kt-inside-inner-col,
.entry-content .kb-row-layout-wrap,
.entry-content .kt-inside-inner-col,
.aipx-block-header .kb-row-layout-wrap,
.aipx-block-footer .kb-row-layout-wrap,
.kb-button,
.kt-accordion-pane,
.kt-blocks-accordion-header,
.kt-tab-inner-content,
.kb-adv-form-field .kb-field,
.wp-block-image img{
	border-radius: 0 !important;
}

/* ---------------------------------------------------------------------------
 * 2. Type
 * ------------------------------------------------------------------------ */

body{
	font-family: var(--aipx-font-body);
	font-size: var(--aipx-body-md);
	line-height: var(--aipx-body-md-line);
	color: var(--aipx-text-body);
	background-color: var(--aipx-dark-bg);
}

h1,
h2,
h3,
h4,
h5,
.entry-title{
	font-family: var(--aipx-font-heading);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

/* Lato ships no true 500/600. Resolving to 700 avoids a synthesised weight. */
h1{ font-size: var(--aipx-h1-size); line-height: var(--aipx-h1-line); letter-spacing: var(--aipx-h1-track); }
h2{ font-size: var(--aipx-h2-size); line-height: var(--aipx-h2-line); letter-spacing: var(--aipx-h2-track); }
h3{ font-size: var(--aipx-h3-size); line-height: var(--aipx-h3-line); letter-spacing: var(--aipx-h3-track); }
h4{ font-size: var(--aipx-h4-size); line-height: var(--aipx-h4-line); }
h5{ font-size: var(--aipx-h5-size); line-height: var(--aipx-h5-line); }
h6{ font-size: var(--aipx-h6-size); line-height: var(--aipx-h6-line); font-weight: 400; }

/*
 * Hero vertical rhythm.
 *
 * Two things fight the design here. Kadence makes .kt-inside-inner-col a flex
 * column with justify-content:center, which pushes the stack down and leaves
 * dead space above the headline; and the design constrains the copy with a
 * two-column grid (1fr 1fr, 64px gap) rather than a max-width on the heading -
 * that half-width column is what sets the headline's wrap.
 *
 * So the stack is pinned to the top, every gap is set explicitly, and the column
 * is capped at half the container. Values below come from the design's own CSS.
 */
.aipx-hero .kt-inside-inner-col{
	display: flex !important;
	flex-direction: column !important;
	justify-content: flex-start !important;
	align-items: flex-start !important;
	row-gap: 0 !important;
	padding: 0 !important;
	max-width: calc((var(--aipx-container) - var(--aipx-space-16)) / 2);
}

/*
 * The hero sets its own vertical rhythm on the inner wrap, so it must not also
 * take the shared .aipx-section padding - the two stack and open a dead band
 * between the header and the headline.
 */
.aipx-hero.aipx-section{
	padding-top: 0;
	padding-bottom: 0;
}

/* Values below are taken verbatim from the design's own hero CSS. */
.aipx-hero > .kt-row-column-wrap{
	padding-top: 88px !important;
	padding-bottom: 84px !important;
}

.aipx-hero h1{
	font-weight: 900;
	font-size: clamp(40px, 5.4vw, 72px);
	line-height: 1.04;
	letter-spacing: -2px;
	margin: 0 0 24px !important;
	max-width: none;
}

.aipx-hero .aipx-hero-sub{
	font-size: var(--aipx-body-lg);
	line-height: var(--aipx-body-lg-line);
	color: var(--aipx-dark-text-body);
	margin: 0 0 40px !important;
	max-width: 64ch;
}

.aipx-hero .kb-button{
	margin: 0 !important;
}

@media (max-width: 1024px) {
.aipx-hero > .kt-row-column-wrap{
		padding-top: 64px !important;
		padding-bottom: 56px !important;
	}}

.aipx-hero .aipx-hero-sub strong{
	color: var(--aipx-dark-text-heading);
	font-weight: 500;
}

/*
 * The hero's decorative layer: the diagonal-line SVG from the design, plus two
 * soft red radial glows. Both are confined to the hero and sit behind the text.
 * The lines anchor to the right edge so the headline column stays clean.
 */
.aipx-hero{
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.aipx-hero::before{
	content: "";
	position: absolute;
	inset: 0 0 0 auto;
	width: 62%;
	background: url(../img/heroLines.svg) right center / cover no-repeat;
	opacity: 1;
	pointer-events: none;
	z-index: -2;
}

.aipx-hero::after{
	content: "";
	position: absolute;
	inset: 0;
	/*
	 * One bloom, upper right, over the waves. The reference keeps the left two
	 * thirds of the frame black, so the old second gradient at 12% 72% - which
	 * lit the bottom left corner - is gone.
	 */
	background:
		radial-gradient(52% 62% at 74% 2%, var(--aipx-dark-glow-strong), transparent 68%),
		radial-gradient(38% 46% at 96% 46%, var(--aipx-dark-glow), transparent 70%);
	pointer-events: none;
	z-index: -1;
}

/* Ratings row: real platform marks, faded until hover. Not a metrics panel. */
.aipx-hero-ratings{
	display: flex;
	align-items: center;
	gap: var(--aipx-space-8);
	flex-wrap: wrap;
	margin: 40px 0 0 !important;
}

.aipx-hero-rating{
	/* Anchors now, so the underline and link colour the theme gives every <a>
	   have to be turned off; the mark and the score carry their own colour. */
	text-decoration: none;
	color: inherit;
	display: inline-flex;
	align-items: center;
	gap: var(--aipx-space-2);
	opacity: .62;
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-hero-rating:hover{
	opacity: 1;
}

.aipx-hero-rating img{
	height: 22px;
	width: auto;
	display: block;
}

.aipx-hero-rating b{
	font-family: var(--aipx-font-heading);
	font-weight: 700;
	font-size: var(--aipx-body-sm);
	color: var(--aipx-dark-text-heading);
}

@media (max-width: 1024px) {
.aipx-hero h1{ max-width: 100%; }

/* The lines are a right-edge flourish; below the split they only muddy the copy. */
	.aipx-hero::before{ width: 100%; opacity: .35; }}

/* A red keyword span inside a heading. Used sparingly, one phrase per heading. */
.aipx-kw{
	color: var(--aipx-brand-500);
}

.aipx-dark .aipx-kw,
.aipx-hero .aipx-kw{
	color: var(--aipx-brand-glow);
}

/*
 * The CTA band is brand red, so a brand-red keyword disappears into it. The
 * headings were written with a highlighted phrase regardless - 43 of the 45
 * pages carrying the band have one - so the phrase takes the band's own ink
 * instead, which is the colour of its button.
 */
.aipx-ctaband .aipx-kw{
	color: var(--aipx-dark-bg);
}

/*
 * Links inside the band. Body links default to brand red, which on the brand
 * red band is invisible - the same failure the keyword highlight above had.
 * White with a rule under it reads as a link without fighting the ground.
 */
.aipx-ctaband a:not(.kb-button):not(.aipx-btn),
.aipx-ctaband .aipx-cta-sub a{
	color: #FFFFFF;
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	text-decoration-color: rgba(255, 255, 255, .55);
	transition: text-decoration-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-ctaband a:not(.kb-button):not(.aipx-btn):hover,
.aipx-ctaband .aipx-cta-sub a:hover{ text-decoration-color: #FFFFFF; }

/* ---------------------------------------------------------------------------
 * 3. The two grounds
 * ------------------------------------------------------------------------ */

.aipx-dark{
	background-color: var(--aipx-dark-bg);
	color: var(--aipx-dark-text-body);
}

.aipx-dark h1,
.aipx-dark h2,
.aipx-dark h3,
.aipx-dark h4,
.aipx-dark h5,
.aipx-dark h6{
	color: var(--aipx-dark-text-heading);
}

.aipx-dark p,
.aipx-dark li{
	color: var(--aipx-dark-text-body);
}

.aipx-light{
	background-color: var(--aipx-light-bg);
	color: var(--aipx-text-body);
}

/*
 * Kadence paints .content-bg on the post article even in unboxed mode, which
 * leaves a light band above and below full-bleed sections on a dark page. The
 * sections own their own grounds, so the article carries none.
 */
body.content-style-unboxed .site,
.entry.content-bg,
.entry-content-wrap,
#primary .content-container{
	background: transparent;
}

body{
	background-color: var(--aipx-dark-bg);
}

/*
 * Full-bleed sections must escape the content column entirely.
 *
 * 100vw includes the scrollbar, so a plain calc overhangs the viewport by its
 * width and only stays hidden because #wrapper clips. Kadence publishes the
 * measured gutter as --scrollbar-offset; subtracting it makes the edges land
 * exactly on the viewport.
 */
.entry-content > .alignfull{
	margin-left: calc(50% - 50vw + (var(--scrollbar-offset, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--scrollbar-offset, 0px) / 2));
	max-width: calc(100vw - var(--scrollbar-offset, 0px));
	width: auto;
}

/*
 * The header and footer are already full-bleed containers, so their rows need
 * no negative pull at all - Kadence's own alignfull maths pushed them a
 * scrollbar's width past the viewport.
 */
.aipx-block-header .alignfull,
.aipx-block-footer .alignfull{
	margin-left: 0 !important;
	margin-right: 0 !important;
	max-width: 100% !important;
	width: 100% !important;
}

/* ---------------------------------------------------------------------------
 * 4. Section rhythm and headings
 * ------------------------------------------------------------------------ */

.aipx-section{
	padding-top: var(--aipx-section-y-md);
	padding-bottom: var(--aipx-section-y-md);
}

/* ---------------------------------------------------------------------------
 * 5. Buttons
 * ------------------------------------------------------------------------ */

.aipx-btn{
	border-radius: 0;
	font-family: var(--aipx-font-body);
	font-weight: 500;
	letter-spacing: .3px;
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

/* On dark, the red button brightens on hover rather than darkening. */
.aipx-dark .aipx-btn-primary:hover,
.aipx-hero .aipx-btn-primary:hover{
	background-color: var(--aipx-brand-glow);
}

/*
 * Buttons render inline with a small trailing chevron. Without these the icon
 * inherits the button's font-size context and blows up to fill the button box.
 */
.kb-button.aipx-btn,
.aipx-hero .kb-button{
	display: inline-flex;
	align-items: center;
	gap: var(--aipx-space-2);
	width: auto;
	padding: 14px 28px;
	font-size: var(--aipx-body-md);
	line-height: 1.2;
}

.kb-button .kb-svg-icon-wrap,
.kb-button .kb-svg-icon-wrap svg{
	width: 18px;
	height: 18px;
	flex: 0 0 auto;
}


/* ---------------------------------------------------------------------------
 * 8. Accordions
 *
 * Rows open independently and close only when their own header is clicked, so
 * no rule here may force a sibling closed.
 * ------------------------------------------------------------------------ */

.aipx-accordion .kt-blocks-accordion-icon-trigger{
	transition: transform var(--aipx-duration-slow) var(--aipx-ease-standard);
}

.aipx-accordion .kt-blocks-accordion-header[aria-expanded="true"] .kt-blocks-accordion-icon-trigger{
	transform: rotate(90deg);
}

/* ---------------------------------------------------------------------------
 * 9. Stats count-up: digits red, the +/% suffix takes the heading colour.
 * ------------------------------------------------------------------------ */

/* ---------------------------------------------------------------------------
 * 10. Sticky header: light,
blurred,
floating over the dark page.
 * ------------------------------------------------------------------------ */

/*
 * Kadence styles the header through the #masthead ID (position:relative,
* z-index:11),
which outranks any class selector. The render function keeps
 * that ID for theme compatibility,
so sticky has to be forced here.
 */
.aipx-block-header,
header#masthead.aipx-block-header{
	position: sticky !important;
	top: 0;
	z-index: 200 !important;
}

.aipx-block-header .aipx-header-bar{
	min-height: var(--aipx-header-height);
	background-color: rgba(255, 254, 252, .82);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--aipx-border-subtle);
}

/* Sharp corners hold even in the light header, including the mega-menu panel. */
.aipx-block-header .kb-navigation ul.sub-menu{
	border-radius: 0 !important;
}

/*
 * Logo | nav | CTA.
 *
 * Kadence prints its own inline grid rule after this stylesheet and forces
 * three equal columns, which squeezes the nav to a third of the container and
 * wraps it onto a second line. The design is emphatic that navigation is one
 * line at desktop, so these three declarations are !important on purpose.
 */
.aipx-block-header .aipx-header-bar > .kt-row-column-wrap{
	display: grid !important;
	grid-template-columns: auto 1fr auto !important;
	gap: var(--aipx-space-6) !important;
	align-items: center;
	max-width: var(--aipx-container);
	margin: 0 auto;
	padding: 0 var(--aipx-space-6) !important;
	min-height: var(--aipx-header-height);
}

/*
 * Child combinators throughout. A descendant selector here also matches the
 * .kt-inside-inner-col wrappers nested inside the mega-menu panels, which lays
 * their stacked intro columns out horizontally and overlaps the text.
 */
.aipx-block-header .aipx-header-bar > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col{
	padding: 0 !important;
}

/* Nav sits right of centre, tight to the CTA, exactly as the design has it. */
.aipx-header-nav > .kt-inside-inner-col,
.aipx-header-cta > .kt-inside-inner-col{
	display: flex;
	flex-direction: row !important;
	justify-content: flex-end;
}

/* One line, never two. */
.aipx-block-header ul.kb-navigation{
	display: flex;
	flex-wrap: nowrap !important;
	align-items: center;
	margin: 0;
	padding: 0;
}

.aipx-block-header ul.kb-navigation > li{
	white-space: nowrap;
}

.aipx-block-header .custom-logo,
.aipx-block-header .wp-block-site-logo img{
	height: 30px;
	width: auto;
	max-width: none;
	display: block;
}

.aipx-block-header .wp-block-site-logo,
.aipx-block-header .wp-block-site-logo a{
	display: block;
	line-height: 0;
}

/* Nav labels are uppercase and lightly tracked, matching the design. */
.aipx-block-header .kb-nav-link-content{
	font-family: var(--aipx-font-body);
	font-size: var(--aipx-body-sm);
	font-weight: 500;
	letter-spacing: .08em;
	text-transform: uppercase !important;
	color: var(--aipx-text-heading);
	padding: 26px var(--aipx-space-3);
	transition: color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-block-header .kb-nav-link-content:hover,
.aipx-block-header .menu-item:hover > .kb-link-wrap > .kb-nav-link-content{
	color: var(--aipx-brand-500);
}

.aipx-block-header .kb-nav-dropdown-toggle-btn{
	color: var(--aipx-text-heading);
	padding-inline: 2px;
}

/*
 * Kadence ships .kb-nav-arrow-svg with align-self: center and then top: 0.125em,
 * a nudge sized for its own 1em arrow sitting beside 1em text. This header
 * overrides the arrow to a fixed 15px while the nudge stays keyed to the
 * button's 16px font size, so it resolved to 2px and pushed every dropdown
 * chevron below the centre of its label. align-self already centres it; the
 * offset just has to go.
 */
.aipx-block-header .kb-nav-dropdown-toggle-btn svg{
	top: 0;
	width: 15px;
	height: 15px;
	transition: transform var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-block-header .menu-item:hover > .kb-link-wrap > .kb-nav-dropdown-toggle-btn svg{
	transform: rotate(180deg);
}

/*
 * Mega panel. Kadence emits the panel content as children of the sub-menu <ul>,
 * so the list semantics are reset here rather than fought with.
 */
.aipx-block-header ul.sub-menu.mega-menu{
	display: block;
	list-style: none;
	margin: 0;
	padding: var(--aipx-space-8) var(--aipx-space-10);
	background-color: var(--aipx-light-bg);
	border-top: 1px solid var(--aipx-border-subtle);
	box-shadow: var(--aipx-shadow-glass);
	box-sizing: border-box;
}

/*
 * Align the panel to the page container, not to the nav item it hangs off.
 *
 * Kadence positions it absolutely with left:0 and a computed negative right,
 * which anchors it under the trigger and pushes a container-width panel off the
 * right of the viewport. The header is the positioned ancestor and spans the
 * full width, so centring inside it lands the panel exactly on the container.
 */
/*
 * Make the header itself the containing block for the mega panels.
 *
 * Kadence marks the nav <ul>,
the column inner,
the row wrap and the row itself
 * position:relative. The nearest of those - the <ul>,
only ~612px wide and
 * offset into the page - was resolving `left: 50%`,
so a centred panel landed
 * 63px right of the container and the full-width variant ran off screen.
 * Neutralising the chain inside the header (and nowhere else) lets the panels
 * centre on the header,
which spans the viewport.
 */
.aipx-block-header .kb-row-layout-wrap,
.aipx-block-header .kt-row-column-wrap,
.aipx-block-header .kt-inside-inner-col,
.aipx-block-header ul.kb-navigation,
.aipx-block-header li.kadence-menu-mega-enabled{
	position: static !important;
}

.aipx-block-header .kb-menu-mega-width-container > ul.sub-menu.mega-menu,
.aipx-block-header .kb-menu-mega-width-full > ul.sub-menu.mega-menu{
	left: 50% !important;
	right: auto !important;
	transform: translateX(-50%) !important;
	width: min(var(--aipx-container), calc(100vw - var(--aipx-space-12))) !important;
}

.aipx-mega,
.aipx-mega > .kt-row-column-wrap{
	max-width: 100% !important;
	width: 100%;
}

/*
 * Kill the row's default vertical padding inside a mega panel.
 *
 * Kadence emits `padding-top/bottom: var(--global-kb-row-default-top, 1.5rem)`
 * against the row's own ID selector, which stacked on top of the panel's own
 * padding and left a deep empty band above the first item. The panel padding is
 * the intended breathing room, so the row contributes none. !important is
 * required: an ID selector outranks this class.
 */
.aipx-mega > .kt-row-column-wrap{
	padding-top: 0 !important;
	padding-bottom: 0 !important;
}

.aipx-mega .kt-inside-inner-col{
	display: block !important;
	padding: 0 !important;
}

/* The design system sets mega panels at 32px padding; without it the first
   link sits hard against the panel edge. */
.aipx-block-header ul.sub-menu.mega-menu{
	padding: var(--aipx-space-8) !important;
}

/*
 * Link lists. One rule set serves every panel: the two category-rail panels and
 * the plain Company and Industries lists, which carry links and nothing else.
 */
.aipx-mega-links{
	margin: 0;
	padding: 0;
	list-style: none;
}

.aipx-mega-links li{
	margin: 0;
}

/*
 * Company and Industries are navigation, not page sections. They were carrying
 * an eyebrow, a headline, body copy, a second call to action and four invented
 * group titles between them; all of that is gone, and what is left is sized to
 * its own content rather than stretched across the container.
 */
/*
 * These two hang off their own trigger rather than centring on the header,
so
 * the item has to be a positioning context again. The header stylesheet pins
 * every mega-enabled item to static so the wide panels can centre on the page;
 * that is right for those and wrong for a content-width dropdown.
 */
.aipx-block-header li.kb-nav-link-nv-co,
.aipx-block-header li.kb-nav-link-nv-in{
	position: relative !important;
}

.aipx-block-header .kb-nav-link-nv-co > ul.sub-menu.mega-menu,
.aipx-block-header .kb-nav-link-nv-in > ul.sub-menu.mega-menu{
	transform: none !important;
	width: max-content !important;
	max-width: calc(100vw - var(--aipx-space-12)) !important;
	padding: var(--aipx-space-6) var(--aipx-space-8) !important;
}

.aipx-block-header .kb-nav-link-nv-co > ul.sub-menu.mega-menu{
	left: 0 !important;
	right: auto !important;
}

/* Industries is the last dropdown in the bar, so it opens leftward from its
   own right edge; anchored to the left it ran 65px past the viewport. */
.aipx-block-header .kb-nav-link-nv-in > ul.sub-menu.mega-menu{
	left: auto !important;
	right: 0 !important;
}

.aipx-mega-plain > .kt-row-column-wrap{
	display: block !important;
	gap: 0 !important;
}

.aipx-mega-plain .aipx-mega-links{
	display: grid;
	row-gap: var(--aipx-space-3);
	column-gap: var(--aipx-space-12);
	align-content: start;
}

.aipx-mega-plain-1col{ grid-template-columns: minmax(0, 1fr); }
.aipx-mega-plain-3col{ grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* ---------------------------------------------------------------------------
 * Services panel: category rail + detail pane
 *
 * Listing all 34 services at once ran the panel to roughly 700px. Here a left
 * rail of five categories drives the right pane, so the panel is only as tall
 * as the rail and one hover reaches any service. mega-menu.js does the
 * switching and the roving-tabindex keyboard handling.
 *
 * The reference design is a compact card, not a container-width band, so this
 * panel overrides the shared container sizing with its own width.
 * ------------------------------------------------------------------------ */
/*
 * The panel itself carries no padding: the divider has to run the full height
 * of the card,
so the inset lives on the two columns instead. With padding on
 * the panel the rule's border stopped short of both edges.
 */
/*
 * Services panel: a black category rail beside a white link viewport.
 *
 * The two grounds are the whole visual idea,
so the panel clips its own corners
 * and carries no padding; each side owns its inset. The rail is fixed: it never
 * moves,
scrolls or resizes,
and only its active marker changes. Everything that
 * animates on a category change happens inside the pane viewport,
which is why
 * that viewport is the clipping context rather than the panel.
 */
/*
 * Both split panels take the container width. The Services panel used to be
 * capped at 1020px while AI Services was not,
which made the same three-column
 * grid noticeably tighter on one of them for no reason a reader could see.
 */
.aipx-block-header .kb-nav-link-nv-sv > ul.sub-menu.mega-menu,
.aipx-block-header .kb-nav-link-nv-ai > ul.sub-menu.mega-menu{
	padding: 0 !important;
	overflow: hidden;
}

/*
 * Interaction bridge. The panel sits a few pixels below the header row, and a
 * pointer crossing that gap would otherwise leave both. The strip is invisible
 * and sits inside the panel's own box, so it costs no layout.
 */
.aipx-block-header .kb-nav-link-nv-sv > ul.sub-menu.mega-menu::before,
.aipx-block-header .kb-nav-link-nv-ai > ul.sub-menu.mega-menu::before{
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -22px;
	height: 22px;
}

.aipx-mega-split > .kt-row-column-wrap{
	grid-template-columns: 300px minmax(0, 1fr) !important;
	gap: 0 !important;
	/* stretch, not start: the rail's ground has to reach the bottom edge when
	   the pane beside it is taller. */
	align-items: stretch;
}

.aipx-mega-split .wp-block-kadence-column,
.aipx-mega-split .aipx-mega-rail > .kt-inside-inner-col,
.aipx-mega-split .aipx-mega-panes > .kt-inside-inner-col{
	height: 100%;
}

/* ---- left: fixed category rail, dark ground ---- */

.aipx-mega-split .aipx-mega-rail{
	background-color: var(--aipx-dark-bg);
}

.aipx-mega-split .aipx-mega-rail > .kt-inside-inner-col{
	padding: var(--aipx-space-6) 0 !important;
	background-color: var(--aipx-dark-bg);
}

.aipx-mega-rail-item{
	position: relative;
	margin: 0;
	/* The scale has no step 7; 24px both sides keeps the label clear of the
	   3px active marker without inventing a token. */
	padding: 13px var(--aipx-space-6);
	cursor: pointer;
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-sm);
	font-weight: 600;
	line-height: 1.4;
	color: var(--aipx-dark-text-body);
	/* Wrap rather than run past the edge: "Product Development & Engineering"
	   is the longest label and overflowed the rail. */
	overflow-wrap: break-word;
	transition: color var(--aipx-duration-base) var(--aipx-ease-standard),
	            background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

/*
 * The active marker is a red edge rule that scales in place. It is drawn on the
 * item rather than travelling between items: a single moving indicator would
 * read as movement in a rail that is meant to feel physically fixed.
 */
.aipx-mega-rail-item::before{
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 3px;
	background-color: var(--aipx-brand-500);
	transform: scaleY(0);
	transform-origin: center;
	transition: transform var(--aipx-duration-slow) var(--aipx-ease-out);
}

.aipx-mega-rail-item:hover{
	color: var(--aipx-dark-text-heading);
}

.aipx-mega-rail-item.is-active{
	color: var(--aipx-dark-text-heading);
	background-color: var(--aipx-dark-bg-raised);
}

.aipx-mega-rail-item.is-active::before{
	transform: scaleY(1);
}

.aipx-mega-rail-item:focus-visible{
	outline: 2px solid var(--aipx-brand-500);
	outline-offset: -2px;
}

/* ---- right: the white viewport content transitions through ---- */

/*
 * The clipping region,
and the containing block the panes position against.
 *
 * This lives on the column rather than on .kt-inside-inner-col because the
 * header stylesheet pins every .kt-inside-inner-col to `position: static
 * !important` - a deliberate rule that stops Kadence wrappers becoming
 * positioning contexts for the mega panels. The column is untouched by it.
 *
 * Height is written by the script per category and eased,
so a five-link
 * category does not leave a sixteen-link hole underneath it and the panel never
 * jumps. The floor stops the smallest category collapsing.
 */
.aipx-mega-split .aipx-mega-panes{
	position: relative;
	overflow: hidden;
	min-height: 232px;
	/*
	 * A ceiling on the panel. The script sizes the viewport to whichever pane is
	 * showing; without a cap the largest category dictates a panel taller than
	 * the window, and the menu stops being a menu. When a pane exceeds this the
	 * pane itself scrolls - see .aipx-mega-pane below.
	 */
	max-height: min(62vh, 560px);
	background-color: var(--aipx-surface);
	transition: height var(--aipx-duration-slow) var(--aipx-ease-standard);
}

.aipx-mega-split .aipx-mega-panes > .kt-inside-inner-col{
	padding: var(--aipx-space-8) !important;
	background-color: var(--aipx-surface);
}

/*
 * Panes stack in one box so an outgoing and an incoming pane can travel
 * together. Absolute rather than a display toggle: a pane that is display:none
 * cannot be measured or animated.
 */
.aipx-mega-pane{
	position: absolute;
	top: var(--aipx-space-8);
	left: var(--aipx-space-8);
	right: var(--aipx-space-8);
	display: grid;
	row-gap: var(--aipx-space-3);
	align-content: start;
	/*
	 * Only a pane that overflows the capped panel scrolls. Scroll chaining is
	 * left at its default on purpose: `contain` would swallow the wheel at the
	 * end of a pane and leave the reader unable to scroll the page from inside
	 * the menu, which is the exact complaint this section is meant to fix.
	 */
	max-height: calc(min(62vh, 560px) - 2 * var(--aipx-space-8));
	overflow-y: auto;
	scrollbar-width: thin;
	opacity: 0;
	/* Written by the script: +1 when the reader moves down the rail, -1 up. */
	transform: translateY(calc(var(--aipx-mega-dir, 1) * 14px));
	pointer-events: none;
	transition: opacity 320ms var(--aipx-ease-standard),
	            transform 320ms var(--aipx-ease-standard);
}

.aipx-mega-pane.is-active{
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

/* The outgoing pane travels the opposite way through the same viewport. */
.aipx-mega-pane.is-leaving{
	opacity: 0;
	transform: translateY(calc(var(--aipx-mega-dir, 1) * -14px));
}

.aipx-mega-pane-1col{ grid-template-columns: minmax(0, 1fr); }

.aipx-mega-pane-2col{
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: var(--aipx-space-8);
}

/*
 * Above 1280px the widest category goes to three columns, which is the
 * difference between a six-row pane and a four-row one. Below that the panel is
 * not wide enough for three readable descriptions, so it stays at two.
 */
@media (min-width: 1281px){
	.aipx-mega-pane-2col{
		grid-template-columns: repeat(3, minmax(0, 1fr));
		column-gap: var(--aipx-space-7);
	}
}

/*
 * No-JS fallback: the first pane shows until the script marks the container
 * ready. Without it the panel renders empty if mega-menu.js fails to load.
 * The .is-ready rules have to out-specify the fallback, hence the doubled class.
 */
.aipx-mega-panes .aipx-mega-pane:first-of-type{
	position: relative;
	top: auto;
	left: auto;
	right: auto;
	opacity: 1;
	transform: none;
	pointer-events: auto;
}

.aipx-mega-panes.is-ready .aipx-mega-pane:first-of-type{
	position: absolute;
	top: var(--aipx-space-8);
	left: var(--aipx-space-8);
	right: var(--aipx-space-8);
}

.aipx-mega-panes.is-ready .aipx-mega-pane:first-of-type:not(.is-active){
	opacity: 0;
	pointer-events: none;
}

/* ---- link treatment: dark type, red rule that grows and retracts ---- */

.aipx-mega-panes .aipx-mega-links a,
.aipx-mega-plain .aipx-mega-links a{
	position: relative;
	display: inline-block;
	line-height: 1.45;
	color: var(--aipx-text-heading);
	text-decoration: none;
	transition: color var(--aipx-duration-fast) var(--aipx-ease-standard);
}

/*
 * Two Kadence defaults have to be undone here, and both show up as bugs rather
 * than as styling.
 *
 * width: 100% on every mega-panel anchor stretched the link box to its whole
 * grid track, so the red rule ran the width of the column instead of sitting
 * under the words.
 *
 * white-space: nowrap is inherited from the sub-menu, so a label wider than its
 * track ran straight over the next column rather than wrapping.
 *
 * The long selector is deliberate: Kadence's rule scores 0,3,2, so it takes
 * four classes to outrank it without reaching for !important.
 */
.aipx-block-header .aipx-mega-split .aipx-mega-panes .aipx-mega-links a,
.aipx-block-header .aipx-mega.aipx-mega-plain .aipx-mega-links a{
	width: auto;
	max-width: 100%;
	white-space: normal;
}

/*
 * One origin serves both directions. Growing from scaleX(0) with the origin on
 * the left runs the rule left to right; shrinking back from scaleX(1) with the
 * same origin retracts it right to left, which is the behaviour asked for. A
 * second origin on exit would collapse it the wrong way.
 */
.aipx-mega-panes .aipx-mega-links a::after,
.aipx-mega-plain .aipx-mega-links a::after{
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -3px;
	height: 2px;
	background-color: var(--aipx-brand-500);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 280ms var(--aipx-ease-out);
}

.aipx-mega-panes .aipx-mega-links a:hover,
.aipx-mega-panes .aipx-mega-links a:focus-visible,
.aipx-mega-plain .aipx-mega-links a:hover,
.aipx-mega-plain .aipx-mega-links a:focus-visible{
	color: var(--aipx-brand-500);
}

.aipx-mega-panes .aipx-mega-links a:hover::after,
.aipx-mega-panes .aipx-mega-links a:focus-visible::after,
.aipx-mega-plain .aipx-mega-links a:hover::after,
.aipx-mega-plain .aipx-mega-links a:focus-visible::after{
	transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
.aipx-mega-pane,
.aipx-mega-split .aipx-mega-panes > .kt-inside-inner-col,
.aipx-mega-panes .aipx-mega-links a::after,
.aipx-mega-plain .aipx-mega-links a::after,
.aipx-mega-rail-item::before{
		transition-duration: 1ms;
	}}

/* Mega menu: restrained open and close, opacity and transform only. */
.aipx-block-header .menu-item-has-children > ul.sub-menu{
	transition: opacity 200ms var(--aipx-ease-out),
	            transform 200ms var(--aipx-ease-out);
}

@media (max-width: 1024px) {
/* This said `columns: 1`, the CSS multi-column property, which does nothing
	   to a grid - so the two-column base rule stayed in force inside the mobile
	   drawer, where there is no room for it. */
	.aipx-mega-links{ grid-template-columns: minmax(0, 1fr); }}

/* ---------------------------------------------------------------------------
 * 11. Footer
 * ------------------------------------------------------------------------ */

.aipx-block-footer{
	background-color: var(--aipx-footer-bg);
	color: var(--aipx-footer-text);
}

.aipx-block-footer h2,
.aipx-block-footer h3,
.aipx-block-footer h4,
.aipx-block-footer h5,
.aipx-block-footer h6{
	color: var(--aipx-dark-text-heading);
}

.aipx-block-footer,
.aipx-block-footer .kb-row-layout-wrap{
	background-color: var(--aipx-footer-bg) !important;
}

.aipx-block-footer p,
.aipx-block-footer li,
.aipx-block-footer a{
	color: var(--aipx-footer-text);
	text-decoration: none;
}

.aipx-block-footer a:hover{ color: var(--aipx-brand-glow); }

/*
 * Six stacked sections, each separated from the next by exactly one hairline
 * and never by internal dividers. Height comes from generous vertical padding
 * rather than larger type, which is what gives the block its near-viewport feel.
 */
.aipx-footer-section > .kt-row-column-wrap{
	padding-top: var(--aipx-space-12) !important;
	padding-bottom: var(--aipx-space-12) !important;
}

.aipx-footer-section + .aipx-footer-section > .kt-row-column-wrap{
	border-top: 1px solid var(--aipx-dark-border);
}

/* The closing row stays compact. */
.aipx-footer-copyrow > .kt-row-column-wrap{
	padding-top: var(--aipx-space-5) !important;
	padding-bottom: var(--aipx-space-5) !important;
}

/*
 * The bottom bar. Legal links and the copyright line used to be two full-width
 * rows stacked on top of each other, which gave the footer three closing rows
 * for what is one line of small print. They share a row now: copyright left,
 * links right, and the pair wraps to two centred lines only when the viewport
 * is too narrow to hold them side by side.
 */
.aipx-footer-copyrow .kadence-columnft-cc > .kt-inside-inner-col{
	display: flex;
	/*
	 * Stated, not inherited: Kadence prints its own
	 * `.kadence-columnft-cc > .kt-inside-inner-col{flex-direction:column}` into
	 * the page, so leaving this at the initial value puts the bar back into two
	 * stacked lines. The extra class here out-specifies that rule.
	 */
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--aipx-space-4) var(--aipx-space-8);
}

/* --- brand --- */
/* The footer mark is a core/image block,
which rewrites width and height into
   an inline style and fails block validation,
so the box is reserved here from
   the file's own 590x84 viewBox instead. */
.aipx-footer-logo img{
	height: 34px;
	width: auto;
	aspect-ratio: 590 / 84;
}

.aipx-footer-blurb{
	max-width: 34ch;
	margin: var(--aipx-space-5) 0 var(--aipx-space-6);
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-dark-text-muted);
}

.aipx-footer-social{
	display: flex;
	gap: var(--aipx-space-5);
	margin: 0;
}

/* Social marks and footer ratings are anchors now, so the theme's link colour
   and underline have to be cleared; the mark carries its own colour. */
.aipx-social,
.aipx-frating{
	text-decoration: none;
	color: inherit;
}

.aipx-social img{
	width: 18px;
	height: 18px;
	display: block;
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-social:hover img{ opacity: .65; }

.aipx-frating:hover,
.aipx-frating:focus-visible{ opacity: .72; }

/* --- review scores, right-aligned beside the brand --- */
.aipx-footer-ratings{
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: var(--aipx-space-4);
	margin: 0;
}

.aipx-frating{
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
	display: inline-flex;
	align-items: center;
	gap: var(--aipx-space-2);
	font-size: var(--aipx-body-sm);
}

.aipx-frating img{ height: 18px; width: auto; }
.aipx-frating-name{ font-weight: 700; color: var(--aipx-dark-text-heading); }
.aipx-frating-score{ font-family: var(--aipx-font-mono); color: var(--aipx-footer-text); }

/* --- nav columns --- */
.aipx-footer-coltitle{
	font-size: var(--aipx-body-sm);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: var(--aipx-dark-text-heading) !important;
	margin: 0 0 var(--aipx-space-5);
}

.aipx-footer-links{
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--aipx-body-sm);
}

.aipx-footer-links li{ margin-bottom: var(--aipx-space-4); }

/* --- offices: a sharp two-letter code chip beside the address --- */
.aipx-footer-office{
	display: flex;
	align-items: flex-start;
	gap: var(--aipx-space-4);
	margin: 0;
	font-size: var(--aipx-body-sm);
}

.aipx-cc{
	flex: 0 0 auto;
	padding: 4px 8px;
	background-color: var(--aipx-dark-surface);
	border: 1px solid var(--aipx-dark-border);
	font-family: var(--aipx-font-mono);
	font-size: var(--aipx-caption);
	letter-spacing: .06em;
	color: var(--aipx-dark-text-heading);
}

.aipx-office-body{ display: flex; flex-direction: column; gap: 6px; }
.aipx-office-country{ font-weight: 700; color: var(--aipx-dark-text-heading); }
.aipx-office-address{ color: var(--aipx-footer-text); }

/* --- contact row --- */
.aipx-footer-contacts{
	display: flex;
	justify-content: center;
	gap: var(--aipx-space-12);
	flex-wrap: wrap;
	margin: 0;
	font-size: var(--aipx-body-sm);
}

.aipx-fcontact b{ color: var(--aipx-dark-text-heading); margin-right: var(--aipx-space-2); }

/* --- legal and copyright --- */
.aipx-footer-legal{
	display: flex;
	/* Right-hand end of the bar; centred only once the bar has wrapped. */
	justify-content: flex-end;
	flex-wrap: wrap;
	gap: var(--aipx-space-6);
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--aipx-body-sm);
}

.aipx-footer-copy{
	margin: 0;
	text-align: left;
	font-size: var(--aipx-body-sm);
	color: var(--aipx-dark-text-muted);
}

@media (max-width: 1024px) {
.aipx-footer-ratings{ align-items: flex-start; }
.aipx-footer-contacts{ gap: var(--aipx-space-6); }

/*
	 * Kadence collapses every footer row to one column below its mobile
	 * breakpoint, which stacks 24 nav links and makes the footer taller than the
	 * page it closes. Two columns keeps it scannable; only the narrowest phones
	 * fall back to one.
	 */
	.aipx-footer-nav > .kt-row-column-wrap{
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
		row-gap: var(--aipx-space-10) !important;
	}

.aipx-footer-brand > .kt-row-column-wrap,
.aipx-footer-offices > .kt-row-column-wrap{
		grid-template-columns: minmax(0, 1fr) !important;
		row-gap: var(--aipx-space-8) !important;
	}

.aipx-footer-section > .kt-row-column-wrap{
		padding-top: var(--aipx-space-10) !important;
		padding-bottom: var(--aipx-space-10) !important;
	}}

/* Only the narrowest phones drop to one column; at 390 two still fit, and the
   two-column footer is roughly half the height to scroll past. */
@media (max-width: 359px){
	.aipx-footer-nav > .kt-row-column-wrap {
		grid-template-columns: minmax(0, 1fr) !important;
	}
}

/* ---------------------------------------------------------------------------
 * 12. Responsive collapse
 *
 * Declared explicitly for every multi-column layout rather than assumed.
 * ------------------------------------------------------------------------ */

@media (max-width: 1024px){
	h1 { font-size: 40px; line-height: 48px; }
	h2 { font-size: 34px; line-height: 42px; }
	h3 { font-size: 28px; line-height: 36px; }

	.aipx-section {
		padding-top: var(--aipx-section-y-sm);
		padding-bottom: var(--aipx-section-y-sm);
	}
}

@media (max-width: 640px) {
h1{ font-size: 32px; line-height: 40px; }
h2{ font-size: 27px; line-height: 35px; }
h3{ font-size: 23px; line-height: 31px; }}

/* ---------------------------------------------------------------------------
 * 13. Reduced motion
 *
 * The site is near-static already. This collapses the remainder, including the
 * count-up, which jumps straight to its target.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce){
	*,
	*::before,
	*::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ---------------------------------------------------------------------------
 * 14. Page sections
 *
 * Everything below styles the homepage sections. Each block mirrors the design
 * capture: sharp corners, hairline separation, and the single red fill-on-hover
 * interaction shared across every card and row.
 * ------------------------------------------------------------------------ */

/* ---------------------------------------------------------------------------
 * Stats band
 *
 * The design separates the figures with vertical hairlines only - there is no
 * rule above or below the band. The dividers run the full height of the row,
* which comes from padding on the columns rather than on the row.
 * ------------------------------------------------------------------------ */

/*
 * The stats band is a second row directly under its own section head,
so the
 * head's section padding would otherwise stack on top of the band's and push
 * the figures far below the intro. Collapse it where the two meet.
 */
.aipx-section:has(+ .aipx-stats){
	padding-bottom: 0;
}

.aipx-stats > .kt-row-column-wrap{
	border: 0;
	padding-top: 0 !important;
	padding-bottom: var(--aipx-space-20) !important;
}

.aipx-stats .kt-inside-inner-col{
	padding: 0 !important;
}

/*
 * The band is one server-rendered block now rather than a Kadence column per
 * figure, so the columns and dividers are laid out here instead of inherited
 * from the row. Auto-flow keeps a four, five or six figure set even.
 */
.aipx-statband{
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(0, 1fr);
}

.aipx-stat{
	/* Sized for six figures across the container, down from five. The band is
	   site-wide, so the cell has to hold "500+ Solutions Delivered" at the
	   narrower width without the label wrapping to three lines. */
	padding: var(--aipx-space-8) var(--aipx-space-4);
	min-height: 150px;
}

.aipx-stat + .aipx-stat{
	border-left: 1px solid var(--aipx-border-subtle);
}

.aipx-stat:first-child{
	padding-left: 0;
}

.aipx-stat-n{
	font-family: var(--aipx-font-heading);
	font-size: 44px;
	line-height: 1.1;
	font-weight: 700;
	color: var(--aipx-brand-500);
	margin: 0 0 var(--aipx-space-3);
	/* Reserves the line before the count-up runs, so nothing shifts. */
	min-height: 48px;
}

/* The suffix takes the heading colour rather than the figure's brand red. */
.aipx-stat-s{
	color: var(--aipx-text-heading);
}

.aipx-stat-l{
	font-family: var(--aipx-font-body);
	font-size: var(--aipx-body-sm);
	line-height: 1.45;
	color: var(--aipx-text-secondary);
	margin: 0;
}

/* --- Client logo wall: static and seamless. No hover, no links, no rules. --- */
.aipx-logowall .kt-inside-inner-col{
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--aipx-space-10);
	padding: 0 !important;
}

.aipx-logowall img{
	height: 34px;
	width: auto;
	max-width: 180px;
	object-fit: contain;
}

/* --- Case study cards --- */
.aipx-case-grid{
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--aipx-space-6);
}

/*
 * Reviews go three across rather than two. Three is what the sections ask for,
 * and at two the third card sat alone on its own row; auto-fit also keeps the
 * success stories page tidy where a section carries a dozen.
 */
.aipx-tst-grid{
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
	gap: var(--aipx-space-6);
	align-items: stretch;
}

.aipx-case-card{
	display: flex;
	flex-direction: column;
	background-color: var(--aipx-surface);
	border: 1px solid var(--aipx-border-subtle);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-case-media{
	display: block;
	line-height: 0;
}

.aipx-case-media img{
	width: 100%;
	height: auto;
	display: block;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

.aipx-case-body{
	padding: var(--aipx-space-6);
}

.aipx-case-cat{
	font-family: var(--aipx-font-mono);
	font-size: 11px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--aipx-brand-500);
	margin: 0 0 var(--aipx-space-3);
}

.aipx-case-title{
	font-size: var(--aipx-h5-size);
	line-height: 1.25;
	margin: 0 0 var(--aipx-space-3);
}

.aipx-case-title a,
.aipx-case-link{
	color: inherit;
	text-decoration: none;
}

.aipx-case-excerpt{
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-text-secondary);
	margin: 0 0 var(--aipx-space-5);
}

.aipx-case-link{
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: var(--aipx-body-sm);
	font-weight: 700;
	color: var(--aipx-brand-500);
}

/* The one hover language, applied to the whole card. */
.aipx-case-card:hover{
	background-color: var(--aipx-brand-500);
}

.aipx-case-card:hover .aipx-case-cat,
.aipx-case-card:hover .aipx-case-title,
.aipx-case-card:hover .aipx-case-title a,
.aipx-case-card:hover .aipx-case-excerpt,
.aipx-case-card:hover .aipx-case-link{
	color: #FFFFFF;
}

.aipx-chevron{
	width: 15px;
	height: 15px;
	flex: 0 0 auto;
}

/* --- Testimonial cards --- */
.aipx-tst-card{
	display: flex;
	flex-direction: column;
	background-color: var(--aipx-surface);
	border: 1px solid var(--aipx-border-subtle);
	padding: var(--aipx-space-8);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

/*
 * The same fill-on-hover every other card and row uses. The stars flip to white
 * with the rest of the text; the avatar inverts so the initial stays readable
 * against the red.
 */
.aipx-tst-card:hover{
	background-color: var(--aipx-brand-500);
	border-color: var(--aipx-brand-500);
}

.aipx-tst-card:hover .aipx-tst-quote,
.aipx-tst-card:hover .aipx-tst-stars,
.aipx-tst-card:hover .aipx-tst-meta b,
.aipx-tst-card:hover .aipx-tst-meta span{
	color: #FFFFFF;
}

.aipx-tst-card:hover .aipx-tst-avatar{
	background-color: #FFFFFF;
	color: var(--aipx-brand-600);
}

/*
 * Head row: where the review came from on the left, the score on the right.
 *
 * The platform mark carries most of the weight here. A quote with a Clutch or
 * GoodFirms logo above it reads as something a third party verified; the same
 * quote with only a name above it reads as copy we wrote about ourselves.
 */
.aipx-tst-head{
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--aipx-space-4);
	margin-bottom: var(--aipx-space-6);
	padding-bottom: var(--aipx-space-5);
	border-bottom: 1px solid var(--aipx-border-subtle);
}

.aipx-tst-src{
	display: flex;
	align-items: center;
	flex: none;
}

.aipx-tst-src img{
	width: auto;
	/* Each mark is a different shape, so they are sized to look equal weight
	   rather than to share one height. */
	height: 21px;
	object-fit: contain;
	/* The three marks are white artwork for the dark hero band; on the light
	   card they are flattened to black, the same treatment the client review
	   score band gives the same three files. */
	filter: brightness(0);
	opacity: .82;
}

.aipx-tst-src--clutch img{ height: 19px; }
.aipx-tst-src--goodfirms img{ height: 17px; }
.aipx-tst-src--upwork img{ height: 20px; }

.aipx-tst-stars{
	display: flex;
	gap: 3px;
	color: var(--aipx-brand-500);
	margin-bottom: var(--aipx-space-5);
}

/* Inside the head row the stars sit on the baseline of the mark, so the
   standalone bottom margin would push the rule away from the logo. */
.aipx-tst-head .aipx-tst-stars{
	margin-bottom: 0;
	flex: none;
}

/* The marks are full-colour artwork, so the red fill-on-hover would leave them
   sitting on a background they were never drawn for. Cards that carry one keep
   the surface and move the border instead. */
.aipx-tst-card.has-src:hover{
	background-color: var(--aipx-surface);
	border-color: var(--aipx-brand-500);
}

.aipx-tst-card.has-src:hover .aipx-tst-quote,
.aipx-tst-card.has-src:hover .aipx-tst-meta b{
	color: var(--aipx-text-heading);
}

.aipx-tst-card.has-src:hover .aipx-tst-stars{ color: var(--aipx-brand-500); }
.aipx-tst-card.has-src:hover .aipx-tst-meta span{ color: var(--aipx-text-muted); }

.aipx-tst-card.has-src:hover .aipx-tst-avatar{
	background-color: var(--aipx-brand-500);
	color: #FFFFFF;
}

/* The quote is the card's job; the author line is pinned to the bottom so a
   grid of cards with different quote lengths still lines up. */
.aipx-tst-card .aipx-tst-author{ margin-top: auto; }

/* Upwork cards are headed by the job title rather than a person, and a few of
   those run to three lines, which would push the card taller than its row. */
.aipx-tst-meta b{
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Two reviews on a service page, three on the success stories page: sized so
   the cards stay readable at either width rather than going narrow at three. */
.aipx-tst-grid{ grid-auto-rows: 1fr; }

.aipx-star{
	width: 17px;
	height: 17px;
}

.aipx-tst-quote{
	/* Down from body-lg: the cards are a third of the row now, not a half. */
	font-size: var(--aipx-body-md);
	line-height: 1.55;
	color: var(--aipx-text-heading);
	margin: 0 0 var(--aipx-space-8);
	border: 0;
	padding: 0;
	quotes: '"' '"';
	/*
	 * Clamped so every card in a row is the same height. The reviews run from
	 * 33 characters to 670; without this the short ones carry half a card of
	 * white space next to the long ones. Nine lines clears the 90th percentile,
	 * so only the three longest reviews are clipped at all.
	 */
	display: -webkit-box;
	-webkit-line-clamp: 7;
	line-clamp: 7;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/*
 * Quote sizing by length. The tier is set server-side from the character count,
 * because CSS cannot measure its own text. Thresholds come from the actual
 * spread of the 32 reviews: median 207, upper quartile 281.
 */
.aipx-tst-quote.is-short{
	font-size: clamp(20px, 1.6vw, 25px);
	line-height: 1.4;
	letter-spacing: -.01em;
	font-family: var(--aipx-font-heading);
	font-weight: 500;
	-webkit-line-clamp: 6;
	line-clamp: 6;
}

.aipx-tst-quote.is-mid{
	font-size: clamp(17px, 1.2vw, 19px);
	line-height: 1.5;
}

.aipx-tst-quote::before{ content: open-quote; }
.aipx-tst-quote::after{ content: close-quote; }

.aipx-tst-author{
	display: flex;
	align-items: center;
	gap: var(--aipx-space-3);
	margin-top: auto;
}

.aipx-tst-avatar{
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background-color: var(--aipx-brand-50);
	color: var(--aipx-brand-600);
	font-family: var(--aipx-font-heading);
	font-weight: 700;
	font-size: var(--aipx-body-sm);
	flex: 0 0 auto;
}

.aipx-tst-meta{
	display: flex;
	flex-direction: column;
	line-height: 1.35;
	font-size: var(--aipx-body-sm);
}

.aipx-tst-meta b{ color: var(--aipx-text-heading); }
.aipx-tst-meta span{ color: var(--aipx-text-muted); }

.aipx-empty{
	color: var(--aipx-text-muted);
	font-size: var(--aipx-body-sm);
}

/*
 * Section head with a trailing action ("See All Work"): heading and intro on
 * the left, button hard right and baseline-aligned with the intro, matching the
 * case-studies layout in the design.
 */
.aipx-head-action > .kt-row-column-wrap{
	align-items: end;
	/* The nested head row carries 24px of its own padding, so this lands the
	   head-to-cards gap on the design's ~56px rather than doubling it. */
	margin-bottom: var(--aipx-space-8);
}

/* The action column supplies the gap below this head, so the intro drops its
   own margin. Its heading keeps the same 20px as every other section. */
.aipx-head-action .aipx-sec-sub{
	margin-bottom: 0 !important;
}

.aipx-head-action h2{
	margin-bottom: var(--aipx-space-5) !important;
}

.aipx-head-action-col > .kt-inside-inner-col{
	display: flex !important;
	flex-direction: row !important;
	justify-content: flex-end;
	align-items: flex-end;
	padding: 0 !important;
}

@media (max-width: 1024px) {
.aipx-head-action-col > .kt-inside-inner-col{
		justify-content: flex-start;
		margin-top: var(--aipx-space-6);
	}}

.aipx-head-action .aipx-btn-ghost{
	border: 1px solid var(--aipx-border);
	background: transparent;
	color: var(--aipx-text-heading);
}

.aipx-head-action .aipx-btn-ghost:hover{
	background-color: var(--aipx-brand-500);
	border-color: var(--aipx-brand-500);
	color: #FFFFFF;
}

@media (max-width: 1024px) {
.aipx-case-grid,
.aipx-tst-grid{ grid-template-columns: minmax(0, 1fr); }
.aipx-stat + .aipx-stat{ border-left: 0; }}

/* ---------------------------------------------------------------------------
 * 15. Section intro copy
 * ------------------------------------------------------------------------ */

/*
 * Kadence leaves a column's inner wrapper as a flex ROW unless a vertical
 * alignment is set on that column,
so section children size to their content
 * instead of filling the container - a logo strip ends up bunched at the left
 * rather than spread across the row. Force the stack,
except in the hero,
which
 * sets its own alignment.
 */
.aipx-section:not(.aipx-hero) > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col{
	flex-direction: column !important;
	align-items: stretch !important;
	/* Kadence adds a 40px row-gap here, which stacks on top of every margin set
	   below and doubles the spacing. Margins are the single source of rhythm. */
	row-gap: 0 !important;
}

.aipx-sec-sub{
	font-size: var(--aipx-body-lg);
	line-height: var(--aipx-body-lg-line);
	max-width: 56ch;
	margin: 0 0 var(--aipx-space-12) !important;
}

.aipx-dark .aipx-sec-sub{ color: var(--aipx-dark-text-body); }
.aipx-light .aipx-sec-sub{ color: var(--aipx-text-secondary); }

/*
 * Section headings wrap only past half the container, per the design system.
 *
 * Scoped to the section's own head: card titles inside loops are also <h2>, and
 * an unscoped rule caps them at half their card, which forced blog headlines to
 * wrap after two or three words.
 */
.aipx-section > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col > h2{
	max-width: 50%;
	margin: 0 0 var(--aipx-space-5);
}

@media (max-width: 1024px) {
.aipx-section > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col > h2{
		max-width: 100%;
	}}

@media (max-width: 1024px) {
.aipx-section h2{ max-width: 100%; }}

/* ---------------------------------------------------------------------------
 * 16. Client logo wall - static and seamless, per the design's own note.
 * ------------------------------------------------------------------------ */

/*
 * Four to five wordmarks spread edge to edge across the container via flexbox,
* all normalised to one height regardless of source proportions. No hover,
no
 * links,
no cards,
no rules between them.
 */
.aipx-logowall-inner{
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--aipx-space-10);
	width: 100%;
	margin: 0;
}

.aipx-logowall-inner img{
	height: 34px;
	width: auto;
	max-width: 190px;
	object-fit: contain;
	flex: 0 0 auto;
}

@media (max-width: 1024px) {
.aipx-logowall-inner{
		justify-content: flex-start;
		gap: var(--aipx-space-8);
	}
.aipx-logowall-inner img{ height: 26px; }}

/* ---------------------------------------------------------------------------
 * 17. Vertical service lists
 *
 * One component for all three: services, AI and industries. A scrolling column
 * on the left, the selected row boxed and red-edged, the detail panel on the
 * right. Every row keeps the same type size - the selected one is marked by
 * weight, colour and the panel, never by growing, which used to push the
 * longest labels past the column edge.
 * ------------------------------------------------------------------------ */

/* Kadence ships its own flex layout for kt-tabs-layout-vtabs; this replaces it. */
.aipx-vtabs .kt-tabs-wrap{
	display: grid !important;
	grid-template-columns: minmax(0, 440px) minmax(0, 1fr) !important;
	gap: var(--aipx-space-10);
	align-items: start;
}

/*
 * The content wrapper also holds the mobile accordion headers. They must be
 * hidden beside the label column - but ONLY there. Hiding them at every width
 * left mobile with no way to reach any row but the first, since the label
 * column is itself hidden once Kadence switches to accordion mode.
 */
@media (min-width: 768px){
	.aipx-vtabs .kt-tabs-content-wrap > .kt-title-item {
		display: none;
	}
}

/* Both grid children must fill their track; Kadence sizes them to content. */
.aipx-vtabs .kt-tabs-title-list,
.aipx-vtabs .kt-tabs-content-wrap{
	width: 100% !important;
	max-width: none !important;
	flex: none !important;
}

.aipx-vtabs .kt-tabs-title-list{
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
}

/*
 * Tablet and up. Below 768 Kadence swaps to its own accordion, which needs the
 * column geometry off entirely.
 */
@media (min-width: 768px){
	.aipx-vtabs .kt-tabs-title-list {
		/* Kadence's list is a flex column. Left as flex the rows shrink to fit
		   the capped height instead of overflowing, so nothing ever scrolls and
		   a twenty-one item list squashes into the space meant for six. */
		display: block !important;
		max-height: 420px;
		overflow-y: auto;
		/* Setting only overflow-y computes overflow-x to auto as well, which put a
		   sideways scrollbar under the longest labels. Labels wrap instead. */
		overflow-x: hidden;
		/* Reserve the scrollbar track in every list, so the six-item column is
		   exactly as wide as the twenty-one item one. */
		scrollbar-gutter: stable;
		overscroll-behavior: contain;
		scrollbar-width: thin;
		scrollbar-color: rgba(255, 255, 255, .18) transparent;
		/* Rows leave the column rather than being cut off at the edge. */
		-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 5%, #000 95%, transparent 100%);
		        mask-image: linear-gradient(to bottom, transparent 0%, #000 5%, #000 95%, transparent 100%);
	}

	.aipx-vtabs .kt-tabs-title-list::-webkit-scrollbar { width: 3px; }
	.aipx-vtabs .kt-tabs-title-list::-webkit-scrollbar-track { background: transparent; }
	.aipx-vtabs .kt-tabs-title-list::-webkit-scrollbar-thumb {
		background: rgba(255, 255, 255, .18);
	}

	/* Every row reserves the selected row's border, so selecting one shifts
	   nothing: only the colours change. */
	.aipx-vtabs .kt-tabs-title-list li {
		border: 1px solid transparent;
		border-left: 3px solid transparent;
	}

	.aipx-vtabs .kt-tabs-title-list li.kt-tab-title-active {
		background: rgba(255, 255, 255, .06);
		-webkit-backdrop-filter: blur(14px) saturate(140%);
		        backdrop-filter: blur(14px) saturate(140%);
		border-color: rgba(255, 255, 255, .13);
		border-left-color: var(--aipx-brand-500);
	}
}

/*
 * Kadence sets this row padding through the block's own ID selector, so it has
 * to be forced. Labels wrap rather than truncate - the longest run past 300px.
 */
.aipx-vtabs .kt-tabs-title-list li a,
.aipx-vtabs .kt-title-item a{
	display: block !important;
	width: 100%;
	/* 22px of clearance past the 3px rule, so no label sits against it. */
	padding: 12px var(--aipx-space-6) 12px 22px !important;
	font-family: var(--aipx-font-heading);
	font-size: 18px !important;
	font-weight: 600 !important;
	letter-spacing: -0.2px;
	line-height: 1.35;
	color: var(--aipx-dark-text-heading) !important;
	background: transparent !important;
	border: 0 !important;
	opacity: .62;
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-vtabs .kt-tabs-title-list li a:hover{ opacity: 1; }

.aipx-vtabs .kt-tabs-title-list li.kt-tab-title-active a{
	font-weight: 700 !important;
	opacity: 1;
}

/*
 * Base panel styling. This has to sit ABOVE the tablet and mobile blocks that
 * follow: media queries add no specificity, so while these rules came after
 * them they silently won, and the tablet padding, min-height and heading size
 * never applied between 768 and 1024px.
 */
.aipx-vtabs .kt-tab-inner-content{
	background-color: var(--aipx-dark-surface);
	border: 1px solid var(--aipx-dark-border);
	padding: var(--aipx-space-10);
	min-height: 320px;
}

.aipx-vtabs .kt-tab-inner-content h3{
	color: var(--aipx-dark-text-heading);
	margin: 0 0 var(--aipx-space-5);
	font-size: var(--aipx-h4-size);
}


/*
 * Tablet: the same split, but a 440px label column would leave the panel too
 * narrow to read, so the column gives ground and the gap tightens.
 */
@media (min-width: 768px) and (max-width: 1024px){
	/* Proportional, not fixed: a 300px column leaves only ~300px of text in the
	   panel at 768, and the copy runs to five hundred pixels tall. */
	.aipx-vtabs .kt-tabs-wrap {
		grid-template-columns: minmax(0, 32%) minmax(0, 1fr) !important;
		gap: var(--aipx-space-6);
	}

	.aipx-vtabs .kt-tabs-title-list li a {
		font-size: 16px !important;
		padding: 10px var(--aipx-space-4) 10px 18px !important;
	}

	.aipx-vtabs .kt-tab-inner-content {
		padding: var(--aipx-space-8);
		min-height: 0;
	}

	.aipx-vtabs .kt-tab-inner-content h3 { font-size: var(--aipx-h5-size); }
}

/*
 * Mobile: Kadence's accordion. Each label becomes its own header with the panel
 * under it, so the column treatment has to come off completely.
 */
@media (max-width: 767px){
	.aipx-vtabs .kt-tabs-title-list li a {
		padding: var(--aipx-space-4) var(--aipx-space-5) !important;
		border-left: 3px solid transparent !important;
	}

	.aipx-vtabs .kt-tabs-title-list li.kt-tab-title-active a {
		background-color: var(--aipx-dark-surface) !important;
		border-left-color: var(--aipx-brand-500) !important;
	}
}

.aipx-tab-body{
	color: var(--aipx-dark-text-body);
	font-size: var(--aipx-body-md);
	line-height: 1.65;
	max-width: 60ch;
	margin: 0;
}

.aipx-chips{
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: var(--aipx-space-4);
	margin: 0;
}

/*
 * Icon then label, left-aligned. The icons are Simple Icons recoloured to the
 * heading tone and self-hosted, so no CDN request and no invert filter at
 * render time. A technology without an icon gets the red square the design
 * uses for that case.
 */
.aipx-chip{
	display: flex;
	align-items: center;
	gap: var(--aipx-space-2);
	padding: var(--aipx-space-3) var(--aipx-space-4);
	font-size: var(--aipx-body-sm);
	line-height: 1.2;
	color: var(--aipx-dark-text-body);
	background-color: var(--aipx-dark-surface);
	border: 1px solid var(--aipx-dark-border);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-chip img{
	width: 18px;
	height: 18px;
	flex: none;
	display: block;
}

.aipx-chip:hover{
	background-color: var(--aipx-brand-500);
	border-color: var(--aipx-brand-500);
	color: #FFFFFF;
}

@media (max-width: 1024px) {
.aipx-chips{ grid-template-columns: repeat(3, minmax(0, 1fr)); }}

@media (max-width: 767px) {
.aipx-vtabs .kt-tabs-wrap,
.aipx-vtabs.kt-tabs-wrap{ grid-template-columns: minmax(0, 1fr) !important; }}

/* ---------------------------------------------------------------------------
 * 19. Accordions
 *
 * One physics for all three (industries, compliance, FAQ): the header fills red
 * when open or hovered, the panel animates on max-height, and rows never force
 * each other closed.
 * ------------------------------------------------------------------------ */

.aipx-accordion .kt-accordion-panel-inner{
	transition: max-height var(--aipx-duration-slow) var(--aipx-ease-standard);
}

.aipx-accordion .kt-blocks-accordion-header{
	display: flex;
	align-items: center;
	gap: var(--aipx-space-3);
	width: 100%;
	padding: var(--aipx-space-5) var(--aipx-space-6);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h6-size);
	font-weight: 700;
	text-align: left;
	border: 1px solid transparent;
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-accordion .kt-accordion-pane{
	margin-bottom: var(--aipx-space-3);
}

/*
 * An open row is one continuous box: the header keeps its side and top edges,
 * drops its bottom edge, and the panel picks up from there. Kadence draws its
 * own panel border which stopped short of the header and left the box open at
 * the top, so both sides are declared here explicitly.
 */
.aipx-accordion .kt-blocks-accordion-header[aria-expanded="true"]{
	border-bottom-color: transparent !important;
}

.aipx-accordion .kt-accordion-panel{
	border: 0 !important;
}

/* FAQ rows on the light ground. */
.aipx-faq-acc .kt-blocks-accordion-header{
	background-color: transparent;
	border-color: var(--aipx-border-subtle);
	color: var(--aipx-text-heading);
}

/*
 * The two light accordions behave differently in the design.
 *
 * Trust & Compliance fills brand-red on hover and while open, as the design
 * system specifies for that block. The FAQ does not: an open question stays on
 * the light ground and the whole row is simply outlined, so long answers are
 * comfortable to read. Both still fill red on hover.
 */
.aipx-faq-acc .kt-blocks-accordion-header:hover{
	background-color: var(--aipx-brand-500) !important;
	border-color: var(--aipx-brand-500) !important;
	color: #FFFFFF !important;
}

.aipx-faq-acc .kt-blocks-accordion-header[aria-expanded="true"]{
	background-color: transparent !important;
	border-color: var(--aipx-text-heading) !important;
	color: var(--aipx-text-heading) !important;
}

/* Each panel continues its own header's edge colour, so the open row reads as
   one box rather than stepping between two borders. */
.aipx-faq-acc .kt-accordion-panel-inner{
	padding: var(--aipx-space-6);
	background-color: var(--aipx-surface);
	border-top: 0 !important;
}

.aipx-faq-acc .kt-accordion-panel-inner{
	border: 1px solid var(--aipx-text-heading) !important;
	border-top: 0 !important;
}

.aipx-faq-answer{
	color: var(--aipx-text-secondary);
	font-size: var(--aipx-body-sm);
	line-height: 1.65;
	margin: 0 0 var(--aipx-space-5);
	max-width: 70ch;
}

.aipx-faq-answer{ margin-bottom: 0; }

/* ---------------------------------------------------------------------------
 * 20. Red CTA band.
 *
 * Both CTAs now share one shape - copy left, button right, full container width
 * - so the band is no longer a centred exception. Layout lives with the CTA box
 * rules further down; only the red-ground colours are set here.
 * ------------------------------------------------------------------------ */

.aipx-ctaband h2{
	color: #FFFFFF;
	max-width: 34ch;
	margin: 0 0 var(--aipx-space-3);
	font-size: var(--aipx-h4-size);
}

.aipx-cta-sub{
	color: rgba(255, 255, 255, .88);
	max-width: 68ch;
	margin: 0;
	font-size: var(--aipx-body-md);
}

.aipx-btn-black{
	background-color: var(--aipx-dark-bg) !important;
	color: #FFFFFF !important;
}

.aipx-btn-black:hover{
	background-color: #000000 !important;
}

/* ---------------------------------------------------------------------------
 * 21. Awards - a seamless row list, bounded top and bottom only.
 * ------------------------------------------------------------------------ */

.aipx-awards .aipx-award-row{
	display: grid;
	grid-template-columns: 90px minmax(0, auto) minmax(0, 1fr);
	align-items: baseline;
	gap: var(--aipx-space-6);
	margin: 0;
	padding: var(--aipx-space-6);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-awards .aipx-award-row:first-of-type{ border-top: 1px solid var(--aipx-border-subtle); }

.aipx-award-year{
	font-family: var(--aipx-font-mono);
	font-size: var(--aipx-body-sm);
	color: var(--aipx-text-muted);
	letter-spacing: .06em;
}

.aipx-award-title{
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h6-size);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

.aipx-award-desc{
	font-size: var(--aipx-body-sm);
	color: var(--aipx-text-muted);
}

.aipx-awards .aipx-award-row:hover{ background-color: var(--aipx-brand-500); }

.aipx-awards .aipx-award-row:hover .aipx-award-year,
.aipx-awards .aipx-award-row:hover .aipx-award-title,
.aipx-awards .aipx-award-row:hover .aipx-award-desc{ color: #FFFFFF; }

/* ---------------------------------------------------------------------------
 * 22. Technology ecosystem grid
 * ------------------------------------------------------------------------ */

.aipx-eco-grid{
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: var(--aipx-space-12) var(--aipx-space-8);
	align-items: center;
	margin: 0;
}

.aipx-eco{
	display: flex;
	align-items: center;
	justify-content: center;
}

.aipx-eco img{
	max-height: 34px;
	max-width: 130px;
	width: auto;
	height: auto;
	object-fit: contain;
	opacity: .82;
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-eco img:hover{ opacity: 1; }

@media (max-width: 1024px) {
.aipx-eco-grid{ grid-template-columns: repeat(3, minmax(0, 1fr)); }}

/* ---------------------------------------------------------------------------
 * 23. FAQ split: project form beside the question list
 * ------------------------------------------------------------------------ */

.aipx-faq-split > .kt-row-column-wrap{
	display: grid !important;
	grid-template-columns: minmax(0, 470px) minmax(0, 1fr) !important;
	gap: var(--aipx-space-10) !important;
	align-items: start;
}

.aipx-faq-formcol .kt-inside-inner-col{
	background-color: var(--aipx-brand-500);
	padding: var(--aipx-space-8) !important;
}

.aipx-form-title{ color: #FFFFFF !important; margin: 0 0 var(--aipx-space-3); font-size: var(--aipx-h5-size); }
.aipx-form-sub{ color: rgba(255, 255, 255, .9); font-size: var(--aipx-body-sm); margin: 0 0 var(--aipx-space-6); }

/*
 * Field grid. Four tracks so a pair can sit half-and-half, and the dialling
 * code can take a narrow track beside the number without a nested row.
 */
.aipx-faq-formcol .kb-advanced-form{
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	column-gap: var(--aipx-space-3);
	row-gap: var(--aipx-space-4);
	align-items: end;
}

/* A half-width field spans three of six; the dialling code takes one track
   beside a two-track number so the pair together equals one half. */
.aipx-f-half{ grid-column: span 3; }
.aipx-f-dial{ grid-column: span 1; }
.aipx-f-phone{ grid-column: span 2; }
.aipx-f-full,
.aipx-faq-formcol .kb-submit-field{ grid-column: 1 / -1; }

.aipx-faq-formcol .kb-adv-form-label{
	color: #FFFFFF;
	font-size: var(--aipx-body-sm);
	font-weight: 500;
	margin-bottom: 6px;
	display: block;
}

.aipx-faq-formcol .kb-adv-form-required{ color: #FFFFFF; }

/* Kadence gives selects no kb-field class, so they are matched by element. */
.aipx-faq-formcol .kb-field,
.aipx-faq-formcol select,
.aipx-faq-formcol textarea{
	width: 100%;
	/* One height for every single-line control. A native select renders taller
	   than a text input from its own UA styling, which left the country code
	   and phone pair six pixels out of line. */
	height: 42px;
	padding: 11px var(--aipx-space-3);
	background-color: rgba(255, 255, 255, .12);
	border: 1px solid rgba(255, 255, 255, .45);
	border-radius: 0;
	font-family: var(--aipx-font-body);
	font-size: var(--aipx-body-sm);
	color: #FFFFFF;
}

/* The textarea and the file control are the exceptions to the shared height. */
.aipx-faq-formcol textarea{ height: auto; }

.aipx-faq-formcol .kb-field::placeholder{ color: rgba(255, 255, 255, .72); }

.aipx-faq-formcol .kb-field:focus{
	outline: 2px solid #FFFFFF;
	outline-offset: -2px;
}

/* The native select popup is drawn by the OS, so its options need real
   contrast rather than the translucent field background. */
.aipx-faq-formcol select option{
	background-color: #FFFFFF;
	color: var(--aipx-text-heading);
}

.aipx-faq-formcol textarea{
	min-height: 104px;
	resize: vertical;
}

/*
 * Inputs align to the bottom of their grid row. Labels are not all one line -
 * "Country code" wraps in a one-track column where "Phone" does not - and
 * without this the two inputs of a pair sit at different heights.
 */
.aipx-faq-formcol .kb-adv-form-field{
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
}

/*
 * Consent checkbox sits inline, box first.
 *
 * Kadence renders this as a fieldset whose visible text is in a <legend> and
 * whose <label> is empty, so the checkbox would otherwise stack under the
 * sentence. Matched on the block class rather than a field id, because the
 * previous rule was tied to one form's ids and silently missed every other.
 */
/*
 * A left gutter, not a flex row. Kadence puts the visible sentence in a
 * <legend>, and a legend is the fieldset's caption rather than one of its flex
 * items, so `display: flex` on the fieldset leaves it stacked above regardless
 * of order. Reserving space on the left and placing the box into it works
 * whatever the legend does.
 */
.aipx-faq-formcol .wp-block-kadence-advanced-form-accept .kb-radio-check-item-wrap{
	position: relative;
	display: block;
	border: 0;
	margin: 0;
	padding: 0 0 0 26px;
}

/*
 * Floated so it joins normal flow. A legend is painted over the fieldset's top
 * border by default, which put it 22px above the content box and out of line
 * with the box in the gutter; floating drops it into the flow where the
 * absolute checkbox can meet its first line.
 */
.aipx-faq-formcol .wp-block-kadence-advanced-form-accept .kb-adv-form-label{
	float: left;
	width: 100%;
	display: block;
	margin: 0;
	padding: 0;
	font-size: var(--aipx-body-sm);
	font-weight: 400;
	line-height: 1.45;
}

.aipx-faq-formcol .wp-block-kadence-advanced-form-accept .kb-radio-check-item-wrap::after{
	content: "";
	display: table;
	clear: both;
}

.aipx-faq-formcol .wp-block-kadence-advanced-form-accept .kb-radio-check-item{
	position: absolute;
	left: 0;
	/* Sits on the first line of the sentence rather than the middle of a
	   sentence that has wrapped. */
	top: 2px;
	display: flex;
	align-items: center;
	margin: 0;
}

.aipx-faq-formcol .wp-block-kadence-advanced-form-accept input[type="checkbox"]{
	width: 16px;
	height: 16px;
	margin: 0;
	flex: 0 0 auto;
	accent-color: #FFFFFF;
	/* The box sits on the brand ground, so it needs its own edge to read. */
	border: 1px solid rgba(255, 255, 255, .6);
}

/* The empty label Kadence prints after the input would add a stray gap. */
.aipx-faq-formcol .wp-block-kadence-advanced-form-accept .kb-radio-check-item label:empty{
	display: none;
}

/* A file field on the brand ground: the native button needs its own contrast. */
.aipx-faq-formcol input[type="file"]{
	width: 100%;
	padding: 9px var(--aipx-space-3);
	background-color: rgba(255, 255, 255, .12);
	border: 1px solid rgba(255, 255, 255, .45);
	color: #FFFFFF;
	font-size: var(--aipx-body-sm);
}

.aipx-faq-formcol input[type="file"]::file-selector-button{
	margin-right: var(--aipx-space-3);
	padding: 5px 12px;
	border: 0;
	background-color: #FFFFFF;
	color: var(--aipx-brand-600);
	font-family: var(--aipx-font-heading);
	font-size: 12px;
	font-weight: 600;
	cursor: pointer;
}

.aipx-faq-formcol .kb-adv-form-help{
	margin-top: 5px;
	font-size: 12px;
	color: rgba(255, 255, 255, .78);
}

.aipx-faq-formcol .kb-adv-form-submit-button{
	width: 100%;
	background-color: var(--aipx-dark-bg) !important;
	color: #FFFFFF !important;
	border: 0 !important;
	border-radius: 0 !important;
	padding: 14px var(--aipx-space-8) !important;
	font-family: var(--aipx-font-heading);
	font-weight: 700;
	justify-content: center;
	cursor: pointer;
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-faq-formcol .kb-adv-form-submit-button:hover{ background-color: #000000 !important; }

@media (max-width: 640px) {
.aipx-f-half{ grid-column: 1 / -1; }
.aipx-f-dial{ grid-column: span 2; }
.aipx-f-phone{ grid-column: span 4; }}

@media (max-width: 1024px) {
.aipx-faq-split > .kt-row-column-wrap{ grid-template-columns: minmax(0, 1fr) !important; }}

/* ---------------------------------------------------------------------------
 * 24. Insights blog cards
 * ------------------------------------------------------------------------ */

.aipx-blog-grid.kb-posts{
	display: grid !important;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--aipx-space-6);
	list-style: none;
	margin: 0;
	padding: 0;
}

.aipx-blog-grid .kb-post-list-item > .entry{
	display: flex;
	flex-direction: column;
	height: 100%;
	background-color: var(--aipx-surface);
	border: 1px solid var(--aipx-border-subtle);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-blog-grid .post-thumbnail img{
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}

.aipx-blog-grid .entry-content-wrap{
	padding: var(--aipx-space-6);
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

/* Full card width - the section-head measure must not reach card titles. */
.aipx-blog-grid .entry-title{
	font-size: var(--aipx-h6-size);
	line-height: 1.35;
	margin: 0 0 var(--aipx-space-3);
	max-width: none !important;
}

.aipx-blog-grid .entry-title a{ color: inherit; text-decoration: none; }

/*
 * Excerpts are author-written and vary in length, which left the three cards
 * ragged. Clamping to three lines gives every card the same block of copy and
 * keeps the read-more links on one baseline.
 */
.aipx-blog-grid .entry-summary{
	flex: 1 1 auto;
	margin-bottom: var(--aipx-space-4);
}

.aipx-blog-grid .entry-summary p{
	font-size: var(--aipx-body-sm);
	color: var(--aipx-text-secondary);
	line-height: 1.6;
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: calc(3 * 1.6 * var(--aipx-body-sm));
}

.aipx-blog-grid .more-link-wrap{ margin-top: auto; }

.aipx-blog-grid .post-more-link{
	color: var(--aipx-brand-500);
	font-size: var(--aipx-body-sm);
	font-weight: 700;
	text-decoration: none;
}

.aipx-blog-grid .entry-meta,
.aipx-blog-grid .entry-taxonomies{
	font-family: var(--aipx-font-mono);
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--aipx-brand-500);
	margin-bottom: var(--aipx-space-2);
}

.aipx-blog-grid .kb-post-list-item > .entry:hover{ background-color: var(--aipx-brand-500); }

.aipx-blog-grid .kb-post-list-item > .entry:hover .entry-title,
.aipx-blog-grid .kb-post-list-item > .entry:hover .entry-title a,
.aipx-blog-grid .kb-post-list-item > .entry:hover .entry-summary p,
.aipx-blog-grid .kb-post-list-item > .entry:hover .entry-meta,
.aipx-blog-grid .kb-post-list-item > .entry:hover .entry-taxonomies,
.aipx-blog-grid .kb-post-list-item > .entry:hover .post-more-link{ color: #FFFFFF; }

@media (max-width: 1024px) {
.aipx-blog-grid.kb-posts{ grid-template-columns: minmax(0, 1fr); }}

/* ---------------------------------------------------------------------------
 * 25. Mobile navigation drawer
 *
 * Below the desktop split the navigation becomes a full-height drawer behind a
 * hamburger. Kadence's own off-canvas block only works inside a kadence/header,
 * so the toggle is rendered by the child theme and the existing navigation is
 * restyled here rather than duplicated.
 * ------------------------------------------------------------------------ */

.aipx-nav-toggle{
	display: none;
	position: absolute;
	top: 50%;
	right: var(--aipx-space-5);
	transform: translateY(-50%);
	z-index: 210;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: 0;
	cursor: pointer;
}

/* Three bars that fold into a cross when open. */
.aipx-nav-toggle-bars,
.aipx-nav-toggle-bars::before,
.aipx-nav-toggle-bars::after{
	position: absolute;
	left: 11px;
	width: 22px;
	height: 2px;
	background-color: var(--aipx-text-heading);
	transition: transform var(--aipx-duration-base) var(--aipx-ease-standard),
	            opacity var(--aipx-duration-fast) var(--aipx-ease-standard);
}

.aipx-nav-toggle-bars{ top: 21px; }
.aipx-nav-toggle-bars::before{ content: ""; top: -7px; }
.aipx-nav-toggle-bars::after{ content: ""; top: 7px; }

.aipx-nav-open .aipx-nav-toggle-bars{ background-color: transparent; }
.aipx-nav-open .aipx-nav-toggle-bars::before{ transform: translateY(7px) rotate(45deg); }
.aipx-nav-open .aipx-nav-toggle-bars::after{ transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 1024px) {
.aipx-nav-toggle{ display: block; }

/*
	 * backdrop-filter establishes a containing block for fixed-position
	 * descendants, which anchored the drawer to the 72px header bar instead of
	 * the viewport and collapsed it to a sliver. The blur is a desktop nicety
	 * only, so it is dropped here in favour of a solid bar.
	 */
	.aipx-block-header .aipx-header-bar{
		-webkit-backdrop-filter: none;
		        backdrop-filter: none;
		background-color: var(--aipx-light-bg);
	}

/* Logo left, toggle right; the nav and CTA move into the drawer. */
	.aipx-block-header .aipx-header-bar > .kt-row-column-wrap{
		grid-template-columns: 1fr !important;
		padding-right: 64px !important;
	}

.aipx-block-header .aipx-header-nav,
.aipx-block-header .aipx-header-cta{
		position: fixed;
		left: 0;
		right: 0;
		width: 100%;
		background-color: var(--aipx-light-bg);
		transform: translateX(100%);
		transition: transform var(--aipx-duration-slow) var(--aipx-ease-standard);
		z-index: 205;
	}

.aipx-block-header .aipx-header-nav{
		top: var(--aipx-header-height);
		bottom: 74px;
		overflow-y: auto;
		padding: var(--aipx-space-5) var(--aipx-space-6);
		border-top: 1px solid var(--aipx-border-subtle);
	}

.aipx-block-header .aipx-header-cta{
		bottom: 0;
		padding: var(--aipx-space-4) var(--aipx-space-6);
		border-top: 1px solid var(--aipx-border-subtle);
	}

.aipx-nav-open .aipx-header-nav,
.aipx-nav-open .aipx-header-cta{ transform: translateX(0); }

/* Stacked links, and the mega panels become plain nested lists. */
	.aipx-block-header ul.kb-navigation{
		flex-direction: column;
		align-items: stretch;
	}

.aipx-block-header ul.kb-navigation > li{ white-space: normal; }

.aipx-block-header .kb-nav-link-content{
		padding: var(--aipx-space-4) 0 !important;
		font-size: var(--aipx-body-md);
	}

.aipx-block-header .kb-menu-mega-width-container > ul.sub-menu.mega-menu,
.aipx-block-header .kb-menu-mega-width-full > ul.sub-menu.mega-menu{
		position: static !important;
		left: auto !important;
		transform: none !important;
		width: 100% !important;
		padding: 0 0 var(--aipx-space-4) !important;
		box-shadow: none;
		border-top: 0;
	}

.aipx-mega > .kt-row-column-wrap{
		grid-template-columns: minmax(0, 1fr) !important;
		gap: var(--aipx-space-6) !important;
	}

/*
	 * Services rail: the two panes stack, so the rail becomes an accordion
	 * header strip and the active category's links open underneath it. The
	 * rail keeps driving the panes, which is the behaviour a drawer wants.
	 */
	.aipx-mega-split > .kt-row-column-wrap{
		grid-template-columns: minmax(0, 1fr) !important;
	}

.aipx-mega-split .aipx-mega-rail > .kt-inside-inner-col{
		padding: var(--aipx-space-3) 0 !important;
	}

/*
	 * The desktop panel stacks its panes absolutely inside a measured viewport
	 * so they can cross-fade. A drawer scrolls, so the height animation and the
	 * absolute stacking both come off and the active pane returns to the flow.
	 */
	.aipx-mega-split .aipx-mega-panes{
		position: static;
		overflow: visible;
		min-height: 0;
		height: auto !important;
		transition: none;
	}

.aipx-mega-split .aipx-mega-panes > .kt-inside-inner-col{
		padding: var(--aipx-space-5) var(--aipx-space-4) !important;
	}

.aipx-mega-pane{
		position: static;
		display: none;
		opacity: 1;
		transform: none;
		transition: none;
	}

.aipx-mega-panes.is-ready .aipx-mega-pane:first-of-type,
.aipx-mega-panes .aipx-mega-pane:first-of-type{
		position: static;
	}

.aipx-mega-panes.is-ready .aipx-mega-pane:first-of-type:not(.is-active){
		display: none;
	}

/* One column of links in a drawer, whatever the desktop layout. */
	.aipx-mega-pane.is-active,
.aipx-mega-plain .aipx-mega-links{
		display: grid;
		grid-template-columns: minmax(0, 1fr);
	}

/*
	 * Back to static in the drawer. On desktop these two items are the
	 * positioning context so their panels can hang off the trigger; in a
	 * drawer that also makes the item the percentage basis, and `width: 100%`
	 * resolved to the width of the menu label rather than the drawer.
	 */
	.aipx-block-header li.kb-nav-link-nv-co,
.aipx-block-header li.kb-nav-link-nv-in{
		position: static !important;
	}

.aipx-block-header .kb-nav-link-nv-co > ul.sub-menu.mega-menu,
.aipx-block-header .kb-nav-link-nv-in > ul.sub-menu.mega-menu{
		width: 100% !important;
		max-width: none !important;
		left: 0 !important;
		right: 0 !important;
	}

/* The compact card sizing is a desktop concern; in the drawer the panel
	   fills the width the drawer gives it. */
	.aipx-block-header .kb-nav-link-nv-sv > ul.sub-menu.mega-menu{
		width: 100% !important;
	}


.aipx-header-cta .kb-button{ width: 100%; justify-content: center; }

/* Lock the page behind the drawer. */
	body.aipx-nav-locked{ overflow: hidden; }}

/* ---------------------------------------------------------------------------
 * 26. Small-screen refinements
 *
 * The 1024 breakpoints above handle the desktop-to-tablet step. These handle
 * phones, where three-up grids of long labels get too tight to read.
 * ------------------------------------------------------------------------ */

@media (max-width: 600px){
	.aipx-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.aipx-eco-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--aipx-space-8) var(--aipx-space-6); }

	/* Awards drop the fixed year column so titles keep their measure. */
	.aipx-awards .aipx-award-row {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--aipx-space-1);
		padding: var(--aipx-space-5) var(--aipx-space-3);
	}

	/* Footer rows stack; the legal list wraps instead of scrolling. */
	.aipx-footer-legal { flex-direction: column; gap: var(--aipx-space-2); }
	.aipx-footer-ratings img { margin: var(--aipx-space-4) var(--aipx-space-4) 0 0; }

	.aipx-logowall-inner { gap: var(--aipx-space-6) var(--aipx-space-8); }
	.aipx-logowall-inner img { height: 22px; }

	/* Testimonial quotes step down a size so cards stay compact. */
	.aipx-tst-quote { font-size: var(--aipx-body-md); }
	.aipx-tst-card,
	.aipx-case-body { padding: var(--aipx-space-6); }
}

/*
 * A single column here stacked thirty tech chips and eighteen partner marks
 * into two very long runs. Both hold two across at 375 without their labels
 * wrapping, so the fallback only tightens the gaps.
 */
@media (max-width: 400px){
	.aipx-eco-grid { gap: var(--aipx-space-6) var(--aipx-space-4); }
	.aipx-chip { padding: var(--aipx-space-2) var(--aipx-space-3); font-size: 13px; }
}

/* ---------------------------------------------------------------------------
 * 27. Corrections
 * ------------------------------------------------------------------------ */

/*
 * A thin red rule marks the seam between two consecutive light sections. The
 * two grounds meet as a sharp cut everywhere else,
so this only applies where
 * light meets light.
 */
.aipx-light + .aipx-light:not(.aipx-stats),
.aipx-light + .aipx-awards,
.aipx-awards + .aipx-light{
	border-top: 1px solid var(--aipx-brand-500);
}


/* The dark sections share one ground; no panel may drift warmer than it. */
.aipx-vtabs .kt-tab-inner-content{
	background-color: var(--aipx-dark-bg-raised);
}

/*
 * --- The two CTA boxes ---
 *
 * Both run the full container width with the copy on the left and the button on
 * the right, which is what keeps them short. The button track is sized to its
 * own content and the text track is minmax(0, 1fr), so long headings wrap
 * rather than pushing into the button.
 */
/* Specificity matches the section stack rule above,
which forces the inner
   wrapper to a stretched flex column with !important. */
.aipx-section.aipx-ctabox > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col,
.aipx-section.aipx-ctaband > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col{
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) max-content;
	grid-template-rows: auto auto;
	align-items: center !important;
	column-gap: var(--aipx-space-10);
	row-gap: 0 !important;
	text-align: left !important;
}

/*
 * The CTA box sits between two dark sections, so the sections either side would
 * otherwise stack 160px of padding around a box that is only 234px tall. Its own
 * top padding collapses and the bottom is halved; the box reads as part of the
 * run above it rather than as a section of its own.
 */
.aipx-dark + .aipx-section.aipx-ctabox{
	padding-top: 0;
	padding-bottom: calc(var(--aipx-section-y-md) / 2);
}

@media (max-width: 1024px) {
.aipx-dark + .aipx-section.aipx-ctabox{
		padding-bottom: calc(var(--aipx-section-y-sm) / 2);
	}}

.aipx-section.aipx-ctabox > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col{
	border: 1px solid var(--aipx-dark-border);
	background-color: var(--aipx-dark-bg-raised);
	padding: var(--aipx-space-8) var(--aipx-space-10) !important;
}

.aipx-ctabox .wp-block-kadence-advancedheading,
.aipx-ctabox .aipx-cta1-sub,
.aipx-ctaband .wp-block-kadence-advancedheading,
.aipx-ctaband .aipx-cta-sub{ grid-column: 1; }

.aipx-ctabox .wp-block-kadence-singlebtn,
.aipx-ctaband .wp-block-kadence-singlebtn{
	grid-column: 2;
	grid-row: 1 / span 2;
	justify-self: end;
}

.aipx-cta1-title{
	max-width: 34ch !important;
	margin: 0 0 var(--aipx-space-3) !important;
	color: var(--aipx-dark-text-heading) !important;
	font-size: var(--aipx-h4-size) !important;
}

.aipx-cta1-sub{
	max-width: 68ch;
	margin: 0 !important;
	color: var(--aipx-dark-text-body);
	font-size: var(--aipx-body-md);
}

/* Below the two-column split the button drops under the copy. */
@media (max-width: 768px){
	.aipx-section.aipx-ctabox > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col,
	.aipx-section.aipx-ctaband > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col {
		grid-template-columns: minmax(0, 1fr);
		row-gap: var(--aipx-space-6) !important;
	}

	.aipx-ctabox .wp-block-kadence-singlebtn,
	.aipx-ctaband .wp-block-kadence-singlebtn {
		grid-column: 1;
		grid-row: auto;
		justify-self: start;
	}
}

/*
 * The id-tied NDA rules that used to sit here have been removed. They targeted
 * .kb-fieldf-nda, a class Kadence never emits - the real one carries the form
 * id (.kb-field77f-nda) - so the whole block was inert. It was also superseded:
 * the working implementation is the .wp-block-kadence-advanced-form-accept
 * group above, which matches on the stable block class and uses a left gutter
 * rather than a flex row, because a <legend> is not a flex item. Reviving these
 * rules would have put two different techniques on the same control.
 */

/* ---------------------------------------------------------------------------
 * 28. Tablet: filling the width instead of stacking into it
 *
 * Kadence collapses multi-column rows to one column at its own tablet
 * breakpoint. On a 1024 or 985px screen that leaves half the viewport empty
 * beside a single column of content, which is what these rules undo. The
 * component layouts themselves are unchanged - only how many columns they use.
 * ------------------------------------------------------------------------ */

@media (min-width: 481px) and (max-width: 1024px){
	/*
	 * Six stats as three across two rows, not six full-width rows.
	 *
	 * These rules used to sit on the row, because the band was once a Kadence
	 * column per figure. It is one server-rendered block now, so forcing the
	 * row to three columns squeezed its single column into a third of the
	 * width and wrapped every label letter by letter. The band lays itself out
	 * instead, and the row is left alone.
	 */
	.aipx-statband {
		grid-auto-flow: row;
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.aipx-stat + .aipx-stat { border-left: 1px solid var(--aipx-border-subtle); }

	/* The fourth figure opens a second row, so it needs its left edge back and
	   the row above it needs a rule underneath. */
	.aipx-stat:nth-child(3n + 1) {
		border-left: 0;
		padding-left: 0;
	}

	.aipx-stat:nth-child(-n + 3) { border-bottom: 1px solid var(--aipx-border-subtle); }

	.aipx-stat {
		min-height: 0;
		padding: var(--aipx-space-6) var(--aipx-space-5);
	}

	.aipx-stats .kt-inside-inner-col { padding: 0 !important; }

	/*
	 * Card grids stack to one column below 1024px, which was written for
	 * phones but catches tablets too: at 986px that is a 923px card carrying a
	 * 519px image, three of which run to over 3000px of scroll. Two across for
	 * the same reason the rest of this block exists.
	 */
	.aipx-blog-grid.kb-posts,
	.aipx-case-grid,
	.aipx-tst-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

@media (min-width: 768px) and (max-width: 1024px) {
/*
	 * Section intros are capped at 56ch for readability on a 1200px container.
	 * At tablet that cap is narrower than the column itself and strands the
	 * right-hand half, so the intro takes the full measure.
	 */
	.aipx-sec-sub,
.aipx-cta1-sub,
.aipx-cta-sub{ max-width: 100%; }

/* Brand block left, review scores right - stacking them wastes the row. */
	.aipx-footer-brand > .kt-row-column-wrap{
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) !important;
	}

.aipx-footer-ratings{ align-items: flex-end; }

/* Three offices fit across; one per row leaves the footer very tall. */
	.aipx-footer-offices > .kt-row-column-wrap{
		grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
	}

/* Four nav columns rather than two, now that the row has the width. */
	.aipx-footer-nav > .kt-row-column-wrap{
		grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
	}

/* The CTA copy and its button still fit side by side here. */
	.aipx-section.aipx-ctabox > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col,
.aipx-section.aipx-ctaband > .kt-row-column-wrap > .wp-block-kadence-column > .kt-inside-inner-col{
		column-gap: var(--aipx-space-6);
	}}

/* Two stats across on large phones. */
@media (max-width: 480px){
	.aipx-statband {
		grid-auto-flow: row;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.aipx-stat + .aipx-stat {
		border-left: 1px solid var(--aipx-border-subtle);
	}

	.aipx-stat:nth-child(odd) {
		border-left: 0;
		padding-left: 0;
	}

	.aipx-stat {
		min-height: 0;
		padding: var(--aipx-space-5) var(--aipx-space-4);
	}

	.aipx-stat-n {
		font-size: 34px;
		min-height: 38px;
	}
}

/* ===========================================================================
 * 29. AI Development Services page
 *
 * Components that exist only on this page. Values are taken from the design
 * capture's own CSS, with one deliberate departure: the capture rounds the
 * mid-page CTA (20px), the compliance cards (16px), the rating capsules and the
 * stack chips (999px). The public site is sharp everywhere, so those four are
 * rendered at zero radius to match the homepage and the design system.
 * ======================================================================== */

/* ---------------------------------------------------------------------------
 * Hero on service, industry and company pages
 *
 * A black field with a single soft red bloom entering from the right edge, and
 * nothing else: no rule grid, no line pattern. The wave flourish belongs to the
 * landing page alone, which is what separates the two heroes.
 *
 * Built from layered radial gradients rather than an image so it scales to any
 * viewport without a second asset to serve.
 * ------------------------------------------------------------------------ */
.aipx-hero-ai{
	position: relative;
	overflow: hidden;
	isolation: isolate;
	background-color: var(--aipx-dark-bg);
	background-image:
		/* the core bloom, right of centre and vertically middled */
		radial-gradient(58% 78% at 88% 44%, rgba(232, 49, 47, .30), transparent 66%),
		/* a warmer, tighter centre inside it so the falloff is not flat */
		radial-gradient(26% 40% at 92% 34%, rgba(255, 106, 88, .20), transparent 70%),
		/* a wide, very low wash that keeps the right third from banding */
		radial-gradient(90% 120% at 108% 52%, rgba(213, 33, 34, .16), transparent 72%);
}

/*
 * The base .aipx-hero rule paints heroLines.svg on its ::before. These pages
 * share that class, so the flourish is switched off here rather than the two
 * hero classes being pulled apart.
 */
.aipx-hero-ai::before{
	content: none;
}

.aipx-hero-ai::after{
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	/* Grain, at a strength that only shows on the gradient. Without it the
	   bloom bands visibly on an 8-bit display across this much width. */
	background-image: radial-gradient(rgba(255, 255, 255, .035) 1px, transparent 1px);
	background-size: 3px 3px;
	opacity: .5;
}

.aipx-hero-ai > .kt-row-column-wrap{
	position: relative;
	z-index: 1;
	/* Matched to the landing hero. These were 168/116 against the landing
	   page's 88/84, which put nearly eighty pixels of dead space above the
	   headline on all sixty-eight pages that use this hero. */
	padding-top: 88px !important;
	padding-bottom: 84px !important;
}

.aipx-hero-ai .kt-inside-inner-col{ max-width: 60%; }
.aipx-hero-ai .aipx-hero-sub{ max-width: 60ch; }

@media (max-width: 1024px) {
.aipx-hero-ai .kt-inside-inner-col{ max-width: 100%; }
.aipx-hero-ai > .kt-row-column-wrap{
		padding-top: 64px !important;
		padding-bottom: 56px !important;
	}}

/* --- Opener: heading left, intro right ----------------------------------- */
.aipx-intro-split > .kt-row-column-wrap{
	gap: var(--aipx-space-12);
	align-items: start;
}

.aipx-intro-split h2{ max-width: none !important; margin: 0 !important; }

.aipx-intro-body{
	margin: 0;
	font-size: var(--aipx-body-lg);
	line-height: var(--aipx-body-lg-line);
	color: var(--aipx-dark-text-body);
}

@media (max-width: 767px) {
.aipx-intro-split > .kt-row-column-wrap{
		grid-template-columns: minmax(0, 1fr) !important;
		row-gap: var(--aipx-space-6) !important;
	}}

/* --- Why us: a numbered row list bounded top and bottom ------------------- */
.aipx-why .aipx-why-row{
	display: grid;
	grid-template-columns: 72px minmax(0, 1fr) minmax(0, 1.25fr);
	gap: var(--aipx-space-8);
	align-items: start;
	margin: 0;
	padding: var(--aipx-space-8) 0;
	border-bottom: 1px solid var(--aipx-dark-border);
}

.aipx-why .aipx-why-row:first-of-type{ border-top: 1px solid var(--aipx-dark-border); }

.aipx-why-n{
	font-family: var(--aipx-font-mono);
	font-size: 13px;
	letter-spacing: .12em;
	color: var(--aipx-brand-glow);
}

.aipx-why-t{
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h5-size);
	font-weight: 700;
	line-height: 1.3;
	color: var(--aipx-dark-text-heading);
}

.aipx-why-b{
	font-size: 17px;
	line-height: 1.65;
	color: var(--aipx-dark-text-body);
}

@media (max-width: 1024px) {
.aipx-why .aipx-why-row{
		grid-template-columns: 44px minmax(0, 1fr);
		gap: var(--aipx-space-4);
	}
.aipx-why-b{ grid-column: 2; }}

/* --- Client ratings: the capture's capsules, squared off ----------------- */
.aipx-scores{
	display: flex;
	flex-direction: column;
	gap: var(--aipx-space-4);
	margin: 0 0 var(--aipx-space-12);
}

.aipx-score{
	text-decoration: none;
	color: inherit;
	transition: border-color var(--aipx-duration-base) var(--aipx-ease-standard);
	display: flex;
	align-items: center;
	gap: var(--aipx-space-4);
	padding: 18px var(--aipx-space-8);
	border: 1px solid var(--aipx-border-subtle);
	background-color: var(--aipx-surface);
}

.aipx-score:hover,
.aipx-score:focus-visible{
	border-color: var(--aipx-brand-500);
}

/* These are the hero's light-ground marks, which are white and vanish on the
   off-white section. brightness(0) flattens them to black, exactly as the
   capture does, so one asset serves both grounds. */
.aipx-score img{
	height: 22px;
	width: auto;
	flex: none;
	filter: brightness(0);
}

/* The Google mark is the Maps pin rather than a wordmark: it already reads on
   both grounds, and flattening it to black would leave an unrecognisable blob. */
.aipx-score img[alt="Google"],
.aipx-hero-rating img[alt="Google"]{
	filter: none;
	height: 20px;
}

.aipx-score-val{
	margin-left: auto;
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h5-size);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

.aipx-score-stars{ color: var(--aipx-brand-500); letter-spacing: 2px; }

.aipx-score-count{
	min-width: 9ch;
	text-align: right;
	font-size: var(--aipx-body-sm);
	color: var(--aipx-text-muted);
}

/* --- Compliance frameworks ----------------------------------------------- */
.aipx-fw-grid{
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--aipx-space-5);
	margin: 0;
}

.aipx-fw{
	display: flex;
	align-items: center;
	min-height: 88px;
	padding: var(--aipx-space-6);
	border: 1px solid var(--aipx-border-subtle);
	background-color: var(--aipx-surface);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-md);
	font-weight: 700;
	line-height: 1.35;
	color: var(--aipx-text-heading);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-fw:hover{
	background-color: var(--aipx-brand-500);
	border-color: var(--aipx-brand-500);
	color: #FFFFFF;
}

/* Three across squeezes "AI Model Transparency and Interpretability Standards"
   into 95px on a phone. Two, then one. */
@media (max-width: 1024px){
	.aipx-fw-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
.aipx-fw-grid{ grid-template-columns: minmax(0, 1fr); }
.aipx-fw{ min-height: 0; padding: var(--aipx-space-5); }}

/* The score row carries a logo, a figure, five stars and a review count; on a
   narrow screen it wraps rather than crushing the count to nothing. */
@media (max-width: 600px){
	.aipx-score {
		flex-wrap: wrap;
		gap: var(--aipx-space-2) var(--aipx-space-4);
		padding: var(--aipx-space-5) var(--aipx-space-5);
	}

	.aipx-score-val { margin-left: auto; }
	.aipx-score-count { min-width: 0; width: 100%; text-align: left; }
}

/* Sub-headings inside a section that already has its own H2. */
.aipx-sub-h{
	font-size: var(--aipx-h5-size) !important;
	margin: 0 0 var(--aipx-space-2) !important;
	max-width: none !important;
	color: var(--aipx-text-heading) !important;
}

.aipx-sub-p{
	margin: 0 0 var(--aipx-space-6) !important;
	max-width: 60ch;
	font-size: var(--aipx-body-sm);
	color: var(--aipx-text-secondary);
}

/* --- Delivery process: two columns of numbered steps on a rule ----------- */
.aipx-steps{
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-template-rows: repeat(4, auto);
	/* Column flow keeps 1-4 in the left column and 5-7 in the right, so the
	   steps read down each column rather than zig-zagging across the pair. */
	grid-auto-flow: column;
	column-gap: var(--aipx-space-16);
	margin: 0;
}

.aipx-step{
	position: relative;
	display: grid;
	grid-template-columns: 56px minmax(0, 1fr);
	column-gap: var(--aipx-space-6);
	margin-left: 11px;
	padding: 0 0 var(--aipx-space-10) var(--aipx-space-6);
	border-left: 1px solid var(--aipx-dark-border);
}

/* The marker sits on the rule, not beside it. */
.aipx-step::before{
	content: "";
	position: absolute;
	left: -6px;
	top: 4px;
	width: 11px;
	height: 11px;
	background-color: var(--aipx-brand-glow);
}

.aipx-step-n{
	grid-column: 1;
	grid-row: 1;
	font-family: var(--aipx-font-mono);
	font-size: 13px;
	letter-spacing: .12em;
	color: var(--aipx-brand-glow);
}

.aipx-step-t{
	grid-column: 2;
	grid-row: 1;
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h6-size);
	font-weight: 700;
	line-height: 1.35;
	color: var(--aipx-dark-text-heading);
}

/*
 * Light-ground variant. The steps were written for dark rows, where the title
 * takes the near-white heading colour; on a light section that left the titles
 * invisible with only the body copy showing.
 */
.aipx-light .aipx-step-t{ color: var(--aipx-text-heading); }
.aipx-light .aipx-step-b{ color: var(--aipx-text-body); }
.aipx-light .aipx-step-n{ color: var(--aipx-brand-500); }
.aipx-light .aipx-step::before{ background-color: var(--aipx-brand-500); }
.aipx-light .aipx-step{ border-color: var(--aipx-border-subtle); }
.aipx-light .aipx-steps{ border-color: var(--aipx-border-subtle); }

.aipx-step-b{
	grid-column: 2;
	grid-row: 2;
	margin-top: var(--aipx-space-2);
	font-size: var(--aipx-body-sm);
	line-height: var(--aipx-body-sm-line);
	color: var(--aipx-dark-text-muted);
}

@media (max-width: 1024px) {
.aipx-steps{
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: none;
		grid-auto-flow: row;
	}
.aipx-step{ grid-template-columns: 40px minmax(0, 1fr); column-gap: var(--aipx-space-4); }}

/* --- Tech stack list: the panel holds chips rather than prose ------------ */
.aipx-stack-tabs .kt-tab-inner-content h3{
	font-size: var(--aipx-h5-size);
	margin-bottom: var(--aipx-space-6);
}

.aipx-stack-tabs .aipx-chips{
	display: flex;
	flex-wrap: wrap;
	gap: var(--aipx-space-3);
	grid-template-columns: none;
}

.aipx-stack-tabs .aipx-chip{ width: auto; }

/* ---------------------------------------------------------------------------
 * 30. Blog index
 *
 * Topic tabs over a full-width column of wide cards: thumbnail left, copy
 * right. Filtering and paging are real URLs rather than JavaScript, so every
 * view is reachable by a crawler and shareable.
 * ------------------------------------------------------------------------ */
.aipx-blog{
	width: 100%;
}

/* ---------------------------------------------------------------------------
 * Topic tabs
 *
 * Sharp hairline chips rather than a segmented strip. A strip has to decide
 * what to do when the row wraps, and neither answer is good: let the cells
 * grow and the last topic alone on row two stretches to the full container
 * width; stop them growing and the strip ends in a ragged half-row. Chips are
 * discrete objects, so any number of them wraps without leaving a hole.
 *
 * Text only. Each topic used to carry its own glyph, which put nine unrelated
 * marks on one row, several unreadable once masked to 16px, from a set that had
 * drifted from the site's single chevron. Removing them is the fix; swapping in
 * a different icon set would not have been.
 *
 * Hover and selection are deliberately different: hover draws the outline and
 * the label red, the selected topic fills solid red. If hover also filled, a
 * pointer resting on the row would be indistinguishable from the current view.
 * ------------------------------------------------------------------------ */
.aipx-blog-tabs{
	display: flex;
	flex-wrap: wrap;
	gap: var(--aipx-space-2);
	margin-bottom: var(--aipx-space-10);
	padding-bottom: var(--aipx-space-6);
	border-bottom: 1px solid var(--aipx-border-subtle);
}

.aipx-blog-tab{
	display: inline-flex;
	align-items: center;
	padding: 9px 16px;
	border: 1px solid var(--aipx-border);
	color: var(--aipx-text-body);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .01em;
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-blog-tab:hover{
	border-color: var(--aipx-brand-500);
	color: var(--aipx-brand-500);
}

.aipx-blog-tab:focus-visible{
	outline: 2px solid var(--aipx-brand-500);
	outline-offset: 2px;
}

.aipx-blog-tab.is-active{
	background: var(--aipx-brand-500);
	border-color: var(--aipx-brand-500);
	color: #FFFFFF;
}

@media (max-width: 640px) {
.aipx-blog-tabs{
		gap: 6px;
		padding-bottom: var(--aipx-space-5);
		margin-bottom: var(--aipx-space-8);
	}

.aipx-blog-tab{
		padding: 8px 12px;
		font-size: 12px;
	}}

/* ------------------------------------------------------------------ cards
 *
 * A three-column grid laid out the way the rest of the site lays out cards:
 * zero gap over a seam-coloured background, so neighbours are separated by a
 * single hairline rather than by drawn borders and whitespace. It replaces a
 * one-per-row stacked list that read as thin on a wide screen and made ten
 * posts a long scroll.
 *
 * Hover is the site's one card interaction, the same one the homepage
 * insights, service, testimonial and case-study cards use: the whole cell
 * fills solid red and every piece of text in it flips to white. The old
 * treatment tinted a border and added a drop shadow, which matched nothing
 * else and broke the rule that separation comes from hairlines, not shadow.
 * ---------------------------------------------------------------------- */
.aipx-blog-list{
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0;
	/*
	 * The seams are drawn by the cards, not by a coloured gap behind them.
	 * A gap-and-background grid paints its empty cells too, so a last row
	 * holding one post showed two grey rectangles where cards were missing.
	 * With the hairlines on the cards, a short row simply ends.
	 */
	border-top: 1px solid var(--aipx-border-subtle);
	border-left: 1px solid var(--aipx-border-subtle);
}

.aipx-blog-card{
	display: flex;
	flex-direction: column;
	background: var(--aipx-surface);
	border-right: 1px solid var(--aipx-border-subtle);
	border-bottom: 1px solid var(--aipx-border-subtle);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-blog-card:hover{
	background: var(--aipx-brand-500);
}

.aipx-blog-media{
	display: block;
	overflow: hidden;
	aspect-ratio: 16 / 10;
	/* Shows through when a post has no featured image, so the card keeps its
	   shape and the row stays aligned. */
	background: var(--aipx-brand-50);
	border-bottom: 1px solid var(--aipx-border-subtle);
}

.aipx-blog-card:hover .aipx-blog-media{
	border-bottom-color: rgba(255, 255, 255, .28);
}

.aipx-blog-media img{
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aipx-blog-body{
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: var(--aipx-space-6);
}

.aipx-blog-card .aipx-blog-cat{
	display: inline-block;
	align-self: flex-start;
	margin: 0 0 var(--aipx-space-3);
	padding: 3px 9px;
	border: 1px solid var(--aipx-border);
	color: var(--aipx-text-muted);
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .07em;
	text-transform: uppercase;
	transition: border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard);
}

/*
 * Titles and excerpts are clamped so cards in a row stay close in height.
 * Without it one three-line headline stretched its whole row and left the
 * shorter cards with a block of empty space above the date.
 */
.aipx-blog-card .aipx-blog-title{
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 0 0 var(--aipx-space-2);
	font-size: 19px;
	line-height: 1.35;
}

.aipx-blog-title a{
	color: var(--aipx-text-heading);
	text-decoration: none;
}

.aipx-blog-card .aipx-blog-excerpt{
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 0 0 var(--aipx-space-5);
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-text-secondary);
}

/* Pushed to the foot of the card so the date line sits level across a row
   whatever length the titles above it run to. */
.aipx-blog-card .aipx-blog-meta{
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--aipx-space-3);
	margin: auto 0 0;
	padding-top: var(--aipx-space-3);
	border-top: 1px solid var(--aipx-border-subtle);
	font-size: 12px;
	color: var(--aipx-text-muted);
}

.aipx-blog-meta .aipx-chevron{
	width: 15px;
	height: 15px;
	flex: none;
}

/* Everything inside the cell flips white together. */
.aipx-blog-card:hover .aipx-blog-title a,
.aipx-blog-card:hover .aipx-blog-excerpt,
.aipx-blog-card:hover .aipx-blog-meta,
.aipx-blog-card:hover .aipx-blog-cat{
	color: #FFFFFF;
}

.aipx-blog-card:hover .aipx-blog-cat{
	border-color: rgba(255, 255, 255, .55);
}

.aipx-blog-card:hover .aipx-blog-meta{
	border-top-color: rgba(255, 255, 255, .28);
}

/* ------------------------------------------------------------- pagination */
.aipx-blog-pager{
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: var(--aipx-space-2);
	margin-top: var(--aipx-space-10);
}

.aipx-blog-pager .page-numbers{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 38px;
	height: 38px;
	padding: 0 12px;
	border: 1px solid var(--aipx-border-subtle);
	color: var(--aipx-text-body);
	font-size: var(--aipx-body-sm);
	text-decoration: none;
	transition: border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-blog-pager a.page-numbers:hover{
	border-color: var(--aipx-brand-300);
	color: var(--aipx-brand-500);
}

.aipx-blog-pager .page-numbers.current{
	border-color: var(--aipx-brand-500);
	background: var(--aipx-brand-500);
	color: #FBF9F8;
	font-weight: 700;
}

.aipx-blog-pager .page-numbers.dots{
	border-color: transparent;
}

/*
 * The collapse the design system prescribes for every multi-column grid:
 * three columns to two at 1024px, to one at 640px. The card itself is a flex
 * column at every width, so only the track count changes.
 */
@media (max-width: 1024px) {
.aipx-blog-list{
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}}

@media (max-width: 640px) {
.aipx-blog-list{
		grid-template-columns: minmax(0, 1fr);
	}

.aipx-blog-body{
		padding: var(--aipx-space-5);
	}

.aipx-blog-card .aipx-blog-title{
		font-size: var(--aipx-body-lg);
	}}

/* ---------------------------------------------------------------------------
 * 31. Blog detail
 *
 * Dark hero band, then a three-track grid: contents rail, article, CTA rail.
 * Both rails stick; the article is the only thing that scrolls past them.
 * ------------------------------------------------------------------------ */

/*
 * The single template renders outside .entry-content,
so it cannot borrow the
 * alignfull rule. Same maths,
applied through a utility this layout owns.
 */
.aipx-fullbleed{
	margin-left: calc(50% - 50vw + (var(--scrollbar-offset, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--scrollbar-offset, 0px) / 2));
	max-width: calc(100vw - var(--scrollbar-offset, 0px));
	width: auto;
}

/*
 * Pages are built from full-bleed sections that each paint their own ground, so
 * the body is dark site-wide to sit behind them. A post is one light article
 * instead, and every strip the article does not cover - the gaps around the
 * grid, and the run down to the footer - showed through black.
 */
body.single-post{
	background-color: var(--aipx-light-bg);
}

.aipx-post{
	display: block;
	background: var(--aipx-light-bg);
}

.aipx-post-hero{
	background: var(--aipx-dark-bg);
	padding: 72px var(--aipx-space-6) 64px;
}

.aipx-post-hero-in{
	max-width: 860px;
	margin: 0 auto;
}

.aipx-post-crumb{
	margin: 0 0 var(--aipx-space-4);
	font-size: var(--aipx-body-sm);
	color: var(--aipx-dark-text-muted);
}

.aipx-post-crumb a{
	color: var(--aipx-brand-glow);
	text-decoration: none;
}

.aipx-post-title{
	margin: 0 0 var(--aipx-space-5);
	color: var(--aipx-dark-text-heading);
	font-weight: 900;
	font-size: clamp(32px, 4.2vw, 52px);
	line-height: 1.1;
	letter-spacing: -1px;
}

.aipx-post-standfirst{
	margin: 0 0 var(--aipx-space-6);
	max-width: 68ch;
	color: var(--aipx-dark-text-body);
	font-size: var(--aipx-body-lg);
	line-height: 1.6;
}

.aipx-post-meta{
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--aipx-space-2);
	margin: 0;
	color: var(--aipx-dark-text-muted);
	font-size: var(--aipx-body-sm);
}

.aipx-post-dot{
	opacity: .5;
}

/* ---------------------------------------------------------------- feature */
.aipx-post-figure{
	margin: 0 auto var(--aipx-space-12);
	max-width: 980px;
	/* Pulled up so the image straddles the hero edge, as the reference does. */
	margin-top: -48px;
	position: relative;
	z-index: 1;
}

.aipx-post-figure img{
	display: block;
	width: 100%;
	height: auto;
	border: 1px solid var(--aipx-border-subtle);
	background: var(--aipx-brand-50);
}

/* ------------------------------------------------------------------- grid */
.aipx-post-grid{
	display: grid;
	grid-template-columns: 240px minmax(0, 1fr) 280px;
	gap: var(--aipx-space-10);
	align-items: start;
	max-width: 1320px;
	margin: 0 auto;
	padding: 0 var(--aipx-space-6);
}

.aipx-post-grid--notoc{
	grid-template-columns: minmax(0, 1fr) 280px;
	max-width: 1080px;
}

/* Both rails clear the sticky header before they pin. */
.aipx-post-side,
.aipx-post-rail{
	position: sticky;
	top: 104px;
}

/* ------------------------------------------------------- table of contents */
.aipx-toc-h{
	margin: 0 0 var(--aipx-space-4);
	padding-bottom: var(--aipx-space-3);
	border-bottom: 1px solid var(--aipx-border-subtle);
	font-family: var(--aipx-font-heading);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--aipx-text-muted);
}

.aipx-toc-list{
	list-style: none;
	margin: 0;
	padding: 0;
	/* Long articles run to 20-plus headings; cap and scroll rather than let the
	   rail outgrow the viewport and break the sticky behaviour. */
	max-height: calc(100vh - 200px);
	overflow-y: auto;
	scrollbar-width: thin;
}

.aipx-toc-i{
	margin: 0;
}

.aipx-toc-i a{
	display: block;
	padding: 6px 0 6px var(--aipx-space-3);
	border-left: 2px solid var(--aipx-border-subtle);
	color: var(--aipx-text-muted);
	font-size: 13px;
	line-height: 1.45;
	text-decoration: none;
	transition: color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-toc-l3 a{
	padding-left: var(--aipx-space-6);
	font-size: 12.5px;
}

.aipx-toc-i a:hover{
	color: var(--aipx-text-heading);
	border-left-color: var(--aipx-neutral-300);
}

.aipx-toc-i.is-current a{
	color: var(--aipx-brand-500);
	border-left-color: var(--aipx-brand-500);
	font-weight: 600;
}

/* ------------------------------------------------------------- CTA rail */
.aipx-post-cta{
	padding: var(--aipx-space-6);
	border: 1px solid var(--aipx-border-subtle);
	background: var(--aipx-brand-50);
}

.aipx-post-cta-h{
	margin: 0 0 var(--aipx-space-3);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-lg);
	font-weight: 700;
	line-height: 1.3;
	color: var(--aipx-text-heading);
}

.aipx-post-cta-b{
	margin: 0 0 var(--aipx-space-5);
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-text-secondary);
}

.aipx-post-cta .aipx-btn{
	display: inline-block;
	padding: 11px var(--aipx-space-5);
	background: var(--aipx-brand-500);
	color: #FBF9F8;
	font-size: var(--aipx-body-sm);
	font-weight: 700;
	text-decoration: none;
}

.aipx-post-cta .aipx-btn:hover{
	background: var(--aipx-brand-600);
}

/* ------------------------------------------------------------ article body */
.aipx-post-body{
	max-width: 74ch;
	color: var(--aipx-text-body);
	font-size: 17px;
	line-height: 1.75;
}

.aipx-post-body > *{
	margin-top: 0;
	margin-bottom: var(--aipx-space-5);
}

.aipx-post-body h2{
	margin-top: var(--aipx-space-12);
	margin-bottom: var(--aipx-space-4);
	font-size: var(--aipx-h4-size);
	line-height: 1.25;
	/* Anchors land below the sticky header instead of under it. */
	scroll-margin-top: 96px;
}

.aipx-post-body h3{
	margin-top: var(--aipx-space-8);
	margin-bottom: var(--aipx-space-3);
	font-size: var(--aipx-h6-size);
	line-height: 1.3;
	scroll-margin-top: 96px;
}

.aipx-post-body a{
	color: var(--aipx-brand-500);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.aipx-post-body ul,
.aipx-post-body ol{
	padding-left: var(--aipx-space-6);
}

.aipx-post-body li{
	margin-bottom: var(--aipx-space-2);
}

.aipx-post-body img{
	max-width: 100%;
	height: auto;
	border: 1px solid var(--aipx-border-subtle);
}

.aipx-post-body figure{
	margin-left: 0;
	margin-right: 0;
}

.aipx-post-body figcaption{
	margin-top: var(--aipx-space-2);
	font-size: 13px;
	color: var(--aipx-text-muted);
}

.aipx-post-body blockquote{
	margin-left: 0;
	margin-right: 0;
	padding: var(--aipx-space-4) var(--aipx-space-6);
	border-left: 3px solid var(--aipx-brand-500);
	background: var(--aipx-neutral-50);
	font-size: var(--aipx-body-lg);
	line-height: 1.6;
}

.aipx-post-body blockquote p:last-child{
	margin-bottom: 0;
}

/* Tables: 55 of them across the imported posts, so they need real styling. */
.aipx-post-body .wp-block-table,
.aipx-post-body figure.wp-block-table{
	/* Wide tables scroll in their own box rather than widening the article. */
	overflow-x: auto;
	max-width: 100%;
}

.aipx-post-body table{
	width: 100%;
	border-collapse: collapse;
	font-size: 15px;
	line-height: 1.55;
}

.aipx-post-body th,
.aipx-post-body td{
	padding: 10px var(--aipx-space-4);
	border: 1px solid var(--aipx-border-subtle);
	text-align: left;
	vertical-align: top;
}

.aipx-post-body thead th{
	background: var(--aipx-neutral-50);
	font-family: var(--aipx-font-heading);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

.aipx-post-body tbody tr:nth-child(even){
	background: rgba(0, 0, 0, .015);
}

/* Code: 19 blocks across the imported posts. */
.aipx-post-body code{
	padding: 2px 6px;
	background: var(--aipx-neutral-50);
	border: 1px solid var(--aipx-border-subtle);
	font-family: var(--aipx-font-mono);
	font-size: .88em;
}

.aipx-post-body pre{
	overflow-x: auto;
	padding: var(--aipx-space-5);
	background: var(--aipx-neutral-900);
	color: #E8E8E8;
	font-family: var(--aipx-font-mono);
	font-size: 14px;
	line-height: 1.6;
}

.aipx-post-body pre code{
	padding: 0;
	background: none;
	border: 0;
	color: inherit;
}

/* ------------------------------------------------------------ author card */
/*
 * Sits in the article column of .aipx-post-grid, so it lines up with the text
 * above it instead of spanning the table of contents and the right rail too.
 * The column already sets the measure; the box must not set its own.
 */
.aipx-post-author{
	grid-column: 2;
	display: flex;
	align-items: flex-start;
	gap: var(--aipx-space-5);
	margin: var(--aipx-space-12) 0 0;
	padding: var(--aipx-space-6);
	border: 1px solid var(--aipx-border-subtle);
	background: var(--aipx-surface);
}

/* Without the contents rail the article is the first column. */
.aipx-post-grid--notoc .aipx-post-author{
	grid-column: 1;
}

/* An author with a Gravatar gets the photograph; the brand disc stays as the
   fallback for anyone who has not registered one. */
.aipx-post-author-av.has-img{ background: var(--aipx-border-subtle); }

/* The byline runs name, role, then bio. The bio takes body colour and a real
   measure so it reads as a sentence rather than as more metadata. */
/*
 * No measure of its own. The 68ch cap it used to carry was narrower than the
 * box, which is what left the large empty band down the right-hand side; the
 * article column now sets the line length.
 */
.aipx-post-author-bio{
	margin: var(--aipx-space-2) 0 0;
	font-size: var(--aipx-body-sm);
	line-height: 1.65;
	color: var(--aipx-text-body);
}

.aipx-post-author-img{
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.aipx-post-author-av{
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 52px;
	height: 52px;
	overflow: hidden;
	border-radius: 50%;
	background: var(--aipx-brand-500);
	color: #FBF9F8;
	font-family: var(--aipx-font-heading);
	font-size: 22px;
	font-weight: 700;
}

.aipx-post-author-n{
	margin: 0;
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-lg);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

.aipx-post-author-d{
	margin: var(--aipx-space-2) 0 0;
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-text-secondary);
}

/* -------------------------------------------------------------- CTA band */
.aipx-post-band{
	margin-top: var(--aipx-space-16);
	padding: var(--aipx-space-10) var(--aipx-space-6);
	background: var(--aipx-brand-500);
}

.aipx-post-band-in{
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--aipx-space-6);
	max-width: 1160px;
	margin: 0 auto;
}

.aipx-post-band-h{
	margin: 0 0 var(--aipx-space-2);
	color: #FBF9F8;
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h5-size);
	font-weight: 800;
	line-height: 1.25;
}

.aipx-post-band-b{
	margin: 0;
	max-width: 62ch;
	color: rgba(255, 255, 255, .88);
	font-size: var(--aipx-body-md);
	line-height: 1.6;
}

.aipx-post-band .aipx-btn-black{
	display: inline-block;
	padding: 13px var(--aipx-space-6);
	background: var(--aipx-neutral-900);
	color: #FBF9F8;
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
}

/* ------------------------------------------------------------- responsive */
@media (max-width: 1200px){
	/* The CTA rail is the first thing to go: it repeats the closing band. */
	.aipx-post-grid,
	.aipx-post-grid--notoc {
		grid-template-columns: 220px minmax(0, 1fr);
		max-width: 940px;
	}

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

	.aipx-post-rail {
		display: none;
	}
}

@media (max-width: 900px) {
.aipx-post-grid,
.aipx-post-grid--notoc{
		grid-template-columns: minmax(0, 1fr);
		gap: var(--aipx-space-8);
	}

	/*
	 * Back to the single column with everything else. Left on grid-column: 2
	 * the box would place itself in an implicit second track, and the grid
	 * would size that track to the box and starve the real column - which
	 * crushed the contents list to 42px.
	 */
	.aipx-post-author{
		grid-column: 1;
	}

/*
	 * Stacked, the contents list becomes a block at the top of the article, so
	 * it must not stick - a pinned full-width list would cover the text.
	 */
	.aipx-post-side{
		position: static;
		padding: var(--aipx-space-5);
		border: 1px solid var(--aipx-border-subtle);
		background: var(--aipx-neutral-50);
	}

.aipx-toc-list{
		max-height: 280px;
	}

.aipx-post-body{
		max-width: none;
	}

.aipx-post-figure{
		margin-top: -24px;
		padding: 0 var(--aipx-space-6);
	}}

@media (max-width: 600px) {
.aipx-post-hero{
		padding: 48px var(--aipx-space-5) 40px;
	}

.aipx-post-band-in{
		flex-direction: column;
		align-items: flex-start;
	}}

/* ---------------------------------------------------------------------------
 * 33. Assessment deliverables grid
 *
 * Six artifacts the client keeps at the end of the fixed-scope assessment.
 * Deliberately not the steps treatment: steps are a sequence on a timeline
 * rule, and these are a set you own, so they read as six equal cards with the
 * index as a label. On the light ground, since the section follows methodology
 * and the alternation would otherwise put two dark bands together.
 * ------------------------------------------------------------------------ */

.aipx-deliv-grid{
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1px;
	margin: 0;
	/* The gap is the rule: one background behind a 1px grid gap draws every
	   divider without six borders that double up where tiles meet. */
	background-color: var(--aipx-border-subtle);
	border: 1px solid var(--aipx-border-subtle);
}

.aipx-deliv{
	display: block;
	padding: var(--aipx-space-8);
	background-color: var(--aipx-surface);
}

.aipx-deliv-n{
	display: block;
	margin-bottom: var(--aipx-space-4);
	font-family: var(--aipx-font-mono);
	font-size: var(--aipx-caption);
	letter-spacing: .1em;
	color: var(--aipx-brand-500);
}

.aipx-deliv-t{
	display: block;
	margin-bottom: var(--aipx-space-2);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-md);
	font-weight: 600;
	line-height: 1.35;
	color: var(--aipx-text-heading);
}

.aipx-deliv-b{
	display: block;
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-text-body);
}

/* A two-column variant for a four-item set: three columns would leave one tile
   alone on the second row. */
.aipx-deliv-grid-2col{ grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Explicit three, for a set that would otherwise inherit a narrower default. */
.aipx-deliv-grid-3col{ grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* On the dark ground the same tiles keep the hairline-gap construction; only
   the two surfaces either side of the gap change. */
.aipx-dark .aipx-deliv-grid{
	background-color: var(--aipx-dark-border);
	border-color: var(--aipx-dark-border);
}

.aipx-dark .aipx-deliv{ background-color: var(--aipx-dark-bg); }
.aipx-dark .aipx-deliv-t{ color: var(--aipx-dark-text-heading); }
.aipx-dark .aipx-deliv-b{ color: var(--aipx-dark-text-body); }

/* Secondary text link under the hero button, on the dark ground. */
.aipx-hero-link{
	margin: var(--aipx-space-5) 0 0 !important;
	font-size: var(--aipx-body-sm);
}

.aipx-hero-link a{
	color: var(--aipx-dark-text-body);
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

.aipx-hero-link a:hover{ color: var(--aipx-dark-text-heading); }

/* ---------------------------------------------------------------------------
 * 34. Standards and what each one means
 *
 * Replaces the chip grid on pages whose spec supplies an application line per
 * standard. The chips restated the same names the paragraph above them had just
 * listed, which is two passes over the same information and no answer to the
 * question a buyer is actually asking. Each row now carries the standard and
 * what it changes about the engagement.
 * ------------------------------------------------------------------------ */

.aipx-std-list{
	display: block;
	margin: 0;
	border-top: 1px solid var(--aipx-border-subtle);
}

.aipx-std{
	display: grid;
	grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
	column-gap: var(--aipx-space-12);
	align-items: baseline;
	padding: var(--aipx-space-5) 0;
	border-bottom: 1px solid var(--aipx-border-subtle);
}

.aipx-std-n{
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-md);
	font-weight: 600;
	line-height: 1.4;
	color: var(--aipx-text-heading);
}

.aipx-std-b{
	font-size: var(--aipx-body-sm);
	line-height: 1.65;
	color: var(--aipx-text-body);
}

/*
 * Dark-ground variant. This component was built for the light proof sections and
 * carries light-ground colours throughout. About Us uses it inside a dark
 * section for Mission and Vision, where the near-black label and dark-grey body
 * were effectively invisible and the light hairlines were far too bright.
 */
.aipx-dark .aipx-std-list,
.aipx-dark .aipx-std{ border-color: var(--aipx-dark-border); }

.aipx-dark .aipx-std-n{ color: var(--aipx-dark-text-heading); }

.aipx-dark .aipx-std-b{ color: var(--aipx-dark-text-body); }

/* The secondary text link under a CTA band button. */
.aipx-cta-link{
	margin: var(--aipx-space-5) 0 0 !important;
	font-size: var(--aipx-body-sm);
}

.aipx-cta-link a{
	color: var(--aipx-dark-text-heading);
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

.aipx-cta-link a:hover{
	color: var(--aipx-dark-text-heading);
	opacity: .78;
}

@media (max-width: 1024px) {
.aipx-deliv-grid,
.aipx-deliv-grid-2col,
.aipx-deliv-grid-3col{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
.aipx-std{ grid-template-columns: minmax(0, 1fr); row-gap: var(--aipx-space-2); }}

@media (max-width: 600px) {
.aipx-deliv-grid,
.aipx-deliv-grid-2col,
.aipx-deliv-grid-3col{ grid-template-columns: minmax(0, 1fr); }
.aipx-deliv{ padding: var(--aipx-space-6); }}

.aipx-svcitem-t{
	margin: 0 0 3px !important;
	font-family: var(--aipx-font-heading);
	font-size: 16px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--aipx-dark-text-heading);
}

.aipx-svcitem-t a{
	color: inherit;
	text-decoration: none;
	background-image: linear-gradient(var(--aipx-brand-500), var(--aipx-brand-500));
	background-size: 0 1px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size var(--aipx-duration-base) var(--aipx-ease-out),
	            color var(--aipx-duration-fast) var(--aipx-ease-standard);
}

.aipx-svcitem-t a:hover,
.aipx-svcitem-t a:focus-visible{
	color: var(--aipx-brand-500);
	background-size: 100% 1px;
}

.aipx-svcitem-b{
	margin: 0 0 var(--aipx-space-5) !important;
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--aipx-dark-text-body);
}

.aipx-svcitem-b:last-child{ margin-bottom: 0 !important; }
.aipx-light .aipx-svcitem-t{ color: var(--aipx-text-heading); }
.aipx-light .aipx-svcitem-b{ color: var(--aipx-text-body); }

/* The "see the projects behind this" link under a proof section that carries a
   checklist rather than case-study cards. Its own rule rather than aipx-cta-link,
   which paints white for the red band and would vanish here. */
.aipx-proof-link{
	margin: var(--aipx-space-8) 0 0 !important;
	font-size: var(--aipx-body-sm);
}

.aipx-proof-link a{
	color: var(--aipx-text-heading);
	text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}

.aipx-proof-link a:hover{ color: var(--aipx-brand-500); }

/* ---------------------------------------------------------------------------
 * 37. Comparison table
 *
 * A real core/table, not a styled grid, because two pages depend on an
 * extractor being able to parse it. Styling therefore has to work with the
 * markup core/table produces: figure.wp-block-table > table.
 * ------------------------------------------------------------------------- */
.aipx-table{
	margin: var(--aipx-space-10) 0 0 !important;
	/* Wide tables scroll inside their own box; the page never scrolls sideways. */
	overflow-x: auto;
}

.aipx-table table{
	width: 100%;
	min-width: 46rem;
	border-collapse: collapse;
	font-size: var(--aipx-body-sm);
}

.aipx-table th,
.aipx-table td{
	padding: var(--aipx-space-4) var(--aipx-space-5);
	text-align: left;
	vertical-align: top;
	border: 1px solid var(--aipx-border-subtle);
	line-height: 1.55;
}

.aipx-table thead th{
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-caption);
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--aipx-text-heading);
	background-color: var(--aipx-neutral-50);
}

/* First cell of each row is a th, so it needs to read as a label and not as a
   second header row. */
.aipx-table tbody th{
	font-weight: 600;
	color: var(--aipx-text-heading);
	background-color: var(--aipx-neutral-50);
}

.aipx-table tbody td{ color: var(--aipx-text-body); }

.aipx-dark .aipx-table th,
.aipx-dark .aipx-table td{ border-color: var(--aipx-dark-border); }
.aipx-dark .aipx-table thead th,
.aipx-dark .aipx-table tbody th{
	color: var(--aipx-dark-text-heading);
	background-color: var(--aipx-dark-surface);
}
.aipx-dark .aipx-table tbody td{ color: var(--aipx-dark-text-body); }

/* A qualifying line under a table: which row to read twice, or when the dates
   were last verified. Narrower than the table so it reads as commentary. */
.aipx-table-note{
	max-width: 68ch;
	margin: var(--aipx-space-5) 0 0 !important;
	font-size: var(--aipx-body-sm);
	line-height: 1.7;
	color: var(--aipx-text-body);
}

.aipx-table-note strong{ color: var(--aipx-text-heading); }

/* ---------------------------------------------------------------------------
 * RELATED SERVICES
 * Card grid closing every service page. Name and link only: the reason a
 * visitor clicks is the service name, so anything else is noise at this point
 * in the page. Built as one paragraph of inline spans, the same idiom as
 * .aipx-model-grid, so the block stays editable in Gutenberg. Scoped under
 * .aipx-related to match how .aipx-why and .aipx-ctabox scope their children.
 * ------------------------------------------------------------------------ */
.aipx-related .aipx-related-grid{
	/* Flex, not grid: the item count varies 4-6 across pages, and a grid leaves
	   the last row's unused tracks showing as an empty slab of container
	   background. Flex lets the final row's cards grow to fill instead. */
	display: flex;
	flex-wrap: wrap;
	gap: 1px;
	margin: var(--aipx-space-10) 0 0 !important;
	background-color: var(--aipx-dark-border);
	border: 1px solid var(--aipx-dark-border);
}

.aipx-related .aipx-related-card{
	display: flex;
	/* 340px basis yields three per row in the 1200px container, matching
	   .aipx-model-grid. Every page carries 5 or 6 related services, so this
	   lands as a balanced 3+2 or 3+3 rather than an orphan on its own row. */
	flex: 1 1 340px;
	align-items: center;
	min-height: 88px;
	padding: var(--aipx-space-6);
	background-color: var(--aipx-dark-surface);
	transition: background-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-related .aipx-related-card:hover{ background-color: var(--aipx-dark-surface-2); }

.aipx-related .aipx-related-card a{
	position: relative;
	display: block;
	padding-right: var(--aipx-space-6);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-h6-size);
	font-weight: 600;
	line-height: 1.35;
	color: var(--aipx-dark-text-heading);
	text-decoration: none;
	transition: color var(--aipx-duration-fast) var(--aipx-ease-standard);
}

/* Chevron drawn in CSS so the card carries no image dependency. */
.aipx-related .aipx-related-card a::after{
	content: "";
	position: absolute;
	top: 50%;
	right: 4px;
	width: 7px;
	height: 7px;
	border-top: 1.5px solid currentColor;
	border-right: 1.5px solid currentColor;
	transform: translateY(-50%) rotate(45deg);
	opacity: .45;
	transition: transform var(--aipx-duration-base) var(--aipx-ease-out),
	            opacity var(--aipx-duration-fast) var(--aipx-ease-standard);
}

.aipx-related .aipx-related-card a:hover,
.aipx-related .aipx-related-card a:focus-visible{ color: var(--aipx-brand-500); }

.aipx-related .aipx-related-card a:hover::after,
.aipx-related .aipx-related-card a:focus-visible::after{
	transform: translateY(-50%) translateX(3px) rotate(45deg);
	opacity: 1;
}

/* Stretch the hit area to the whole card without nesting a second anchor. */
.aipx-related .aipx-related-card a::before{
	content: "";
	position: absolute;
	inset: calc(var(--aipx-space-6) * -1);
}

/* Light ground, for pages that close on a light section. */
.aipx-light.aipx-related .aipx-related-grid{
	background-color: var(--aipx-border-subtle);
	border-color: var(--aipx-border-subtle);
}

.aipx-light.aipx-related .aipx-related-card{ background-color: var(--aipx-surface); }
.aipx-light.aipx-related .aipx-related-card:hover{ background-color: var(--aipx-neutral-50); }
.aipx-light.aipx-related .aipx-related-card a{ color: var(--aipx-text-heading); }

@media (max-width: 767px) {
.aipx-related .aipx-related-card{ flex-basis: 100%; min-height: 0; padding: var(--aipx-space-5); }}

/* ---------------------------------------------------------------------------
 * ITEM QUALIFIERS
 * The labelled line the source files attach to a service, stage or role
 * ("Screened for: ...", "Blast radius: ...", "Settled here: ..."). It is the
 * sharpest sentence in most items, so it reads as a distinct annotation rather
 * than as more body copy: mono label, hairline above, tighter type.
 * ------------------------------------------------------------------------ */
.aipx-qual{
	margin: var(--aipx-space-4) 0 0 !important;
	padding-top: var(--aipx-space-3);
	border-top: 1px solid var(--aipx-dark-border);
	font-size: var(--aipx-body-sm);
	line-height: var(--aipx-body-sm-line);
	color: var(--aipx-dark-text-muted);
}

.aipx-qual-l{
	display: block;
	margin-bottom: 2px;
	font-family: var(--aipx-font-mono);
	font-size: var(--aipx-caption);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--aipx-brand-glow);
}

.aipx-light .aipx-qual{
	border-top-color: var(--aipx-border-subtle);
	color: var(--aipx-text-muted);
}

.aipx-light .aipx-qual-l{ color: var(--aipx-brand-600); }

/* Inside an inline span grid (steps, deliverables) the qualifier is a span, so
   it has to be promoted to its own line rather than inheriting the flow. */
.aipx-step-q,
.aipx-deliv-q{
	display: block;
	margin-top: var(--aipx-space-3);
	padding-top: var(--aipx-space-3);
	border-top: 1px solid var(--aipx-dark-border);
	font-size: var(--aipx-body-sm);
	line-height: var(--aipx-body-sm-line);
	color: var(--aipx-dark-text-muted);
}

.aipx-step-q .aipx-qual-l,
.aipx-deliv-q .aipx-qual-l{ display: block; }

.aipx-light .aipx-step-q,
.aipx-light .aipx-deliv-q{
	border-top-color: var(--aipx-border-subtle);
	color: var(--aipx-text-muted);
}

/* ---------------------------------------------------------------------------
 * Pointer line on a dark ground.
 * .aipx-proof-link sets the light-theme heading colour, which on .aipx-dark
 * renders as near-black on near-black. Restore the theme's own link colour so
 * these read the same as every other inline link on the page.
 * ------------------------------------------------------------------------ */
.aipx-dark .aipx-proof-link a{ color: var(--aipx-brand-500); }
.aipx-dark .aipx-proof-link a:hover,
.aipx-dark .aipx-proof-link a:focus-visible{ color: var(--aipx-brand-400); }

/* ---------------------------------------------------------------------------
 * Deliverable grid, fill variant.
 * A fixed column count leaves the last row's unused tracks showing as an empty
 * slab of container background whenever the item count does not divide evenly.
 * Flex lets the final row's tiles grow to close it, the same fix as
 * .aipx-related-grid.
 * ------------------------------------------------------------------------ */
.aipx-deliv-grid-fill{
	display: flex;
	flex-wrap: wrap;
}

.aipx-deliv-grid-fill > .aipx-deliv{
	flex: 1 1 300px;
}

@media (max-width: 767px) {
.aipx-deliv-grid-fill > .aipx-deliv{ flex-basis: 100%; }}

/* ---------------------------------------------------------------------------
 * SERVICE / SECTOR LIST INSIDE A TAB
 * The homepage lists 29 services, 28 sectors and 11 AI services. As a
 * three-column grid those read as a table, so they now sit in the same
 * vertical tabs the service pages use, one tab per group. The tab body holds
 * the group's items in two columns, reusing .aipx-svcitem-t / -b so the copy
 * and its styling carry over unchanged.
 * ------------------------------------------------------------------------ */
.aipx-svclist{
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--aipx-space-6) var(--aipx-space-8);
	margin: 0 !important;
}

.aipx-svclist .aipx-svcitem{ display: block; }

.aipx-svclist .aipx-svcitem-t{
	display: block;
	margin-bottom: 3px;
	font-family: var(--aipx-font-heading);
	font-size: 16px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--aipx-dark-text-heading);
}

.aipx-svclist .aipx-svcitem-b{
	display: block;
	font-size: var(--aipx-body-sm);
	line-height: var(--aipx-body-sm-line);
	color: var(--aipx-dark-text-muted);
}

.aipx-light .aipx-svclist .aipx-svcitem-t{ color: var(--aipx-text-heading); }
.aipx-light .aipx-svclist .aipx-svcitem-b{ color: var(--aipx-text-muted); }

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

/* ---------------------------------------------------------------------------
 * TECHNOLOGY CHIPS — sized to their label
 * The earlier rule pinned these to a six-column grid, so a cell was as narrow
 * as the shortest label allowed and "Tailwind CSS" broke across three lines.
 * Flex lets each chip take the width of its own name and wrap onto as many
 * rows as the list needs, which is what a stack of 15 technologies requires.
 * ------------------------------------------------------------------------ */
.aipx-chips{
	display: flex !important;
	flex-wrap: wrap;
	gap: var(--aipx-space-3) var(--aipx-space-4);
	grid-template-columns: none !important;
}

/*
 * Tighter gap on the narrowest phones. This has to live after the rule above:
 * it previously sat with the other small-screen rules further up the file and
 * was silently overridden, because the flex rewrite sets gap at the same
 * specificity and later in source order.
 */
@media (max-width: 400px){
	.aipx-chips{ gap: var(--aipx-space-2); }
}

.aipx-chip{
	flex: 0 0 auto;
	white-space: nowrap;
}

@media (max-width: 480px) {
/* narrow phones: let a very long label wrap rather than overflow the row */
	.aipx-chip{ white-space: normal; }}

/* ---------------------------------------------------------------------------
 * TICK LIST
 * The industry feature panels are flat one-clause lines with no label of their
 * own, which none of the existing grids carry: aipx-std and aipx-deliv both
 * need a name, aipx-chip needs something short enough to sit on one line.
 * Same spans-in-a-paragraph construction as the rest, so it drops into a tab
 * pane without a wrapper block.
 * ------------------------------------------------------------------------- */
.aipx-ticks{
	display: grid;
	/* 260px, not 300: the tab pane is about 590px wide on a 1200px container,
	   so a larger floor keeps the list stuck in one column. */
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
	gap: var(--aipx-space-3) var(--aipx-space-8);
	margin: var(--aipx-space-5) 0 0 !important;
}

.aipx-tick{
	position: relative;
	padding-left: var(--aipx-space-6);
	font-size: var(--aipx-body-sm);
	line-height: 1.6;
	color: var(--aipx-dark-text-body);
}

/* Drawn rather than a list marker, so the rule stays put when the line wraps. */
.aipx-tick::before{
	content: "";
	position: absolute;
	top: .62em;
	left: 0;
	width: 10px;
	height: 1px;
	background-color: var(--aipx-brand-500);
}

.aipx-light .aipx-tick{ color: var(--aipx-text-body); }
/* ---------------------------------------------------------------------------
 * Long-form policy pages
 *
 * Terms, refund and privacy are the only pages on the site that are read
 * top to bottom as continuous prose, and nothing in the component set fits
 * that: the span grids are all scannable summaries. A measure, a heading
 * rhythm and list styling, and nothing else.
 * ------------------------------------------------------------------------ */
.aipx-legal{
	max-width: 76ch;
}

.aipx-legal h2{
	margin: var(--aipx-space-12) 0 var(--aipx-space-4);
	font-size: var(--aipx-h5-size);
	line-height: 1.25;
	color: var(--aipx-text-heading);
}

.aipx-legal h2:first-child{ margin-top: 0; }

.aipx-legal h3{
	margin: var(--aipx-space-8) 0 var(--aipx-space-3);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-lg);
	font-weight: 700;
	color: var(--aipx-text-heading);
}

.aipx-legal p{
	margin: 0 0 var(--aipx-space-4);
	font-size: var(--aipx-body-md);
	line-height: 1.7;
	color: var(--aipx-text-body);
}

.aipx-legal ul{
	margin: 0 0 var(--aipx-space-5);
	padding-left: var(--aipx-space-5);
	color: var(--aipx-text-body);
}

.aipx-legal li{
	margin-bottom: var(--aipx-space-2);
	font-size: var(--aipx-body-md);
	line-height: 1.65;
}

.aipx-legal a{
	color: var(--aipx-brand-600);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.aipx-legal-updated{
	margin: 0 0 var(--aipx-space-8);
	font-family: var(--aipx-font-mono);
	font-size: 12px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--aipx-text-muted);
}

/* ---------------------------------------------------------------------------
 * People cards
 *
 * The client review card cannot be reused for colleagues: it leads on a
 * platform badge and a star rating, and a person describing their own job has
 * neither. Same construction, different opening - an oversized quote glyph,
 * which is the one place on the site that device appears.
 * ------------------------------------------------------------------------ */
.aipx-people-grid{
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
	/* Equal rows, so a short quote does not leave a short card beside a tall
	   one and break the line the attributions sit on. */
	grid-auto-rows: 1fr;
	gap: var(--aipx-space-5);
	margin: 0 !important;
}

.aipx-person{
	position: relative;
	display: flex;
	flex-direction: column;
	/* The scale has no step 7 - it runs 1 to 6 then jumps to 8 - and a single
	   undefined custom property voids the entire shorthand. */
	padding: var(--aipx-space-8) var(--aipx-space-6) var(--aipx-space-6);
	background-color: var(--aipx-surface);
	border: 1px solid var(--aipx-border-subtle);
	transition: border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            box-shadow var(--aipx-duration-base) var(--aipx-ease-standard),
	            transform var(--aipx-duration-base) var(--aipx-ease-standard);
}

/*
 * The glyph sits in normal flow as the card's first flex item, not behind the
 * text. Absolutely positioning it put it on top of whatever the first two lines
 * of the quote happened to be. Decorative, so it lives in a pseudo-element and
 * stays out of the accessibility tree.
 */
.aipx-person::before{
	content: "\201C";
	display: block;
	margin: 0 0 -14px -2px;
	font-family: var(--aipx-font-heading);
	font-size: 52px;
	font-weight: 800;
	line-height: 1;
	color: var(--aipx-brand-500);
	opacity: .22;
	pointer-events: none;
	transition: opacity var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-person:hover{
	border-color: var(--aipx-brand-300);
	box-shadow: 0 2px 22px -12px rgba(29, 29, 29, .32);
	transform: translateY(-2px);
}

.aipx-person:hover::before{ opacity: .4; }

.aipx-person-q{
	display: block;
	position: relative;
	margin-bottom: var(--aipx-space-6);
	font-size: var(--aipx-body-md);
	line-height: 1.62;
	color: var(--aipx-text-body);
}

/* Hairline between the quote and who said it, so the attribution reads as a
   signature rather than as another line of the quote. */
.aipx-person-n{
	display: block;
	margin-top: auto;
	padding-top: var(--aipx-space-5);
	border-top: 1px solid var(--aipx-border-subtle);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-md);
	font-weight: 700;
	letter-spacing: -.01em;
	color: var(--aipx-text-heading);
}

.aipx-person-r{
	display: block;
	margin-top: 3px;
	font-family: var(--aipx-font-mono);
	font-size: 11.5px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--aipx-text-muted);
}

/* ---------------------------------------------------------------------------
 * Culture gallery
 *
 * A fixed mosaic, not auto-flow: one hero at two by two, a pair stacked beside
 * it, and a panorama across the base. Photographs of a room full of people
 * need the space; five equal tiles read as stock imagery.
 * ------------------------------------------------------------------------ */
.aipx-gallery{
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-auto-rows: 190px;
	gap: var(--aipx-space-3);
	margin: 0 !important;
}

.aipx-shot{
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: 2px;
	background-color: var(--aipx-surface-alt, #F4F1EE);
}

.aipx-shot img{
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transform: scale(1.001);
	transition: transform 620ms var(--aipx-ease-out, cubic-bezier(.22,.61,.36,1));
}

/*
 * The overlay is always present at low strength and deepens on hover. It is
 * not decoration: the caption is white, and these are photographs whose upper
 * range we do not control, so without a wash the text would sit on whatever
 * happened to be in the bottom of the frame.
 */
.aipx-shot::after{
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to top,
		rgba(13, 10, 10, .78) 0%,
		rgba(13, 10, 10, .34) 38%,
		rgba(13, 10, 10, 0) 68%);
	opacity: .42;
	transition: opacity 380ms var(--aipx-ease-standard, ease);
	pointer-events: none;
}

.aipx-shot:hover::after,
.aipx-shot:focus-within::after{ opacity: 1; }

.aipx-shot:hover img,
.aipx-shot:focus-within img{ transform: scale(1.07); }

.aipx-shot-cap{
	position: absolute;
	left: var(--aipx-space-5);
	right: var(--aipx-space-5);
	bottom: var(--aipx-space-4);
	z-index: 1;
	font-family: var(--aipx-font-heading);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
	color: #FFFFFF;
	opacity: 0;
	transform: translateY(10px);
	transition: opacity 320ms var(--aipx-ease-standard, ease),
	            transform 320ms var(--aipx-ease-out, cubic-bezier(.22,.61,.36,1));
}

.aipx-shot:hover .aipx-shot-cap,
.aipx-shot:focus-within .aipx-shot-cap{ opacity: 1; transform: translateY(0); }

/* The mosaic. Placement is explicit so the shape does not change when the
   caption lengths do. */
.aipx-gallery > .aipx-shot:nth-child(1){ grid-column: span 2; grid-row: span 2; }
.aipx-gallery > .aipx-shot:nth-child(2){ grid-column: span 2; }
.aipx-gallery > .aipx-shot:nth-child(3){ grid-column: span 1; }
.aipx-gallery > .aipx-shot:nth-child(4){ grid-column: span 1; }
.aipx-gallery > .aipx-shot:nth-child(5){ grid-column: span 4; grid-row: span 1; }

@media (max-width: 900px){
	.aipx-gallery{ grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 160px; }
	.aipx-gallery > .aipx-shot:nth-child(1){ grid-column: span 2; grid-row: span 2; }
	.aipx-gallery > .aipx-shot:nth-child(2){ grid-column: span 2; }
	.aipx-gallery > .aipx-shot:nth-child(5){ grid-column: span 2; }
}

@media (max-width: 560px){
	.aipx-gallery{ grid-template-columns: minmax(0, 1fr); grid-auto-rows: 200px; }
	.aipx-gallery > .aipx-shot:nth-child(n){ grid-column: span 1; grid-row: span 1; }
	/* Touch has no hover, so the caption is simply always readable. */
	.aipx-shot::after{ opacity: 1; }
	.aipx-shot-cap{ opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce){
	.aipx-shot img,
	.aipx-shot::after,
	.aipx-shot-cap,
	.aipx-person{ transition: none; }
	.aipx-shot:hover img,
	.aipx-shot:focus-within img{ transform: none; }
	.aipx-person:hover{ transform: none; }
}


/* ---------------------------------------------------------------------------
 * Case study index
 *
 * Card leads on the client name because two of the ten studies have a featured
 * image and eight do not - a media grid would be mostly empty frames. Every
 * study does have a named client, which on a proof page carries more weight
 * than a stock photograph would.
 * ------------------------------------------------------------------------ */

.aipx-cs-archive{
	/* The template renders outside Kadence's content wrapper, so the width and
	   rhythm are set here rather than inherited. */
	max-width: var(--aipx-container, 1200px);
	margin: 0 auto;
	padding: 0 var(--aipx-space-6);
}

/* ---- hero ---- */
.aipx-cs-hero{
	background-color: var(--aipx-dark-bg);
	background-image:
		radial-gradient(58% 78% at 88% 44%, rgba(232, 49, 47, .30), transparent 66%),
		radial-gradient(26% 40% at 92% 34%, rgba(255, 106, 88, .20), transparent 70%);
	color: var(--aipx-dark-text-body);
}

.aipx-cs-hero-in{
	max-width: var(--aipx-container, 1200px);
	margin: 0 auto;
	padding: 88px var(--aipx-space-6) 84px;
}

/*
 * Scoped to the hero on purpose. `.aipx-dark p` sets the body colour at
 * specificity (0,2,1); a bare `.aipx-cs-eyebrow` is (0,1,0) and loses, so the
 * eyebrow rendered in muted grey instead of brand red.
 */
.aipx-cs-hero .aipx-cs-eyebrow{
	margin: 0 0 var(--aipx-space-4);
	font-family: var(--aipx-font-mono);
	font-size: 11.5px;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--aipx-brand-400, #FF6B5E);
}

.aipx-cs-h1{
	margin: 0;
	max-width: 20ch;
	font-family: var(--aipx-font-heading);
	font-size: clamp(32px, 5vw, 56px);
	font-weight: 800;
	line-height: 1.06;
	letter-spacing: -.03em;
	color: var(--aipx-dark-text-heading, #FFFFFF);
	text-wrap: balance;
}

.aipx-cs-hero .aipx-cs-standfirst{
	margin: var(--aipx-space-6) 0 0;
	max-width: 62ch;
	font-size: var(--aipx-body-lg);
	line-height: 1.6;
	color: var(--aipx-dark-text-muted);
}

/* Two figures, set as a description list so the label reads with the number. */
.aipx-cs-stats{
	display: flex;
	flex-wrap: wrap;
	gap: var(--aipx-space-10);
	margin: var(--aipx-space-10) 0 0;
}

.aipx-cs-stats div{ margin: 0; }

.aipx-cs-stats dt{
	font-family: var(--aipx-font-mono);
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--aipx-dark-text-muted);
}

.aipx-cs-stats dd{
	margin: 4px 0 0;
	font-family: var(--aipx-font-heading);
	font-size: 30px;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -.02em;
	color: var(--aipx-brand-400, #FF6B5E);
	font-variant-numeric: tabular-nums;
}

/* ---- filter row ---- */
/*
 * The industry filter tabs that used to sit here are gone, along with their
 * count chips and the "showing N in X" line. With twenty-six studies over ten
 * sectors most tabs returned one or two cards, so the row advertised the gaps
 * rather than the work. The index now pages through everything instead, using
 * the shared .aipx-blog-pager component.
 */

/* ---- grid ---- */
.aipx-cs-grid{
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
	gap: var(--aipx-space-5);
	margin-bottom: var(--aipx-space-16);
}

.aipx-cs-card{
	display: flex;
	flex-direction: column;
	padding: var(--aipx-space-8) var(--aipx-space-6) var(--aipx-space-6);
	background-color: var(--aipx-surface);
	border: 1px solid var(--aipx-border-subtle);
	transition: border-color var(--aipx-duration-base) var(--aipx-ease-standard),
	            box-shadow var(--aipx-duration-base) var(--aipx-ease-standard),
	            transform var(--aipx-duration-base) var(--aipx-ease-standard);
}

.aipx-cs-card:hover{
	border-color: var(--aipx-brand-300);
	box-shadow: 0 2px 22px -12px rgba(29, 29, 29, .32);
	transform: translateY(-2px);
}

.aipx-cs-sector{
	margin: 0 0 var(--aipx-space-3);
	font-family: var(--aipx-font-mono);
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--aipx-brand-500);
}

/* The card's anchor: a real company name, set at display size. */
.aipx-cs-client{
	margin: 0 0 var(--aipx-space-2);
	font-family: var(--aipx-font-heading);
	font-size: clamp(24px, 2.4vw, 30px);
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -.025em;
	color: var(--aipx-text-heading);
}

.aipx-cs-title{
	margin: 0 0 var(--aipx-space-4);
	padding-top: var(--aipx-space-4);
	border-top: 1px solid var(--aipx-border-subtle);
	font-family: var(--aipx-font-heading);
	font-size: var(--aipx-body-md);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: -.01em;
}

.aipx-cs-title a{
	color: var(--aipx-text-heading);
	text-decoration: none;
}

.aipx-cs-title a:hover{ color: var(--aipx-brand-500); }

.aipx-cs-excerpt{
	margin: 0 0 var(--aipx-space-6);
	font-size: var(--aipx-body-sm);
	line-height: 1.62;
	color: var(--aipx-text-body);
	/* Excerpts run 100 to 200 characters; four lines keeps every card's link on
	   the same baseline without clipping the shorter ones. */
	display: -webkit-box;
	-webkit-line-clamp: 4;
	line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.aipx-cs-link{
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: auto;
	font-size: var(--aipx-body-sm);
	font-weight: 600;
	color: var(--aipx-brand-500);
	text-decoration: none;
}

.aipx-cs-link svg{ transition: transform var(--aipx-duration-base) var(--aipx-ease-standard); }
.aipx-cs-card:hover .aipx-cs-link svg{ transform: translateX(3px); }

@media (max-width: 1024px){
	.aipx-cs-hero-in{ padding: 64px var(--aipx-space-6) 56px; }
	.aipx-cs-stats{ gap: var(--aipx-space-8); }
}

@media (max-width: 560px){
	.aipx-cs-grid{ grid-template-columns: minmax(0, 1fr); }
	.aipx-cs-stats{ gap: var(--aipx-space-6); }
	.aipx-cs-stats dd{ font-size: 26px; }
}

@media (prefers-reduced-motion: reduce){
	.aipx-cs-card,
	.aipx-cs-link svg{ transition: none; }
	.aipx-cs-card:hover{ transform: none; }
	.aipx-cs-card:hover .aipx-cs-link svg{ transform: none; }
}

/* ---------------------------------------------------------------------------
 * 38. Service categories as cards
 *
 * The services and industries lists ran 11 to 13 items per category, each with
 * a three-line description, in two columns beside a label rail. On a 900px
 * viewport that pushed the section past the fold before the reader had chosen
 * anything, and the rail's own 420px scroll cap hid half the categories.
 *
 * This variant collapses it. The categories render as a grid of cards carrying
 * their item count, and one category's list opens beneath the grid. The first
 * card is open on load so the section reads as content rather than an index. It layers over section 17 rather than replacing it,
 * because Kadence still owns tab activation and the mobile accordion, and it
 * carries !important for the same reason section 17 does: Kadence's vtabs
 * layout uses it and these rules sit at equal specificity.
 *
 * Everything here is desktop-only. Below 768px Kadence swaps to its own
 * accordion, whose headers live inside the content wrapper, so hiding that
 * wrapper at mobile widths would leave nothing on screen at all.
 * ------------------------------------------------------------------------ */

.aipx-svccards .kt-tabs-wrap{
	display: block !important;
	grid-template-columns: none !important;
	gap: 0 !important;
}

@media (min-width: 768px){
	/* The rail becomes the grid. Everything that made it a scrolling column has
	   to come off: the height cap, the fade mask and the scrollbar gutter. */
	.aipx-svccards .kt-tabs-title-list{
		display: grid !important;
		grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
		gap: 1px !important;
		max-height: none !important;
		overflow: visible !important;
		scrollbar-gutter: auto !important;
		-webkit-mask-image: none !important;
		        mask-image: none !important;
		background: var(--aipx-dark-border);
		border: 1px solid var(--aipx-dark-border);
		margin: 0 !important;
	}

	.aipx-svccards .kt-tabs-title-list li{
		border: 0 !important;
		margin: 0 !important;
		background: var(--aipx-dark-bg);
		transition: background var(--aipx-duration-base) var(--aipx-ease-standard);
	}

	.aipx-svccards .kt-tabs-title-list li a{
		display: flex !important;
		align-items: center;
		justify-content: space-between;
		gap: var(--aipx-space-4);
		min-height: 78px;
		padding: var(--aipx-space-5) var(--aipx-space-6) !important;
	}

	/* The site's one card interaction: fill red, flip the text white. */
	.aipx-svccards .kt-tabs-title-list li:hover,
	.aipx-svccards .kt-tabs-title-list li.kt-tab-title-active{
		background: var(--aipx-brand-500) !important;
		-webkit-backdrop-filter: none !important;
		        backdrop-filter: none !important;
	}

	.aipx-svccards .kt-tabs-title-list li:hover .kt-title-text,
	.aipx-svccards .kt-tabs-title-list li.kt-tab-title-active .kt-title-text{
		color: #FFFFFF !important;
	}

	.aipx-svccards .kt-tabs-title-list li:hover .aipx-cat-count,
	.aipx-svccards .kt-tabs-title-list li.kt-tab-title-active .aipx-cat-count{
		color: #FFFFFF;
		border-color: rgba(255, 255, 255, .55);
	}

	/* The first category opens on load; clicking its card closes it again. */
	.aipx-svccards[data-collapsed] .kt-tabs-content-wrap{ display: none !important; }

	.aipx-svccards .kt-tabs-content-wrap{ margin-top: var(--aipx-space-10); }
}

/* Count badge, written in by JS from the number of items in each panel. */
.aipx-cat-count{
	flex: none;
	font-family: var(--aipx-font-mono);
	font-size: 12px;
	line-height: 1;
	padding: 5px 8px;
	border: 1px solid var(--aipx-dark-border-strong);
	color: var(--aipx-dark-text-muted);
	font-variant-numeric: tabular-nums;
	transition: color var(--aipx-duration-base) var(--aipx-ease-standard),
	            border-color var(--aipx-duration-base) var(--aipx-ease-standard);
}

/* The open panel now spans the full width, so the list can take a third column. */
@media (min-width: 1025px){
	.aipx-svccards .aipx-svclist{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 768px) and (max-width: 1024px){
	.aipx-svccards .kt-tabs-title-list{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

/*
 * The stats band was designed without a heading and deliberately sits flush
 * against the section above it, which is why .aipx-stats zeroes its top padding.
 * The eleven AI pages now label their figures, and a label with no space above it
 * collides with the dark section ending directly overhead.
 *
 * Scoped with :has() so the 53 pages whose stats band is still headingless keep
 * the original tight treatment. Do not move this into the base .aipx-stats rule.
 */
.aipx-stats > .kt-row-column-wrap:has(h2, .aipx-sub-h){
	padding-top: var(--aipx-space-16) !important;
}
