/**
 * DigiOps design system.
 *
 * Ported from app/globals.css in the DigiOps Next.js site. Written as plain
 * CSS rather than Tailwind on purpose:
 *
 *   - Tailwind's Preflight is a global element reset. Inside WordPress it
 *     fights Elementor's own widget styles and can visibly break the editor
 *     chrome, and the usual fix (disabling Preflight) removes most of what
 *     Tailwind was contributing anyway.
 *   - Utility classes baked into a template cannot be overridden from the
 *     Elementor panel, so a client adjusting spacing there would find their
 *     changes ignored. Semantic classes leave the panel in charge.
 *   - It removes a build step from the client's deploy. The theme is a folder
 *     you upload; nothing has to be compiled.
 *
 * Section order mirrors the original stylesheet so the two stay comparable.
 */

/* ============================================================
   1. Tokens
   ============================================================ */

:root {
	--color-violet: #4245b4;
	--color-lavender: #ededfb;
	--color-tint: #d9daf5;
	--color-deep: #2c2e7e;
	--color-ink: #1b1c3a;
	--color-onv: #c9caf0;

	--font-display: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
	--font-body: "Manrope", ui-sans-serif, system-ui, sans-serif;

	--gradient-brand: linear-gradient(90deg, #8b5cf6 0%, #6325d0 30%, #466fff 65%, #58c7ff 100%);

	--section-pad: clamp(3.5rem, 8vw, 7rem);
	--radius-card: 1.25rem;
}

/* ============================================================
   2. Base
   ------------------------------------------------------------
   A deliberately small reset. It touches only what the design
   depends on, so Elementor's widgets keep their own defaults.
   ============================================================ */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: auto;
	scrollbar-width: thin;
	scrollbar-color: var(--color-violet) #fff;
	-webkit-text-size-adjust: 100%;
	/* Full-bleed bands are sized in vw, which counts the scrollbar and so
	   overhangs the viewport by its width. Clip it at the root: `clip` rather
	   than `hidden` because `hidden` on the root silently disables
	   position: sticky, which the header depends on. */
	overflow-x: clip;
}

body {
	margin: 0;
	background: #fff;
	color: var(--color-ink);
	font-family: var(--font-body);
	font-weight: 500;
	/* 1.5, not 1.6: Tailwind's preflight sets html { line-height: 1.5 } and the
	   original never overrides it. 1.6 made every run of body text ~6% taller. */
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	overflow-x: clip;
}

img,
video {
	max-width: 100%;
	height: auto;
}

a {
	color: inherit;
}

::selection {
	background: var(--color-violet);
	color: #fff;
}

::-webkit-scrollbar {
	width: 6px;
}

::-webkit-scrollbar-track {
	background: #fff;
}

::-webkit-scrollbar-thumb {
	background: var(--color-violet);
	border-radius: 99px;
}

/* ============================================================
   3. Typography
   ============================================================ */

.font-display {
	font-family: var(--font-display);
}

.h-hero,
.h-xl,
.h-lg,
.h-md {
	font-family: var(--font-display);
	margin: 0;
}

.h-hero {
	font-weight: 700;
	letter-spacing: -0.03em;
	line-height: 0.98;
	font-size: clamp(2.75rem, 7.2vw, 7rem);
}

.h-xl {
	font-weight: 700;
	letter-spacing: -0.03em;
	line-height: 1.02;
	font-size: clamp(2.25rem, 5.4vw, 5rem);
}

.h-lg {
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.05;
	font-size: clamp(1.75rem, 3.6vw, 3.25rem);
}

.h-md {
	font-weight: 600;
	letter-spacing: -0.02em;
	line-height: 1.1;
	font-size: clamp(1.35rem, 2.2vw, 1.9rem);
}

.label {
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	margin: 0;
}

.text-gradient-brand {
	background: var(--gradient-brand);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* ---------- word mask reveal ----------
   Each word is wrapped in .wm and its inner span in .wm-i, so the inner
   span can be slid up from below while the wrapper clips it. The padding /
   negative margin pair gives descenders room inside the clip. */

.wm {
	display: inline-block;
	overflow: hidden;
	vertical-align: bottom;
	padding-bottom: 0.08em;
	margin-bottom: -0.08em;
}

.wm-i {
	display: inline-block;
	will-change: transform;
}

/* stack a masked-text reveal one word per line */
.stack-words .wm {
	display: block;
}

/*
 * The word-mask reveal itself — the CSS counterpart of TextReveal.tsx.
 *
 * The original slid each .wm-i up from yPercent 120 with a 0.03s stagger on
 * a power4.out curve. Here each word carries its own --wm-i index, so the
 * same stagger falls out of a transition-delay, and the easing below is the
 * closest cubic-bezier to power4.out.
 *
 * Words only start hidden once the document is marked `js`. Without
 * JavaScript, or under reduced motion, the text is simply there — a headline
 * stuck at translateY(120%) would be an invisible page.
 */
.js [data-digiops-wm] .wm-i {
	transform: translateY(120%);
	transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
	transition-delay: calc( var(--wm-delay, 0s) + var(--wm-i, 0) * 0.03s );
}

.js [data-digiops-wm].is-revealed .wm-i {
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.js [data-digiops-wm] .wm-i {
		transform: none;
		transition: none;
	}
}

/* React's TextReveal accents a **word** with this class; the gradient variant
   is opt-in per section rather than the default. */
.text-violet {
	color: var(--color-violet);
}

.text-white {
	color: #fff;
}

/*
 * The rest of the palette as text utilities. In the original these came free
 * from Tailwind's @theme (text-onv, text-ink, …); the theme loads no Tailwind,
 * so they must exist here or a template that emits one silently renders in the
 * inherited colour — the AutoBGV and DevServiceList eyebrows came out white
 * instead of on-violet. One rule per @theme colour token, so none is missing.
 */
.text-onv {
	color: var(--color-onv);
}

.text-ink {
	color: var(--color-ink);
}

.text-deep {
	color: var(--color-deep);
}

.text-tint {
	color: var(--color-tint);
}

.text-lavender {
	color: var(--color-lavender);
}

/* ============================================================
   4. Layout
   ============================================================ */

.container-x {
	width: 100%;
	max-width: 84rem;
	margin-inline: auto;
	padding-inline: clamp(1.25rem, 4vw, 4rem);
}

/*
 * No blanket section padding. There used to be a
 * `.site-main > section { padding-block: var(--section-pad) }` here, left over
 * from the theme's first, generic draft. Its specificity (0,1,1) beat every
 * section's own single-class padding rule, so any section sitting directly in
 * <main> was silently flattened to the same ~112px — the closing CTA rendered
 * at 112px where the original's md:py-40 is 160px. Each ported section now
 * owns its vertical rhythm, exactly as each React component did.
 * --section-pad remains available for a section that wants the default.
 */

/* A hero supplies its own vertical rhythm. (The marquee sets its own padding
   in assets/css/sections/marquee.css and is deliberately not zeroed here.) */
.site-main > .digiops-hero,
.site-main > .digiops-page-hero {
	padding-block: 0;
}

/* ============================================================
   5. Buttons
   ============================================================ */

.pill {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	border-radius: 999px;
	/* every pill carries a 1.5px border so solid and outlined buttons are the
	   same size; solid variants leave it transparent, outlined ones colour it */
	border: 1.5px solid transparent;
	padding: 0.95rem 2rem;
	font-family: var(--font-body);
	font-weight: 700;
	font-size: 0.95rem;
	line-height: 1.5;
	letter-spacing: 0.01em;
	text-decoration: none;
	cursor: pointer;
	white-space: nowrap;
	/* colour only: buttons change colour on hover but never move */
	transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.pill-violet {
	background: var(--color-violet);
	color: #fff;
}

.pill-violet:hover {
	background: var(--color-deep);
}

.pill-white {
	background: #fff;
	color: var(--color-violet);
}

.pill-white:hover {
	background: var(--color-lavender);
}

.pill-ghost-white {
	border-color: rgba(255, 255, 255, 0.6);
	color: #fff;
}

.pill-ghost-white:hover {
	border-color: #fff;
	background: rgba(255, 255, 255, 0.08);
}

.pill-ghost-ink {
	border-color: var(--color-tint);
	color: var(--color-ink);
}

.pill-ghost-ink:hover {
	border-color: var(--color-violet);
	color: var(--color-violet);
}

.tagpill {
	display: inline-flex;
	align-items: center;
	/* Often a <p>, as in the manifesto tag row: zero its default 1em margin,
	   the way .label and the .h-* classes do. */
	margin: 0;
	border-radius: 999px;
	padding: 0.32rem 0.85rem;
	font-size: 0.78rem;
	font-weight: 700;
	background: var(--color-lavender);
	color: var(--color-deep);
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.3s ease, color 0.3s ease;
}

/* tag pill sitting on a violet / dark ground */
.tagpill-onv {
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
}

.digiops-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 0.85rem;
	margin-top: 2rem;
}

/* ============================================================
   6. Link underline sweep
   ============================================================ */

.u-sweep {
	position: relative;
	text-decoration: none;
}

.u-sweep::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: -3px;
	width: 100%;
	height: 1.5px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: right center;
	transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.u-sweep:hover::after,
.u-sweep.is-active::after {
	transform: scaleX(1);
	transform-origin: left center;
}

/* ============================================================
   7. Reveal on scroll
   ------------------------------------------------------------
   The original site hid elements at opacity 0 and faded them in
   with GSAP. Doing that here would leave a blank page for any
   visitor without JavaScript, so the hidden state is applied
   only once the document is marked `js`, and is skipped
   entirely when the visitor asks for reduced motion.
   ============================================================ */

.js [data-digiops-reveal] {
	opacity: 0;
	transform: translateY(18px);
	/* Longhands, never the `transition` shorthand. The shorthand also sets
	   transition-delay to 0s, and at this specificity (0,2,0) it silently beat
	   every section that staggers its reveals with a plain class rule — the
	   AutoBGV hero's 0.1 / 0.3 / 0.4s sequence all fired at once. Leaving the
	   delay unset here lets a section's own transition-delay always apply. */
	transition-property: opacity, transform;
	transition-duration: 0.7s;
	transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
	will-change: opacity, transform;
}

.js [data-digiops-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.js [data-digiops-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
	}

	/* Looping decoration is switched off outright rather than sped up —
	   an infinite animation at 0.01ms still repaints forever. */
	.marquee-track,
	.spin-y,
	.cap-fade,
	.eq-bar,
	.product-glow,
	.product-aurora,
	.shield-pulse,
	.home-hero-scrim,
	.home-hero-scrim::before,
	.home-hero-scrim::after {
		animation: none;
	}

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

/* ============================================================
   8. Header
   ============================================================ */

.digiops-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: #fff;
	transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

.digiops-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding-block: 1rem;
}

.digiops-header__title {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.35rem;
	letter-spacing: -0.02em;
	text-decoration: none;
}

.digiops-header.is-over-dark {
	background: transparent;
	color: #fff;
}

.digiops-header.is-stuck {
	box-shadow: 0 1px 0 rgba(27, 28, 58, 0.08);
}

.digiops-nav__list {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 2.4vw, 2.25rem);
	margin: 0;
	padding: 0;
	list-style: none;
	font-weight: 600;
	font-size: 0.95rem;
}

.digiops-nav__list a {
	text-decoration: none;
	position: relative;
}

.digiops-nav__list a:hover {
	color: var(--color-violet);
}

.digiops-header.is-over-dark .digiops-nav__list a:hover {
	color: #fff;
	opacity: 0.75;
}

/* Sub-menus open on hover and on keyboard focus alike. */
.digiops-nav__list .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	min-width: 14rem;
	margin: 0;
	padding: 0.75rem 0;
	list-style: none;
	background: #fff;
	color: var(--color-ink);
	border-radius: 0.9rem;
	box-shadow: 0 18px 40px rgba(27, 28, 58, 0.14);
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}

.digiops-nav__list li {
	position: relative;
}

.digiops-nav__list li:hover > .sub-menu,
.digiops-nav__list li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.digiops-nav__list .sub-menu a {
	display: block;
	padding: 0.5rem 1.25rem;
	font-weight: 500;
}

.digiops-header__actions {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.digiops-burger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--color-ink);
	cursor: pointer;
}

.digiops-burger__bar {
	display: block;
	width: 18px;
	height: 1.5px;
	margin-inline: auto;
	background: #fff;
	transition: transform 0.3s ease, opacity 0.3s ease;
}

.digiops-burger[aria-expanded="true"] .digiops-burger__bar:first-child {
	transform: translateY(3.25px) rotate(45deg);
}

.digiops-burger[aria-expanded="true"] .digiops-burger__bar:last-child {
	transform: translateY(-3.25px) rotate(-45deg);
}

.digiops-mobile-nav {
	border-top: 1px solid var(--color-tint);
	background: #fff;
	color: var(--color-ink);
}

.digiops-mobile-nav__list {
	margin: 0;
	padding: 1rem clamp(1.25rem, 4vw, 4rem) 1.5rem;
	list-style: none;
	display: grid;
	gap: 0.85rem;
	font-weight: 600;
}

.digiops-mobile-nav__list .sub-menu {
	margin: 0.5rem 0 0;
	padding-left: 1rem;
	list-style: none;
	display: grid;
	gap: 0.5rem;
	font-weight: 500;
	opacity: 0.8;
}

.digiops-mobile-nav a {
	text-decoration: none;
}

@media (max-width: 1023px) {
	.digiops-nav,
	.digiops-header__cta {
		display: none;
	}

	.digiops-burger {
		display: flex;
	}
}

@media (min-width: 1024px) {
	.digiops-mobile-nav {
		display: none !important;
	}
}

/* ============================================================
   9. Hero
   ------------------------------------------------------------
   The generic hero that used to live here has been removed.
   It defined a second, conflicting .digiops-hero* set — a
   different scrim ramp, body size and padding — that tied on
   specificity with the real port in assets/css/sections/hero.css
   and with .home-hero/.home-hero-scrim, so which one won came
   down to source order. The faithful values now live in the
   section stylesheet; .digiops-page-hero keeps its own rules
   below because no React component backs it.
   ============================================================ */

.digiops-page-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	background-color: #04061c;
	background-size: cover;
	background-position: center;
	color: #fff;
}

.digiops-page-hero__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	padding-block: clamp(4.5rem, 10vw, 7rem);
}

.digiops-page-hero__eyebrow {
	color: var(--color-onv);
	margin-bottom: 1.25rem;
}

.digiops-page-hero__heading {
	max-width: 22ch;
}

.digiops-page-hero__body {
	max-width: 46ch;
	margin: 1.5rem 0 0;
	font-size: clamp(1rem, 1.5vw, 1.2rem);
	color: rgba(255, 255, 255, 0.82);
}

.digiops-page-hero .digiops-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: 0;
	background: radial-gradient(135% 105% at 50% 45%, rgba(2, 2, 12, 0.6) 0%, rgba(2, 2, 12, 0.82) 100%);
}
/* ============================================================
   10. Marquee
   ============================================================ */

@keyframes digiops-marquee-x {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

/* The original stylesheet named this animation `marquee-x`. Markup copied
   across from the React site can set `animation-name: marquee-x` inline, so
   the original name is kept as an alias. */
@keyframes marquee-x {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}




.marquee {
	overflow: hidden;
	width: 100%;
}

.marquee-track {
	display: flex;
	width: max-content;
	align-items: center;
	animation: digiops-marquee-x var(--marquee-dur, 30s) linear infinite;
	will-change: transform;
}

.marquee-hover-pause:hover .marquee-track {
	animation-play-state: paused;
}

/* hide scrollbars on drag-carousels */
.no-scrollbar {
	scrollbar-width: none;
}

.no-scrollbar::-webkit-scrollbar {
	display: none;
}




.outline-word {
	color: transparent;
	-webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.65);
	transition: color 0.35s ease;
}

.outline-word:hover {
	color: #fff;
}

.outline-word-dark {
	color: transparent;
	-webkit-text-stroke: 1px rgba(27, 28, 58, 0.5);
	transition: color 0.35s ease;
}

.outline-word-dark:hover {
	color: var(--color-ink);
}

/* ============================================================
   11. Services index
   ============================================================ */

.digiops-services__heading {
	max-width: 18ch;
	margin-bottom: 3rem;
}

.digiops-services__list {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--color-tint);
}

.digiops-services__item {
	border-bottom: 1px solid var(--color-tint);
}

.digiops-services__link {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: clamp(1rem, 3vw, 2.5rem);
	padding-block: clamp(1.5rem, 3vw, 2.25rem);
	text-decoration: none;
	transition: color 0.3s ease;
}

a.digiops-services__link:hover {
	color: var(--color-violet);
}

.digiops-services__num {
	color: var(--color-violet);
}

.digiops-services__body {
	display: grid;
	gap: 0.5rem;
}

.digiops-services__pitch {
	max-width: 56ch;
	font-size: 0.98rem;
	opacity: 0.72;
}

.digiops-services__art {
	display: block;
	width: clamp(4.5rem, 10vw, 8rem);
	aspect-ratio: 3 / 2;
	overflow: hidden;
	border-radius: 0.85rem;
}

.digiops-services__art img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

@media (max-width: 640px) {
	.digiops-services__link {
		grid-template-columns: auto 1fr;
	}

	.digiops-services__art {
		display: none;
	}
}

/* ============================================================
   12. Stacked journey
   ============================================================ */

.digiops-journey__heading {
	max-width: 18ch;
	margin-bottom: 3rem;
}

.digiops-journey__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: clamp(1.25rem, 3vw, 2rem);
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: none;
}

.digiops-journey__step {
	padding: clamp(1.5rem, 3vw, 2.25rem);
	border: 1px solid var(--color-tint);
	border-radius: var(--radius-card);
	background: #fff;
	transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.digiops-journey__step:hover {
	border-color: var(--color-violet);
	box-shadow: 0 18px 40px rgba(27, 28, 58, 0.08);
}

.digiops-journey__num {
	color: var(--color-violet);
}

.digiops-journey__title {
	margin: 1rem 0 0.65rem;
}

.digiops-journey__body {
	margin: 0;
	font-size: 0.98rem;
	opacity: 0.72;
}

/* ============================================================
   13. Testimonials
   ============================================================ */

.digiops-testimonials {
	background: var(--color-lavender);
}

.digiops-testimonials__heading {
	max-width: 18ch;
	margin-bottom: 3rem;
}

.digiops-testimonials__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
	gap: clamp(1.25rem, 3vw, 2rem);
}

.digiops-testimonials__card {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 1.75rem;
	margin: 0;
	padding: clamp(1.5rem, 3vw, 2.25rem);
	background: #fff;
	border-radius: var(--radius-card);
}

.digiops-testimonials__quote {
	margin: 0;
	font-size: 1.05rem;
	line-height: 1.55;
}

.digiops-testimonials__quote::before {
	content: "\201C";
}

.digiops-testimonials__quote::after {
	content: "\201D";
}

.digiops-testimonials__person {
	display: flex;
	align-items: center;
	gap: 0.85rem;
}

.digiops-testimonials__avatar {
	width: 56px;
	height: 56px;
	border-radius: 999px;
	object-fit: cover;
}

.digiops-testimonials__name {
	display: block;
	font-weight: 700;
}

.digiops-testimonials__role {
	display: block;
	font-size: 0.88rem;
	opacity: 0.66;
}

/* ============================================================
   14. FAQ
   ============================================================ */

.digiops-faq__heading {
	margin-bottom: 2.5rem;
}

.digiops-faq__list {
	max-width: 52rem;
	border-top: 1px solid var(--color-tint);
}

.digiops-faq__item {
	border-bottom: 1px solid var(--color-tint);
}

.digiops-faq__question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding-block: 1.35rem;
	font-family: var(--font-display);
	font-weight: 600;
	font-size: clamp(1.05rem, 1.6vw, 1.3rem);
	cursor: pointer;
	list-style: none;
}

/* Hide the native disclosure triangle in both engines. */
.digiops-faq__question::-webkit-details-marker {
	display: none;
}

.digiops-faq__icon {
	position: relative;
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
}

.digiops-faq__icon::before,
.digiops-faq__icon::after {
	content: "";
	position: absolute;
	inset: 50% 0 auto 0;
	height: 1.5px;
	background: var(--color-violet);
	transition: transform 0.3s ease;
}

.digiops-faq__icon::after {
	transform: rotate(90deg);
}

.digiops-faq__item[open] .digiops-faq__icon::after {
	transform: rotate(0deg);
}

.digiops-faq__answer {
	padding-bottom: 1.5rem;
	max-width: 62ch;
	opacity: 0.75;
}

.digiops-faq__answer p {
	margin: 0;
}

/* ============================================================
   15. CTA finale
   ============================================================ */

.digiops-cta {
	position: relative;
	overflow: hidden;
	background: #04061c;
	color: #fff;
	text-align: center;
}

.digiops-cta__glow {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(46% 56% at 92% 6%, rgba(66, 69, 180, 0.32), transparent 70%),
		radial-gradient(40% 50% at 4% 96%, rgba(47, 107, 255, 0.22), transparent 70%);
}

.digiops-cta__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.digiops-cta__heading {
	max-width: 20ch;
}

.digiops-cta__body {
	max-width: 46ch;
	margin: 1.25rem 0 0;
	color: rgba(255, 255, 255, 0.78);
}

/* ============================================================
   16. Blog
   ============================================================ */

.digiops-blog__heading {
	max-width: 18ch;
	margin-bottom: 3rem;
}

.digiops-blog__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
	gap: clamp(1.25rem, 3vw, 2rem);
}

.digiops-blog__card {
	border-radius: var(--radius-card);
	overflow: hidden;
	background: #fff;
	border: 1px solid var(--color-tint);
	transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.digiops-blog__card:hover {
	border-color: var(--color-violet);
	box-shadow: 0 18px 40px rgba(27, 28, 58, 0.08);
}

.digiops-blog__link {
	display: grid;
	gap: 0.65rem;
	text-decoration: none;
	height: 100%;
	align-content: start;
}

.digiops-blog__art {
	display: block;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	margin-bottom: 0.5rem;
}

.digiops-blog__art img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.digiops-blog__card:hover .digiops-blog__art img {
	transform: scale(1.04);
}

.digiops-blog__meta,
.digiops-blog__title,
.digiops-blog__excerpt {
	padding-inline: clamp(1.1rem, 2vw, 1.5rem);
}

.digiops-blog__meta {
	color: var(--color-violet);
	font-size: 0.7rem;
}

.digiops-blog__excerpt {
	padding-bottom: clamp(1.25rem, 2vw, 1.75rem);
	font-size: 0.96rem;
	opacity: 0.72;
}

/* ============================================================
   17. Form slot
   ============================================================ */

.digiops-formsection__inner {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
	gap: clamp(2rem, 5vw, 4rem);
	align-items: start;
}

.digiops-formsection__body {
	margin-top: 1.1rem;
	max-width: 44ch;
	opacity: 0.75;
}

.digiops-formsection__placeholder {
	padding: 1.25rem;
	border: 1px dashed var(--color-tint);
	border-radius: var(--radius-card);
	font-size: 0.9rem;
	opacity: 0.7;
}

/*
 * Style whatever the form plugin outputs. Selectors are intentionally
 * generic so WPForms, Contact Form 7 and Fluent Forms all inherit the
 * design without the theme depending on any one of them.
 */
.digiops-formsection input[type="text"],
.digiops-formsection input[type="email"],
.digiops-formsection input[type="tel"],
.digiops-formsection input[type="url"],
.digiops-formsection input[type="number"],
.digiops-formsection select,
.digiops-formsection textarea {
	width: 100%;
	padding: 0.9rem 1.1rem;
	border: 1.5px solid var(--color-tint);
	border-radius: 0.75rem;
	background: #fff;
	color: var(--color-ink);
	font-family: var(--font-body);
	font-size: 1rem;
	transition: border-color 0.25s ease;
}

.digiops-formsection input:focus,
.digiops-formsection select:focus,
.digiops-formsection textarea:focus {
	outline: none;
	border-color: var(--color-violet);
}

.digiops-formsection button[type="submit"],
.digiops-formsection input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 999px;
	border: 1.5px solid transparent;
	padding: 0.95rem 2rem;
	background: var(--color-violet);
	color: #fff;
	font-family: var(--font-body);
	font-weight: 700;
	font-size: 0.95rem;
	cursor: pointer;
	transition: background-color 0.3s ease;
}

.digiops-formsection button[type="submit"]:hover,
.digiops-formsection input[type="submit"]:hover {
	background: var(--color-deep);
}

/* ============================================================
   18. Footer
   ============================================================ */

.digiops-footer {
	background: #04061c;
	color: #fff;
}

.digiops-footer__inner {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
	gap: clamp(2rem, 4vw, 3.5rem);
	padding-block: clamp(3rem, 6vw, 5rem);
}

.digiops-footer__title {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.6rem;
	letter-spacing: -0.02em;
	text-decoration: none;
}

.digiops-footer__tagline {
	margin: 0.75rem 0 0;
	max-width: 32ch;
	opacity: 0.66;
	font-size: 0.95rem;
}

.digiops-footer__contact {
	display: grid;
	gap: 0.6rem;
	align-content: start;
	font-size: 0.98rem;
}

.digiops-footer__contact a {
	justify-self: start;
	text-decoration: none;
}

.digiops-footer__list,
.digiops-footer__legal-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.digiops-footer__list {
	display: grid;
	gap: 0.6rem;
	font-size: 0.98rem;
}

.digiops-footer__list a {
	text-decoration: none;
	opacity: 0.8;
	transition: opacity 0.25s ease;
}

.digiops-footer__list a:hover {
	opacity: 1;
}

.digiops-footer__legal {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 1.5rem;
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	font-size: 0.85rem;
	opacity: 0.6;
}

.digiops-footer__legal p {
	margin: 0;
}

.digiops-footer__legal-list {
	display: flex;
	flex-wrap: wrap;
	gap: 1.25rem;
}

.digiops-footer__legal-list a {
	text-decoration: none;
}

/* ============================================================
   19. Prose, comments, pagination
   ============================================================ */

.digiops-prose {
	max-width: 48rem;
	padding-block: clamp(2.5rem, 5vw, 4rem);
	font-size: 1.05rem;
	line-height: 1.75;
}

.digiops-prose > * + * {
	margin-top: 1.4em;
}

.digiops-prose h2 {
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 3vw, 2.25rem);
	letter-spacing: -0.02em;
	line-height: 1.15;
	margin-top: 2.2em;
}

.digiops-prose h3 {
	font-family: var(--font-display);
	font-size: clamp(1.25rem, 2.2vw, 1.6rem);
	letter-spacing: -0.01em;
	margin-top: 1.8em;
}

.digiops-prose a {
	color: var(--color-violet);
	text-underline-offset: 3px;
}

.digiops-prose blockquote {
	margin-inline: 0;
	padding-left: 1.25rem;
	border-left: 2px solid var(--color-violet);
	font-size: 1.15rem;
}

.digiops-prose img {
	border-radius: var(--radius-card);
}

.digiops-prose code {
	padding: 0.15em 0.4em;
	border-radius: 0.35rem;
	background: var(--color-lavender);
	font-size: 0.9em;
}

.digiops-prose pre {
	padding: 1.25rem;
	border-radius: var(--radius-card);
	background: var(--color-ink);
	color: #fff;
	overflow-x: auto;
}

.digiops-single__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	padding-bottom: 2rem;
}

.digiops-postnav {
	display: flex;
	justify-content: space-between;
	gap: 1.5rem;
	padding-bottom: clamp(3rem, 6vw, 5rem);
	font-weight: 600;
}

.digiops-postnav a {
	text-decoration: none;
}

.digiops-pagination {
	display: flex;
	justify-content: center;
	padding-block: 3rem;
}

.digiops-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5rem;
	height: 2.5rem;
	padding-inline: 0.5rem;
	margin-inline: 0.15rem;
	border-radius: 999px;
	text-decoration: none;
	font-weight: 600;
}

.digiops-pagination .page-numbers.current {
	background: var(--color-violet);
	color: #fff;
}

.digiops-comments {
	max-width: 48rem;
	padding-block: clamp(2.5rem, 5vw, 4rem);
}

.digiops-comments__list {
	margin: 2rem 0;
	padding: 0;
	list-style: none;
}

.digiops-comments__list .children {
	margin-left: 1.5rem;
	list-style: none;
	padding-left: 0;
}

.digiops-comments__list .comment-body {
	padding-block: 1.25rem;
	border-bottom: 1px solid var(--color-tint);
}

.digiops-none,
.digiops-404 {
	display: grid;
	justify-items: start;
	gap: 1.5rem;
	padding-block: clamp(3rem, 6vw, 5rem);
}

.digiops-404 {
	justify-items: center;
}

/* ============================================================
   20. Motion primitives
   ------------------------------------------------------------
   The loops the original site runs on its product cards and its
   3D hero mark. Each is a named keyframe plus the one class
   that carries it, so markup can opt in without any JS.
   ============================================================ */

/* live voice equalizer: each bar breathes on its own phase */
@keyframes eq-bounce {
	0%,
	100% {
		transform: scaleY(0.4);
	}
	50% {
		transform: scaleY(1);
	}
}

.eq-bar {
	transform-box: fill-box;
	transform-origin: center;
	animation: eq-bounce 1.25s ease-in-out infinite;
	will-change: transform;
}

/* the card glow slowly breathes and drifts */
@keyframes glow-breathe {
	0%,
	100% {
		transform: translate(-50%, 0) scale(1);
		opacity: 0.8;
	}
	50% {
		transform: translate(-50%, 5%) scale(1.22);
		opacity: 1;
	}
}

.product-glow {
	animation: glow-breathe 7s ease-in-out infinite;
	will-change: transform, opacity;
}

/* a second wash sliding across the card for a gradient shimmer */
@keyframes gradient-pan {
	0%,
	100% {
		transform: translate3d(-18%, 0, 0);
	}
	50% {
		transform: translate3d(18%, 0, 0);
	}
}

.product-aurora {
	animation: gradient-pan 11s ease-in-out infinite;
	will-change: transform;
}

/* slow pulse for the verification shield */
@keyframes shield-pulse {
	0%,
	100% {
		transform: scale(1);
		opacity: 0.9;
	}
	50% {
		transform: scale(1.05);
		opacity: 1;
	}
}

.shield-pulse {
	animation: shield-pulse 4.5s ease-in-out infinite;
	will-change: transform, opacity;
}

/* ---------- 3d hero mark ---------- */

.persp {
	perspective: 1200px;
}

.preserve-3d {
	transform-style: preserve-3d;
}

@keyframes spin-y {
	from {
		transform: rotateY(0deg);
	}
	to {
		transform: rotateY(360deg);
	}
}

.spin-y {
	animation: spin-y 14s linear infinite;
	transform-style: preserve-3d;
}

/* the capability grid re-runs this each time a category is picked */
@keyframes cap-fade-in {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

.cap-fade {
	animation: cap-fade-in 0.4s ease-out;
}

/* ============================================================
   21. Interactive components
   ============================================================ */

/* ---------- accordion (grid rows trick) ---------- */
.acc-panel {
	display: grid;
	/* minmax 0/0fr, not bare 0fr: the auto component of a grid row still
	   defers to the min-content size of its content unless explicitly
	   bounded, so bare 0fr leaves a sliver of the first line visible while
	   closed — the minmax form is what actually lets the row hit zero.
	   overflow:hidden here (not just on the child below) is what actually
	   clips that child once the row shrinks past its natural height —
	   without it the grid track resizes correctly but the child still
	   paints at its own content height, poking out past the 0px row. */
	grid-template-rows: minmax(0, 0fr);
	overflow: hidden;
	transition: grid-template-rows 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

.acc-panel.open {
	grid-template-rows: minmax(0, 1fr);
}

.acc-panel > div {
	overflow: hidden;
}

/* ---------- services index row ---------- */
.srow-bg {
	position: absolute;
	inset: 0;
	background: var(--color-lavender);
	transform: scaleY(0);
	transform-origin: bottom center;
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform;
}

.srow:hover .srow-bg,
.srow.open .srow-bg {
	transform: scaleY(1);
}

.srow-num {
	transition: color 0.4s ease;
}

.srow:hover .srow-num,
.srow.open .srow-num {
	color: var(--color-violet);
}

/* ---------- work card ---------- */
.workcard .workcover {
	transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform;
}

.workcard:hover .workcover {
	transform: scale(1.05);
}

.workcard .worktitle {
	background-image: linear-gradient(currentColor, currentColor);
	background-size: 0% 1.5px;
	background-repeat: no-repeat;
	background-position: 0 100%;
	transition: background-size 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.workcard:hover .worktitle {
	background-size: 100% 1.5px;
	color: var(--color-violet);
}

/* ---------- bento cards ---------- */
.bento {
	border-radius: 1.25rem;
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.5s ease;
	will-change: transform;
}

.bento:hover {
	transform: translateY(-6px);
	box-shadow: 0 24px 60px -30px rgba(44, 46, 126, 0.35);
}

/* ============================================================
   22. Shared decorative surfaces
   ------------------------------------------------------------
   From here to section 28 the rules are pure paint: gradients,
   photo grounds and masks lifted unchanged from the original
   stylesheet. Image paths are the one thing that changes —
   the site's /public folder lives at assets/images/ here.
   ============================================================ */

/* vertical indigo-tinted wash + ambient glows — used by the home blog
   section and the tinted final-CTA variant */
.wash-indigo {
	background: linear-gradient(180deg, #ffffff 0%, #f3f4fd 34%, #ebedfa 62%, #ffffff 100%);
}

.wash-indigo-glow {
	background:
		radial-gradient(40% 48% at 74% 14%, rgba(66, 69, 180, 0.16), transparent 70%),
		radial-gradient(36% 44% at 12% 64%, rgba(126, 134, 232, 0.16), transparent 70%),
		radial-gradient(32% 40% at 94% 86%, rgba(66, 69, 180, 0.12), transparent 70%);
}

/* photo-backed final-CTA variant */
.cta-photo {
	background-color: #e9e9ee;
	background-image: url(../images/about/about-contact.webp);
	background-size: cover;
	background-position: right center;
}

/* ============================================================
   23. Home page surfaces
   ============================================================ */

/* static hero: single background image over a brand-violet base */
.home-hero {
	background-color: var(--color-violet);
	background-image: url(../images/Home_BG.webp);
	background-size: cover;
	background-position: center;
}

/* dark gradient overlay that keeps the centered white copy legible over the
   background image, and slowly drifts for a subtle living sheen. Only this
   overlay animates — the background image itself stays still. */
.home-hero-scrim {
	/* medium-dark base so the image is toned down (visible but not too bright) */
	background: radial-gradient(135% 105% at 50% 45%, rgba(4, 4, 16, 0.42) 0%, rgba(4, 4, 16, 0.66) 100%);
	overflow: hidden;
	/* the whole overlay slowly breathes darker/lighter — a clearly visible,
	   colourless pulse on top of the wandering shadow pools */
	animation: hero-breathe 9s ease-in-out infinite;
}

@keyframes hero-breathe {
	0%,
	100% {
		opacity: 0.55;
	}
	50% {
		opacity: 1;
	}
}

/* two dark blobs wander to scattered positions across the hero on non-matching
   timers — a shifting pool of deeper shadow that both dims the image further
   where it passes and makes the motion clearly noticeable */
.home-hero-scrim::before,
.home-hero-scrim::after {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	height: 62%;
	width: 42%;
	border-radius: 50%;
	filter: blur(70px);
	will-change: transform, opacity;
}

.home-hero-scrim::before {
	background: radial-gradient(circle, rgba(2, 2, 12, 0.62), transparent 62%);
	animation: hero-glow-a 21s ease-in-out infinite;
}

.home-hero-scrim::after {
	background: radial-gradient(circle, rgba(3, 4, 20, 0.58), transparent 62%);
	animation: hero-glow-b 27s ease-in-out infinite;
}

/* scattered, non-collinear waypoints so the drift feels random */
@keyframes hero-glow-a {
	0% {
		transform: translate(15%, 8%) scale(1);
		opacity: 0.6;
	}
	22% {
		transform: translate(115%, 55%) scale(1.3);
		opacity: 0.85;
	}
	45% {
		transform: translate(140%, 6%) scale(0.9);
		opacity: 0.7;
	}
	68% {
		transform: translate(35%, 62%) scale(1.25);
		opacity: 0.9;
	}
	85% {
		transform: translate(80%, 18%) scale(1.05);
		opacity: 0.7;
	}
	100% {
		transform: translate(15%, 8%) scale(1);
		opacity: 0.6;
	}
}

@keyframes hero-glow-b {
	0% {
		transform: translate(125%, 48%) scale(1.2);
		opacity: 0.55;
	}
	26% {
		transform: translate(20%, 10%) scale(0.9);
		opacity: 0.85;
	}
	52% {
		transform: translate(150%, 60%) scale(1.3);
		opacity: 0.7;
	}
	74% {
		transform: translate(55%, 30%) scale(1);
		opacity: 0.9;
	}
	100% {
		transform: translate(125%, 48%) scale(1.2);
		opacity: 0.55;
	}
}

/* Phones hold the overlay still. The breathing pulse and the two drifting
   blobs are the expensive part of this hero — large blurred layers being
   recomposited every frame — and the motion reads as noise on a small
   screen. The scrim settles at its darkest keyframe, which is the state
   the copy was checked against, and the blobs are dropped rather than
   frozen so they can't park as a dark patch in the top-left corner. */
@media (max-width: 767px) {
	.home-hero-scrim {
		animation: none;
	}

	.home-hero-scrim::before,
	.home-hero-scrim::after {
		display: none;
	}
}

/* readability without a dark overlay: soften the copy onto the image */
.home-hero h1,
.home-hero p {
	text-shadow: 0 2px 26px rgba(0, 0, 0, 0.55);
}

/* Pastel aurora echoing the hero's beat colours. One definition for every
   section that sits on it: the home manifesto, the promo process band and
   the AutoBGV journey. */
.home-manifesto-glow,
.promo-process-glow,
.journey-glow {
	background:
		radial-gradient(44% 58% at 10% 96%, rgba(255, 170, 100, 0.5), transparent 70%),
		radial-gradient(52% 62% at 48% 104%, rgba(125, 130, 235, 0.44), transparent 70%),
		radial-gradient(46% 56% at 88% 94%, rgba(105, 175, 235, 0.52), transparent 70%);
}

/* services index: icy diagonal band */
.home-services {
	background: linear-gradient(-30deg, #b9d8f1 0%, #ffffff 25%, #ffffff 75%, #b9d8f1 100%);
}

/* products: dark premium ground + fine dotted texture */
.home-products {
	background:
		radial-gradient(120% 70% at 50% -10%, #1b1c33 0%, #0b0b12 55%),
		radial-gradient(50% 40% at 85% 8%, rgba(66, 69, 180, 0.28), transparent 70%);
}

.home-products-texture {
	background-image: repeating-radial-gradient(circle at 20% 30%, #fff 0 1px, transparent 1px 26px);
}

/* highlight/portfolio band: light grey diagonal */
.home-highlight {
	background: linear-gradient(135deg, #e9ecf1 0%, #ffffff 50%, #e9ecf1 100%);
}

/* get in touch: soft indigo wash settling to white before the footer */
.home-getintouch {
	background: linear-gradient(180deg, #eef0fb 0%, #f7f8fd 42%, #ffffff 80%);
}

/* faint starfield inside the violet contact panel */
.home-contact-starfield {
	background-image:
		radial-gradient(1.5px 1.5px at 12% 18%, rgba(255, 255, 255, 0.55), transparent 60%),
		radial-gradient(1.5px 1.5px at 68% 8%, rgba(255, 255, 255, 0.45), transparent 60%),
		radial-gradient(1.5px 1.5px at 88% 32%, rgba(255, 255, 255, 0.5), transparent 60%),
		radial-gradient(1.5px 1.5px at 28% 52%, rgba(255, 255, 255, 0.35), transparent 60%),
		radial-gradient(1.5px 1.5px at 78% 62%, rgba(255, 255, 255, 0.45), transparent 60%),
		radial-gradient(1.5px 1.5px at 42% 86%, rgba(255, 255, 255, 0.4), transparent 60%),
		radial-gradient(1.5px 1.5px at 8% 74%, rgba(255, 255, 255, 0.3), transparent 60%),
		radial-gradient(70% 55% at 78% 78%, rgba(255, 255, 255, 0.16), transparent 70%);
}

/* footer: darkened mesh-wave backdrop under the brand gradient */
.home-footer-mesh {
	background-image: url(../images/footer-bg.webp);
	background-size: cover;
	background-position: center;
}

/* footer: brand gradient masked to fade upward */
.home-footer-glow {
	background: linear-gradient(90deg, #06064a 0%, #6325d0 28%, #466fff 52%, #2f6bff 78%, #4b3bff 100%);
	-webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.55) 42%, transparent 100%);
	mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.55) 42%, transparent 100%);
}

/* ============================================================
   24. About page surfaces
   ============================================================ */

/* story section: white aurora with two soft brand glows */
.about-story {
	background:
		linear-gradient(180deg, #ffffff 0%, #f6f7fd 45%, #ffffff 100%),
		radial-gradient(40% 48% at 12% 18%, rgba(66, 69, 180, 0.14), transparent 70%),
		radial-gradient(36% 44% at 88% 72%, rgba(126, 134, 232, 0.16), transparent 70%);
}

/* core-values band: logo-toned edges fading to white in the centre */
.about-values {
	background: linear-gradient(-30deg, #c7c7e2 0%, #e4e4f3 28%, #ffffff 50%, #e4e4f3 72%, #c7c7e2 100%);
}

/* hero: dark canvas easing into brand blue at the base */
.about-hero {
	background: radial-gradient(
		108% 78% at 50% 130%,
		#4d88ff 0%,
		#2350dc 20%,
		#11256e 40%,
		#071033 58%,
		#020417 76%,
		#000006 100%
	);
}

.about-hero-photo {
	background-image: url(../images/about/about-DIGI.webp);
	background-size: cover;
	background-position: right center;
	-webkit-mask-image: linear-gradient(to left, #000 0%, rgba(0, 0, 0, 0.55) 38%, transparent 78%);
	mask-image: linear-gradient(to left, #000 0%, rgba(0, 0, 0, 0.55) 38%, transparent 78%);
}

.about-hero-sheen {
	background: linear-gradient(
		115deg,
		transparent 26%,
		rgba(140, 175, 255, 0.16) 46%,
		rgba(140, 175, 255, 0.05) 56%,
		transparent 68%
	);
}

/* what-we-do: soft grey/white gradient with faint violet glows, plus photo texture */
.about-whatwedo {
	background:
		radial-gradient(55% 50% at 12% 8%, rgba(66, 69, 180, 0.07), transparent 70%),
		radial-gradient(50% 45% at 92% 90%, rgba(66, 69, 180, 0.06), transparent 70%),
		linear-gradient(180deg, #ffffff 0%, #f7f7fb 50%, #ffffff 100%);
}

.about-whatwedo-photo {
	background-image: url(../images/about/about.webp);
	background-size: cover;
	background-position: center;
	-webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
	mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
}

/* vision/mission band: black shoulders around a centred indigo core */
.about-vision {
	background: linear-gradient(
		100deg,
		#000000 0%,
		#26262e 25%,
		#3730a3 49%,
		#3730a3 51%,
		#26262e 75%,
		#000000 100%
	);
}

/* clientele: faint brand glow so the black doesn't read flat */
.about-clientele-glow {
	background: radial-gradient(60% 100% at 50% 0%, rgba(99, 37, 208, 0.35), transparent 70%);
}

/* ============================================================
   25. Web design & development page surfaces
   ============================================================ */

.web-hero {
	background-color: #04061c;
	background-image: url(../images/web.webp);
	background-size: cover;
	background-position: center;
}

/* dark scrim over the photo — keeps the hero copy legible and matches the
   darkened treatment used on the home hero (.home-hero-scrim) */
.web-hero-scrim {
	background: radial-gradient(135% 105% at 50% 45%, rgba(2, 2, 12, 0.6) 0%, rgba(2, 2, 12, 0.82) 100%);
}

/* web-development page only — lighter center fade than the shared .web-hero-scrim */
.web-dev-hero-scrim {
	background: radial-gradient(135% 105% at 50% 45%, rgb(2 2 12 / 1%) 0%, rgba(2, 2, 12, 0.82) 100%);
}

.web-hero-glow {
	background:
		radial-gradient(42% 52% at 86% 18%, rgba(99, 37, 208, 0.38), transparent 70%),
		radial-gradient(36% 46% at 8% 42%, rgba(66, 69, 180, 0.32), transparent 70%);
}

.web-services-glow {
	background:
		radial-gradient(46% 56% at 92% 6%, rgba(66, 69, 180, 0.22), transparent 70%),
		radial-gradient(40% 50% at 4% 96%, rgba(47, 107, 255, 0.16), transparent 70%);
}

.web-dev-glow {
	background:
		radial-gradient(62% 72% at 6% 8%, rgba(139, 92, 246, 0.22), transparent 70%),
		radial-gradient(40% 50% at 96% 94%, rgba(47, 107, 255, 0.14), transparent 70%);
}

/* stronger variant — same recipe, more visible */
.web-dev-glow-strong {
	background:
		radial-gradient(68% 78% at 6% 8%, rgba(139, 92, 246, 0.4), transparent 72%),
		radial-gradient(48% 58% at 96% 94%, rgba(47, 107, 255, 0.3), transparent 72%);
}

/* closed service card: black easing into indigo-blue */
.web-card-idle {
	background: linear-gradient(150deg, #06060f 0%, #0e1030 46%, #23327f 100%);
}

/* design section: pastel gradient photo background */
.web-design-bg {
	background-color: #f3f3f5;
	background-image: url(../images/design-bg.jpg);
	background-size: cover;
	background-position: center;
}

/* same gradient image as .web-design-bg, applied to a rotated oversized layer
   (kept separate so the rotation doesn't affect web-development's Design section) */
.dm-services-bg {
	background-image: url(../images/design-bg.jpg);
	background-size: cover;
	background-position: center;
}

.web-stats-bg {
	background: linear-gradient(120deg, #06064a 0%, #2c2e7e 34%, #4245b4 62%, #2f6bff 100%);
}

/* ============================================================
   26. Contact page surfaces
   ============================================================ */

.contact-hero-bg {
	background-color: #04061c;
	background-image: url(../images/bg8.webp);
	background-size: cover;
	background-position: center;
}

/* dark scrim over the photo so the hero copy and white form card stay legible */
.contact-hero-scrim {
	background: radial-gradient(135% 105% at 50% 45%, rgba(2, 2, 12, 0.55) 0%, rgba(2, 2, 12, 0.88) 100%);
}

.contact-hero-glow {
	background:
		radial-gradient(46% 60% at 88% 8%, rgba(139, 92, 246, 0.3), transparent 70%),
		radial-gradient(40% 54% at 8% 92%, rgba(47, 107, 255, 0.2), transparent 70%);
}

/* ============================================================
   27. Blog, training and AutoBGV surfaces
   ============================================================ */

.blog-hero-bg {
	/* the colour also covers the moment before the artwork has loaded */
	background-color: #0a0618;
	background-image: url(../images/bg12.webp);
	background-size: cover;
	background-position: center;
}

.training-hero-bg {
	/* the colour also covers the moment before the artwork has loaded */
	background-color: #05050a;
	background-image: url(../images/bg12.webp);
	background-size: cover;
	background-position: center;
}

@media (min-width: 1024px) {
	/* Bleeds the CTA band's photo to the true right edge of the screen while
	   the text column stays on container-x's grid — same maths as the
	   agent-band panel bleed below: the gap from this element's content
	   edge to the screen edge is container-x's own padding, plus half of
	   whatever the viewport overshoots the 84rem max-width by. Needs
	   overflow-hidden on the section since 100vw counts the scrollbar and
	   this can overrun by a few px. */
	.training-cta-image {
		margin-right: calc(-1 * (max(0px, (100vw - 84rem) / 2) + clamp(1.25rem, 4vw, 4rem)));
	}
}

/* faceted gradient blob behind the hero wordmark, an original stand-in for
   the reference's 3D render — same idea (a colourful shape with bold type
   laid over it) built from the brand gradient instead */
.training-hero-shape {
	background: conic-gradient(from 200deg at 50% 45%, #58c7ff, #466fff, #6325d0, #8b5cf6, #58c7ff);
	border-radius: 42% 58% 63% 37% / 47% 41% 59% 53%;
	filter: blur(0.5px);
}

.training-hero-shape::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: radial-gradient(60% 50% at 30% 25%, rgba(255, 255, 255, 0.35), transparent 60%);
}

/* dark-to-lighter-blue backdrop for the "why learn from an agency" band */
.training-why-bg {
	background: linear-gradient(135deg, #0b0e2e 0%, #23288f 50%, #4a5bf0 100%);
}

.autobgv-hero-bg {
	/* the colour also covers the moment before the artwork has loaded */
	background-color: #05050f;
	background-image: url("../images/bg17.webp");
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.autobgv-hero-glow {
	background:
		/* Listed first so it paints over the three glows below it: darkens the
		   middle of the frame, where the headline and buttons sit, so they read
		   cleanly against the brighter wave lines in the artwork. Fades out well
		   before the edges, leaving the artwork and the glows intact there. */
		radial-gradient(
			75% 68% at 50% 42%,
			rgba(4, 6, 20, 0.82),
			rgba(4, 6, 20, 0.5) 45%,
			rgba(4, 6, 20, 0) 78%
		),
		radial-gradient(45% 60% at 50% 0%, rgba(139, 92, 246, 0.32), transparent 70%),
		radial-gradient(40% 50% at 88% 90%, rgba(47, 107, 255, 0.2), transparent 70%),
		radial-gradient(35% 45% at 8% 85%, rgba(139, 92, 246, 0.16), transparent 70%);
}

.autobgv-caps-glow {
	background:
		radial-gradient(55% 65% at 8% 10%, rgba(139, 92, 246, 0.22), transparent 70%),
		radial-gradient(40% 50% at 95% 90%, rgba(47, 107, 255, 0.16), transparent 70%);
}

/* ============================================================
   28. Agent network band (AutoBGV)
   ------------------------------------------------------------
   One continuous band of flush panels with square corners,
   running light -> brand -> light -> dark, each stamped with
   its own number.
   ============================================================ */

.agent-band {
	display: grid;
	grid-template-columns: 1fr;
	box-shadow: 0 26px 60px -22px rgba(27, 28, 58, 0.3);
}

@media (min-width: 768px) {
	.agent-band {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	/* the dark panel carries the widest column, as in the reference */
	.agent-band {
		grid-template-columns: 1fr 1fr 1fr 1.22fr;
	}
}

/* the last panel runs off the right edge of the screen, so the band has to
   be allowed to spill out of the section without opening a scrollbar */
.agent-section {
	overflow-x: clip;
}

.agent-panel {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	padding: 2rem 1.6rem 2.25rem;
	transition: transform 0.35s ease, box-shadow 0.35s ease;
}

.agent-panel:hover {
	transform: scale(1.03);
	z-index: 5;
	box-shadow: 0 22px 46px -16px rgba(27, 28, 58, 0.42);
}

@media (min-width: 1024px) {
	/* Bleed the last panel to the right edge of the viewport. container-x is
	   centred at max-width 84rem with padding-inline clamp 1.25rem/4vw/4rem,
	   so the distance from its content edge to the screen edge is that padding
	   plus whatever the viewport overshoots the max-width by. 100vw counts the
	   scrollbar, so this overruns by a few px — .agent-section clips it. */
	.agent-band > .agent-panel:last-child {
		margin-right: calc(-1 * (max(0px, (100vw - 84rem) / 2) + clamp(1.25rem, 4vw, 4rem)));
	}

	.agent-panel {
		padding: 2.25rem 1.9rem 2.5rem;
	}
}

.agent-panel--light {
	background: #ffffff;
}

.agent-panel--brand {
	background: linear-gradient(150deg, #4a4dc4 0%, #3a3da8 45%, #2c2e7e 100%);
}

.agent-panel--dark {
	background: linear-gradient(160deg, #101740 0%, #0a0f2c 55%, #05081c 100%);
}

/* Scrim over the node web: keeps the text edge calm while the network stays
   readable towards the outer edge, the way the reference panel reads. */
.agent-panel--dark::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -5;
	background: linear-gradient(
		105deg,
		rgba(5, 8, 28, 0.93) 0%,
		rgba(5, 8, 28, 0.66) 55%,
		rgba(5, 8, 28, 0.22) 100%
	);
}

.agent-panel--light .agent-title {
	color: var(--color-ink);
}

.agent-panel--brand .agent-title,
.agent-panel--dark .agent-title {
	color: #ffffff;
}

.agent-panel--light .agent-list {
	color: rgba(27, 28, 58, 0.65);
}

.agent-panel--brand .agent-list {
	color: rgba(255, 255, 255, 0.8);
}

.agent-panel--dark .agent-list {
	color: rgba(255, 255, 255, 0.72);
}

.agent-panel--light .agent-dot {
	background: var(--color-violet);
}

.agent-panel--brand .agent-dot {
	background: rgba(255, 255, 255, 0.85);
}

.agent-panel--dark .agent-dot {
	background: #56bdea;
}

/* ============================================================
   29. Stacked-step journey figure
   ============================================================ */

.journey-bg {
	background: #ffffff;
}

/* One fixed-aspect stage: the plate stack, the callouts and the connector
   lines are all positioned in % of this box, so the diagram scales as a
   single unit and the elbows stay attached to their plates. */
.journey-figure {
	width: 100%;
	max-width: 1120px;
	/* One ratio at every width. It was 16/12 below 1280px back when the
	   callouts ran at leading-relaxed and stood 117px tall; at leading-snug
	   they are ~104px, so that headroom just became dead space above and
	   below the diagram. Do not stretch this much further — the three
	   callouts down each side are what set the floor, and at 1024px (the
	   narrowest width this is shown at) they are already only ~37px apart.
	   Below lg the stacked layout runs instead, since three callouts a side
	   need real width. */
	aspect-ratio: 16 / 9;
	/* The empty band below the lowest callout is trimmed with a negative
	   margin set from JS — see the trim effect in StackedStepJourney. It is
	   measured rather than expressed here because a percentage margin would
	   resolve against the container's width, not this element's, and so would
	   overshoot once the figure stops growing at max-width. */
}

/* ============================================================
   29b. Word fill
   ------------------------------------------------------------
   The port of components/WordFill.tsx, shared by every section
   that uses it (the home manifesto and the closing CTA). Markup
   comes from digiops_word_fill() and the scrub from theme.js.

   It lived in two places once, as two section scripts with their
   own CSS, and they drifted: one reproduced GSAP's scrub
   smoothing and the other did not. One owner now.

   Each word is stacked twice: the base sits in the pale tint and
   an overlay in ink (violet when **accented**) fades in over it,
   word by word, as the heading scrolls through.
   ============================================================ */

.wf {
	position: relative;
	display: inline-block;
	color: var(--color-tint);
}

.wf-top {
	position: absolute;
	inset: 0;
	color: var(--color-ink);
}

.wf-top.is-accent {
	color: var(--color-violet);
}

/* WordFill's `light` prop, for dark backgrounds. */
.wf--light {
	color: rgba(255, 255, 255, 0.3);
}

.wf--light .wf-top {
	color: #fff;
}

.wf--light .wf-top.is-accent {
	color: #b3b8ff;
}

/* Overlays are hidden only once the script has armed the heading, which it
   does only after confirming it can run. Every other path — no JavaScript,
   reduced motion, a blocked script, an error before arming — leaves the words
   filled and readable. Pale tint on white is decoration, not copy, so it is
   never the resting state. No transition: opacity is written per frame and a
   transition would fight the scrub. */
[data-digiops-wordfill].is-wf-armed .wf-top {
	opacity: 0;
}

/* components/Magnetic.tsx. It once pulled its child toward the cursor; the
   site later decided buttons should stay put, so it became a plain
   inline-block wrapper kept only for layout. Deliberately no behaviour here —
   porting the old cursor effect would reintroduce something the original
   removed on purpose. A caller's layout classes (e.g. `block w-full` on form
   buttons) go on alongside this in the section's own CSS. */
.digiops-magnetic {
	display: inline-block;
}

/*
 * Inside the Elementor editor everything is shown at once. Scroll reveals,
 * word masks and word fills all start hidden and wait for the visitor to
 * scroll; in the editor's canvas that meant a client clicked a section and
 * saw a blank white band while editing its text in the panel. Motion is for
 * visitors, not for the person editing.
 */
.elementor-editor-active [data-digiops-reveal],
.elementor-editor-active .wm-i {
	opacity: 1 !important;
	transform: none !important;
	transition: none !important;
}

/* Three sections stagger their children instead of the wrapper (FAQ rows,
   the Home product cards, the AutoBGV agent panels), so the children are
   what stays hidden until the reveal fires. */
.elementor-editor-active [data-digiops-reveal] > .digiops-faq__item,
.elementor-editor-active [data-digiops-reveal] > .digiops-products__card-wrap,
.elementor-editor-active [data-digiops-reveal] > .agent-panel {
	opacity: 1 !important;
	transform: none !important;
	translate: none !important;
}

/* The header is fixed and floats over the first section. It is not edited in
   Elementor (Menus and the Customizer drive it), so in the editor clicks pass
   through it to the section underneath — otherwise the top 65px of every
   page's hero could not be selected. Layout is unchanged. */
.elementor-editor-active [data-digiops-header] {
	pointer-events: none;
}

.elementor-editor-active [data-digiops-wordfill].is-wf-armed .wf-top,
.elementor-editor-active .wf-top {
	opacity: 1 !important;
}

/* ------------------------------------------------------------
   Contact Form 7 inside the theme's form sections.

   The CF7 form carries the section's own form class (html_class), so the
   design's layout already applies. These rules only restyle what CF7 adds
   around the fields, to match the original's error line (#dc2626, 0.875rem,
   600) instead of CF7's coloured boxes. Scoped to the theme's forms, so a CF7
   form placed elsewhere keeps CF7's defaults.
   ------------------------------------------------------------ */
.wpcf7 form[class*="digiops-"] .wpcf7-form-control-wrap {
	display: block;
}

.wpcf7 form[class*="digiops-"] .wpcf7-not-valid-tip {
	margin-top: 0.375rem;
	font-size: 0.8125rem;
	line-height: 1.125rem;
	font-weight: 600;
	color: #dc2626;
}

.wpcf7 form[class*="digiops-"] .wpcf7-not-valid {
	border-color: #dc2626;
}

.wpcf7 form[class*="digiops-"] .wpcf7-response-output {
	margin: 1rem 0 0;
	padding: 0;
	border: 0;
	font-size: 0.875rem;
	line-height: 1.25rem;
	font-weight: 600;
	color: #dc2626;
}

.wpcf7 form[class*="digiops-"].sent .wpcf7-response-output {
	color: var(--color-violet);
}

.wpcf7 form[class*="digiops-"].submitting button[type="submit"] {
	opacity: 0.7;
	cursor: progress;
	pointer-events: none;
}

/* Shown in place of an enquiry form that has nowhere to post. */
.digiops-form-offline__notice {
	margin: 0 0 1rem;
	padding: 0.9rem 1.1rem;
	border: 1px dashed var(--color-tint);
	border-radius: 0.75rem;
	font-size: 0.85rem;
	opacity: 0.8;
}

.digiops-form-offline__lead {
	margin: 0;
	font-size: 1.05rem;
	font-weight: 600;
}

.digiops-form-offline__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin: 1.25rem 0 0;
}

/* ============================================================
   30. WordPress required classes
   ------------------------------------------------------------
   Every theme must style these, whether or not the design uses
   them, because the editor can output them at any time.
   ============================================================ */

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

.screen-reader-text:focus {
	clip-path: none;
	display: block;
	top: 5px;
	left: 5px;
	z-index: 100000;
	width: auto;
	height: auto;
	padding: 0.85rem 1.5rem;
	background: #fff;
	color: var(--color-violet);
	border-radius: 999px;
	font-weight: 700;
	text-decoration: none;
}

.skip-link {
	position: absolute;
}

.alignleft {
	float: left;
	margin-right: 1.5rem;
	margin-bottom: 1rem;
}

.alignright {
	float: right;
	margin-left: 1.5rem;
	margin-bottom: 1rem;
}

.aligncenter {
	display: block;
	margin-inline: auto;
}

.alignwide {
	max-width: 72rem;
	margin-inline: auto;
}

.alignfull {
	max-width: none;
	margin-inline: calc(50% - 50vw);
	width: 100vw;
}

.wp-caption {
	max-width: 100%;
}

.wp-caption-text,
.gallery-caption {
	margin-top: 0.5rem;
	font-size: 0.88rem;
	opacity: 0.7;
	text-align: center;
}

.sticky .digiops-blog__title::after {
	content: "★";
	margin-left: 0.4rem;
	color: var(--color-violet);
}

.bypostauthor > .comment-body .fn::after {
	content: " ✓";
	color: var(--color-violet);
}

/* Visible focus for keyboard users everywhere. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--color-violet);
	outline-offset: 3px;
	border-radius: 4px;
}

/* ============================================================
   31. Elementor compatibility
   ------------------------------------------------------------
   Sections are designed as full-bleed bands and bring their own
   padding. Elementor wraps every widget in its own container,
   so without these rules each section would sit inside a second
   set of margins and the vertical rhythm would read as double.
   ============================================================ */

.digiops-elementor-widget {
	width: 100%;
}

/*
 * Four of the sections are designed as full-bleed bands that run edge to edge.
 * Elementor's default container is boxed, so dropping a hero into a page would
 * otherwise render it inside a narrow column and the design would read as
 * broken. These break back out to the viewport width.
 *
 * `overflow-x: clip` on body absorbs the scrollbar-width difference between
 * 100vw and the visible area, so this cannot introduce a horizontal scrollbar.
 *
 * A container set to Full Width in Elementor needs none of this and is
 * unaffected — the margins resolve to zero.
 */
/* Elementor wraps widget output in .elementor-widget-container, except when
   a site has its "optimized markup" experiment on, where that wrapper is
   absent. Both shapes are matched so the theme works either way. */
.digiops-elementor-widget > .digiops-hero,
.digiops-elementor-widget > .digiops-page-hero,
.digiops-elementor-widget > .digiops-cta,
.digiops-elementor-widget > .digiops-marquee,
.digiops-elementor-widget > .elementor-widget-container > .digiops-hero,
.digiops-elementor-widget > .elementor-widget-container > .digiops-page-hero,
.digiops-elementor-widget > .elementor-widget-container > .digiops-cta,
.digiops-elementor-widget > .elementor-widget-container > .digiops-marquee {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/*
 * Inside the Elementor editor a section with no content yet would collapse to
 * nothing and become impossible to select. Give empty widgets a minimum
 * height, but only in the editor.
 */
.elementor-editor-active .digiops-elementor-widget:empty {
	min-height: 120px;
	border: 1px dashed var(--color-tint);
}

/* Elementor Canvas has no theme header, so the sticky offset is irrelevant. */
.elementor-template-canvas .digiops-header {
	display: none;
}

/* ------------------------------------------------------------------
   Home: the white page that slides over the pinned hero.
   app/page.tsx wraps everything after HeroSection in
   `relative z-10 bg-white`, which is what lets the hero stay pinned
   underneath while the rest scrolls over it.
   ------------------------------------------------------------------ */
.home-overlay {
	position: relative;
	z-index: 10;
	background: #fff;
}
