/* Qyx AI Dashboard - glassmorphism, glows, premium SaaS tweaks. */

:root {
	--qyx-bg: hsl(0 0% 98%); /* must match --background so SVG dividers blend seamlessly */
	--qyx-ink: #0f172a;

	/* UI tokens - subtle border, primary text, faint hover surface. */
	--qyx-border: rgba(15, 23, 42, 0.10);
	--qyx-text: #0f172a;
	--qyx-surface: rgba(15, 23, 42, 0.05);

	/* Source theme tokens - needed by header-landing.php classes. */
	--background: 0 0% 98%;
	--foreground: 0 0% 17%;
	--heading-foreground: 0 0% 17%;
	--primary: 0 0% 0%;
	--primary-foreground: 0 0% 100%;

	--gradient-1: #5AAAF6;
	--gradient-2: #D52FCA;
	--gradient-3: #FF4754;
	--gradient-4: #FFB33B;
	--gradient-5: #43CC3E;
	--gradient-stops: var(--gradient-1), var(--gradient-2), var(--gradient-3), var(--gradient-4), var(--gradient-5);

	/* Dark-section glow palette (features + generators ambient/aurora). */
	--qyx-violet: #7a61b2;
	--qyx-aurora-blue: #527aad;
	--qyx-aurora-indigo: #6455d4;
	--qyx-aurora-cyan: #3fd0d6;
}

/* Custom utilities for source-theme color tokens (HSL-based).
   These mirror the Tailwind theme.extend.colors that the SCSS source assumes. */
.text-foreground { color: hsl(var(--foreground)); }
.text-background { color: hsl(var(--background)); }
.bg-background { background-color: hsl(var(--background)); }
.bg-foreground { background-color: hsl(var(--foreground)); }
.bg-heading-foreground { background-color: hsl(var(--heading-foreground)); }
.fill-foreground { fill: hsl(var(--foreground)); }
.fill-background { fill: hsl(var(--background)); }
.border-foreground\/5 { border-color: hsl(var(--foreground) / 0.05); }
.text-foreground\/30 { color: hsl(var(--foreground) / 0.30); }
.text-foreground\/40 { color: hsl(var(--foreground) / 0.40); }
.text-foreground\/50 { color: hsl(var(--foreground) / 0.50); }
.text-foreground\/60 { color: hsl(var(--foreground) / 0.60); }
.text-foreground\/70 { color: hsl(var(--foreground) / 0.70); }
.hover\:text-foreground:hover { color: hsl(var(--foreground)); }
.hover\:text-background:hover { color: hsl(var(--background)); }
.hover\:border-background:hover { border-color: hsl(var(--background)); }
.hover\:bg-background:hover { background-color: hsl(var(--background)); }
.hover\:bg-foreground:hover { background-color: hsl(var(--foreground)); }

/* Header dark-mode hover override - when site-header has .is-dark (over a dark
   section), hovering a CTA changes BG to white. Force readable dark text
   regardless of Tailwind variant compilation. Targets the rounded-full pill CTAs
   (Sign In, Join Hub, Dashboard) but not the logo or burger. */
.site-header.is-dark a.rounded-full:hover,
.site-header.is-dark a.rounded-full:hover .relative,
.site-header.is-dark a.rounded-full:hover > span {
	color: hsl(var(--foreground)) !important;
}
.site-header.is-dark button.rounded-full:hover,
.site-header.is-dark button.rounded-full:hover svg {
	color: hsl(var(--foreground)) !important;
}

/* Outline-glow base - gradient ring around CTAs (Sign In / Join Hub / Dashboard).
   Source base lives in the parent "default" theme; this is a faithful rebuild
   so the buttons render correctly until you paste the original base SCSS. */
.lqd-outline-glow {
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.3s ease;
	z-index: 0;
}
.lqd-outline-glow::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	padding: var(--outline-glow-w, 2px);
	background: conic-gradient(from 290deg, var(--gradient-1), var(--gradient-2), var(--gradient-3), var(--gradient-4), var(--gradient-5));
	-webkit-mask:
		linear-gradient(#fff 0 0) content-box,
		linear-gradient(#fff 0 0);
	mask:
		linear-gradient(#fff 0 0) content-box,
		linear-gradient(#fff 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
}
.lqd-outline-glow-custom::before {
	background: conic-gradient(from 290deg, var(--gradient-1), var(--gradient-2), var(--gradient-3), var(--gradient-4), var(--gradient-5));
}

/* Source-theme typography utilities used by hero. */
.font-body { font-family: var(--font-body, 'Inter'), 'Inter', ui-sans-serif, system-ui, sans-serif; }
.font-heading { font-family: var(--font-heading, 'Spline Sans'), 'Spline Sans', ui-sans-serif, system-ui, sans-serif; }
.text-3xs { font-size: 0.6875rem; line-height: 1rem; } /* ~11px */

/* Hero H1 - matches source `--h1-font-size: 4.75rem` (76px) with responsive scaling. */
.banner-title {
	font-family: var(--font-heading, 'Spline Sans'), 'Inter', ui-sans-serif, system-ui, sans-serif;
	font-size: clamp(2.25rem, 4vw + 1rem, 3.5rem); /* ~36px mobile -> ~56px desktop (friendlier than the old 76px) */
	font-weight: 600;
	letter-spacing: var(--h1-letter-spacing, -0.01em);
	line-height: 1.1;
	color: hsl(var(--heading-foreground));
}

/* Text rotator - width transitions handled by JS reading active item width. */
.lqd-text-rotator { vertical-align: bottom; }
.lqd-text-rotator-item > span {
	background: linear-gradient(90deg, var(--gradient-1), var(--gradient-2), var(--gradient-3), var(--gradient-4), var(--gradient-5));
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* Hero entrance - staggered fade + slide-up for the badge, headline, copy, CTAs
   and the screencast.

   Deliberately a CSS animation and NOT a JS class toggle. This block used to be
   Tailwind `group-[.page-loaded]/body:` variants, with .page-loaded added to
   <body> on window.load. The hero holds the LCP element (the hero video's
   poster), and while it sits at opacity:0 it cannot count as painted - so LCP
   could never beat the load event. Measured on throttled mobile (Slow 4G + 4x
   CPU) that put LCP at 8.4s against a 2.5s budget, because `load` waits on six
   render-blocking third-party CDN scripts. DOMContentLoaded is no escape either:
   it measured 7.37s, since it also waits for those same scripts to execute.

   A CSS animation runs as soon as the element renders, so the hero now paints
   with the first frame the browser produces and owes nothing to any script.

   Per-element timing comes from two custom properties set inline in hero.php:
     --qyx-hero-delay  stagger (was Tailwind delay-150 / delay-300 / ...)
     --qyx-hero-shift  slide distance (was translate-y-3 / -6 / -7)
   See template-parts/landing/hero.php. */
@keyframes qyxHeroIn {
	from { opacity: 0; transform: translateY(var(--qyx-hero-shift, 0)); }
	to   { opacity: 1; transform: none; }
}
.qyx-hero-in {
	animation: qyxHeroIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: var(--qyx-hero-delay, 0ms);
}
@media (prefers-reduced-motion: reduce) {
	.qyx-hero-in { animation: none; opacity: 1; transform: none; }
}

/* ============================================================
   Hero product screencast (right column). Replaced the 2-row widget
   carousel. The clip carries its own gradient backdrop and browser
   chrome, so the frame around it stays quiet - radius plus a layered
   shadow to lift it off the hero, and nothing that competes with it.
   ============================================================ */
.qyx-hero-video {
	position: relative;
	border-radius: 1.25rem; /* 20px - same card language as the rest of the hero */
	overflow: hidden;
	box-shadow:
		0 18px 40px -12px rgba(15, 23, 42, 0.28),
		0 4px 10px -4px rgba(15, 23, 42, 0.12);
	isolation: isolate;
}

/* Hairline ring drawn over the clip, so its gradient edge reads as an edge
   rather than bleeding into the hero background. */
.qyx-hero-video::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	border-radius: inherit;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
}

/* The width/height attributes on <video> reserve the box, so height:auto here
   scales it without shifting layout while the poster/first frame arrives. */
.qyx-hero-video__media {
	display: block;
	width: 100%;
	height: auto;
}

/* Play button over the poster. Sits under the hairline ring (z-index 1) but over the
   clip, and steps aside the moment playback starts so the native controls own the
   frame - that bar is what gives fullscreen. */
.qyx-hero-video__play {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: grid;
	place-items: center;
	padding: 0;
	border: 0;
	background: hsl(240 6% 8% / 22%);
	cursor: pointer;
	transition: opacity 0.25s ease, background 0.25s ease;
}
.qyx-hero-video__play svg {
	width: 72px;
	height: 72px;
	padding: 22px;
	border-radius: 9999px;
	background: hsl(0 0% 100% / 94%);
	color: #16161a;
	box-shadow: 0 10px 30px hsl(0 0% 0% / 30%);
	transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), background 0.25s ease;
}
.qyx-hero-video__play:hover { background: hsl(240 6% 8% / 12%); }
.qyx-hero-video__play:hover svg { transform: scale(1.08); background: #fff; }
.qyx-hero-video__play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; }
.qyx-hero-video__media.is-playing ~ .qyx-hero-video__play {
	opacity: 0;
	pointer-events: none;
}
@media (max-width: 767px) {
	.qyx-hero-video__play svg { width: 56px; height: 56px; padding: 17px; }
}

@media (prefers-reduced-motion: reduce) {
	.qyx-hero-video { transition: none; }
	.qyx-hero-video__play, .qyx-hero-video__play svg { transition: none; }
	.qyx-hero-video__play:hover svg { transform: none; }
}
/* Curved section dividers - fill matches body bg so the transition between
   light and dark sections has zero visible seam. Use a very shallow curve
   (matches reference site) so the white "shoulders" against the tinted hero
   gradient stay minimal and the seam stays invisible. */
.qyx-features__divider path,
.qyx-generators__divider path {
	fill: var(--qyx-bg);
}

/* Features dark section - glassmorphism cards + ambient glow blobs. */
/* Violet corner glow - anchored top-left, brightest in the corner and fading
   to transparent at 60% so it never reaches the top wave (no periwinkle seam). */
.qyx-features__glow--violet {
	inset: 0 auto auto 0;
	width: 720px;
	height: 520px;
	pointer-events: none;
	background: radial-gradient(circle at 0% 0%,
		color-mix(in srgb, var(--qyx-violet) 55%, transparent), transparent 60%);
	animation: qyx-glow-breathe 12s ease-in-out infinite;
}
/* Blue ambient - soft indigo wash centred behind the cards, complements violet. */
.qyx-features__glow--blue {
	background: radial-gradient(50% 50% at 50% 35%,
		color-mix(in srgb, var(--qyx-aurora-indigo) 30%, transparent), transparent 70%);
	filter: none;
	opacity: 1;
}
.qyx-feature__icon {
	box-shadow:
		inset 0 2px 8px rgba(255, 255, 255, 0.12),
		inset 0 -1px 4px rgba(0, 0, 0, 0.4),
		0 8px 24px -8px rgba(0, 0, 0, 0.5);
}

/* Generators dark section - pure black base so it flows seamlessly out of
   features above. Tinting is provided by ambient glow blobs (see below). */
.qyx-generators__bg {
	background: #090508;
}
.qyx-generators__glow {
	position: absolute;
	border-radius: 9999px;
	pointer-events: none;
	filter: blur(130px);
}
.qyx-generators__glow--pink {
	top: 25%; right: -5%;
	width: 480px; height: 480px;
	background: #ec4899;
	opacity: 0.22;
}
.qyx-generators__glow--sky {
	bottom: 10%; left: 30%;
	width: 520px; height: 520px;
	background: #38bdf8;
	opacity: 0.18;
}
/* Bottom aurora band - blurred brand-colour wash along the dark section's lower
   edge. Each radial peaks at y=100% (section bottom), where the opaque white
   wave divider (z-2) paints over it - so nothing bleeds past the curve onto the
   light section below. The visible portion sits above the crest, already fading. */
.qyx-generators__aurora {
	filter: blur(40px);
	opacity: 0.85;
	background:
		radial-gradient(45% 130% at 12% 100%, var(--qyx-aurora-blue),   transparent 60%),
		radial-gradient(45% 130% at 45% 100%, var(--qyx-aurora-indigo), transparent 60%),
		radial-gradient(45% 130% at 88% 100%, var(--qyx-aurora-cyan),   transparent 60%);
	animation: qyx-aurora-drift 18s ease-in-out infinite;
}
.qyx-tab--active .qyx-tab__icon {
	background: rgba(255, 255, 255, 0.10);
}

/* ============================================================
   Section #4 Part A - persona matcher (persona-matcher.php, light).
   ============================================================ */
.qyx-persona__eyebrow {
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: #94a3b8;
}
.qyx-persona__selector {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.5rem;
}
.qyx-persona__option {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.8rem 1.25rem;
	border-radius: 9999px;
	border: 1.5px solid var(--qyx-border);
	background: #fff;
	color: #334155;
	font-size: 0.95rem;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
}
.qyx-persona__option:hover { border-color: #cbd5e1; color: var(--qyx-text); box-shadow: 0 4px 12px -4px rgba(15, 23, 42, 0.12); }
.qyx-persona__option:focus-visible { outline: 2px solid #0f172a; outline-offset: 2px; }
/* Active = dark fill + white text (brand near-black), matching the loop's active tab. No light-blue. */
.qyx-persona__option--active {
	background: #0f172a;
	border-color: #0f172a;
	color: #fff;
	box-shadow: 0 10px 24px -10px rgba(15, 23, 42, 0.45);
}
.qyx-persona__option--active:hover { color: #fff; border-color: #0f172a; }
.qyx-persona__option-icon { width: 1.2rem; height: 1.2rem; flex-shrink: 0; }

.qyx-persona__pains { display: flex; flex-direction: column; gap: 0.75rem; }
.qyx-persona__pain {
	display: flex;
	align-items: center;
	gap: 0.875rem;
	padding: 1rem 1.25rem;
	border-radius: 1rem;
	background: #fff;
	border: 1px solid var(--qyx-border);
	box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.qyx-persona__avatar {
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 9999px;
	object-fit: cover;
	flex-shrink: 0;
	box-shadow: 0 0 0 3px #fff, 0 1px 4px rgba(15, 23, 42, 0.12);
}
.qyx-persona__avatar--fallback {
	display: grid;
	place-items: center;
	background: linear-gradient(135deg, #334155, #0f172a);
	color: #fff;
}
.qyx-persona__avatar--fallback svg { width: 1.05rem; height: 1.05rem; }
.qyx-persona__pain-text { font-size: 0.9375rem; line-height: 1.5; color: #334155; }
/* Pain phrase: dark-rose, bold, with a soft highlighter-pen marker under it so
   the eye lands on the pain. */
.qyx-persona__hl {
	color: #be123c;
	font-weight: 700;
	padding: 0 0.12em;
	border-radius: 2px;
	background-image: linear-gradient(transparent 58%, rgba(244, 63, 94, 0.20) 0);
	box-decoration-break: clone;
	-webkit-box-decoration-break: clone;
}

/* Solution card - the brand-gradient "winner" card (white inner card holds the
   check list). Deliberately richer than the muted pain cards so the eye lands
   on the answer. */
.qyx-persona__solution-card {
	position: relative;
	padding: 1.5rem;
	border-radius: 1.5rem;
	background: var(--qyx-bg-dark);
	box-shadow: 0 28px 60px -28px rgba(8, 12, 22, 0.55);
}
.qyx-persona__solution-head {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin-bottom: 1.1rem;
	padding-left: 0.25rem;
}
.qyx-persona__brand-mark {
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 0.6rem;
	background: rgba(255, 255, 255, 0.18);
	color: #fff;
}
.qyx-persona__brand-name {
	font-weight: 700;
	font-size: 1.125rem;
	letter-spacing: -0.01em;
	color: #fff;
}
.qyx-persona__solution-inner {
	background: #fff;
	border-radius: 1.1rem;
	padding: 1.25rem 1.4rem;
	box-shadow: 0 10px 24px -16px rgba(15, 23, 42, 0.3);
}
.qyx-persona__solution-lead { font-size: 0.875rem; color: #64748b; }
.qyx-persona__solutions {
	margin-top: 0.85rem;
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
	list-style: none;
	padding: 0;
}
.qyx-persona__solution {
	display: flex;
	align-items: flex-start;
	gap: 0.625rem;
	font-size: 0.9375rem;
	font-weight: 500;
	color: #1e293b;
}
.qyx-persona__solution-icon { flex-shrink: 0; color: #0f172a; margin-top: 1px; }

/* Choreographed reveal when a persona is selected. CSS animations restart every
   time the panel switches from display:none to block, so each tab change plays
   the sequence: pains rise in, the solution card slides in, its checks tick on
   one by one. */
@keyframes qyxPersonaIn {
	from { opacity: 0; transform: translateY(12px); }
	to   { opacity: 1; transform: translateY(0); }
}
@keyframes qyxPersonaCardIn {
	from { opacity: 0; transform: translateY(14px) scale(0.985); }
	to   { opacity: 1; transform: translateY(0) scale(1); }
}
.qyx-persona__pain {
	animation: qyxPersonaIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: calc(var(--pi, 0) * 0.08s);
}
.qyx-persona__solution-card {
	animation: qyxPersonaCardIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: 0.1s;
}
.qyx-persona__solution {
	animation: qyxPersonaIn 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: calc(0.24s + var(--si, 0) * 0.05s);
}
@media (prefers-reduced-motion: reduce) {
	.qyx-persona__pain,
	.qyx-persona__solution-card,
	.qyx-persona__solution { animation: none; }
}

/* Same choreographed reveal for the lifecycle-loop stages: the phase animation
   eases in while the copy and CTA stagger up, each time a stage tab is selected. */
@keyframes qyxLoopFigIn {
	from { opacity: 0; transform: translateY(16px) scale(0.97); }
	to   { opacity: 1; transform: translateY(0) scale(1); }
}
.qyx-loop__panels [role="tabpanel"] .qyx-loop__figure {
	animation: qyxLoopFigIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.qyx-loop__reveal > * {
	animation: qyxPersonaIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.qyx-loop__reveal > *:nth-child(1) { animation-delay: 0.1s; }
.qyx-loop__reveal > *:nth-child(2) { animation-delay: 0.18s; }
.qyx-loop__reveal > *:nth-child(3) { animation-delay: 0.26s; }
.qyx-loop__reveal > *:nth-child(4) { animation-delay: 0.34s; }
@media (prefers-reduced-motion: reduce) {
	.qyx-loop__panels [role="tabpanel"] .qyx-loop__figure,
	.qyx-loop__reveal > * { animation: none; }
}

/* ============================================================
   Section #4 Part B - lifecycle loop (lifecycle-loop.php, dark).
   Reuses .qyx-generators* decor; the stage graphic is .qyx-loop__figure
   (see loop-anim.css). Adds the loop nav (mobile vertical stepper ->
   desktop horizontal loop row).
   ============================================================ */

/* Section background - fades from the light page colour into the dark so the
   top edge connects seamlessly with the light persona section above (the
   bottom edge already transitions out via the .qyx-generators__divider wave). */
/* Reserved dark section - fades from the light wash into the single dark token. */
.qyx-loop__bg {
	background: linear-gradient(to bottom, var(--qyx-bg-light) 0%, var(--qyx-bg-dark) 130px);
}
/* Reserved dark section - solid dark token (was hardcoded bg-[#070508]). */
.qyx-pricing { background-color: var(--qyx-bg-dark); }
/* Desktop: trim the top padding so the (tall) offer card + CTA sit higher and
   need less scrolling. Bottom padding stays (py-24 = 6rem) to clear the wave
   divider. Mobile keeps its own rhythm token below 1024px. */
@media (min-width: 1024px) {
	.qyx-pricing.site-section { padding-top: 3rem; }
}

/* [QYX-ANIM] loop dark-island waves + threshold | static | dep: --qyx-bg-light / --qyx-threshold | DO-NOT: gradient wave fill or threshold opacity > .3 */
.qyx-loop__wave {
	position: absolute;
	left: 0;
	width: 100%;
	height: 7vw;
	min-height: 46px;
	max-height: 96px;
	z-index: 2;
	display: block;
	pointer-events: none;
}
.qyx-loop__wave--top { top: -1px; }
.qyx-loop__wave--bottom { bottom: -1px; }
.qyx-loop__threshold {
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 240px;
	z-index: 0;
	background: var(--qyx-threshold);
	-webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 50%, #000 100%);
	mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 50%, #000 100%);
	opacity: 0.3;
	pointer-events: none;
}

/* Dark-card brand aurora - a colourful brand glow at the card's lower edge so
   dark cards read as connected to the palette (reference technique), not flat
   black blocks. The card's own overflow:hidden clips the blurred glow inside. */
.qyx-aura { position: relative; overflow: hidden; }
.qyx-aura::after {
	content: "";
	position: absolute;
	left: -10%;
	right: -10%;
	bottom: -45%;
	height: 85%;
	background: var(--qyx-accent-gradient);
	filter: blur(90px);
	opacity: 0.32;
	pointer-events: none;
	z-index: 0;
}
.qyx-aura > * { position: relative; z-index: 1; }

/* Pricing: a soft brand glow at the top edge bridges the colourful marquee band
   above it (the bottom edge already glows into FAQ via the accent divider). */
.qyx-pricing::before {
	content: "";
	position: absolute;
	top: -10%;
	left: 50%;
	transform: translateX(-50%);
	width: 120%;
	height: 360px;
	background: var(--qyx-accent-gradient);
	filter: blur(120px);
	opacity: 0.16;
	pointer-events: none;
	z-index: 0;
}
@media (prefers-reduced-motion: reduce) {
	.qyx-aura::after, .qyx-pricing::before { animation: none; }
}

.qyx-loop__nav {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0.5rem;
	margin-bottom: 2.5rem;
}
.qyx-loop__stage {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	width: 100%;
	padding: 0.875rem 1.25rem;
	border-radius: 9999px;
	border: 1px solid rgba(255, 255, 255, 0.10);
	background: rgba(255, 255, 255, 0.05);
	color: rgba(255, 255, 255, 0.6);
	font-weight: 600;
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
/* [QYX-ANIM] clearer hover so inactive pills obviously respond to the mouse (clickable affordance) */
.qyx-loop__stage:hover { background: rgba(255, 255, 255, 0.14); color: #fff; border-color: rgba(255, 255, 255, 0.3); }
.qyx-loop__stage:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 2px; }
/* active = a SOLID white pill so the selected tab pops on the dark island (was black-on-dark,
   nearly invisible); inactive stay faint -> reads clearly as "one selected, others selectable" */
.qyx-loop__stage--active { background: #fff; color: #0b0b0e; border-color: #fff; }
.qyx-loop__stage--active:hover { background: #fff; color: #0b0b0e; }
.qyx-loop__num {
	display: grid;
	place-items: center;
	min-width: 1.75rem;
	height: 1.75rem;
	padding: 0 0.4rem;
	border-radius: 9999px;
	background: rgba(255, 255, 255, 0.08);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
}
.qyx-loop__stage--active .qyx-loop__num { background: rgba(255, 255, 255, 0.16); }
/* Stepper pill icon (replaces the 01-05 number). Inherits the pill's colour via
   currentColor, so it brightens with the active state. The connector chevron
   keeps the existing .qyx-loop__arrow svg sizing/rotation. */
.qyx-loop__icon { width: 20px; height: 20px; flex-shrink: 0; }
.qyx-loop__label { font-size: 0.9375rem; }
/* [QYX-ANIM] centred hint above the pills - the single biggest clarity cue */
.qyx-loop__hint {
	margin: -0.5rem auto 1.5rem;
	text-align: center;
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.01em;
	color: rgba(255, 255, 255, 0.5);
}
.qyx-loop__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;   /* chevrons inherit; the path reads via the animated opacity wave below */
}
/* [QYX-ANIM] three chevrons nested into one ">>>" connector. A travelling opacity wave
   (qyx-loop-flow, staggered per chevron) pulls the eye forward along the Think->Engage
   path. GPU-only (opacity + tiny translateX); the wave itself is set in the >=1024 row
   block (arrows only show there) and disabled for reduced-motion. */
.qyx-loop__arrow svg {
	width: 0.72rem;
	height: 0.72rem;
	margin-inline: -0.16rem;        /* nest the trio tight */
	opacity: 0.16;
	transform: rotate(90deg);       /* column fallback; the row layout sets none + animates */
}
@keyframes qyx-loop-flow {
	0%, 100% { opacity: 0.12; transform: translateX(-1px); }
	45%      { opacity: 0.9;  transform: translateX(1px); }
}
.qyx-loop__return {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	align-self: center;
	margin-top: 0.25rem;
	color: rgba(255, 255, 255, 0.45);
	font-size: 0.8125rem;
}
.qyx-loop__return svg { width: 1.1rem; height: 1.1rem; }
.qyx-loop__stage-step {
	display: inline-block;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.4);
}
@media (min-width: 1024px) {
	.qyx-loop__nav {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		justify-content: center;
		gap: 0.5rem 0.75rem;
	}
	.qyx-loop__stage { width: auto; }
	/* row layout: chevrons point forward (no rotation) and flow with a staggered wave */
	.qyx-loop__arrow svg { transform: none; animation: qyx-loop-flow 1.8s ease-in-out infinite; }
	.qyx-loop__arrow svg:nth-child(2) { animation-delay: 0.22s; }
	.qyx-loop__arrow svg:nth-child(3) { animation-delay: 0.44s; }
	.qyx-loop__return { width: 100%; justify-content: center; margin-top: 0.75rem; }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-loop__arrow svg { animation: none; opacity: 0.26; }
}

/* ============================================================
   Dark-section motion - scroll reveal, glow drift, mockup anim.
   All gated behind prefers-reduced-motion at the bottom of this block.
   ============================================================ */

/* Scroll reveal - fade + slide-up, staggered via --reveal-delay. JS adds
   .is-in-view once (IntersectionObserver, see assets/js/qyx-reveal.js). */
[data-reveal] {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
	transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal].is-in-view {
	opacity: 1;
	transform: none;
}

/* Kinetic word marquee - track holds two identical word-runs; translating by
   -50% loops seamlessly. See template-parts/landing/marquee.php. */
.qyx-marquee__track {
	width: max-content;
	animation: qyx-marquee 28s linear infinite;
}
.qyx-marquee:hover .qyx-marquee__track {
	animation-play-state: paused;
}
@keyframes qyx-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

/* Marketing-tools - cards fan out (rotation per --rotate) on lg+; GSAP reads
   this as the resting state and animates the fly-in toward it. */
@media (min-width: 1024px) {
	.qyx-mtools__card { transform: rotate(var(--rotate, 0deg)); }
}

/* Marketing-tools - flanking platform badges gently oscillate. */
.qyx-mtools__badge--wa { animation: qyx-oscillate 1.5s ease-in-out infinite; }
.qyx-mtools__badge--tg { animation: qyx-oscillate 1.5s ease-in-out infinite 0.2s; }
@keyframes qyx-oscillate {
	0%, 100% { transform: translateY(0) rotate(-4deg); }
	50%      { transform: translateY(-10px) rotate(4deg); }
}

/* "Start Training" - spinning conic-gradient ring around the pill. */
.qyx-train-ring::before {
	content: "";
	position: absolute;
	inset: -3px;
	border-radius: 9999px;
	padding: 3px;
	background: conic-gradient(from 0deg, #5AAAF6, #D52FCA, #FF4754, #FFB33B, #43CC3E, #5AAAF6);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	mask-composite: exclude;
	animation: qyx-spin 4s linear infinite;
}
@keyframes qyx-spin { to { transform: rotate(360deg); } }

/* Flickity testimonials - room below for page dots; cells keep Flickity's
   own absolute layout (do NOT force flex on .flickity-slider - it breaks it). */
.qyx-testimonials__carousel .flickity-page-dots {
	bottom: -2.25rem;
}
.qyx-testimonials__carousel:focus,
.qyx-testimonials__carousel .flickity-viewport:focus { outline: none; }

/* Glow "breathing" + aurora drift - subtle ambient life. */
@keyframes qyx-aurora-drift {
	0%, 100% { transform: translateX(0) scale(1); }
	50%      { transform: translateX(2.5%) scale(1.05); }
}
@keyframes qyx-glow-breathe {
	0%, 100% { opacity: 0.85; }
	50%      { opacity: 1; }
}

/* Mockup - skeleton shimmer sweep on the "draft" preview bars. */
.qyx-skeleton {
	background: linear-gradient(90deg,
		rgba(255, 255, 255, 0.04) 25%,
		rgba(255, 255, 255, 0.10) 37%,
		rgba(255, 255, 255, 0.04) 63%);
	background-size: 400% 100%;
	animation: qyx-shimmer 1.6s ease infinite;
}
@keyframes qyx-shimmer {
	0%   { background-position: 100% 0; }
	100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
	[data-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
	}
	.qyx-generators__aurora,
	.qyx-features__glow--violet,
	.qyx-skeleton,
	.qyx-marquee__track,
	.qyx-mtools__badge--wa,
	.qyx-mtools__badge--tg,
	.qyx-train-ring::before {
		animation: none;
	}
}

/* Phone perf: the oversized blur blobs are GPU-heavy and can stutter/freeze
   mobile Chrome when scrolled into the dark animation sections. Shrink the
   worst offenders and drop the aurora layer on small screens. */
@media (max-width: 767px) {
	.qyx-generators__glow,
	.qyx-generators__glow--pink,
	.qyx-generators__glow--sky {
		filter: blur(60px);
		opacity: 0.45;
	}
	.qyx-features__glow--violet,
	.qyx-features__glow--blue {
		filter: blur(70px);
	}
	.qyx-generators__aurora {
		display: none;
	}
	/* Stop the continuously-running non-composited animations: each repaints or
	   relayouts every frame on the main thread (background-position, box-shadow)
	   or re-rasters a large blur (drifting orbs). Lighthouse flagged these as the
	   mobile jank sources (Style&Layout + Rendering ≈ 3.1s). Static fallbacks
	   below keep the same look, just without the per-frame cost. Desktop is
	   untouched - these rules live only inside this max-width:767px block. */
	.qyx-skeleton,               /* qyx-shimmer      - background-position paint */
	.qyx-pulse::after,           /* qyxPulse         - box-shadow paint */
	.qyx-features__glow--violet, /* qyx-glow-breathe */
	.qyx-aurora__orb {           /* qyx-drift-*      - animated blur(90px) re-raster */
		animation: none !important;
	}
	/* The hero text rotator tweens `width` (Tailwind transition-[width]) on each
	   word swap, forcing a layout every frame. Kill the tween only - JS still
	   sets the width instantly per word, so the rotation still works. */
	.lqd-text-rotator {
		transition: none !important;
	}
}

/* Vertical-slider (cta.php) - stack all slides in a single grid cell instead of
   absolute-positioning them. The stage then grows to fit the active slide at any
   width (the old `absolute inset-0` couldn't grow, so stacked mobile content
   overflowed the fixed-height box and overlapped the prev/next nav). Only the
   active slide is visible via x-show; during a transition both briefly share the
   cell and cross-fade. */
.qyx-vslider__stage { display: grid; }
.qyx-vslider__slide { grid-area: 1 / 1; }
/* Decorative gradient band is sm+ only (matches the source vertical-slider). */
@media (max-width: 639.98px) { .qyx-vslider__band { display: none; } }

/* Tools "stacking cards" on mobile/tablet (<lg) - robust CSS position:sticky
   stack, replacing the GSAP pin (which mis-positions on mobile because the
   address bar resizes the viewport mid-scroll). Each .tool-item sticks at the
   same top with a small per-index offset, so cards stack with earlier ones
   peeking behind. Desktop (lg+) keeps the GSAP pin/scale - see initToolsPin. */
@media (max-width: 1023.98px) {
	#ai-tools {
		overflow: visible; /* the section's overflow:hidden would trap sticky */
	}
	#ai-tools .tool-item {
		min-height: 0;     /* drop min-h-screen: each card's scroll segment = its own height */
		padding-top: 1.25rem;
		padding-bottom: 1.25rem;
		position: sticky;
		top: calc(80px + var(--i, 0) * 7px);
	}
}

/* ============================================================
   "As seen on" platform logos row.
   ============================================================ */
.qyx-as-seen-on {
	background:
		radial-gradient(ellipse 70% 100% at 50% 50%, rgba(213, 47, 202, 0.04), transparent 70%);
}
.qyx-platform {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	color: #475569;
	font-weight: 700;
	font-size: 1.0625rem;
	letter-spacing: -0.01em;
	opacity: 0.65;
	transition: opacity .2s ease, color .2s ease;
}
.qyx-platform:hover { opacity: 1; color: #0f172a; }
.qyx-platform svg { width: 22px; height: 22px; }
.qyx-platform__name { line-height: 1; }

/* Ecosystem section - AI model name pills (ecosystem.php). */
.qyx-model-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	flex-shrink: 0;
	padding: 0.5rem 0.9rem;
	border-radius: 999px;
	background: #fff;
	border: 1px solid rgba(15, 23, 42, 0.08);
	box-shadow: 0 2px 6px -2px rgba(15, 23, 42, 0.06);
	font-size: 0.875rem;
	font-weight: 600;
	color: #1e293b;
	white-space: nowrap;
}
.qyx-model-pill__dot {
	width: 0.6rem;
	height: 0.6rem;
	border-radius: 999px;
	background: linear-gradient(135deg, var(--gradient-2), var(--gradient-1));
	flex-shrink: 0;
}

/* Brand logo (header/footer) - assets/images/branding logos/.
   In the header the white variant swaps in over dark sections (.is-dark). */
.qyx-logo { height: 30px; width: auto; display: block; }
.qyx-logo--dark { display: none; }
.site-header.is-dark .qyx-logo--light { display: none; }
.site-header.is-dark .qyx-logo--dark { display: block; }

/* Mobile hamburger drawer "Log in" - secondary/ghost pill, subordinate to the
   solid register CTA (outline vs solid carries the hierarchy). Mobile-only:
   hidden at the lg breakpoint where the desktop nav takes over. */
.qyx-drawer__login {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 44px;
	margin-bottom: 1rem;
	padding: 12px 16px;
	border: 1px solid var(--qyx-border);
	border-radius: 9999px;
	background: transparent;
	color: var(--qyx-text);
	font-size: 15px;
	font-weight: 500;
	line-height: 1;
	text-align: center;
	text-decoration: none;
	transition: background-color 0.2s ease, border-color 0.2s ease;
}
.qyx-drawer__login:hover { background: var(--qyx-surface); }
.qyx-drawer__login:focus-visible {
	outline: 2px solid var(--qyx-text);
	outline-offset: 2px;
}
@media (min-width: 1024px) {
	.qyx-drawer__login { display: none; } /* desktop nav has its own Sign In */
}

/* When the header is .is-dark (over a dark section) but the mobile drawer is
   OPEN, the drawer background is the solid white/95 panel - so the inherited
   .is-dark white text would vanish. Force readable dark text inside the open
   drawer. (Login button keeps its full-strength --qyx-text.) */
.site-header.is-dark .site-nav-container.lqd-is-active a,
.site-header.is-dark .site-nav-container.lqd-is-active p {
	color: rgba(15, 23, 42, 0.6);
}
.site-header.is-dark .site-nav-container.lqd-is-active a:hover {
	color: var(--qyx-text);
}
.site-header.is-dark .site-nav-container.lqd-is-active .qyx-drawer__login {
	color: var(--qyx-text);
}
.site-header.is-dark .site-nav-container.lqd-is-active .border-t {
	border-color: rgba(15, 23, 42, 0.08);
}

/* Ecosystem section - static AI model pills (logo + name), everbot-style. */
.qyx-model-pill__logo {
	width: 1.25rem;
	height: 1.25rem;
	object-fit: contain;
	flex-shrink: 0;
}
.qyx-model-grid {
	max-width: 64rem;
	margin: 2.5rem auto 50px;
	padding: 0 1rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.625rem;
}
.qyx-model-more {
	align-self: center;
	padding: 0 0.35rem;
	font-size: 0.95rem;
	font-weight: 600;
	color: rgba(15, 23, 42, 0.45);
}
.qyx-model-pill--more {
	cursor: pointer;
	font-family: inherit;
	font-weight: 700;
	color: #334155;
	gap: 0.35rem;
}
.qyx-model-pill--more:hover {
	background: #f1f5f9;
	border-color: rgba(15, 23, 42, 0.18);
	color: #0f172a;
}
.qyx-model-pill__chev {
	width: 0.85rem;
	height: 0.85rem;
}
@media (min-width: 640px) {
	.qyx-model-grid { gap: 0.75rem; margin-top: 3rem; }
}
/* Phones: the 37 model pills wrapped into ~19 stacked rows (~950px) - a huge dead
   scroll. Show the first 9 flagship models; the rest live in .qyx-model-rest and
   expand/collapse SMOOTHLY via the grid-template-rows 0fr->1fr trick (animates to the
   exact content height, no max-height guessing). "and more" / "show less" toggle
   .is-open. On desktop the wrapper is display:contents, so all 37 still flow as one
   seamless cluster and the toggle buttons are hidden. */
.qyx-model-rest,
.qyx-model-rest__inner { display: contents; }
@media (max-width: 639px) {
	.qyx-model-rest {
		display: block;
		width: 100%;
		max-height: 0;
		overflow: hidden;
		/* cap sits comfortably above the tallest the rest gets on a phone (~700px);
		   the extra headroom is invisible (overflow clipped, no content there). */
		transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1);
	}
	.qyx-model-grid.is-open .qyx-model-rest { max-height: 1200px; }
	.qyx-model-rest__inner {
		display: flex;
		flex-wrap: wrap;
		justify-content: center;
		align-items: center;
		gap: 0.625rem;
		padding-top: 0.625rem;
	}
}
@media (min-width: 640px) {
	.qyx-model-pill--more { display: none; }   /* full list shown on desktop; no toggle needed */
}
@media (prefers-reduced-motion: reduce) {
	.qyx-model-rest { transition: none; }
}
/* "+ more leading models" line under the model pills. */
.qyx-model-note { margin: -1.5rem auto 50px; padding: 0 1rem; text-align: center; font-size: 0.95rem; color: var(--qyx-text-muted, #6b7080); }

/* Pull the ecosystem section up under the hero; keep a tight bottom so it
   flows into the persona section without a big empty gap (these paddings live
   here, not as Tailwind utilities, so they can't be purged out). */
.qyx-ecosystem { margin-top: -120px; padding-bottom: 2.5rem; }
@media (min-width: 640px) { .qyx-ecosystem { padding-bottom: 3rem; } }
/* Persona: modest top padding (the gap above it was too large). */
.qyx-persona { padding-top: 2.5rem; }
@media (min-width: 1024px) { .qyx-persona { padding-top: 3.5rem; } }
/* Hero CTA + secondary: left-aligned stack on mobile, centred row on >=640. */
@media (min-width: 640px) { .qyx-hero-ctas { align-items: center; } }
/* Price / guarantee line under the hero CTAs. */
.qyx-hero-microcopy { margin-top: 1rem; font-size: 0.85rem; color: var(--qyx-text-muted, #6b7080); }

/* "Always the latest AI models" - live pulsing dot (signals 24/7 updates). */
.qyx-live-dot {
	position: relative;
	display: inline-block;
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 999px;
	background: #10b981;
	flex-shrink: 0;
}
.qyx-live-dot::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: #10b981;
	animation: qyxLivePing 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes qyxLivePing {
	0%        { transform: scale(1);   opacity: 0.55; }
	70%, 100% { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-live-dot::before { animation: none; }
}

/* ============================================================
   AI Models Marquee - horizontal infinite scroll, dual-row.
   ============================================================ */
.qyx-marquee {
	position: relative;
	overflow: hidden;
}
/* Edge fade lives on the words only, so it never fades the wave divider or the
   colour glow at the section's left/right edges. */
.qyx-marquee__words {
	-webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0%, #000 6%, #000 94%, transparent 100%);
}
.qyx-marquee__track {
	display: flex;
	gap: 0.75rem;
	width: max-content;
	animation: qyxMarqueeScroll var(--qyx-marquee-duration, 60s) linear infinite;
}
.qyx-marquee[data-dir="right"] .qyx-marquee__track {
	animation-direction: reverse;
}
.qyx-marquee__set {
	display: flex;
	gap: 0.75rem;
	flex-shrink: 0;
	padding-right: 0.75rem;
}
.qyx-marquee:hover .qyx-marquee__track {
	animation-play-state: paused;
}
@keyframes qyxMarqueeScroll {
	0%   { transform: translateX(0); }
	100% { transform: translateX(calc(-50% - 0.375rem)); }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-marquee__track { animation: none; }
}

/* Flat light base (matches the reference's --background: 0 0% 98%). A flat bg is
   what makes the dark sections' fade-in / wave dividers blend SEAMLESSLY - a
   gradient wash here left a #fafafa fade band that no longer matched the body,
   showing as a white gap at the dark sections. Colour cohesion comes from the
   dark-section brand auroras, not a global wash (the reference does the same). */
html, body { background: var(--qyx-bg-light); }
html { scroll-padding-top: 120px; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* Only hide elements that explicitly opt in with x-cloak. Never gate <body>
   on Alpine init - if Alpine ever errors, the page must still render. */
[x-cloak] { display: none !important; }

/* ============================================================
   Background ambient glows - soft, blurred, low opacity.
   ============================================================ */
.qyx-ambient {
	position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
}
.qyx-ambient::before,
.qyx-ambient::after,
.qyx-ambient > span {
	content: ""; position: absolute; border-radius: 9999px; filter: blur(80px);
}
.qyx-ambient::before {
	width: 520px; height: 520px; left: -120px; top: -160px;
	background: radial-gradient(closest-side, rgba(139, 92, 246, 0.35), transparent 70%);
	opacity: 0.55;
}
.qyx-ambient::after {
	width: 560px; height: 560px; right: -140px; top: -180px;
	background: radial-gradient(closest-side, rgba(56, 189, 248, 0.30), transparent 70%);
	opacity: 0.55;
}
.qyx-ambient > span {
	width: 420px; height: 420px; left: 50%; top: 60px; transform: translateX(-50%);
	background: radial-gradient(closest-side, rgba(244, 114, 182, 0.25), transparent 70%);
	opacity: 0.55;
}

/* ============================================================
   Glass card - used by most floating panels.
   ============================================================ */
.qyx-glass {
	background: rgba(255,255,255,0.78);
	backdrop-filter: saturate(140%) blur(14px);
	-webkit-backdrop-filter: saturate(140%) blur(14px);
	border: 1px solid rgba(255,255,255,0.55);
	box-shadow: 0 10px 40px rgba(15, 23, 42, 0.06);
	border-radius: 1.5rem;
}
.qyx-glass-strong {
	background: rgba(255,255,255,0.92);
	backdrop-filter: saturate(160%) blur(18px);
	-webkit-backdrop-filter: saturate(160%) blur(18px);
	border: 1px solid rgba(255,255,255,0.6);
	box-shadow: 0 18px 60px rgba(15, 23, 42, 0.08);
	border-radius: 1.5rem;
}
.qyx-lift {
	transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.qyx-lift:hover {
	transform: translateY(-2px);
	box-shadow: 0 18px 60px rgba(15, 23, 42, 0.10);
	border-color: rgba(139, 92, 246, 0.25);
}

/* ============================================================
   Brand gradient - used for the + Create button and accent fills.
   ============================================================ */
.qyx-grad {
	background-image: linear-gradient(90deg, #ec4899 0%, #a855f7 45%, #38bdf8 100%);
}
.qyx-grad-soft {
	background-image: linear-gradient(135deg, rgba(168, 85, 247, 0.12), rgba(56, 189, 248, 0.10));
}
.qyx-grad-text {
	background-image: linear-gradient(90deg, #a855f7, #ec4899, #f97316);
	-webkit-background-clip: text; background-clip: text; color: transparent;
}
.qyx-grad-border > .qyx-grad-border__inner {
	background: white; border-radius: inherit;
}

/* ============================================================
   Sidebar - floating, blurred, soft right edge.
   ============================================================ */
.qyx-sidebar {
	background: rgba(255,255,255,0.75);
	backdrop-filter: saturate(140%) blur(14px);
	-webkit-backdrop-filter: saturate(140%) blur(14px);
	border-right: 1px solid rgba(226, 232, 240, 0.6);
}
.qyx-sidebar-scroll { scrollbar-width: thin; scrollbar-color: #e2e8f0 transparent; }
.qyx-sidebar-scroll::-webkit-scrollbar { width: 4px; }
.qyx-sidebar-scroll::-webkit-scrollbar-thumb { background: #e2e8f0; border-radius: 9999px; }

.qyx-nav-label {
	font-size: 10px; line-height: 1.15; letter-spacing: 0.01em; text-align: center;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.qyx-nav-item { position: relative; transition: background-color .25s ease, color .25s ease; }
.qyx-nav-item.is-active {
	background: linear-gradient(180deg, rgba(168, 85, 247, 0.12), rgba(56, 189, 248, 0.08));
	color: #0f172a;
}
.qyx-nav-item.is-active::before {
	content: ""; position: absolute; left: -2px; top: 12px; bottom: 12px; width: 3px;
	border-radius: 9999px;
	background: linear-gradient(180deg, #a855f7, #38bdf8);
}

/* ============================================================
   Top navbar - sticky, transparent, blurred.
   ============================================================ */
.qyx-navbar {
	background: rgba(248, 250, 252, 0.65);
	backdrop-filter: saturate(140%) blur(14px);
	-webkit-backdrop-filter: saturate(140%) blur(14px);
	border-bottom: 1px solid rgba(226, 232, 240, 0.6);
}

/* ============================================================
   AI search bar - large, floating, soft shadow.
   ============================================================ */
.qyx-search {
	background: rgba(255,255,255,0.92);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border: 1px solid rgba(226, 232, 240, 0.9);
	box-shadow: 0 24px 60px -20px rgba(168, 85, 247, 0.25),
	            0 8px 24px -12px rgba(56, 189, 248, 0.15);
	border-radius: 9999px;
}

/* ============================================================
   Status pulse for "Live" campaigns.
   ============================================================ */
.qyx-pulse { position: relative; }
.qyx-pulse::after {
	content: ""; position: absolute; inset: -2px; border-radius: inherit;
	box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4);
	animation: qyxPulse 2s ease-out infinite;
}
@keyframes qyxPulse {
	0%   { box-shadow: 0 0 0 0   rgba(16, 185, 129, 0.45); }
	70%  { box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); }
	100% { box-shadow: 0 0 0 0   rgba(16, 185, 129, 0); }
}

/* ============================================================
   Floating assistant FAB (mobile / always-on).
   ============================================================ */
.qyx-fab {
	background-image: linear-gradient(135deg, #a855f7 0%, #ec4899 60%, #38bdf8 120%);
	box-shadow: 0 14px 40px -10px rgba(168, 85, 247, 0.55);
}

/* ============================================================
   Tone gradients (assist Tailwind utility coverage at runtime).
   We list all dynamic Tailwind class roots so the CDN keeps them.
   ============================================================ */
/*! tailwind-keep
   from-violet-500/15 from-sky-500/15 from-emerald-500/15 from-amber-500/15
   from-rose-500/15 from-indigo-500/15 from-teal-500/15 from-fuchsia-500/15
   from-blue-500/15 to-fuchsia-500/0 to-cyan-500/0 to-teal-500/0 to-orange-500/0
   to-pink-500/0 to-violet-500/0 to-emerald-500/0 to-indigo-500/0
   bg-violet-100 text-violet-600 bg-sky-100 text-sky-600 bg-emerald-100 text-emerald-600
   bg-amber-100 text-amber-600 bg-rose-100 text-rose-600 bg-indigo-100 text-indigo-600
   bg-teal-100 text-teal-600 bg-fuchsia-100 text-fuchsia-600 bg-blue-100 text-blue-600 */

/* ============================================================
   Focus rings - soft.
   ============================================================ */
:where(button, a, input, [role="button"]):focus-visible {
	outline: 2px solid rgba(168, 85, 247, 0.45);
	outline-offset: 2px;
	border-radius: 12px;
}

/* ============================================================
   SITE HEADER - floating island navigation.
   The <header> itself is a position:fixed wrapper. The visible pill is
   the inner .qyx-island; .is-scrolled (added by JS at scrollY > 50) bumps
   shadow + opacity for a subtle "lift" effect.
   ============================================================ */

.site-header { background: transparent; }

/* Defensive - kill any stray border-top / outline on elements directly after the
   header that could render as a 1px line on mobile (some browser stylesheets or
   third-party scripts inject these). */
.site-header,
.site-header-nav,
.site-header + svg,
.site-header ~ main,
.site-header ~ main > section:first-child,
.site-section {
	border: 0 !important;
	outline: 0 !important;
}
.site-header-nav::after,
.site-header-nav::before { display: none !important; }

/* Safety net - if GSAP ScrollTrigger ever runs and creates .pin-spacer wrappers,
   make sure they don't render any visible boundary. */
.pin-spacer { border: 0 !important; box-shadow: none !important; background: transparent !important; }

.qyx-island {
	background: rgba(255, 255, 255, 0.82);
	-webkit-backdrop-filter: saturate(180%) blur(18px);
	backdrop-filter: saturate(180%) blur(18px);
	box-shadow:
		0 1px 0 rgba(255, 255, 255, 0.6) inset,
		0 8px 24px -10px rgba(15, 23, 42, 0.12),
		0 2px 6px -2px rgba(15, 23, 42, 0.06);
	border: 1px solid rgba(15, 23, 42, 0.06);
	transition: background-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.site-header.is-scrolled .qyx-island {
	background: rgba(255, 255, 255, 0.92);
	box-shadow:
		0 1px 0 rgba(255, 255, 255, 0.7) inset,
		0 14px 36px -12px rgba(15, 23, 42, 0.18),
		0 4px 10px -4px rgba(15, 23, 42, 0.08);
	transform: translateY(0);
}

/* Nav link underline (gradient, slides in on hover). */
.nav-link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 4px;
	height: 2px;
	border-radius: 9999px;
	background-image: linear-gradient(90deg, #7c3aed, #ec4899);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.3s ease;
}
.nav-link:hover::after,
.nav-link:focus-visible::after { transform: scaleX(1); }

/* Primary CTA - gradient with hover lift. Used in the floating header pill
   ("Join Hub") and other secondary spots. */
.btn-primary {
	background-image: linear-gradient(135deg, #7c3aed 0%, #ec4899 100%);
	box-shadow: 0 6px 18px -6px rgba(124, 58, 237, 0.45);
	transition: transform 0.25s ease, box-shadow 0.25s ease, filter 0.25s ease;
}
.btn-primary:hover {
	transform: translateY(-2px);
	box-shadow: 0 10px 24px -6px rgba(124, 58, 237, 0.55);
	filter: brightness(1.04);
}
.btn-primary:active { transform: translateY(0); }

/* Rainbow CTA - dark pill with a blurred rainbow halo behind. Used by the
   primary hero button. The ::before halo sits OUTSIDE the button (inset:-3px)
   and intensifies on hover, so we deliberately avoid overflow: hidden. */
.btn-rainbow {
	position: relative;
	z-index: 0;
	background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
	color: #fff;
	transition: transform 0.25s ease, box-shadow 0.25s ease;
	box-shadow: 0 6px 18px -6px rgba(15, 23, 42, 0.45);
}
.btn-rainbow::before {
	content: "";
	position: absolute;
	inset: -3px;
	border-radius: inherit;
	z-index: -1;
	background: linear-gradient(135deg, #7c3aed 0%, #ec4899 33%, #f59e0b 66%, #10b981 100%);
	opacity: 0.7;
	filter: blur(12px);
	transition: opacity 0.3s ease, filter 0.3s ease;
}
.btn-rainbow:hover {
	transform: translateY(-2px);
	box-shadow: 0 10px 24px -8px rgba(15, 23, 42, 0.55);
}
.btn-rainbow:hover::before {
	opacity: 1;
	filter: blur(16px);
}
.btn-rainbow:active { transform: translateY(0); }

/* Hamburger button - three lines that morph to an X. */
.burger__lines {
	position: relative;
	display: inline-block;
	width: 22px;
	height: 16px;
}
.burger__line {
	position: absolute;
	left: 0;
	width: 100%;
	height: 2px;
	border-radius: 2px;
	background: #0f172a;
	transition: transform 0.3s ease, opacity 0.2s ease, top 0.3s ease;
}
.burger__line:nth-child(1) { top: 0; }
.burger__line:nth-child(2) { top: 7px; }
.burger__line:nth-child(3) { top: 14px; }

.burger.is-open .burger__line:nth-child(1) { top: 7px; transform: rotate(45deg); }
.burger.is-open .burger__line:nth-child(2) { opacity: 0; }
.burger.is-open .burger__line:nth-child(3) { top: 7px; transform: rotate(-45deg); }

/* Mobile panel scrollbar tidy. */
.mobile-panel { scrollbar-width: thin; scrollbar-color: #e2e8f0 transparent; }

/* Respect reduced motion. */
@media (prefers-reduced-motion: reduce) {
	.btn-primary,
	.nav-link::after,
	.burger__line,
	.qyx-island { transition: none; }
}

/* ============================================================
   HERO - aurora orbs, noise, gradient text shift, typewriter, tilt.
   ============================================================ */

/* Aurora container */
.qyx-aurora {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
	z-index: 0;
}
.qyx-aurora__orb {
	position: absolute;
	border-radius: 9999px;
	filter: blur(90px);
	will-change: transform;
}
.qyx-aurora__orb--1 {
	width: 520px; height: 520px;
	background: radial-gradient(closest-side, rgba(124, 58, 237, 0.65), transparent 70%);
	top: -120px; left: -100px;
	opacity: 0.85;
	animation: qyx-drift-1 22s ease-in-out infinite alternate;
}
.qyx-aurora__orb--2 {
	width: 560px; height: 560px;
	background: radial-gradient(closest-side, rgba(236, 72, 153, 0.55), transparent 70%);
	top: 40px; right: -160px;
	opacity: 0.8;
	animation: qyx-drift-2 24s ease-in-out infinite alternate;
}
.qyx-aurora__orb--3 {
	width: 480px; height: 480px;
	background: radial-gradient(closest-side, rgba(34, 211, 238, 0.45), transparent 70%);
	bottom: -120px; left: 35%;
	opacity: 0.7;
	animation: qyx-drift-3 18s ease-in-out infinite alternate;
}
.qyx-aurora__orb--4 {
	width: 420px; height: 420px;
	background: radial-gradient(closest-side, rgba(16, 185, 129, 0.40), transparent 70%);
	top: 30%; right: 18%;
	opacity: 0.65;
	animation: qyx-drift-4 26s ease-in-out infinite alternate;
}
@keyframes qyx-drift-1 {
	from { transform: translate3d(0, 0, 0) scale(1); }
	to   { transform: translate3d(140px, 90px, 0) scale(1.15); }
}
@keyframes qyx-drift-2 {
	from { transform: translate3d(0, 0, 0) scale(1.05); }
	to   { transform: translate3d(-110px, 140px, 0) scale(0.95); }
}
@keyframes qyx-drift-3 {
	from { transform: translate3d(0, 0, 0) scale(1); }
	to   { transform: translate3d(90px, -110px, 0) scale(1.10); }
}
@keyframes qyx-drift-4 {
	from { transform: translate3d(0, 0, 0) scale(0.95); }
	to   { transform: translate3d(-130px, -70px, 0) scale(1.10); }
}

/* SVG noise grain - inline data URI, very subtle */
.qyx-noise {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 1;
	opacity: 0.05;
	mix-blend-mode: overlay;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* Animated gradient text - pink → orange (matches hero "autopilot" word) */
.qyx-grad-text-shift {
	background-image: linear-gradient(90deg, #ec4899 0%, #f59e0b 50%, #ec4899 100%);
	background-size: 200% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	animation: qyx-grad-shift 8s ease-in-out infinite;
}
@keyframes qyx-grad-shift {
	0%   { background-position: 0% 50%; }
	50%  { background-position: 100% 50%; }
	100% { background-position: 0% 50%; }
}

/* Typewriter - placeholder reserves width, words stack absolute, opacity-fade */
.qyx-typewriter {
	position: relative;
	display: inline-block;
	vertical-align: baseline;
}
.qyx-typewriter__placeholder {
	visibility: hidden;
	display: inline-block;
}
.qyx-typewriter__word {
	position: absolute;
	left: 0;
	top: 0;
	white-space: nowrap;
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 0.55s ease, transform 0.55s ease;
	pointer-events: none;
}
.qyx-typewriter__word.is-active {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

/* 3D-tilt - perspective parent + transformed card.
   Default values give a subtle "resting" tilt (rotateY -5deg, rotateX 2deg)
   that matches the magicproject-style phone presentation. JS overrides via
   inline style on pointermove; pointerleave clears inline → CSS default
   resumes (so the phone always sits in a flattering 3D pose). */
.qyx-tilt {
	perspective: 1400px;
}
.qyx-tilt__card {
	--rx: 2deg;
	--ry: -5deg;
	transform: rotateX(var(--rx)) rotateY(var(--ry)) translateZ(0);
	transform-style: preserve-3d;
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform;
}
.qyx-tilt.is-active .qyx-tilt__card {
	transition: transform 0.1s linear;
}

/* ============================================================
   HERO BACKGROUND - radial gradient ellipses + bottom wave.
   ============================================================ */
.qyx-hero-bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background:
		radial-gradient(ellipse 80% 50% at 50% -10%, rgba(139, 92, 246, 0.18), transparent 70%),
		radial-gradient(ellipse 60% 50% at 85% 45%, rgba(236, 72, 153, 0.15), transparent 70%),
		radial-gradient(ellipse 60% 50% at 15% 80%, rgba(59, 130, 246, 0.15), transparent 70%);
}
.qyx-hero-bg::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 55%;
	pointer-events: none;
	opacity: 0.55;
	background-repeat: no-repeat;
	background-position: bottom center;
	background-size: cover;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'><path fill='%23a5b4fc' fill-opacity='0.18' d='M0,224 C240,288 480,288 720,224 C960,160 1200,160 1440,224 L1440,320 L0,320 Z'/><path fill='%23f9a8d4' fill-opacity='0.16' d='M0,256 C240,192 480,192 720,256 C960,320 1200,320 1440,256 L1440,320 L0,320 Z'/></svg>");
}

/* ============================================================
   PHONE MOCKUP - realistic iPhone built entirely in CSS/HTML.
   Outer frame uses gradient + dual ring + multi-layer drop shadow
   to mimic anodised aluminium edge.
   ============================================================ */
.qyx-phone {
	position: relative;
	width: 290px;
	height: 600px;
	border-radius: 48px;
	padding: 12px;
	background: linear-gradient(145deg, #1c1c1e 0%, #2c2c2e 100%);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.10),
		0 0 0 2px #2c2c2e,
		0 36px 64px -20px rgba(15, 23, 42, 0.55),
		0 20px 40px -12px rgba(15, 23, 42, 0.35);
}
@media (min-width: 640px) {
	.qyx-phone { width: 320px; height: 650px; border-radius: 50px; }
}
.qyx-phone__notch {
	position: absolute;
	top: 18px;
	left: 50%;
	transform: translateX(-50%);
	width: 110px;
	height: 30px;
	background: #000;
	border-radius: 9999px;
	z-index: 2;
}
@media (min-width: 640px) {
	.qyx-phone__notch { width: 120px; height: 34px; }
}
.qyx-phone__screen {
	position: relative;
	width: 100%;
	height: 100%;
	border-radius: 38px;
	background: #ffffff;
	overflow: hidden;
	display: flex;
	flex-direction: column;
}
@media (min-width: 640px) {
	.qyx-phone__screen { border-radius: 40px; }
}

/* Soft coloured reflection / glow under the phone */
.qyx-phone-reflection {
	position: absolute;
	left: 50%;
	bottom: -50px;
	transform: translateX(-50%);
	width: 75%;
	height: 110px;
	border-radius: 50%;
	filter: blur(34px);
	background: radial-gradient(
		ellipse at center,
		rgba(124, 58, 237, 0.30) 0%,
		rgba(236, 72, 153, 0.20) 40%,
		transparent 72%
	);
	z-index: -1;
	pointer-events: none;
}
.qyx-phone__chat {
	background-color: #ECE5DD;
	background-image:
		radial-gradient(circle at 1px 1px, rgba(15, 23, 42, 0.04) 1px, transparent 0);
	background-size: 14px 14px;
}

/* Chat bubbles */
.qyx-bubble {
	max-width: 80%;
	padding: 7px 10px;
	font-size: 12px;
	line-height: 1.35;
	border-radius: 14px;
	box-shadow: 0 1px 1px rgba(15, 23, 42, 0.06);
	color: #1e293b;
}
.qyx-bubble--in {
	background: #ffffff;
	border-top-left-radius: 4px;
	margin-right: auto;
}
.qyx-bubble--out {
	background: #DCF8C6;
	border-top-right-radius: 4px;
	margin-left: auto;
}
.qyx-bubble--typing {
	display: inline-flex;
	gap: 4px;
	padding: 10px 12px;
	width: max-content;
}
.qyx-bubble--typing span {
	width: 6px;
	height: 6px;
	border-radius: 9999px;
	background: #94a3b8;
	animation: qyx-typing 1.2s ease-in-out infinite;
}
.qyx-bubble--typing span:nth-child(2) { animation-delay: 0.15s; }
.qyx-bubble--typing span:nth-child(3) { animation-delay: 0.30s; }
@keyframes qyx-typing {
	0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
	40%           { transform: translateY(-4px); opacity: 1; }
}

/* ============================================================
   FLOATING ANIMATIONS - used by phone, chips, avatar, badges.
   ============================================================ */
@keyframes qyx-float {
	0%, 100% { transform: translateY(0); }
	50%      { transform: translateY(-14px); }
}
@keyframes qyx-float-slow {
	0%, 100% { transform: translateY(0) rotate(0deg); }
	50%      { transform: translateY(-20px) rotate(2deg); }
}
.qyx-float      { animation: qyx-float 3.4s ease-in-out infinite; will-change: transform; }
.qyx-float-slow { animation: qyx-float-slow 4.6s ease-in-out infinite; will-change: transform; }

/* Reduced motion - kill kinetic effects */
@media (prefers-reduced-motion: reduce) {
	.qyx-aurora__orb,
	.qyx-grad-text-shift,
	.qyx-float,
	.qyx-float-slow,
	.qyx-bubble--typing span { animation: none !important; }
	.qyx-tilt__card { transform: none !important; transition: none; }
	.qyx-typewriter__word { transition: none; }
}

/* ============================================================
   Use-cases card fan ("Oh no. AI is taking your job.")
   Three cards show at once: the active card sits centred,
   upright and elevated; its neighbours fan out tilted to the
   left and right; the next ones peek faded behind. Clicking an
   arrow rotates the fan one step (right -> centre -> left ->
   out) and loops. Positions are set inline by cardStyle().
   ============================================================ */
/* Trap the cards' inline z-index (up to 100) inside the section so they can't
   paint over the sticky z-50 header or the next (ai-tools) section as the page
   scrolls past. */
.qyx-usecases { isolation: isolate; }

.qyx-usecases__deck {
	position: relative;
	max-width: min( 28rem, 86vw );
	margin: 3.5rem auto 0;
	min-height: 620px;
	cursor: grab;
}
/* Cards are absolutely positioned (inset:0) and clip their overflow, so the deck -
   not the content - decides how tall a card is. The real media tiles are much taller
   than the icon placeholders they replaced, so this has to clear the TALLEST card
   (the English -> French clip pair plus its language chips, ~652px). */
@media (min-width: 640px) { .qyx-usecases__deck { max-width: 30rem; min-height: 680px; } }
/* [QYX-ANIM] fan-swipe drag state | trigger: .is-dragging toggled by JS | dep: pointer handlers | DO-NOT: animate during drag (transition off for 1:1 finger tracking) */
.qyx-usecases__deck.is-dragging { cursor: grabbing; user-select: none; transition: none; }
.qyx-usecase { -webkit-user-drag: none; }
.qyx-usecase img { -webkit-user-drag: none; }

.qyx-usecase {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	border-radius: 24px;
	padding: clamp(28px, 3.2vw, 36px);
	overflow: hidden; /* keep every element inside the rounded card box */
	background: var(--card-bg);
	color: var(--card-ink);
	border: 1.5px solid var(--card-border);
	/* reference card shell: soft single shadow (dark variant deepens it below) */
	box-shadow: 0 16px 34px hsl(0 0% 0% / 5%);
}

/* Fan stacking: every card occupies the same spot; cardStyle() drives the
   fan-out (translateX/Y, rotate, scale, blur, opacity). One smooth transition
   turns a click into the "rotate the fan" motion. */
.qyx-usecases__deck .qyx-usecase {
	position: absolute;
	inset: 0;
	width: 100%;
	transform-origin: 50% 70%;
	/* [QYX-ANIM] only transform+opacity transition (both GPU-composited). filter/blur
	   is deliberately NOT transitioned: animating filter runs on the main thread and
	   re-rasters every frame across all cards = the swipe jank. Blur still applies at
	   rest (set inline by cardStyle) - it just snaps instead of tweening (imperceptible
	   next to the opacity fade). will-change stays on the two composited props only. */
	transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.3s ease;   /* snappier = rapid Tinder-style swiping */
	/* [QYX-ANIM] no PERMANENT will-change: 8 always-promoted layers made scroll-through
	   janky (every card composited each frame). The browser auto-promotes the transitioning
	   transform/opacity during the 0.6s swipe anyway, so the swipe stays smooth; at rest the
	   cards paint into the page and scroll cheaply. will-change added only while dragging (below). */
}
/* promote to a layer ONLY during an active drag, then drop it (no permanent cost) */
.qyx-usecases__deck.is-dragging .qyx-usecase { will-change: transform; }

/* Per-category card palettes (ported from the reference qyx-cards markup). Each card
   carries its own surface + ink + accent + CTA via custom props; the pieces below all
   read these vars so one variant class fully colours a card. In the fan, neighbours
   recede by opacity/blur (cardStyle), so full-saturation category colours are fine. */
.qyx-usecase--pink {
	--card-bg: #fbe7ee; --card-border: rgba(0, 0, 0, 0.045);
	--card-ink: #3a1326; --card-muted: rgba(58, 19, 38, 0.6); --card-divider: rgba(58, 19, 38, 0.12);
	--card-accent: #bc2e84; --card-accent-deep: #b02a78; --badge-bg: rgba(196, 46, 142, 0.12);
	--cta-bg: #d24e80; --cta-ink: #fff; --cta-shadow: rgba(210, 78, 128, 0.4);
}
.qyx-usecase--green {
	--card-bg: #dcefe4; --card-border: rgba(0, 0, 0, 0.045);
	--card-ink: #143a27; --card-muted: rgba(20, 58, 39, 0.62); --card-divider: rgba(20, 58, 39, 0.13);
	--card-accent: #1b7a4d; --card-accent-deep: #176b43; --badge-bg: rgba(27, 122, 77, 0.14);
	--cta-bg: #186e4a; --cta-ink: #fff; --cta-shadow: rgba(24, 110, 74, 0.4);
}
.qyx-usecase--blue {
	--card-bg: #dceafb; --card-border: rgba(0, 0, 0, 0.045);
	--card-ink: #16294a; --card-muted: rgba(22, 41, 74, 0.62); --card-divider: rgba(22, 41, 74, 0.13);
	--card-accent: #2a6fd6; --card-accent-deep: #2a6fd6; --badge-bg: rgba(42, 111, 214, 0.13);
	--cta-bg: #2a6fd6; --cta-ink: #fff; --cta-shadow: rgba(42, 111, 214, 0.4);
}
.qyx-usecase--dark {
	--card-bg: #18181b; --card-border: rgba(255, 255, 255, 0.06);
	--card-ink: #fff; --card-muted: rgba(255, 255, 255, 0.58); --card-divider: rgba(255, 255, 255, 0.1);
	--card-accent: #4ec98e; --card-accent-deep: #43cc8a; --badge-bg: rgba(78, 201, 142, 0.14);
	--cta-bg: #fff; --cta-ink: #18181b; --cta-shadow: rgba(0, 0, 0, 0.32);
	box-shadow: 0 18px 38px hsl(0 0% 0% / 14%);
}

/* reference badge: a soft pill tinted in the card's accent colour */
.qyx-usecase__tag {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 6px 13px;
	border-radius: 999px;
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: 0.01em;
	background: var(--badge-bg);
	color: var(--card-accent);
}
.qyx-usecase__tag svg { width: 14px; height: 14px; }

.qyx-usecase__title {
	margin-top: 18px;
	font-size: 24px;               /* Spline Sans (inherited from h3) */
	font-weight: 700;
	line-height: 1.18;
	letter-spacing: -0.01em;
	color: var(--card-ink);
	max-width: 300px;
}
/* full-width hairline divider (reference) - its own element after the title.
   flex-shrink:0 so it can't be squeezed to 0 on the taller cards (chat/languages),
   where total content slightly exceeds the fixed fan-card height. */
.qyx-usecase__divider {
	flex: 0 0 auto;
	width: 100%;
	height: 1px;
	margin-top: 16px;
	background: var(--card-divider);
}

/* [QYX-ANIM] Option B hover (front card, hover-capable devices only): a thin rainbow
   gradient outline fades in + the shadow deepens for a gentle lift. The translateY lift
   from the demo is intentionally done via shadow, NOT transform - transform is owned by
   the fan's cardStyle() and must not be overridden. GPU-only (opacity), paint-on-hover. */
/* The ring lives in ::before but its gradient + mask (expensive to composite) are
   applied ONLY on :hover - so during scroll the pseudo is empty/transparent and adds
   zero per-frame cost. Hover isn't a scroll state, so the mask paints harmlessly then. */
.qyx-usecases__deck .qyx-usecase[aria-hidden="false"]::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
	z-index: 3;
}
@media (hover: hover) {
	.qyx-usecases__deck .qyx-usecase[aria-hidden="false"]:hover::before {
		opacity: 1;
		padding: 1.5px;
		background: var(--qyx-accent-gradient);
		-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
		-webkit-mask-composite: xor;
		        mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
		        mask-composite: exclude;
	}
	.qyx-usecases__deck .qyx-usecase[aria-hidden="false"]:hover {
		box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 22px 44px -16px rgba(15, 23, 42, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.65);
	}
}
.qyx-usecase__body {
	margin-top: 16px;
	max-width: 312px;
	font-size: 15px;
	line-height: 1.5;
	color: var(--card-muted);
}

/* ---- visual wrappers ---- */
.qyx-usecase__visual {
	width: 100%;
	margin-top: 1.5rem;
}
.qyx-usecase__visual--pair,
.qyx-usecase__visual--triptych {
	display: flex;
	align-items: stretch;
	justify-content: center;
	gap: 0.55rem;
}
.qyx-usecase__arrow {
	flex: 0 0 auto;
	align-self: center;
	color: var(--card-accent);
}
.qyx-usecase__arrow svg { width: 1.15rem; height: 1.15rem; display: block; }

/* ---- tiles (pair + triptych) = reference .qyx-tile: white card, coloured media ---- */
.qyx-utile {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	border-radius: 16px;
	overflow: hidden;
	background: #fff;
	border: 1px solid rgba(0, 0, 0, 0.06);
	box-shadow: 0 6px 16px hsl(0 0% 0% / 5%);
}
.qyx-utile__body {
	flex: 1 1 auto;
	display: grid;
	place-items: center;
	min-height: 96px;
	padding: 0.85rem;
}
.qyx-utile__cap {
	padding: 10px 6px;
	font-size: 12.5px;
	font-weight: 500;
	line-height: 1.2;
	text-align: center;
	color: var(--card-muted);
}
/* "before"/neutral media: warm grey + muted icon */
.qyx-utile--from .qyx-utile__body { background: #f1ede7; color: #a8a39b; }
/* "after" media: accent-tinted + accent icon + accent-deep label */
.qyx-utile--to { border-color: color-mix( in srgb, var(--card-accent) 22%, transparent ); }
.qyx-utile--to .qyx-utile__body { background: color-mix( in srgb, var(--card-accent) 30%, #fff ); color: var(--card-accent); }
.qyx-utile--to .qyx-utile__cap { color: var(--card-accent-deep); font-weight: 600; }

/* dark-card tiles (Video cards) - dark surfaces per the reference */
.qyx-usecase--dark .qyx-utile { background: #262629; border-color: rgba(255, 255, 255, 0.08); box-shadow: 0 6px 16px hsl(0 0% 0% / 12%); }
.qyx-usecase--dark .qyx-utile--from .qyx-utile__body { background: #202023; color: rgba(255, 255, 255, 0.4); }
.qyx-usecase--dark .qyx-utile--to { border-color: var(--card-accent-deep); }
.qyx-usecase--dark .qyx-utile--to .qyx-utile__body { background: rgba(78, 201, 142, 0.09); color: var(--card-accent); }

/* ---- media tiles: the real before/after photos and clips ---- */
/* The BOX owns the geometry, not the media: a fixed 4:5 frame reserves its height
   before anything loads (so a lazy image or a poster can never shift the card) and
   gives every card the same rhythm. Sources run from 9:16 portrait clips to 1:1
   stills, so they are cropped to the frame rather than letterboxed - every one of
   them is centre-composed, so the crop keeps the subject. */
.qyx-utile--media .qyx-utile__body {
	position: relative;
	aspect-ratio: 4 / 5;
	min-height: 0;
	padding: 0;
	overflow: hidden;
	background: #e6e2db;
}
.qyx-usecase--dark .qyx-utile--media .qyx-utile__body { background: #202023; }
.qyx-utile__media {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* Play button. Clips never start on their own - they carry sound, so they wait to be
   asked. Once playing the button gets out of the way and the frame itself pauses. */
.qyx-utile__play {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: grid;
	place-items: center;
	padding: 0;
	border: 0;
	background: hsl(0 0% 0% / 20%);
	cursor: pointer;
	transition: opacity 0.2s ease, background 0.2s ease;
}
.qyx-utile__play svg {
	width: 42px;
	height: 42px;
	padding: 12px;
	border-radius: 9999px;
	background: hsl(0 0% 100% / 92%);
	color: #16161a;
	box-shadow: 0 4px 14px hsl(0 0% 0% / 28%);
	transition: transform 0.2s ease, background 0.2s ease;
}
.qyx-utile__play:hover { background: hsl(0 0% 0% / 10%); }
.qyx-utile__play:hover svg { transform: scale(1.09); background: #fff; }
.qyx-utile__play:focus-visible { outline: 2px solid var(--card-accent); outline-offset: -3px; }
/* the triptych tiles are a third of the width - a full-size button would swamp them */
.qyx-usecase__visual--triptych .qyx-utile__play svg { width: 32px; height: 32px; padding: 9px; }
@media (max-width: 767px) {
	.qyx-utile__play svg { width: 36px; height: 36px; padding: 10px; }
	.qyx-usecase__visual--triptych .qyx-utile__play svg { width: 26px; height: 26px; padding: 7px; }
}
.qyx-utile__body.is-playing .qyx-utile__play { opacity: 0; pointer-events: none; }
.qyx-utile__body.is-playing .qyx-utile__media { cursor: pointer; }   /* click the frame to pause */
@media (prefers-reduced-motion: reduce) {
	.qyx-utile__play, .qyx-utile__play svg { transition: none; }
	.qyx-utile__play:hover svg { transform: none; }
}

/* single-tile cards: the selling chatbot, and the URL -> finished ad clip */
.qyx-usecase__visual--single {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.7rem;
}
/* wider than a pair tile: these two carry a whole UI screenshot / finished ad, and
   at pair-tile width nothing in them is legible */
.qyx-usecase__visual--single .qyx-utile { flex: 0 0 auto; width: min( 72%, 230px ); }

/* url bar - kept from the old mockup, now sitting above the real clip */
.qyx-uvis__url {
	display: flex;
	align-items: center;
	gap: 9px;
	width: 100%;
	padding: 12px 14px;
	border-radius: 13px;
	background: #232326;
	border: 1px solid rgba(255, 255, 255, 0.08);
	color: rgba(255, 255, 255, 0.78);
	font-size: 13.5px;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.qyx-uvis__url svg { flex: 0 0 auto; opacity: 0.6; }

/* language chips, under the English -> French clip pair */
.qyx-usecase__langs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-top: 0.85rem;
}
.qyx-chip {
	padding: 7px 13px;
	border-radius: 9999px;
	background: #eaf5ef;
	border: 1px solid color-mix( in srgb, var(--card-accent) 28%, transparent );
	font-size: 12.5px;
	color: var(--card-accent);
}
.qyx-chip--accent { background: var(--cta-bg); border-color: var(--cta-bg); color: #fff; font-weight: 600; }

/* ---- solid CTA pill (reference): accent-coloured, lifts + opens its gap on hover ---- */
.qyx-usecase__cta {
	margin-top: 24px;
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 13px 28px;
	border-radius: 9999px;
	background: var(--cta-bg);
	color: var(--cta-ink);
	font-size: 14.5px;
	font-weight: 600;
	text-decoration: none;
	transition: transform 0.3s ease, box-shadow 0.3s ease, gap 0.3s ease;
}
.qyx-usecase__cta svg { width: auto; height: 0.72rem; transition: transform 0.2s ease; }   /* starburst arrow: size by height, keep aspect */
.qyx-usecase__cta:hover { transform: translateY( -2px ); gap: 13px; box-shadow: 0 12px 22px var(--cta-shadow); }
.qyx-usecase__cta:hover svg { transform: translateX( 3px ); }

/* Side cards are clickable to bring them to the centre; their CTA stays inert
   so a click navigates the fan instead of following the link. */
.qyx-usecase[aria-hidden="true"] { cursor: pointer; }
.qyx-usecase[aria-hidden="true"] .qyx-usecase__cta { pointer-events: none; }

/* SplitText reveal wraps "(Finally.)" into word spans, which would drop the
   background-clip gradient - re-apply it to those spans so the word keeps its
   gradient while it writes out on scroll. */
.qyx-usecases .qyx-grad-text * {
	background-image: linear-gradient( 90deg, #a855f7, #ec4899, #f97316 );
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* Controls: arrow + counter + dots + arrow, centred under the deck */
.qyx-usecases__controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
	margin-top: 2.5rem;
}
.qyx-usecases__counter {
	display: flex;
	align-items: baseline;
	gap: 0.3rem;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
	color: #0f172a;
}
.qyx-usecases__counter-now { font-size: 1.15rem; }
.qyx-usecases__counter-sep,
.qyx-usecases__counter-total { font-size: 0.95rem; color: #94a3b8; }

.qyx-usecases__dots {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}
.qyx-usecases__dot {
	width: 8px;
	height: 8px;
	border-radius: 9999px;
	background: #cbd5e1;
	transition: width 0.25s ease, background 0.25s ease;
	cursor: pointer;
}
.qyx-usecases__dot--active {
	width: 24px;
	background: #0f172a;
}

.qyx-usecases__nav {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 9999px;
	border: 1px solid var(--qyx-border, #e2e8f0);
	background: #fff;
	color: #0f172a;
	cursor: pointer;
	transition: background 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
}
.qyx-usecases__nav svg { width: 1.1rem; height: 1.1rem; }
.qyx-usecases__nav:hover:not(:disabled) { background: #0f172a; color: #fff; }
.qyx-usecases__nav:disabled { opacity: 0.35; cursor: default; }
.qyx-usecases__nav:active:not(:disabled) { transform: scale(0.94); }

@media (prefers-reduced-motion: reduce) {
	.qyx-usecases__deck .qyx-usecase,
	.qyx-usecase__cta,
	.qyx-usecases__dot,
	.qyx-usecases__nav { transition: none; }
}

/* ============================================================
   Business loop ("Pick a phase. See the tools.")
   A sticky tab switcher over five phases; each phase is its own
   CSS position:sticky scroll-stack (every card sticks and the
   next scrolls up to stack over it). No ancestor may set
   overflow other than visible, or sticky breaks.
   ============================================================ */
.qyx-bizloop { background: var(--qyx-bg); }
.qyx-bizloop__eyebrow {
	display: inline-block;
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: #6366f1;
}

/* sticky tab switcher */
.qyx-bizloop__tabs {
	position: sticky;
	/* [QYX-ANIM] tools-pill-sticky - pinned just BELOW the fixed header for the whole
	   tools scroll | trigger: CSS sticky + --qyx-header-h (measured by JS) | DO-NOT:
	   top:0 (would hide under the header), do not restyle the pill */
	top: calc(var(--qyx-header-h, 96px) + 12px);
	z-index: 20; /* above the cards, below the header (z-50) */
	margin-top: 2.5rem;
	padding: 0.5rem 0;
}
/* Phones keep the sticky pill too. It used to be position:static here, from back
   when the cards did not scroll-stack on mobile - they do, so a static pill just
   scrolled away and left the deck with no phase label. The deck lands below it
   (see --deck-guard), so it never covers a card. */
@media (max-width: 767px) { .qyx-bizloop__tabs { margin-top: 1.75rem; } }
.qyx-bizloop__tabs-inner {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.3rem;
	width: max-content;
	max-width: 100%;
	margin: 0 auto;
	padding: 0.4rem;
	border-radius: 9999px;
	border: 1px solid var(--qyx-border, #e2e8f0);
	/* [QYX-ANIM] no backdrop blur on ANY breakpoint: a backdrop-filter on a sticky
	   element re-samples the blurred backdrop every frame, and on a fast desktop
	   scroll Chrome can't keep up and the pill flashes. Opaque reads the same.
	   DO-NOT: put backdrop-filter back here. */
	background: rgba(255, 255, 255, 0.96);
	box-shadow: 0 10px 30px -16px rgba(15, 23, 42, 0.25);
}
.qyx-bizloop__tab {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.5rem 0.95rem;
	border-radius: 9999px;
	font-size: 0.85rem;
	font-weight: 600;
	color: #64748b;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease;
}
.qyx-bizloop__tab:hover { color: #0f172a; }
.qyx-bizloop__tab-num { font-size: 0.72rem; font-variant-numeric: tabular-nums; opacity: 0.5; }
.qyx-bizloop__tab--active { background: #2b2b2b; color: #fff; }
.qyx-bizloop__tab--active:hover { color: #fff; }
.qyx-bizloop__tab--active .qyx-bizloop__tab-num { opacity: 0.65; }
/* Loop cues: arrows between phases + a return curl, echoing the dark
   lifecycle-loop above so the eye reads this as the same clickable loop. */
.qyx-bizloop__arrow,
.qyx-bizloop__return { display: none; align-items: center; color: #cbd5e1; }
.qyx-bizloop__arrow svg { width: 1rem; height: 1rem; }
.qyx-bizloop__return { color: #94a3b8; padding-left: 0.15rem; }
.qyx-bizloop__return svg { width: 1.05rem; height: 1.05rem; }
@media (min-width: 768px) {
	.qyx-bizloop__arrow,
	.qyx-bizloop__return { display: inline-flex; }
}
@media (max-width: 768px) { .qyx-bizloop__tab-num { display: none; } .qyx-bizloop__tab { padding: 0.45rem 0.7rem; font-size: 0.8rem; } }

/* per-phase scroll-stack */
.qyx-bizloop__stack { padding-bottom: 3rem; }
/* [QYX-ANIM] last-card runway - an empty block after the cards. Every card holds
   its landing line for a full card-height (until the next one covers it); the
   LAST card of a phase has nothing behind it, so it reached its line and was
   immediately shoved back up under the sticky tab pill (~40px of dwell). That is
   what made 26/26 in Create read as "hidden behind the nav". This gives it the
   same beat. It is consumed while the card is parked (the finale rises up behind
   it), so it never shows as a gap.
   DO-NOT: turn this into padding-bottom on the stack - Chrome clamps a sticky
   element to its containing block's CONTENT box, so trailing padding buys no
   dwell at all. DO-NOT: move it after .qyx-progress - the progress bar must stay
   the last in-flow child or it unsticks early and rides up into the deck. */
.qyx-bizloop__runway { height: min(52vh, 440px); }

/* [QYX-ANIM] bizloop seam-blend bg - cross-fades to the active card's pastel AND
   melts to the light bg (#fafafa) at the top + bottom edges so the section blends
   into the white sections above/below instead of "living its own life" | trigger:
   JS sets background via IntersectionObserver | dep: active card | DO-NOT: animate
   layout props, do not remove the mask (the melt is what connects the neighbours) */
.qyx-bizloop__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	background: var(--qyx-bg);
	transition: background-color 0.6s ease;
	pointer-events: none;
}
/* [QYX-ANIM] edge melt - the pastel fades into the neighbouring sections over
   ~220px top and bottom. This used to be a mask-image on .qyx-bizloop__bg, but
   that element spans the WHOLE section: on a phone the Create stack makes it
   ~14000px tall, and a mask forces the browser to rasterise the masked element
   as its own layer - 14000 x 390 CSS px is ~42000px at DPR 3, far past the GPU's
   max texture size, so it had to be re-rastered continuously while scrolling.
   That is what made the pinned tab pill shake. Two short gradient strips painting
   the page colour OVER the pastel give the identical result, and leave the big
   element as a plain solid-colour background that needs no layer at all.
   DO-NOT: go back to mask-image / filter / opacity on this element - anything
   that forces it into its own layer brings the judder back | dep: --qyx-bg must
   stay the page/background colour */
.qyx-bizloop__bg::before,
.qyx-bizloop__bg::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	height: 220px;
	pointer-events: none;
}
.qyx-bizloop__bg::before { top: 0; background: linear-gradient(to bottom, var(--qyx-bg), transparent); }
.qyx-bizloop__bg::after { bottom: 0; background: linear-gradient(to top, var(--qyx-bg), transparent); }
@media (prefers-reduced-motion: reduce) { .qyx-bizloop__bg { transition: none; } }

/* [QYX-ANIM] progress-seg - cards passed vs remaining | trigger: JS .is-passed/.is-active | dep: active card | DO-NOT: animate width with layout props */
.qyx-progress {
	position: sticky;
	bottom: 24px;
	z-index: 10;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: center;
	max-width: 90%;
	margin: 2.5rem auto 0;
}
/* separate short segments (gaps between them), each a muted track that a solid
   black fill sweeps left-to-right when its card becomes active/passed */
.qyx-progress__seg {
	position: relative;
	height: 4px;
	flex: 1 1 0;
	min-width: 16px;
	max-width: 40px;
	border: 0;
	padding: 0;
	border-radius: 999px;
	cursor: pointer;
	overflow: hidden;
	background: rgba(0, 0, 0, 0.12); /* muted track (upcoming) */
}
/* [QYX-ANIM] seg-fill - fills left-to-right when its card is active/passed | trigger: JS toggles .is-active/.is-passed on the seg | dep: active card | DO-NOT: animate width, transform only */
.qyx-progress__fill {
	position: absolute;
	inset: 0;
	transform: scaleX(0);
	transform-origin: left;
	background: var(--qyx-text); /* solid black */
	transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.qyx-progress__seg.is-active .qyx-progress__fill,
.qyx-progress__seg.is-passed .qyx-progress__fill { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .qyx-progress__fill { transition: none; } }
/* mobile: cards already collapse to normal flow; hide the progress nav */
@media (max-width: 767px) { .qyx-progress { display: none; } }

.qyx-bizcard {
	position: sticky;
	/* [QYX-ANIM] deck - EVERY card sticks on the exact same line, so the next card
	   lands squarely on the previous one and hides it completely (card over card,
	   no peeking edges, no per-card stagger). That line centres the card in the
	   space below the fixed header, so it reads clearly and is never tucked under
	   the header/tab pill or cut off at the bottom. The old `150px + --i * 14px`
	   stagger grew with the card count, which is what pushed the last Create cards
	   off the bottom of the viewport.
	   The centring subtracts the real card height (--deck-card-h, measured by
	   qyx-bizloop.js) rather than using translateY(-50%): a transform would move
	   the card visually without moving its layout box, and the tab pill - which is
	   still in normal flow until it sticks - would then float straight across the
	   middle of the first card.
	   DO-NOT: reintroduce --i here (the offset must not scale with the card
	   count), do not re-centre with a transform, do not swap 100svh for 100dvh
	   (a dynamic unit makes the whole deck jiggle as the mobile URL bar hides) */
	/* everything the card must stay clear of: the fixed header, then the sticky
	   tab pill (both measured by qyx-bizloop.js), plus a 12px breath either side */
	--deck-guard: calc(var(--qyx-header-h, 96px) + 12px + var(--qyx-tabs-h, 48px) + 12px);
	/* max(): on a short phone the header + pill + card can exceed the viewport, and
	   plain centring would split the overflow and push the card up under the pill.
	   Clamping to --deck-guard keeps the pill readable and sends the whole overflow
	   to the bottom, where it only costs the card's own padding. */
	top: max(var(--deck-guard), calc((100vh + var(--deck-guard) - var(--deck-card-h, 380px)) / 2));
	top: max(var(--deck-guard), calc((100svh + var(--deck-guard) - var(--deck-card-h, 380px)) / 2));
	/* Landing on one line only hides the card below if every card is the SAME
	   height. Desktop is uniform by construction (the 16:9 figure is taller than
	   the copy, so align-items:center makes the row the figure's height), but the
	   single-column phone card follows its description, which runs 2 to 6 lines.
	   qyx-bizloop.js measures the tallest card per phase into --deck-card-h and
	   this levels the rest up to it | DO-NOT: hardcode a px value, it moves with
	   the phone width and the copy */
	min-height: var(--deck-card-h, 0px);
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 2rem;
	align-items: center;
	margin-top: 1.75rem;
	padding: 1.5rem;
	border-radius: 28px;
	border: 1px solid rgba(15, 23, 42, 0.05);
	/* The figure's frame shadow (see .qyx-bizcard__fig) reaches ~45px past the
	   card's bottom edge. Staggered that read as depth, but now that the cards land
	   on ONE line all of them cast it into the exact same spot - 26 x 5% stacks
	   into a solid grey smudge poking out under the top card. Clip it to the card;
	   the shadow still lifts the screenshot inside the frame.
	   DO-NOT: this is safe only because no sticky element lives INSIDE a card -
	   overflow on an ancestor is what breaks position:sticky. */
	overflow: hidden;
	/* each card = a lightened tint of ITS OWN pastel (set inline by index, i%5:
	   cyan/peach/lilac/mint/rose) so adjacent cards visibly differ. Mix 60% pastel
	   + 40% white == the reference's lightenColor(40). */
	background: color-mix(in srgb, var(--card-pastel, #fff) 60%, #fff);
	/* [QYX-ANIM] stack seam - the incoming card slides over the previous one, and
	   for the whole travel it covers only PART of it. With both cards coplanar on
	   the same landing line and no elevation cue, that mid-scroll state read as one
	   card sliced in half rather than a card lying on a card: a hard horizontal
	   edge straight through a screenshot and a sentence.
	   The shadow is thrown UPWARD, so it falls on the strip of the outgoing card
	   that is still showing - exactly where the depth cue is needed - and the hairline
	   above it separates two pastels that would otherwise touch flat.
	   This is why the old "no card shadow" rule is gone: that one was a full
	   drop-shadow, and since every landed card shares one line and one height, all
	   of them pooled into a grey smudge under the pile. An upward shadow cannot -
	   each landed card is fully covered by the one above it, so only the topmost,
	   still-travelling card ever casts a visible one.
	   DO-NOT: give this a downward offset or a large spread, both bring the smudge
	   back. */
	box-shadow:
		0 -10px 28px -8px rgba(15, 23, 42, 0.13),
		0 -1px 0 0 rgba(255, 255, 255, 0.9);
}
.qyx-bizloop__stack .qyx-bizcard:first-child { margin-top: 2.5rem; }
@media (min-width: 768px) { .qyx-bizcard { gap: 3rem; padding: 2rem; } }
@media (max-width: 767px) {
	/* [QYX-ANIM] Phones: cards STACK on each other (sticky scroll-stack / curtain)
	   like the reference + desktop, instead of plain flow. Single column, each card
	   sticks just under the header with a small per-card stagger so the pile shows.
	   The IntersectionObserver bg cross-fade then reads as the same curtain effect. */
	.qyx-bizcard {
		grid-template-columns: 1fr;
		position: sticky;
		/* no phone-specific landing line: the desktop rule is already driven by the
		   measured header height, so it centres correctly on both. */
		/* the height --deck-card-h adds must pile up BELOW the content, not stretch
		   the figure's 16:9 track (grid's default align-content would do exactly
		   that and crop the screenshot) */
		align-content: start;
	}
}

.qyx-bizcard__fig {
	position: relative;
	/* 16/9, not the original 4/3: the tool screenshots are ~16:9, and a 4/3 box
	   would crop a quarter of the width off a UI capture. Cards still waiting on
	   a shot keep the same ratio so the sticky stack stays one uniform rhythm. */
	aspect-ratio: 16 / 9;
	display: grid;
	place-items: center;
	border-radius: 20px;
	border: 8px solid rgba(255, 255, 255, 0.6);
	background-color: #f1f5f9;
	overflow: hidden;
}
/* The figure is a centring grid; display:contents hands the grid cell straight
   to the <img> so it can fill the frame instead of sitting inline inside it. */
.qyx-bizcard__fig--shot picture {
	display: contents;
}
/* contain, not cover: these are interface captures. A few shots are squarer than
   the rest, and cropping one would slice off the very UI it exists to show - the
   pale frame colour letterboxes them instead, and holds the box's height while
   the image is still lazy-loading. */
.qyx-bizcard__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center;
}
.qyx-bizcard__chip {
	display: grid;
	place-items: center;
	width: 4rem;
	height: 4rem;
	border-radius: 1rem;
}
.qyx-bizcard__preview {
	position: absolute;
	right: 1rem;
	bottom: 0.75rem;
	font-size: 11px;
	font-weight: 500;
	color: #94a3b8;
}

.qyx-bizcard__eyebrow {
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: #94a3b8;
}
.qyx-bizcard__title {
	margin-top: 0.6rem;
	font-size: 1.7rem;
	font-weight: 700;
	line-height: 1.15;
	letter-spacing: -0.01em;
	color: #0f172a;
}
@media (min-width: 1024px) { .qyx-bizcard__title { font-size: 2rem; } }
.qyx-bizcard__desc {
	margin-top: 0.8rem;
	font-size: 1rem;
	line-height: 1.55;
	color: #64748b;
}
.qyx-bizcard__ctas {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
	margin-top: 1.6rem;
}
/* The secondary "See the feature" link sits BESIDE the primary button on one row
   (the container is flex/align-center); it wraps below only when the row is too
   narrow. Guarantee a 44px tap target without touching its look - the link's own
   height is text-sized, which is too small to tap reliably. */
.qyx-bizcard__ctas .qyx-cta-link { min-height: 44px; }
.qyx-bizcard__demo {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.7rem 1.1rem;
	border-radius: 9999px;
	border: 1px solid var(--qyx-border, #e2e8f0);
	background: #fff;
	font-size: 0.88rem;
	font-weight: 600;
	color: #0f172a;
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	transition: background 0.2s ease;
}
.qyx-bizcard__demo:hover { background: #f8fafc; }
.qyx-bizcard__demo svg { text-decoration: none; opacity: 0.7; }

/* closing card */
.qyx-bizloop__finale {
	margin: 3.5rem auto 0;
	max-width: 56rem;
	padding: 3rem 2rem;
	border-radius: 32px;
	text-align: center;
	background: var(--qyx-bg-dark);
	box-shadow: 0 40px 90px -40px rgba(15, 23, 42, 0.6);
}
.qyx-bizloop__finale-title {
	font-size: 1.9rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	color: #fff;
}
@media (min-width: 768px) { .qyx-bizloop__finale-title { font-size: 2.5rem; } }
.qyx-bizloop__finale-desc {
	margin: 1rem auto 0;
	max-width: 34rem;
	font-size: 1.05rem;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.6);
}
.qyx-bizloop__finale-cta { margin-top: 1.75rem; display: flex; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
	.qyx-bizloop__tab,
	.qyx-bizcard__demo { transition: none; }
}

/* Keep the pricing top edge the dark token so the dark marquee wave above it
   connects seamlessly; the glow only shows below this fade. */
.qyx-pricing__topdark {
	position: absolute;
	inset-inline: 0;
	top: 0;
	height: 150px;
	z-index: 0;
	pointer-events: none;
	background: linear-gradient(to bottom, var(--qyx-bg-dark) 0%, var(--qyx-bg-dark) 18%, rgba(8, 5, 7, 0) 100%);
}

/* ============================================================
   "Six tools? One Qyx." - compact WIDE closing card. Height = content
   (no forced tall block); decorative rainbow bar + spinning ring sit behind.
   ============================================================ */
.qyx-wif__card {
	position: relative;
	overflow: hidden;
	border-radius: 34px;
	background: var(--qyx-bg-dark);
	padding: clamp(28px, 5vw, 96px);
}
.qyx-wif__row {
	position: relative;
	z-index: 1;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 2.5rem;
}
.qyx-wif__col-left,
.qyx-wif__col-right { width: 100%; }
@media (min-width: 1024px) {
	.qyx-wif__col-left { width: 50%; }
	.qyx-wif__col-right { width: 41.66%; }
}
.qyx-wif__list { display: flex; flex-direction: column; gap: 24px; margin: 0; padding: 0; list-style: none; }
.qyx-wif__item { display: flex; align-items: center; gap: 1rem; }
.qyx-wif__chip {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 8px;
	background: rgba(255, 255, 255, 0.2);
	color: #fff;
}
.qyx-wif__chip svg { width: 1.25rem; height: 1.25rem; }

/* "Built for" eyebrow: restore the intended gap above the checklist. The markup
   asks for `mb-6`, but that utility is purged out of the Tailwind build, so the
   label rendered glued (0px) to the first item on every breakpoint. */
.qyx-wif__col-right > span { display: block; margin-bottom: 1.5rem; }

/* decor: rainbow threshold bar, bottom-left, masked to fade upward */
.qyx-wif__bar {
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 0;
	width: 70%;
	height: 240px;
	background: var(--qyx-threshold);
	-webkit-mask-image: linear-gradient(180deg, rgba(249, 249, 249, 0) 65%, #f9f9f9 100%);
	mask-image: linear-gradient(180deg, rgba(249, 249, 249, 0) 65%, #f9f9f9 100%);
	opacity: 0.4;
	pointer-events: none;
}
/* decor: faint ring, partly off the right edge, slow ambient spin */
.qyx-wif__ring {
	position: absolute;
	right: -7%;
	top: 50%;
	transform: translateY(-50%);
	z-index: 0;
	width: clamp(360px, 38vw, 540px);
	aspect-ratio: 1;
	pointer-events: none;
}
.qyx-wif__ring svg {
	width: 100%;
	height: 100%;
	/* [QYX-ANIM] cta-ring - slow ambient spin | trigger: CSS animation | DO-NOT: GSAP/scroll */
	animation: qyx-ring-spin 40s linear infinite;
}
@keyframes qyx-ring-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .qyx-wif__ring svg { animation: none; } }
@media (max-width: 1023px) { .qyx-wif__ring { display: none; } }

/* Pricing cost calculator ("Stop collecting subscriptions") */
.qyx-calc-card {
	border-radius: 1.5rem;
	background: rgba(255, 255, 255, 0.04);
	border: 1px solid rgba(255, 255, 255, 0.10);
	padding: 1.5rem;
}
@media (min-width: 640px) { .qyx-calc-card { padding: 2rem; } }
.qyx-calc__group {
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.4);
}
/* ============================================================
   Unified primary CTA - MagicAI signature button (user-supplied, 1:1).
   A dark pill with a hard rainbow strip tucked 5px below it (::after,
   z-index:-1, NO blur). On hover the body inverts to light and the
   strip slides up to hide behind it. `isolation: isolate` keeps the
   negative-z strip visible even inside opaque cards (the old z-index:-1
   bug only happened because the bg used to sit on the <a>; it now sits
   on __body). One look on every background; sizes: default/--hero/--sm.
   display lives in :where() (zero specificity) so the header's
   `hidden lg:inline-flex` / `lg:hidden` Tailwind toggles still win.
   ============================================================ */
.qyx-cta {
	position: relative;
	isolation: isolate;
	text-decoration: none;
	--cta-radius: 12px;
	--cta-peek: 5px;
}
:where(.qyx-cta) { display: inline-flex; }
:where(.qyx-cta--full) { display: flex; width: 100%; }

.qyx-cta::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: calc(var(--cta-peek) * -1);
	width: 100%;
	height: 100%;
	z-index: -1;
	border-radius: var(--cta-radius);
	background: linear-gradient(to right, #3b6bff, #8b5cf6, #ff3bcf, #ff4d4d, #ff9b3b, #34d27a);
	pointer-events: none;
	transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
.qyx-cta__body {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	background: #2b2b2b;
	color: #fafafa;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1;
	letter-spacing: -0.01em;
	padding: 1.25rem 1.75rem;
	border-radius: var(--cta-radius);
	transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), color 0.15s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Brand arrow: sized by font (keeps its 17:12 aspect ratio across CTA sizes). */
.qyx-cta__arrow { height: 0.78em; width: auto; flex: none; transition: transform 0.15s ease; }
.qyx-cta--full .qyx-cta__body { width: 100%; }

.qyx-cta:hover .qyx-cta__body { background: #fafafa; color: #2b2b2b; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12); }
.qyx-cta:hover .qyx-cta__arrow { transform: translateX(3px); }
.qyx-cta:hover::after { transform: translateY(calc(var(--cta-peek) * -1)); }

/* On dark sections the resting button is WHITE (the dark pill disappears on
   black); hover then inverts to dark. Style/shape/strip/arrow are unchanged. */
[data-color-scheme="dark"] .qyx-cta__body { background: #fafafa; color: #2b2b2b; }
[data-color-scheme="dark"] .qyx-cta:hover .qyx-cta__body { background: #2b2b2b; color: #fafafa; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35); }

/* sm - header + in-card CTAs */
.qyx-cta--sm { --cta-radius: 10px; --cta-peek: 4px; }
.qyx-cta--sm .qyx-cta__body { gap: 0.55rem; font-size: 0.85rem; padding: 0.7rem 1.1rem; }

@media (prefers-reduced-motion: reduce) {
	.qyx-cta::after, .qyx-cta__body, .qyx-cta__arrow { transition: none; }
}

/* Secondary - hypertext link with a small dark circle arrow (MagicAI). */
.qyx-cta-link { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; }
.qyx-cta-link__text {
	color: #11121a;
	font-weight: 600;
	font-size: 0.9375rem;
	line-height: 1;
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.15s ease;
}
.qyx-cta-link__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	border-radius: 50%;
	background: #11121a;
	flex: none;
	transition: transform 0.15s ease;
}
.qyx-cta-link__icon svg { stroke: #fff; }
.qyx-cta-link:hover .qyx-cta-link__icon { transform: translateX(2px); }
/* On dark sections the link flips to light ink + light chip. */
[data-color-scheme="dark"] .qyx-cta-link__text { color: #f1f5f9; }
[data-color-scheme="dark"] .qyx-cta-link__icon { background: #f1f5f9; }
[data-color-scheme="dark"] .qyx-cta-link__icon svg { stroke: #0b0b0e; }

/* Quiet - plain muted text link (hero "Discover Qyx"). */
.qyx-cta-quiet {
	font-weight: 500;
	font-size: 1.0625rem;
	color: #9094a3;
	text-decoration: none;
	transition: color 0.15s ease;
}
.qyx-cta-quiet:hover { color: #5b6072; }
[data-color-scheme="dark"] .qyx-cta-quiet { color: rgba(255, 255, 255, 0.5); }
[data-color-scheme="dark"] .qyx-cta-quiet:hover { color: rgba(255, 255, 255, 0.8); }

/* Phones: hero CTAs go (almost) full-width, stacked one below the other - the
   primary fills the content column, the quiet "Discover Qyx" centres beneath it. */
@media (max-width: 639px) {
	.qyx-hero-ctas { align-items: stretch; }
	.qyx-hero-ctas > .qyx-cta { width: 100%; }
	.qyx-hero-ctas > .qyx-cta .qyx-cta__body { width: 100%; justify-content: center; }
	.qyx-hero-ctas > .qyx-cta-quiet { width: 100%; text-align: center; padding: 0.25rem 0; }
}

/* ============================================================
   Header "join" CTA - a rainbow ring-outline pill. The conic ring rotates via
   @property (animatable custom angle); browsers without @property show a static
   ring (looks the same at rest). Floats over light AND dark sections - white
   ink over dark, hover fills white and the ring fades. display lives in
   :where() so the header's `hidden lg:inline-flex` / `lg:hidden` toggles win.
   ============================================================ */
@property --join-a { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
@keyframes join-flow { to { --join-a: 360deg; } }
.join-hub {
	position: relative;
	align-items: center;
	border-radius: 9999px;
	padding: 12px 16px;
	background: transparent;
	color: #2b2b2b;
	font: 600 14px/1 var(--qyx-font);
	letter-spacing: -0.01em;
	text-decoration: none;
	white-space: nowrap;
	transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1), background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
:where(.join-hub) { display: inline-flex; }
.join-hub::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	padding: 3px;
	background: conic-gradient(from var(--join-a), #3b6bff, #8b5cf6, #ff3bcf, #ff4d4d, #ff9b3b, #34d27a, #3b6bff);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
	animation: join-flow 4s linear infinite;
	pointer-events: none;
	transition: opacity 0.15s ease;
}
.join-hub:hover { transform: scale(1.05); background: #fff; color: #2b2b2b; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.08); }
.join-hub:hover::before { opacity: 0; }
/* Over a dark section the header carries .is-dark: white ink, hover back to dark. */
.site-header.is-dark .join-hub { color: #fff; }
.site-header.is-dark .join-hub:hover { color: #2b2b2b; }
@media (prefers-reduced-motion: reduce) {
	.join-hub::before { animation: none; }
}

.qyx-calc__row {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.6rem 0;
	cursor: pointer;
	border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.qyx-calc__row:hover .qyx-calc__name { color: #fff; }
.qyx-calc__row:last-child { border-bottom: 0; }
.qyx-calc__cb { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.qyx-calc__box {
	flex: 0 0 auto;
	width: 1.3rem;
	height: 1.3rem;
	border-radius: 7px;
	border: 1.5px solid rgba(255, 255, 255, 0.25);
	display: grid;
	place-items: center;
	color: #fff;
	transition: background 0.15s ease, border-color 0.15s ease;
}
.qyx-calc__box svg { width: 0.8rem; height: 0.8rem; opacity: 0; transition: opacity 0.15s ease; }
.qyx-calc__box.is-on { background: #34b869; border-color: transparent; }
.qyx-calc__box.is-on svg { opacity: 1; }
.qyx-calc__cb:focus-visible + .qyx-calc__box { outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 2px; }
.qyx-calc__name { flex: 1 1 auto; min-width: 0; font-size: 0.9rem; color: rgba(255, 255, 255, 0.85); }
.qyx-calc__price { flex: 0 0 auto; font-size: 0.85rem; color: rgba(255, 255, 255, 0.45); font-variant-numeric: tabular-nums; }
.qyx-calc__note { margin-top: 1.25rem; font-size: 0.72rem; color: rgba(255, 255, 255, 0.35); }

.qyx-calc-offer {
	background: #0d0a12;
	border: 1.5px solid rgba(255, 255, 255, 0.14);
	border-radius: 1.5rem;
	padding: 1.75rem;
	box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.6);
}
.qyx-calc__was { font-size: 0.8rem; color: rgba(255, 255, 255, 0.4); text-decoration: line-through; font-variant-numeric: tabular-nums; }
.qyx-calc__badge {
	font-size: 0.7rem;
	font-weight: 600;
	padding: 0.25rem 0.6rem;
	border-radius: 9999px;
	background: rgba(52, 211, 153, 0.15);
	color: #6ee7b7;
	white-space: nowrap;
}
.qyx-calc__save {
	padding: 1.1rem 1.25rem;
	border-radius: 1rem;
	text-align: center;
	background: rgba(255, 255, 255, 0.05);
	border: 1px solid rgba(255, 255, 255, 0.10);
}
.qyx-calc__save-big { font-size: 1.9rem; font-weight: 800; line-height: 1.1; margin: 0.3rem 0; }
.qyx-calc__bullet { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.9rem; color: rgba(255, 255, 255, 0.82); }
.qyx-calc__bullet-ic { flex: 0 0 auto; color: #34d399; display: inline-flex; margin-top: 0.05rem; }
.qyx-calc__bullet-ic svg { width: 1.15rem; height: 1.15rem; }

/* Live subtotal at the foot of the left calculator card. */
.qyx-calc__subtotal {
	margin-top: 1.1rem;
	padding-top: 1rem;
	border-top: 1px solid rgba(255, 255, 255, 0.10);
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	font-size: 0.9rem;
	color: rgba(255, 255, 255, 0.6);
}
.qyx-calc__subtotal > span:last-child {
	font-size: 1.35rem;
	font-weight: 700;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

/* Offer header: a dark "bubble" (same shell as the savings / credits panels) with a
   3-column price line - struck anchor (brand red) · ALL-IN-ONE PLAN (white, Spline
   Sans) · $1/day hero (brand green). Reads as one of the dark offer-card bubbles. */
.qyx-offer-head {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 0.75rem;
	background: rgba(255, 255, 255, 0.05);
	border: 1px solid rgba(255, 255, 255, 0.10);
	border-radius: 1rem;
	padding: 1.1rem 1.35rem;
	margin-bottom: 0.85rem;
}
.qyx-offer-head__anchor { display: flex; flex-direction: column; gap: 0.1rem; }
.qyx-offer-head__stop { font-size: 0.72rem; font-weight: 700; color: #ff5a63; }
.qyx-offer-head__was {
	font-size: 1rem;
	font-weight: 600;
	color: rgba(255, 90, 99, 0.6);
	text-decoration: line-through;
	text-decoration-thickness: 2px;
	font-variant-numeric: tabular-nums;
}
.qyx-offer-head__plan {
	text-align: center;
	font-size: 0.82rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	line-height: 1.2;
	color: rgba(255, 255, 255, 0.92);
}
.qyx-offer-head__hero { display: flex; flex-direction: column; align-items: flex-end; }
.qyx-offer-head__price { display: flex; align-items: baseline; gap: 0.1rem; }
.qyx-offer-head__amount {
	font-size: 1.9rem;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.01em;
	color: #fff;
	font-variant-numeric: tabular-nums;
}
.qyx-offer-head__per { font-size: 0.9rem; font-weight: 600; color: rgba(255, 255, 255, 0.5); }
.qyx-offer-head__billed { margin-top: 0.1rem; font-size: 0.78rem; font-weight: 700; color: rgba(255, 255, 255, 0.85); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Savings: monthly is the headline; the number picks up the brand gradient. */
.qyx-calc__save-main { font-size: 1.3rem; font-weight: 800; line-height: 1.25; color: #fff; margin: 0; }
.qyx-calc__save-sub { display: block; margin-top: 0.4rem; font-size: 0.85rem; color: rgba(255, 255, 255, 0.5); }

/* "What you actually get" value panel (the highlight box). */
.qyx-calc__get {
	margin-top: 1.25rem;
	padding: 1.25rem;
	border-radius: 1rem;
	background: rgba(255, 255, 255, 0.05);
	border: 1px solid rgba(139, 92, 246, 0.40);
}
.qyx-calc__get-title { font-size: 0.95rem; font-weight: 700; color: #fff; }
.qyx-calc__get-lead { margin-top: 0.4rem; font-size: 0.85rem; line-height: 1.5; color: rgba(255, 255, 255, 0.65); }
.qyx-calc__get-list { margin-top: 0.9rem; display: flex; flex-direction: column; gap: 0.5rem; }
.qyx-calc__get-list li { display: flex; align-items: flex-start; gap: 0.55rem; font-size: 0.88rem; color: rgba(255, 255, 255, 0.9); }
.qyx-calc__get-list li svg { flex: 0 0 auto; width: 1rem; height: 1rem; color: #34d399; margin-top: 0.12rem; }
.qyx-calc__get-foot { margin-top: 0.9rem; font-size: 0.72rem; font-style: italic; color: rgba(255, 255, 255, 0.4); }

/* ============================================================
   Landing footer - light + minimal (reference: marketingbot):
   brand + socials, columns of underlined links, and a centred
   language selector. Colours live here (not Tailwind utilities).
   ============================================================ */
/* [QYX-ANIM] footer uses the same bg token as every light section + no hard border line,
   so it reads as a continuous surface with the section above (was #fafafb + a 1px rule = seam). */
.qyx-footer { background: var(--qyx-bg-light); color: #0f172a; }
.qyx-footer__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
}
@media (min-width: 1024px) {
	/* Brand column carries the tagline, badge, CTA and support block, so it gets
	   the extra width; the three link columns share the rest evenly. */
	.qyx-footer__grid { grid-template-columns: 1.35fr repeat(3, minmax(0, 1fr)); column-gap: 2.5rem; }
}
.qyx-footer__brand { grid-column: span 2; }
@media (min-width: 1024px) { .qyx-footer__brand { grid-column: span 1; max-width: 22rem; } }
.qyx-footer__tagline {
	font-size: clamp(1.15rem, 1rem + 0.6vw, 1.45rem);
	line-height: 1.25;
	font-weight: 700;
	letter-spacing: -0.02em;
	color: #0f172a;
	margin-bottom: 1.5rem;
}
.qyx-footer__socials { display: flex; align-items: center; gap: 0.5rem; margin-top: 1.5rem; }
.qyx-footer__social {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 9999px;
	color: #0f172a;
	transition: background-color 0.2s ease, transform 0.2s ease;
}
.qyx-footer__social:hover { background: #eef0f3; transform: translateY(-1px); }
.qyx-footer__heading { font-size: 0.95rem; font-weight: 700; color: #0f172a; }
.qyx-footer__list { margin-top: 1.25rem; display: flex; flex-direction: column; gap: 0.85rem; }
.qyx-footer__link {
	font-size: 0.95rem;
	color: #334155;
	text-decoration: underline;
	text-decoration-color: rgba(15, 23, 42, 0.25);
	text-underline-offset: 4px;
	transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.qyx-footer__link:hover { color: #0f172a; text-decoration-color: #0f172a; }
/* Legal block sits under the Company links as a quieter second group. */
.qyx-footer__list--legal {
	margin-top: 1.25rem;
	padding-top: 1.25rem;
	border-top: 1px solid rgba(15, 23, 42, 0.08);
	gap: 0.7rem;
}
.qyx-footer__list--legal .qyx-footer__link { font-size: 0.85rem; color: #64748b; }

/* "Made in Europe" origin badge. */
.qyx-footer__eu {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: 1.5rem;
	padding: 0.4rem 0.75rem 0.4rem 0.5rem;
	border: 1px solid rgba(15, 23, 42, 0.1);
	border-radius: 9999px;
	font-size: 0.82rem;
	font-weight: 600;
	color: #334155;
	background: #fff;
}
.qyx-footer__eu-flag { flex: none; border-radius: 4px; }

.qyx-footer__cta { margin-top: 1.75rem; }
.qyx-footer__support { margin-top: 2rem; }
/* Below the 4-column breakpoint the Company column would sit alone in the left
   half with 7 legal links trailing off it - let it span the row and lay the
   legal block out in two columns instead. */
@media (max-width: 1023px) {
	.qyx-footer__company { grid-column: span 2; }
	.qyx-footer__list--legal { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.5rem; }
}

.qyx-footer__bottom {
	margin-top: 3.5rem;
	padding-top: 2rem;
	border-top: 1px solid #ececef;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1rem;
}
.qyx-footer__lang { position: relative; }
.qyx-footer__lang-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.55rem 1rem;
	border-radius: 9999px;
	border: 1px solid #e2e8f0;
	background: #fff;
	font-size: 0.95rem;
	font-weight: 600;
	color: #0f172a;
	cursor: pointer;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.qyx-footer__lang-btn:hover { border-color: #cbd5e1; box-shadow: 0 6px 18px -12px rgba(15, 23, 42, 0.35); }
.qyx-footer__lang-globe { width: 1.2rem; height: 1.2rem; color: #64748b; }
.qyx-footer__lang-chev { width: 1rem; height: 1rem; color: #94a3b8; }
.qyx-footer__lang-menu {
	position: absolute;
	bottom: calc(100% + 0.6rem);
	/* Centre without transform: Alpine's x-transition animates `transform`, which
	   would clobber a translateX(-50%) centring and make the menu flash in off-centre
	   then jump. left + negative margin keeps positioning independent of transform. */
	left: 50%;
	width: 12rem;
	margin-left: -6rem;
	padding: 0.35rem;
	border-radius: 0.85rem;
	background: #fff;
	border: 1px solid #e2e8f0;
	box-shadow: 0 18px 40px -18px rgba(15, 23, 42, 0.3);
	z-index: 10;
}
.qyx-footer__lang-item {
	display: block;
	padding: 0.55rem 0.75rem;
	border-radius: 0.6rem;
	font-size: 0.9rem;
	color: #334155;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.qyx-footer__lang-item:hover { background: #f1f5f9; color: #0f172a; }
/* #94a3b8 on the footer wash was 2.45:1 - below WCAG AA. The muted token is the
   same visual weight and clears 4.5:1. */
.qyx-footer__copy { font-size: 0.8rem; color: var(--qyx-text-muted, #6b7080); }

/* ============================================================
   [QYX-ANIM] MOBILE / TABLET RESPONSIVE PASS - SCOPED <=1023px ONLY
   Desktop (>=1024px) is FROZEN: every declaration below lives inside a
   max-width media query, so no desktop pixel changes. Hero is excluded
   throughout (.site-section.min-h-screen). Tokens only; GPU-only; no markup.
   ============================================================ */
@media (max-width: 1023px) {

	/* 1. RHYTHM - one consistent vertical padding token on every section except
	   hero, so the page reads heading -> content -> next at a steady cadence.
	   Overrides the assorted py-* utilities at equal specificity (theme.css loads
	   after Tailwind) and only below 1024px, so desktop spacing is untouched. */
	.site-section:not(.min-h-screen),
	#faq {
		padding-top: clamp(38px, 9vw, 64px);
		padding-bottom: clamp(38px, 9vw, 64px);
	}
	/* [QYX-ANIM] wave/dark sections keep more room: their SVG dividers (~46px) + the
	   lifecycle top fade (90px) need clearance, so their content never rides into the
	   wave or the light fade band. (Their visual "gap" is the wave, not empty space.) */
	.qyx-loop.site-section, .qyx-pricing.site-section, .qyx-marquee.site-section {
		padding-top: clamp(56px, 12vw, 80px);
		padding-bottom: clamp(56px, 12vw, 80px);
	}

	/* 2. SECTION CONNECTION - use the SAME token as desktop: a single flat
	   var(--qyx-bg-light) behind every light section so they all read as one
	   continuous surface (the earlier per-section pastel tints made adjacent
	   sections look mismatched). The dark islands + their wave dividers keep the
	   only intentional colour breaks - exactly like desktop. Mobile == desktop bg. */
	html, body { background: var(--qyx-bg-light); }

	/* [QYX-ANIM] 3. "What do you do?" triggers: a CENTERED WRAPPING pill row so EVERY
	   option is visible at once (the previous x-scroll row hid 3 of the 5 pills). Compact
	   pills keep it from becoming a tall stack; >=44px tap target preserved. */
	.qyx-persona__selector { flex-wrap: wrap; justify-content: center; gap: 0.5rem; }
	.qyx-persona__option { min-height: 44px; font-size: 0.84rem; padding: 0.55rem 0.9rem; }

	/* 4. SOLID CARDS - the ai-tools tool cards read defined (not faint empty
	   rectangles) until the live demos land in the figure: a touch more pastel
	   and a clearer border/edge. */
	.qyx-bizcard {
		background: color-mix(in srgb, var(--card-pastel, #fff) 80%, #fff);
		border-color: color-mix(in srgb, var(--card-pastel, #fff) 45%, #cbd5e1);
	}
	.qyx-bizcard__fig { border-color: rgba(255, 255, 255, 0.75); }
}

/* [QYX-ANIM] Phones (<=767px): the ai-tools tool cards were a wall of huge empty
   "preview" figure boxes plus duplicate per-card CTAs - reads as unfinished. Until
   live demos drop into the figure, make each card tidy and intentional: the figure
   becomes a compact branded banner (capped height, bigger centred icon, no "preview"
   caption), and the text tightens. The per-card Start/See-it CTAs stay (parity with
   desktop) but stack full-width so they fit the narrow single-column card. Desktop AND
   tablet (>=768px) keep the full 2-column sticky cards untouched. Placed last so it wins. */
@media (max-width: 767px) {
	.qyx-bizcard { padding: 0.875rem; gap: 0; border-radius: 20px; }
	/* The figure used to be squashed to a 132px icon banner here, because on phones
	   it was an empty "preview" box and a full-height one read as unfinished. It now
	   holds a real screenshot, so it keeps its 16:9 frame - just with a thinner
	   border to claw back width. */
	.qyx-bizcard__fig {
		border-width: 5px;
		border-radius: 16px;
		margin-bottom: 0.95rem;
	}
	.qyx-bizcard__chip { width: 3.25rem; height: 3.25rem; border-radius: 0.9rem; }
	.qyx-bizcard__chip svg { width: 1.75rem; height: 1.75rem; }
	.qyx-bizcard__preview { display: none; }
	.qyx-bizcard__eyebrow { font-size: 0.68rem; }
	.qyx-bizcard__title { margin-top: 0.35rem; font-size: 1.18rem; line-height: 1.25; }
	.qyx-bizcard__desc { margin-top: 0.4rem; font-size: 0.9rem; line-height: 1.45; }
	/* [QYX-ANIM] keep "Get started" and "See it in action" on ONE row. Both are
	   auto-width (the card passes no full=>true, whatever the old comment here
	   claimed), so they sit side by side via flex - but measured, the pair wanted
	   329px against 328px of card width on a 390px phone, so it wrapped to two
	   rows on every phone up to 390. Tightening the button's horizontal padding
	   and its text/arrow gap buys back ~30px, which fits from 360px up. Scoped to
	   the deck cards, so every other CTA on the site keeps its full padding.
	   flex-wrap stays on: below 360px the pair genuinely cannot fit, and wrapping
	   is a better failure than overflowing the card. */
	.qyx-bizcard__ctas { margin-top: 1.1rem; gap: 0.5rem; }
	.qyx-bizcard__ctas .qyx-cta__body { padding-left: 1rem; padding-right: 1rem; gap: 0.55rem; }
	.qyx-bizcard__ctas .qyx-cta-link__text,
	.qyx-bizcard__ctas .qyx-cta__body { white-space: nowrap; }
}

/* ============================================================
   [QYX-ANIM] PART B - RESPONSIVE FIXES (<=1023px ONLY, desktop frozen)
   Every rule below lives in a max-width query. Hero + use-cases fan untouched.
   ============================================================ */

/* lifecycle-loop: phase nav was a tall vertical stack of 5 full-width pills below
   1024px (~350px of dead nav). Make it a compact horizontal wrapping pill row
   (matches the task standard), drop the connector chevrons + the "back to the
   start" return on mobile. Desktop (>=1024) keeps its own row rule untouched. */
@media (max-width: 1023px) {
	.qyx-loop__nav { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.5rem; }
	/* [QYX-ANIM] centre the panel content (step / title / body / CTA) on mobile so it matches
	   the rest of the centred mobile layout - the CTA was left-aligned and looked off. */
	.qyx-loop__reveal { text-align: center; }
	.qyx-loop__stage { width: auto; padding: 0.6rem 1rem; }
	.qyx-loop__arrow, .qyx-loop__return { display: none; }
}

/* pricing "Do the math": keep the offer badge from crowding the price row, soften
   the big savings figure, and give the calc rows a >=44px tap height at narrow widths. */
@media (max-width: 1023px) {
	.qyx-calc__row { min-height: 44px; align-items: center; }
}
@media (max-width: 639px) {
	.qyx-calc__badge { margin-left: 0; margin-top: 0.4rem; }
	.qyx-calc__save-big { font-size: 1.5rem; }
}

/* footer: it carries no .site-section class so it missed the rhythm token; give it
   the same mobile padding, collapse the 2-col grid (Resources was an orphan) to one
   column, and bump link / social tap targets to >=44px. */
@media (max-width: 1023px) {
	.qyx-footer > div { padding-top: clamp(56px, 12vw, 80px); padding-bottom: clamp(56px, 12vw, 80px); }
	.qyx-footer__link { display: block; padding-block: 0.5rem; }   /* ~40px touch row, not too sparse */
	.qyx-footer__social { width: 2.75rem; height: 2.75rem; }
}
@media (max-width: 767px) {
	/* [QYX-ANIM] 2-column link grid (was a single sparse column of 12 stacked links -
	   too tall/empty). brand+social span the top; the link groups sit two-up below. */
	.qyx-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.5rem; row-gap: 2.25rem; }
	.qyx-footer__brand { grid-column: span 2; }
}

/* benefits "Six tools?": tighten the dark card padding + row gap on phones.
   Extra BOTTOM padding + a softer rainbow bar so the last "Built for" item
   ("Local businesses") isn't jammed onto the bright band and read as cropped. */
@media (max-width: 767px) {
	.qyx-wif__card { padding: 1.5rem 1.5rem 2.75rem; }
	.qyx-wif__row { gap: 1.5rem; }
	.qyx-wif__bar { height: 170px; opacity: 0.24; }
}

/* benefits CTA: on phones make it full-width + centred, exactly like the hero
   primary (mirrors the .qyx-hero-ctas rule at the same <=639px breakpoint). */
@media (max-width: 639px) {
	.qyx-wif__col-left .qyx-cta { width: 100%; }
	.qyx-wif__col-left .qyx-cta .qyx-cta__body { width: 100%; justify-content: center; }
}

/* ecosystem: halve the desktop-tuned -120px pull-up so the logo grid can't ride up
   into the hero on small phones; give the "and more" button a >=44px tap height. */
@media (max-width: 767px) { .qyx-ecosystem { margin-top: -60px; } }
@media (max-width: 1023px) { .qyx-model-pill--more { padding-block: 0.7rem; } }

/* ai-tools: shrink the finale card padding/title on phones; let the tab strip size
   to content (no max-content first-paint overflow flash). */
@media (max-width: 767px) {
	.qyx-bizloop__finale { padding: 2rem 1.25rem; border-radius: 24px; }
	.qyx-bizloop__finale-title { font-size: 1.55rem; }
	/* [QYX-ANIM] phase tabs on ONE line with ALL 5 visible inside the pill (the wrap put
	   "Engage" on row 2; the scroll version cut it off). Tight enough that Think/Create/
	   Publish/Convert/Engage all fit at 360px; nowrap, centred, no scrollbar. */
	.qyx-bizloop__tabs-inner {
		width: auto;
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		gap: 0.1rem;
		justify-content: center;
		padding: 0.3rem;
		/* [QYX-ANIM] no backdrop blur on phones: the pill is sticky here, and a
		   backdrop-filter on a sticky element has to re-sample the blurred backdrop
		   every frame - on mobile that visibly judders as you scroll. An opaque
		   pill reads the same over this light section and composites for free.
		   DO-NOT: put backdrop-filter back on the phone breakpoint. */
		background: rgba(255, 255, 255, 0.96);
		backdrop-filter: none;
		-webkit-backdrop-filter: none;
	}
	/* [QYX-ANIM] the five tabs fit the pill from 375px up (measured: content ==
	   box), so above 360px drop the scroll container. A nested scroller inside a
	   position:sticky element forces the browser to keep a second composited
	   scrolling layer glued to a parent it re-positions every frame, which is a
	   known source of sticky judder on mobile. Below 361px they really do overflow
	   (21px at 320px), so the scroller stays there. */
	@media (min-width: 361px) {
		.qyx-bizloop__tabs-inner { overflow-x: visible; }
	}
	/* [QYX-ANIM] give the pinned pill its own compositor layer. It sits on top of
	   .qyx-bizloop__bg, a full-section masked layer that cross-fades its colour, so
	   without promotion the pill is repainted as the page scrolls under it.
	   DO-NOT: widen this to the cards - 26 promoted layers would cost far more than
	   they save. */
	.qyx-bizloop__tabs { will-change: transform; }
	.qyx-bizloop__tabs-inner::-webkit-scrollbar { display: none; }
	.qyx-bizloop__tab { flex: 0 0 auto; padding: 0.5rem 0.62rem; font-size: 0.78rem; white-space: nowrap; gap: 0; }
	.qyx-bizloop__tab-num { display: none; }   /* drop the "01" number on mobile to save width */
}

/* persona: guarantee the selector pills meet the 44px tap minimum on touch. */
@media (max-width: 1023px) { .qyx-persona__option { min-height: 44px; } }

/* [QYX-ANIM] MARQUEE on phones - the kinetic word strip read as "broken": 100px words
   showed only giant fragments, and the rainbow glow (anchored bottom, 500px tall) had its
   soft fade-in band ABOVE the short section, so it started at full strength = a hard top
   colour edge. Fix: smaller words (clean scrolling line) + glow fills the section and fades
   at BOTH edges so it melts into the neighbours instead of a hard seam. Mobile-only. */
@media (max-width: 767px) {
	.qyx-marquee__cell { font-size: 52px; opacity: 0.24; }   /* smaller + a bit more visible (was 0.15) */
	/* nudge the scrolling words UP so they sit clear of the glow + the bottom wave and stay legible */
	.qyx-marquee__words { transform: translateY(-26px); }
	.qyx-marquee__glow {
		inset: 0;
		height: auto;
		opacity: 0.42 !important;   /* override the inline opacity:0.6 */
		-webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 62%, transparent 100%) !important;
		        mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 62%, transparent 100%) !important;
	}
}

/* [QYX-ANIM] PRICING calculator - MOBILE compacting (desktop frozen). The disclosure
   toggle is a NEW element hidden on desktop (so desktop is pixel-identical: the chevron
   never shows >=1024 and the list stays open). All real layout/behaviour changes below
   live inside @media (max-width:1023px). The Alpine inputs are untouched - collapsing is
   pure CSS max-height on the wrapper, so live recalculation keeps working. */
.qyx-calc__toggle { display: none; }   /* desktop: hidden (new element, zero desktop pixels) */

@media (max-width: 1023px) {
	/* A) RESULT FIRST: show the payoff before the checklist (CSS order only, markup unmoved) */
	.qyx-calc-offer { order: -1; }

	/* the tap-to-expand header + chevron (mobile only) */
	.qyx-calc__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; cursor: pointer; }
	.qyx-calc__toggle {
		display: inline-grid; place-items: center;
		flex: 0 0 auto; width: 2.5rem; height: 2.5rem; min-height: 44px; min-width: 44px;
		border-radius: 9999px; background: rgba(255, 255, 255, 0.08);
		border: 1px solid rgba(255, 255, 255, 0.14); color: #fff; cursor: pointer;
	}
	.qyx-calc__chevron { width: 1.1rem; height: 1.1rem; transition: transform 0.25s ease; }
	.qyx-calc__chevron.is-open { transform: rotate(180deg); }

	/* B) COLLAPSE the checklist (inputs stay in DOM - just CSS max-height) */
	.qyx-calc__list { overflow: hidden; max-height: 1600px; transition: max-height 0.35s ease, opacity 0.25s ease, margin-top 0.2s ease; }
	.qyx-calc__list.is-collapsed { max-height: 0; opacity: 0; margin-top: 0; }

	/* C) TIGHTER ROWS when expanded */
	.qyx-calc__list > div + div { margin-top: 0.85rem; }   /* group spacing (overrides space-y-5) */
	.qyx-calc__row { padding-block: 0.4rem; gap: 0.6rem; }
	.qyx-calc__box { width: 1.15rem; height: 1.15rem; }
	.qyx-calc__name { font-size: 0.86rem; line-height: 1.3; }
	.qyx-calc__price { font-size: 0.78rem; }
	.qyx-calc__group { font-size: 0.72rem; }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-calc__list, .qyx-calc__chevron { transition: none; }
}

/* [QYX-ANIM] PRICING bottom wave divider - MOBILE only (desktop >=1024 frozen). On phones the
   500px accent glow (whose mask made it STRONGEST right at the bottom) smeared a rainbow across
   the wave, so the dark->white divider read as a dirty cut with hard-looking side corners. Fix:
   tame the glow to a small accent that fades fully OUT above the wave, drop the w-screen (100vw)
   width so it can't sit asymmetrically / overflow, and keep the wave a crisp full-width solid-
   light edge (it already stretches preserveAspectRatio=none). Below the curve stays clean light. */
@media (max-width: 1023px) {
	.qyx-pricing__glow {
		width: 100%;            /* was w-screen / 100vw - kill edge asymmetry + overflow risk */
		height: 200px;          /* was 500px - a small base accent, not a full-section smear */
		opacity: 0.16;          /* was .30 - subtler on the short mobile section */
		/* fade the colour IN then fully OUT well above the wave -> the divider is a clean dark->white */
		-webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 40%, transparent 70%) !important;
		        mask-image: linear-gradient(180deg, transparent 0%, #000 40%, transparent 70%) !important;
	}
	.qyx-pricing__wave { display: block; height: 60px; }   /* crisp, full-width, no inline gap */
}

/* ============================================================
   [QYX-ANIM] REFERENCE CARD STYLE PASS - shared light/dark card polish to match
   marketing-bot. Style only (no content/markup change); colour via --qyx-* tokens.
   LIGHT cards (ai-tools bizcards): image-frame shadow + title divider + hover lift.
   (use-cases cards already carry the equivalent Option-B treatment.)
   DARK cards (benefits, persona solution): neumorphic icon chip + conic hover-glow.
   Perf: the conic glow's gradient+mask+spin exist ONLY on :hover, so idle cost = 0.
   ============================================================ */

/* LIGHT - ai-tools bizcard: the figure already has the 8px translucent-white frame;
   add the spec's soft low-opacity shadow + a hairline divider under the title + lift. */
.qyx-bizcard__fig { box-shadow: 0 33px 44px hsl(0 0% 0% / 0.05); }
.qyx-bizcard__title { padding-bottom: 0.7rem; border-bottom: 1px solid var(--qyx-border); }
/* No hover lift on .qyx-bizcard: it is a sticky deck, so while scrolling the
   pointer hands :hover from the parked card to the one sliding over it. The
   covered card was still scaled 1.02 for the 0.3s shrink-back and poked out
   around the new top card, which read as the deck flickering in Chrome.
   DO-NOT: add a transform/scale hover back to the deck cards. */

/* DARK - neumorphic icon chip (light catching the top/left edges) + scale on hover */
.qyx-wif__chip, .qyx-persona__brand-mark {
	box-shadow: inset 1px 1px 0 hsl(0 0% 100% / 0.4), inset 2px 2px 4px -1px hsl(0 0% 100% / 0.2),
	            inset -1px -1px 3px -2px hsl(0 0% 100% / 0.4), inset -3px -3px 4px -4px hsl(0 0% 100% / 0.4);
	transition: transform 0.3s ease;
}
@media (hover: hover) {
	.qyx-wif__card:hover .qyx-wif__chip,
	.qyx-persona__solution-card:hover .qyx-persona__brand-mark { transform: scale(1.1); }
}

/* DARK - conic-gradient hover-glow outline (the reference's signature dark-card detail) */
@property --qyx-card-glow-a { syntax: "<angle>"; initial-value: 290deg; inherits: false; }
@keyframes qyx-card-glow-spin { to { --qyx-card-glow-a: 650deg; } }
.qyx-wif__card, .qyx-persona__solution-card { position: relative; }
.qyx-wif__card::after, .qyx-persona__solution-card::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	opacity: 0;
	transition: opacity 0.4s ease;
	pointer-events: none;
	z-index: 0;
}
@media (hover: hover) {
	.qyx-wif__card:hover::after, .qyx-persona__solution-card:hover::after {
		opacity: 1;
		padding: 3px;
		background: conic-gradient(from var(--qyx-card-glow-a), var(--qyx-grad-1), var(--qyx-grad-2), var(--qyx-grad-3), var(--qyx-grad-4), var(--qyx-grad-5), var(--qyx-grad-1));
		-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
		-webkit-mask-composite: xor;
		        mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
		        mask-composite: exclude;
		animation: qyx-card-glow-spin 4s linear infinite;
	}
}
@media (prefers-reduced-motion: reduce) {
	.qyx-wif__chip, .qyx-persona__brand-mark { transition: none; }
	.qyx-wif__card:hover::after, .qyx-persona__solution-card:hover::after { animation: none; }
}

/* ============================================================
   /pricing page (page-pricing.php + template-parts/pricing/*).
   Mobile-first; enhances at 768/1024. Matches the dashboard/Galaxy
   reference design, reuses theme tokens.
   ============================================================ */
.qyx-pricing-page {
	background: var(--qyx-bg-light);
	color: #1e293b;
	padding-top: calc(var(--qyx-header-h, 72px) + 1rem);
}
.qyx-pr-container { width: 100%; max-width: 74rem; margin-inline: auto; padding-inline: clamp(1rem, 5vw, 2rem); }
.qyx-pr-container--narrow { max-width: 48rem; }
.qyx-pr-vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.qyx-pr-h2 { font-family: var(--qyx-font-heading, inherit); font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.75rem); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; text-align: center; color: #0f172a; }
.qyx-pr-eyebrow { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.85rem; border-radius: 999px; background: #ecfdf5; color: #047857; font-size: 0.78rem; font-weight: 700; box-shadow: inset 0 0 0 1px #a7f3d0; }
.qyx-pr-eyebrow--plain { background: #eef2ff; color: #4338ca; box-shadow: inset 0 0 0 1px #c7d2fe; }
.qyx-pr-check { flex: 0 0 auto; width: 1.05rem; height: 1.05rem; margin-top: 0.1rem; color: #16a34a; }

/* ---------- B1 hero ---------- */
.qyx-pr-hero { text-align: center; padding: clamp(2rem, 5vw, 4rem) 0 clamp(1.5rem, 4vw, 3rem); }
.qyx-pr-hero__title { margin: 1.1rem auto 0; max-width: 18ch; font-family: var(--qyx-font-heading, inherit); font-size: clamp(2.1rem, 1.2rem + 4.4vw, 4rem); font-weight: 800; letter-spacing: -0.025em; line-height: 1.05; color: #0f172a; }
.qyx-pr-hero__sub { margin: 1.1rem auto 0; max-width: 46ch; font-size: clamp(1rem, 0.95rem + 0.4vw, 1.2rem); line-height: 1.55; color: #64748b; }

/* ---------- B2 plans ---------- */
.qyx-pr-plans { padding: clamp(1.5rem, 4vw, 3rem) 0; }
.qyx-pr-plans > .qyx-pr-container { text-align: center; }
.qyx-pr-toggle { display: inline-flex; gap: 0.25rem; margin: 1.5rem auto 2.25rem; padding: 0.3rem; border-radius: 999px; background: #eef1f6; box-shadow: inset 0 0 0 1px rgba(15,23,42,0.06); }
.qyx-pr-toggle__opt { display: inline-flex; align-items: center; gap: 0.5rem; min-height: 44px; padding: 0 1.15rem; border: 0; border-radius: 999px; background: transparent; font: inherit; font-weight: 700; font-size: 0.95rem; color: #475569; cursor: pointer; transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease; }
.qyx-pr-toggle__opt.is-active { background: #fff; color: #0f172a; box-shadow: 0 2px 8px -2px rgba(15,23,42,0.18); }
.qyx-pr-toggle__badge { padding: 0.15rem 0.5rem; border-radius: 999px; background: #dcfce7; color: #15803d; font-size: 0.7rem; font-weight: 800; }

.qyx-pr-plan { position: relative; max-width: 42rem; margin: 0 auto; text-align: left; background: #fff; border: 1.5px solid rgba(15,23,42,0.08); border-radius: clamp(1.25rem, 1rem + 1vw, 1.75rem); box-shadow: 0 24px 60px -28px rgba(15,23,42,0.28); padding: clamp(1.5rem, 1rem + 2.4vw, 2.5rem); transition: border-color 0.3s ease, box-shadow 0.3s ease; }
.qyx-pr-plan.is-yearly { border-color: #34d399; box-shadow: 0 24px 60px -26px rgba(16,185,129,0.4); }
.qyx-pr-plan__flag { display: inline-block; margin-bottom: 1rem; padding: 0.35rem 0.8rem; border-radius: 999px; background: #16a34a; color: #fff; font-size: 0.75rem; font-weight: 800; letter-spacing: 0.01em; }
.qyx-pr-plan__intro { margin-bottom: 1.25rem; padding: 0.95rem 1.1rem; border-radius: 0.9rem; background: #f5f3ff; color: #4c1d95; font-size: 0.95rem; font-weight: 600; line-height: 1.5; box-shadow: inset 0 0 0 1px #ddd6fe; }
.qyx-pr-plan__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.4rem; }
.qyx-pr-plan__ref { font-size: 1.4rem; font-weight: 600; color: #94a3b8; text-decoration: line-through; }
.qyx-pr-plan__amount { font-size: clamp(2.5rem, 2rem + 2.4vw, 3.25rem); font-weight: 850; line-height: 1; letter-spacing: -0.03em; color: #0f172a; }
.qyx-pr-plan__per { font-size: 1rem; font-weight: 600; color: #64748b; }
.qyx-pr-plan__equiv { flex-basis: 100%; margin-top: 0.15rem; font-size: 0.95rem; font-weight: 800; color: #15803d; }
.qyx-pr-plan__capacity { margin-top: 1rem; font-size: 0.9rem; line-height: 1.5; color: #64748b; }
.qyx-pr-plan__capacity--box { padding: 0.85rem 1rem; border-radius: 0.8rem; background: #f4f5f7; color: #475569; }
.qyx-pr-plan__cta { margin-top: 1.5rem; }
.qyx-pr-plan__micro { margin-top: 0.7rem; font-size: 0.82rem; color: #64748b; text-align: center; }
.qyx-pr-plan__features { list-style: none; margin: 1.6rem 0 0; padding: 1.6rem 0 0; border-top: 1px solid rgba(15,23,42,0.08); display: grid; grid-template-columns: 1fr; gap: 0.7rem 1.5rem; }
.qyx-pr-plan__feature { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.92rem; line-height: 1.4; color: #334155; }

/* ---------- B3 packs ---------- */
.qyx-pr-packs { padding: clamp(2rem, 5vw, 4rem) 0; }
.qyx-pr-packs__head { text-align: center; }
.qyx-pr-packs__sub { margin: 0.75rem auto 0; max-width: 42ch; color: #64748b; font-size: 1rem; }
.qyx-pr-packs__list { list-style: none; margin: 2rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 1rem; }
.qyx-pr-pack { display: flex; flex-direction: column; gap: 1.1rem; padding: 1.35rem; background: #fff; border: 1.5px solid rgba(15,23,42,0.08); border-radius: 1.15rem; box-shadow: 0 10px 26px -18px rgba(15,23,42,0.22); }
.qyx-pr-pack--popular { border-color: #34d399; }
.qyx-pr-pack--best { border-color: #a78bfa; }
.qyx-pr-pack__lead { display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; }
.qyx-pr-pack__badge { margin-bottom: 0.4rem; padding: 0.22rem 0.7rem; border-radius: 999px; font-size: 0.7rem; font-weight: 800; }
.qyx-pr-pack--popular .qyx-pr-pack__badge { background: #16a34a; color: #fff; }
.qyx-pr-pack--best .qyx-pr-pack__badge { background: #ede9fe; color: #6d28d9; }
.qyx-pr-pack__credits { font-size: 2rem; font-weight: 850; letter-spacing: -0.02em; color: #0f172a; line-height: 1; }
.qyx-pr-pack__unit { font-size: 0.9rem; color: #94a3b8; }
.qyx-pr-pack__price { margin-top: 0.5rem; font-size: 1.15rem; font-weight: 800; color: #0f172a; }
.qyx-pr-pack__once { font-size: 0.85rem; font-weight: 500; color: #94a3b8; }
.qyx-pr-pack__rate { font-size: 0.8rem; color: #94a3b8; }
.qyx-pr-pack__features { display: grid; grid-template-columns: 1fr; gap: 0.55rem 1.5rem; }
.qyx-pr-pack__col { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.qyx-pr-pack__col li { display: flex; align-items: flex-start; gap: 0.55rem; font-size: 0.88rem; line-height: 1.35; color: #475569; }
.qyx-pr-pack__col strong { color: #0f172a; font-weight: 800; }
.qyx-pr-pack__action { display: flex; }
.qyx-pr-choose { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; width: 100%; padding: 0.7rem 1.6rem; border-radius: 0.8rem; background: #22c55e; color: #052e16; font-weight: 800; font-size: 0.95rem; text-decoration: none; transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease; }
.qyx-pr-choose:hover { background: #16a34a; color: #fff; transform: translateY(-1px); box-shadow: 0 10px 20px -10px rgba(22,163,74,0.6); }
.qyx-pr-choose:focus-visible { outline: 2px solid #15803d; outline-offset: 2px; }
.qyx-pr-packs__foot { margin: 1.75rem auto 0; max-width: 52ch; text-align: center; font-size: 0.9rem; color: #64748b; }

/* ---------- B4 receipts ---------- */
.qyx-pr-receipts { padding: clamp(2rem, 5vw, 4rem) 0; }
.qyx-pr-receipts__head { text-align: center; }
.qyx-pr-receipts__sub { margin: 0.75rem auto 0; max-width: 44ch; color: #64748b; font-size: 1rem; }
.qyx-pr-receipts__grid { margin: 2.5rem 0 0; display: grid; grid-template-columns: 1fr; gap: 2rem; }
.qyx-pr-receipt { position: relative; margin: 0; }
.qyx-pr-receipt__badge { position: absolute; top: -0.75rem; z-index: 2; padding: 0.4rem 0.9rem; border-radius: 999px; color: #fff; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.04em; box-shadow: 0 6px 14px -6px rgba(15,23,42,0.5); }
.qyx-pr-receipt__badge--red { left: 1rem; background: #ef4444; transform: rotate(-3deg); }
.qyx-pr-receipt__badge--green { right: 1rem; background: #16a34a; transform: rotate(3deg); }
.qyx-pr-receipt__paper { background: #fffdf8; border: 1px solid rgba(15,23,42,0.1); border-radius: 0.5rem; box-shadow: 0 20px 44px -22px rgba(15,23,42,0.4); padding: 1.5rem 1.25rem 1.25rem; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.84rem; color: #334155; }
.qyx-pr-receipt__brand { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; text-align: center; padding-bottom: 1rem; }
.qyx-pr-receipt__glyph { width: 1.6rem; height: 1.6rem; color: #0f172a; margin-bottom: 0.25rem; }
.qyx-pr-receipt__store { font-weight: 800; letter-spacing: 0.06em; color: #0f172a; }
.qyx-pr-receipt__brand-sub { font-size: 0.75rem; color: #94a3b8; }
.qyx-pr-receipt__banner { margin: 0 0 0.75rem; padding: 0.6rem; text-align: center; border-radius: 0.5rem; background: #dcfce7; color: #15803d; font-weight: 800; letter-spacing: 0.04em; font-size: 0.78rem; box-shadow: inset 0 0 0 1px #86efac; }
.qyx-pr-receipt__table { width: 100%; border-collapse: collapse; }
.qyx-pr-receipt__label { caption-side: top; padding: 0.5rem 0 0.75rem; text-align: center; font-size: 0.72rem; letter-spacing: 0.12em; color: #94a3b8; border-top: 2px dashed rgba(15,23,42,0.18); }
.qyx-pr-receipt__table th, .qyx-pr-receipt__table td { padding: 0.28rem 0; text-align: left; font-weight: 400; vertical-align: top; }
.qyx-pr-receipt tbody th { font-weight: 400; color: #334155; }
.qyx-pr-receipt__pcol { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.qyx-pr-receipt__tick { color: #16a34a; margin-right: 0.4rem; }
.qyx-pr-receipt__struck th, .qyx-pr-receipt__struck td { color: #cbd5e1; }
.qyx-pr-receipt__struck del { text-decoration-color: #cbd5e1; }
.qyx-pr-receipt__included th { color: #15803d; font-weight: 700; padding-top: 0.5rem; }
.qyx-pr-receipt__included td { color: #15803d; padding-top: 0.5rem; }
.qyx-pr-receipt tfoot th, .qyx-pr-receipt tfoot td { padding-top: 0.4rem; }
.qyx-pr-receipt__sub th, .qyx-pr-receipt__sub td { color: #64748b; }
.qyx-pr-receipt tfoot .qyx-pr-receipt__sub:first-child th, .qyx-pr-receipt tfoot .qyx-pr-receipt__sub:first-child td { border-top: 2px dashed rgba(15,23,42,0.18); padding-top: 0.7rem; }
.qyx-pr-receipt__discount th, .qyx-pr-receipt__discount td { color: #dc2626; }
.qyx-pr-receipt__total th, .qyx-pr-receipt__total td { font-weight: 850; font-size: 1.15rem; border-top: 2px solid rgba(15,23,42,0.3); padding-top: 0.7rem; }
.qyx-pr-receipt__total--due th, .qyx-pr-receipt__total--due td { color: #dc2626; }
.qyx-pr-receipt__total--pay th, .qyx-pr-receipt__total--pay td { color: #16a34a; }
.qyx-pr-receipt__mo { font-size: 0.72rem; font-weight: 600; color: #94a3b8; }
.qyx-pr-receipt__saved { margin: 0.75rem 0 0; padding: 0.6rem; text-align: center; border-radius: 0.5rem; background: #f0fdf4; color: #15803d; font-weight: 850; letter-spacing: 0.02em; }
.qyx-pr-receipt__foot { margin: 0.9rem 0 0; text-align: center; font-size: 0.72rem; color: #94a3b8; }
.qyx-pr-receipt__foot--warn { color: #b45309; }
.qyx-pr-receipt__foot--good { color: #15803d; }
.qyx-pr-receipts__note { margin: 2rem auto 0; max-width: 60ch; text-align: center; font-size: 0.78rem; line-height: 1.5; color: #94a3b8; }

/* ---------- B5 models ---------- */
.qyx-pr-models { padding: clamp(2rem, 5vw, 4rem) 0; }
.qyx-pr-models__cols { margin-top: 2rem; display: grid; grid-template-columns: 1fr; gap: 1.75rem 1.5rem; }
.qyx-pr-models__more-title { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin: 2.75rem 0 0; font-size: 1.1rem; font-weight: 800; color: #0f172a; text-align: center; }
.qyx-pr-mgroup__cat { font-size: 0.75rem; font-weight: 800; letter-spacing: 0.08em; color: #94a3b8; margin: 0 0 0.75rem; }
.qyx-pr-mgroup__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.qyx-pr-mgroup__item { display: flex; align-items: flex-start; gap: 0.55rem; font-size: 0.9rem; color: #334155; line-height: 1.35; }
.qyx-pr-micon { flex: 0 0 auto; width: 1.05rem; height: 1.05rem; margin-top: 0.1rem; }
.qyx-pr-micon--check { color: #16a34a; }
.qyx-pr-micon--plus { color: #7c3aed; }
.qyx-pr-models__more-title .qyx-pr-micon { width: 1.25rem; height: 1.25rem; }

/* ---------- B6 faq ---------- */
.qyx-pr-faq { padding: clamp(2.5rem, 5vw, 4.5rem) 0 clamp(3rem, 7vw, 6rem); }
.qyx-pr-faq__head { text-align: center; }
.qyx-pr-faq__head .qyx-pr-h2 { margin-top: 0.75rem; }
.qyx-pr-faq__sub { margin: 0.75rem auto 0; color: #64748b; }
.qyx-pr-faq__list { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.75rem; }
.qyx-pr-faq__item { background: #fff; border: 1px solid rgba(15,23,42,0.08); border-radius: 0.9rem; overflow: hidden; }
.qyx-pr-faq__q { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 44px; padding: 1rem 1.25rem; cursor: pointer; list-style: none; font-weight: 700; font-size: 1rem; color: #0f172a; }
.qyx-pr-faq__q::-webkit-details-marker { display: none; }
.qyx-pr-faq__q:focus-visible { outline: 2px solid #7c3aed; outline-offset: -2px; border-radius: 0.9rem; }
.qyx-pr-faq__chev { flex: 0 0 auto; width: 1.25rem; height: 1.25rem; color: #94a3b8; transition: transform 0.25s ease; }
.qyx-pr-faq__item[open] .qyx-pr-faq__chev { transform: rotate(180deg); }
.qyx-pr-faq__a { padding: 0 1.25rem 1.15rem; }
.qyx-pr-faq__a p { margin: 0; color: #475569; line-height: 1.6; font-size: 0.95rem; }

/* ---------- responsive enhancements ---------- */
@media (min-width: 768px) {
	.qyx-pr-plan__features { grid-template-columns: 1fr 1fr; }
	.qyx-pr-pack { display: grid; grid-template-columns: minmax(9rem, 12rem) 1fr minmax(9rem, 11rem); align-items: center; gap: 1.75rem; padding: 1.5rem 1.75rem; }
	.qyx-pr-pack__features { grid-template-columns: 1fr 1fr; }
	.qyx-pr-receipts__grid { grid-template-columns: 1fr 1fr; align-items: start; gap: 1.5rem; }
	.qyx-pr-receipt--without .qyx-pr-receipt__paper { transform: rotate(-1.1deg); }
	.qyx-pr-receipt--with .qyx-pr-receipt__paper { transform: rotate(1.1deg); }
	.qyx-pr-models__cols { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
	.qyx-pr-models__cols { grid-template-columns: repeat(4, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-pr-faq__chev, .qyx-pr-toggle__opt, .qyx-pr-plan, .qyx-pr-choose { transition: none; }
	.qyx-pr-receipt__paper, .qyx-pr-receipt__badge { transform: none; }
}
/* Guarantee 44px tap targets for every CTA on the pricing page. */
.qyx-pricing-page .qyx-cta { min-height: 44px; }

/* ============================================================
   /contact and /about pages (page-contact.php, page-about.php).
   Mobile-first; reuses theme tokens.
   ============================================================ */

/* ---------- /contact ---------- */
.qyx-contact-page { background: var(--qyx-bg-light); color: #1e293b; padding-top: calc(var(--qyx-header-h, 72px) + 1rem); }
.qyx-ct { padding: clamp(2.5rem, 6vw, 5rem) 0 clamp(3rem, 8vw, 6rem); }
.qyx-ct__container { width: 100%; max-width: 40rem; margin-inline: auto; padding-inline: clamp(1rem, 5vw, 2rem); }
.qyx-ct__head { text-align: center; }
.qyx-ct__title { font-family: var(--qyx-font-heading, inherit); font-size: clamp(2rem, 1.3rem + 3vw, 3rem); font-weight: 800; letter-spacing: -0.025em; line-height: 1.1; color: #0f172a; }
.qyx-ct__sub { margin: 1rem auto 0; max-width: 40ch; font-size: clamp(1rem, 0.95rem + 0.3vw, 1.15rem); line-height: 1.55; color: #64748b; }
.qyx-ct__email { margin-top: 0.75rem; font-size: 0.95rem; color: #64748b; }
.qyx-ct__email a { color: #4338ca; font-weight: 700; text-decoration: none; }
.qyx-ct__email a:hover { text-decoration: underline; }
.qyx-ct__note { margin: 1.75rem 0 0; padding: 0.9rem 1.1rem; border-radius: 0.75rem; font-weight: 600; font-size: 0.95rem; }
.qyx-ct__note--ok { background: #f0fdf4; color: #15803d; box-shadow: inset 0 0 0 1px #86efac; }
.qyx-ct__note--err { background: #fef2f2; color: #b91c1c; box-shadow: inset 0 0 0 1px #fecaca; }
.qyx-ct__form { margin-top: 2rem; display: flex; flex-direction: column; gap: 1.1rem; }
.qyx-ct__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.qyx-ct__field { display: flex; flex-direction: column; gap: 0.4rem; }
.qyx-ct__field label { font-size: 0.88rem; font-weight: 700; color: #334155; }
.qyx-ct__field input, .qyx-ct__field textarea {
	width: 100%; padding: 0.8rem 1rem; border: 1.5px solid rgba(15, 23, 42, 0.12); border-radius: 0.75rem;
	background: #fff; color: #0f172a; font: inherit; font-size: 1rem; line-height: 1.5;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.qyx-ct__field textarea { resize: vertical; min-height: 8rem; }
.qyx-ct__field input::placeholder, .qyx-ct__field textarea::placeholder { color: #94a3b8; }
.qyx-ct__field input:focus, .qyx-ct__field textarea:focus { outline: none; border-color: var(--gradient-2, #7c3aed); box-shadow: 0 0 0 3px color-mix(in srgb, var(--gradient-2, #7c3aed) 18%, transparent); }
.qyx-ct__submit {
	align-self: flex-start; min-height: 48px; padding: 0.8rem 2rem; border: 0; border-radius: 999px;
	background: #16161a; color: #fff; font: inherit; font-weight: 700; font-size: 1rem; cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.qyx-ct__submit:hover { transform: translateY(-1px); box-shadow: 0 12px 24px -12px rgba(15, 23, 42, 0.5); }
.qyx-ct__submit:focus-visible { outline: 2px solid var(--gradient-2, #7c3aed); outline-offset: 2px; }
@media (max-width: 480px) { .qyx-ct__submit { align-self: stretch; text-align: center; } }

/* ---------- /about ---------- */
.qyx-about-page { background: var(--qyx-bg-light); color: #1e293b; padding-top: calc(var(--qyx-header-h, 72px) + 1rem); }
.qyx-ab-container { width: 100%; max-width: 70rem; margin-inline: auto; padding-inline: clamp(1rem, 5vw, 2rem); }
.qyx-ab-container--narrow { max-width: 46rem; }
.qyx-ab-h2 { font-family: var(--qyx-font-heading, inherit); font-size: clamp(1.6rem, 1.2rem + 1.8vw, 2.25rem); font-weight: 800; letter-spacing: -0.02em; color: #0f172a; text-align: center; }
.qyx-ab-hero { text-align: center; padding: clamp(2rem, 5vw, 4rem) 0 clamp(1.5rem, 4vw, 3rem); }
.qyx-ab-hero__title { margin: 1.1rem auto 0; max-width: 20ch; font-family: var(--qyx-font-heading, inherit); font-size: clamp(2.1rem, 1.2rem + 4vw, 3.75rem); font-weight: 800; letter-spacing: -0.025em; line-height: 1.06; color: #0f172a; }
.qyx-ab-hero__sub { margin: 1.25rem auto 0; max-width: 56ch; font-size: clamp(1rem, 0.95rem + 0.4vw, 1.2rem); line-height: 1.6; color: #475569; }
.qyx-ab-why { padding: clamp(1.5rem, 4vw, 3rem) 0; }
.qyx-ab-why .qyx-ab-h2 { text-align: left; }
.qyx-ab-prose { margin-top: 1.25rem; }
.qyx-ab-prose p { margin: 0 0 1rem; font-size: 1.05rem; line-height: 1.7; color: #334155; }
.qyx-ab-prose p:last-child { margin-bottom: 0; }
.qyx-ab-values { padding: clamp(2rem, 5vw, 4rem) 0; }
.qyx-ab-grid { margin-top: 2rem; display: grid; grid-template-columns: 1fr; gap: 1rem; }
.qyx-ab-card { padding: 1.5rem; background: #fff; border: 1px solid rgba(15, 23, 42, 0.08); border-radius: 1.1rem; box-shadow: 0 10px 26px -18px rgba(15, 23, 42, 0.2); }
.qyx-ab-card__icon { display: inline-grid; place-items: center; width: 3rem; height: 3rem; border-radius: 0.9rem; background: #eef2ff; color: #4338ca; }
.qyx-ab-card__title { margin: 1rem 0 0; font-size: 1.15rem; font-weight: 800; color: #0f172a; }
.qyx-ab-card__body { margin: 0.5rem 0 0; font-size: 0.95rem; line-height: 1.55; color: #64748b; }
.qyx-ab-cta { padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(3rem, 7vw, 6rem); }
.qyx-ab-cta__box { text-align: center; padding: clamp(2rem, 4vw, 3.25rem) clamp(1.25rem, 4vw, 2.5rem); border-radius: clamp(1.25rem, 1rem + 1vw, 1.75rem); background: var(--qyx-bg-dark, #080507); color: #fff; }
.qyx-ab-cta__title { font-family: var(--qyx-font-heading, inherit); font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2.1rem); font-weight: 800; letter-spacing: -0.02em; color: #fff; }
.qyx-ab-cta__sub { margin: 0.75rem auto 0; color: rgba(255, 255, 255, 0.6); font-size: 1.05rem; }
.qyx-ab-cta__btn { margin-top: 1.5rem; display: flex; justify-content: center; }

@media (min-width: 768px) {
	.qyx-ab-grid { grid-template-columns: 1fr 1fr; gap: 1.25rem; }
}

/* ============================================================
   /legal/* pages (page-legal.php + template-parts/legal/*).
   Readable long-form legal prose + a sticky doc-nav sidebar.
   ============================================================ */
.qyx-legal-page { background: var(--qyx-bg-light); color: #1e293b; padding-top: calc(var(--qyx-header-h, 72px) + 1rem); }
.qyx-legal { width: 100%; max-width: 72rem; margin-inline: auto; padding: clamp(1.5rem, 4vw, 3rem) clamp(1rem, 5vw, 2rem) clamp(3rem, 7vw, 6rem); display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
.qyx-legal__doc { min-width: 0; max-width: 46rem; }
.qyx-legal__title { font-family: var(--qyx-font-heading, inherit); font-size: clamp(1.9rem, 1.3rem + 2.6vw, 2.75rem); font-weight: 800; letter-spacing: -0.02em; line-height: 1.12; color: #0f172a; }
.qyx-legal__updated { margin: 0.75rem 0 0; font-size: 0.85rem; font-weight: 600; color: #94a3b8; }
.qyx-legal__doc h2 { margin: 2.25rem 0 0.75rem; font-size: clamp(1.25rem, 1.1rem + 0.8vw, 1.5rem); font-weight: 800; letter-spacing: -0.01em; color: #0f172a; }
.qyx-legal__doc h3 { margin: 1.5rem 0 0.5rem; font-size: 1.05rem; font-weight: 700; color: #1e293b; }
.qyx-legal__doc p { margin: 0.85rem 0 0; font-size: 1rem; line-height: 1.7; color: #334155; }
.qyx-legal__doc ul, .qyx-legal__doc ol { margin: 0.85rem 0 0; padding-left: 1.4rem; display: flex; flex-direction: column; gap: 0.45rem; }
.qyx-legal__doc li { font-size: 1rem; line-height: 1.65; color: #334155; }
.qyx-legal__doc a { color: #4338ca; text-decoration: underline; text-underline-offset: 2px; }
.qyx-legal__doc a:hover { color: #3730a3; }
.qyx-legal__doc strong { color: #0f172a; font-weight: 700; }
.qyx-legal__lead { margin-top: 1.25rem; font-size: 1.1rem; line-height: 1.65; color: #475569; }
.qyx-legal__doc address { margin-top: 0.85rem; font-style: normal; line-height: 1.7; color: #334155; }
.qyx-legal__sig { margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid rgba(15, 23, 42, 0.1); font-size: 0.85rem; color: #64748b; }
/* tables (privacy legal-basis, sub-processors) */
.qyx-legal__table-wrap { margin-top: 1.25rem; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.qyx-legal__doc table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: 0.92rem; }
.qyx-legal__doc caption { text-align: left; font-weight: 700; color: #0f172a; padding-bottom: 0.5rem; }
.qyx-legal__doc th, .qyx-legal__doc td { padding: 0.6rem 0.8rem; text-align: left; vertical-align: top; border-bottom: 1px solid rgba(15, 23, 42, 0.08); line-height: 1.5; }
.qyx-legal__doc thead th { font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; color: #64748b; background: #f4f5f7; }
.qyx-legal__doc tbody th { font-weight: 700; color: #1e293b; }
/* doc nav */
.qyx-legal__nav { font-size: 0.92rem; }
.qyx-legal__nav-title { display: block; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #94a3b8; margin-bottom: 0.75rem; }
.qyx-legal__nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.qyx-legal__nav a { display: block; padding: 0.5rem 0.75rem; border-radius: 0.6rem; color: #475569; text-decoration: none; font-weight: 600; }
.qyx-legal__nav a:hover { background: #eef1f6; color: #0f172a; }
.qyx-legal__nav a[aria-current="page"] { background: #eef2ff; color: #4338ca; }

@media (min-width: 1024px) {
	.qyx-legal { grid-template-columns: 1fr 16rem; gap: 3.5rem; align-items: start; }
	.qyx-legal__nav { position: sticky; top: calc(var(--qyx-header-h, 72px) + 1.5rem); order: 2; }
	.qyx-legal__doc { order: 1; }
}
/* legal index / hub */
.qyx-legal__index { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
.qyx-legal__index a { display: block; padding: 1.1rem 1.25rem; border: 1px solid rgba(15, 23, 42, 0.08); border-radius: 0.9rem; background: #fff; text-decoration: none; transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.qyx-legal__index a:hover { border-color: rgba(15, 23, 42, 0.18); box-shadow: 0 10px 24px -16px rgba(15, 23, 42, 0.25); }
.qyx-legal__index-title { display: block; font-weight: 800; color: #0f172a; }
.qyx-legal__index-desc { display: block; margin-top: 0.2rem; font-size: 0.9rem; color: #64748b; }
@media (min-width: 640px) { .qyx-legal__index { grid-template-columns: 1fr 1fr; } }

/* ============================================================
   Header mega-menu dropdowns (AI Tools, Use-cases submenus).
   ============================================================ */
.qyx-submenu { list-style: none; margin: 0; padding: 0; }
.qyx-submenu__link {
	display: flex; align-items: center; gap: 0.6rem;
	padding: 0.6rem 0.85rem; border-radius: 0.55rem;
	color: #334155; font-size: 0.92rem; font-weight: 600; text-decoration: none; white-space: nowrap;
	transition: background 0.15s ease, color 0.15s ease;
}
.qyx-submenu__link:hover, .qyx-submenu__link:focus-visible { background: #eef1f6; color: #0f172a; outline: none; }
.qyx-submenu__icon { width: 1.05rem; height: 1.05rem; flex-shrink: 0; color: #94a3b8; }
.qyx-submenu__link:hover .qyx-submenu__icon { color: #0f172a; }
/* A tool whose landing page is not built yet: same row, but nothing to click. It
   still highlights on hover so the menu does not feel dead. */
.qyx-submenu__link--soon { cursor: default; }
.qyx-nav-toggle:focus-visible { outline: 2px solid var(--gradient-2, #7c3aed); outline-offset: 3px; border-radius: 0.5rem; }
/* desktop: floating dropdown card under the toggle */
@media (min-width: 992px) {
	.qyx-nav-has-sub { position: relative; }
	.qyx-submenu {
		position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
		/* 1.5rem, not 0.75rem: the nav <li> sits inside the nav card's own padding,
		   so top:100% is ~16px ABOVE the card's bottom edge - at 0.75rem the panel
		   started 4px INSIDE the card and, being white on white, read as one merged
		   blob with the header. Keep .qyx-submenu::before (the hover bridge) at the
		   same size or the mouse falls out of the item on its way down. */
		margin-top: 1.5rem; min-width: 15rem; padding: 0.5rem;
		background: #fff; border: 1px solid rgba(15, 23, 42, 0.08); border-radius: 0.9rem;
		box-shadow: 0 22px 44px -18px rgba(15, 23, 42, 0.28); display: flex; flex-direction: column; gap: 0.1rem; z-index: 60;
	}
	/* Invisible hover bridge that fills the gap between the toggle and the card, so
	   the mouse never leaves the item on its way down (otherwise mouseleave closes
	   the dropdown before you reach an item). It is part of the submenu (a child of
	   the <li>), so hovering it keeps the item "hovered". */
	.qyx-submenu::before {
		content: ""; position: absolute; left: 0; right: 0; top: -1.6rem; height: 1.6rem;
	}
	/* Mega variant - the AI Tools panel carries 24 tools, which as one column
	   would run far past the bottom of the viewport. Three columns keep it to
	   8 rows. */
	.qyx-submenu--mega {
		/* Anchored to the LEFT EDGE of its trigger, not centred on it. The panel is
		   ~630px wide against a 76px "AI Tools" button, so the inherited
		   left:50%/translateX(-50%) threw it 278px out past the trigger - it ran
		   back under the logo, sat hard against the nav card's left edge and left a
		   ~580px void on the right. DO-NOT: restore the centring here, it only
		   works for the narrow single-column submenus. */
		left: 0;
		transform: none;
		/* Column-first, and each column only as wide as its own longest label
		   (max-content). Fixed equal columns (1fr) padded every short label out to
		   the widest one, which read as ragged gutters. */
		display: grid;
		grid-auto-flow: column;
		grid-template-rows: repeat(8, auto);
		grid-auto-columns: max-content;
		column-gap: 1.5rem;
		row-gap: 0.1rem;
		width: max-content;
		max-width: min(56rem, calc(100vw - 3rem));
	}
}
@media (min-width: 992px) and (max-width: 1199px) {
	/* narrow laptops: two columns of 12 rather than letting the panel span the nav */
	.qyx-submenu--mega { grid-template-rows: repeat(12, auto); }
}
/* mobile: inline indented list inside the drawer */
@media (max-width: 991px) {
	.qyx-submenu { width: 100%; margin-top: 0.25rem; padding-left: 1rem; display: flex; flex-direction: column; }
	.qyx-submenu__link { padding: 0.55rem 0.75rem; }
}
@media (prefers-reduced-motion: reduce) { .qyx-nav-toggle svg { transition: none; } }

/* ============================================================
   Shared hero + trust strip (.qyx-svc-*) - used by the landing-page builder
   (template-parts/landing-cpt/hero.php, trust.php). /services has its own
   copy in services.css, loaded after this file.
   ============================================================ */
/* eyebrow */
.qyx-svc-eyebrow {
	display: inline-flex; align-items: center; gap: 0.5rem;
	font-size: 0.72rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--qyx-text-muted, #6b7080);
}
.qyx-svc-eyebrow__dot {
	width: 7px; height: 7px; border-radius: 999px;
	background: var(--qyx-grad-2, #7c3aed); box-shadow: 0 0 0 4px color-mix(in srgb, var(--qyx-grad-2, #7c3aed) 18%, transparent);
}

/* ---------- hero ---------- */
/* Top padding mirrors the HP landing hero exactly (pt-24 mobile / pt-44 desktop),
   so the gap under the overlapping header matches across pages. */
.qyx-svc-hero { padding-top: 6rem !important; }
@media (min-width: 1024px) { .qyx-svc-hero { padding-top: 11rem !important; } }
.qyx-svc-hero__title {
	margin-top: 1.1rem; font-size: clamp(2.2rem, 1rem + 4.4vw, 3.6rem); line-height: 1.05;
	font-weight: 700; letter-spacing: -0.025em; color: var(--qyx-heading, #111);
}
.qyx-svc-hero__sub { margin-top: 1.25rem; font-size: clamp(1.02rem, 0.95rem + 0.5vw, 1.2rem); line-height: 1.55; color: var(--qyx-text-muted, #6b7080); }
/* Mirror the HP hero CTAs: stacked + left-aligned on mobile, row on sm+. */
.qyx-svc-hero__ctas { margin-top: 1.9rem; display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; }
@media (min-width: 640px) { .qyx-svc-hero__ctas { flex-direction: row; align-items: center; gap: 1rem; } }
/* Phones: same treatment as the HP hero - primary fills the column, the quiet
   link centres beneath it (mirrors the .qyx-hero-ctas rule at <=639px). */
@media (max-width: 639px) {
	.qyx-svc-hero__ctas { align-items: stretch; }
	.qyx-svc-hero__ctas > .qyx-cta { width: 100%; }
	.qyx-svc-hero__ctas > .qyx-cta .qyx-cta__body { width: 100%; justify-content: center; }
	.qyx-svc-hero__ctas > .qyx-cta-quiet { width: 100%; text-align: center; padding: 0.25rem 0; }
}
.qyx-svc-hero__microcopy {
	margin-top: 1.1rem; display: inline-flex; align-items: center; gap: 0.45rem;
	font-size: 0.85rem; color: var(--qyx-text-muted, #6b7080);
}
.qyx-svc-hero__microcopy i { color: var(--qyx-grad-5, #22c55e); }

/* before/after proof */
.qyx-svc-hero__proof { display: flex; align-items: center; justify-content: center; gap: 0.5rem; }
.qyx-svc-proof { position: relative; flex: 1 1 0; margin: 0; max-width: 15rem; }
.qyx-svc-proof__media {
	position: relative; aspect-ratio: 4 / 5; border-radius: var(--qyx-card-radius, 24px);
	border: 1px solid var(--qyx-border, #e5e7eb); overflow: hidden;
}
.qyx-svc-proof--before .qyx-svc-proof__media { background: linear-gradient(150deg, #eef1f6, #dfe4ec); }
.qyx-svc-proof--after .qyx-svc-proof__media {
	background: linear-gradient(150deg, color-mix(in srgb, var(--qyx-grad-1,#3b82f6) 16%, #fff), color-mix(in srgb, var(--qyx-grad-3,#ec4899) 16%, #fff));
	box-shadow: 0 30px 60px -30px rgba(15, 23, 42, 0.35);
}
.qyx-svc-proof--after { transform: translateY(-0.75rem) rotate(1.5deg); }
.qyx-svc-proof--before { transform: rotate(-1.5deg); }
.qyx-svc-proof__media[data-placeholder]::after {
	content: attr(data-placeholder); position: absolute; inset: 0; display: grid; place-items: center;
	font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(15,23,42,0.35);
}
.qyx-svc-proof__tag {
	margin-top: 0.6rem; text-align: center; font-size: 0.78rem; font-weight: 600; color: var(--qyx-text-muted,#6b7080);
}
.qyx-svc-proof__tag--accent { color: var(--qyx-heading,#111); }
.qyx-svc-proof__arrow { flex: 0 0 auto; display: grid; place-items: center; width: 2rem; height: 2rem; color: var(--qyx-text-muted,#6b7080); }

/* ---------- trust strip ---------- */
.qyx-svc-trust { padding-block: 1.75rem !important; border-block: 1px solid var(--qyx-border, #e5e7eb); background: color-mix(in srgb, var(--qyx-bg-light,#fafafa) 60%, #fff); }
.qyx-svc-trust__list { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.9rem 2.25rem; list-style: none; margin: 0; padding: 0; }
.qyx-svc-trust__item { display: inline-flex; align-items: center; gap: 0.55rem; font-size: 0.9rem; font-weight: 600; color: var(--qyx-text, #2b2b2b); }
.qyx-svc-trust__icon { display: grid; place-items: center; color: var(--qyx-grad-2, #7c3aed); }
@media (max-width: 640px) {
	.qyx-svc-hero__proof { max-width: 22rem; margin-inline: auto; }
}
@media (prefers-reduced-motion: reduce) {
	.qyx-svc-proof--after, .qyx-svc-proof--before { transform: none; }
}

/* ==========================================================================
   Smart Templates - rolling carousel below pricing.
   Light section sitting between the dark pricing block and the light FAQ.
   All custom classes on purpose: the Tailwind build is purged, so new utility
   classes in markup are dead until `npm run build:css` runs.
   ========================================================================== */

.qyx-templates {
	position: relative;
	background: #fff;
	padding-block: clamp(3.5rem, 7vw, 6rem);
	overflow: hidden;
}

/* "See all N templates" link under the Smart Templates lead (homepage). */
.qyx-templates__all { margin-top: 0.85rem; font-size: 0.95rem; font-weight: 600; }
.qyx-templates__all a { color: var(--qyx-heading, #111); text-decoration: underline; text-underline-offset: 3px; }
.qyx-templates__all a:hover { text-decoration-thickness: 2px; }

.qyx-templates__header {
	max-width: 42rem;
	margin-inline: auto;
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
	text-align: center;
}

.qyx-templates__heading {
	font-family: var(--qyx-font-heading, inherit);
	font-weight: 700;
	letter-spacing: -0.02em;
	font-size: clamp(1.875rem, 1.2rem + 2.4vw, 3rem);
	line-height: 1.1;
	color: #0f172a;
}

.qyx-templates__lead {
	margin-top: 1rem;
	font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
	color: #64748b;
}

/* Flickity needs a plain flex row here; it takes over layout on init. */
.qyx-templates__carousel {
	--cols: 1;
	--gap: 30px;
	position: relative;
}

.qyx-templates__track {
	display: flex;
	margin-inline: calc(var(--gap) / -2);
}

/* No bottom margin: the dots row now sits in normal flow after the carousel and
   brings its own spacing. A cell margin would be counted into Flickity's
   adaptiveHeight measurement and stack on top of it. */
.qyx-templates__cell {
	flex: 0 0 auto;
	width: calc(100% / var(--cols));
	padding-inline: calc(var(--gap) / 2);
}

@media (min-width: 768px) {
	.qyx-templates__carousel { --cols: 2; }
}

@media (min-width: 1024px) {
	.qyx-templates__carousel { --cols: 4; }
}

.qyx-templates__tile {
	display: grid;
	place-items: center;
	aspect-ratio: 1 / 0.77;
	margin-bottom: 1.5rem;
	padding: 1rem;
	border-radius: 18px;
	background: rgb(0 0 0 / 3%);
}

.qyx-templates__icon {
	width: 60px;
	height: auto;
	max-width: 100%;
}

/* Titles and descriptions are clamped to a fixed number of lines and reserve
   that height even when shorter, so every card is exactly the same height.
   Without this the carousel's height changes as you page through it and the
   whole page below shifts. 11 of the 154 descriptions are longer than three
   lines and end in an ellipsis here; their full text stays in the database. */
.qyx-templates__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
	min-height: 2.6em;   /* 2 lines x 1.3 line-height */
	margin-bottom: 0.875rem;
	font-family: var(--qyx-font-heading, inherit);
	font-size: 1.125rem;
	font-weight: 700;
	line-height: 1.3;
	color: #0f172a;
}

.qyx-templates__desc {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
	min-height: 4.8em;   /* 3 lines x 1.6 line-height */
	margin: 0;
	font-size: 1rem;
	line-height: 1.6;
	color: #475569;
}

/* Prev / next. Flickity injects these into its page-dots container, which is
   why they are absolutely positioned relative to that row rather than here. */
.qyx-templates__nav {
	display: inline-grid;
	place-items: center;
	flex-shrink: 0;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 9999px;
	background: rgb(0 0 0 / 5%);
	color: #0f172a;
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}

.qyx-templates__nav svg { width: 1rem; height: 1rem; }

.qyx-templates__nav:hover,
.qyx-templates__nav:focus-visible {
	background: #0f172a;
	color: #fff;
}

/* The dots row doubles as the arrows' container - Flickity injects prev/next
   into it - so it is what spaces them out to the outer edges. The init script
   moves this holder out of the carousel element and into the section wrapper,
   so it can sit in normal flow here instead of being absolutely positioned.
   wrap is a departure from the reference: it shows a handful of dots, this
   shows ~39, and without wrapping they overflow the viewport below 1024px. */
.qyx-templates .flickity-page-dots {
	position: static;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
	width: 100%;
	margin: 2.5rem 0 0;
	padding: 0;
	line-height: 1;
}

/* Dots as the reference styles them: 10px circles at 25% opacity, the active
   one widening into a pill. Hidden below 640px, also as the reference does,
   where the arrows alone are the control. */
.qyx-templates .flickity-page-dots .dot {
	display: block;
	flex-shrink: 0;
	width: 0.625rem;
	height: 0.625rem;
	margin: 0;
	border-radius: 9999px;
	background: currentColor;
	opacity: 0.25;
	transition: width 200ms ease, opacity 200ms ease;
}

.qyx-templates .flickity-page-dots .dot.is-selected {
	width: 1.125rem;
	opacity: 1;
}

/* Below 1024px the ~39 dots no longer fit on one line and wrap into a three-row
   blob that reads worse than no dots at all. The reference hides them only under
   640px, but it shows a handful of dots where this shows 39. Arrows remain the
   control at every width. */
@media (max-width: 1023px) {
	.qyx-templates .flickity-page-dots .dot { display: none; }
}

.qyx-templates .flickity-viewport,
.qyx-templates .flickity-slider { width: 100%; }

@media (prefers-reduced-motion: reduce) {
	.qyx-templates__nav,
	.qyx-templates .flickity-page-dots .dot { transition: none; }
}

/* [QYX-PERF] Scroll performance - 2026-10-24.
   1. Sections far off screen pause their CSS animations (qyx-reveal.js toggles .is-offscreen).
   2. bizloop background: the colour now cross-fades between two solid tint layers by
      opacity (compositor only). Animating background-color on the 4000px-tall layer
      re-rasterised it every frame and the page flashed on a fast scroll. */
.is-offscreen,
.is-offscreen *,
.is-offscreen *::before,
.is-offscreen *::after {
	animation-play-state: paused !important;
}

.qyx-bizloop__bg {
	transition: none;
}

.qyx-bizloop__bg::before,
.qyx-bizloop__bg::after {
	z-index: 2;
}

.qyx-bizloop__tint {
	position: absolute;
	inset: 0;
	z-index: 0;
	opacity: 0;
	transition: opacity 0.6s;
	pointer-events: none;
}

.qyx-bizloop__tint.is-front {
	z-index: 1;
}

.qyx-bizloop__tint.is-on {
	opacity: 1;
}

.qyx-bizloop__tint.is-instant {
	transition: none;
}

@media (prefers-reduced-motion: reduce) {
	.qyx-bizloop__tint {
		transition: none;
	}
}

/* Footer "Product": 26 AI Tools links - two columns on desktop instead of one tall list. */
@media (min-width: 1024px) {
	.qyx-footer__grid:has(.qyx-footer__list--split) {
		grid-template-columns: 1.35fr 2fr 1fr 1fr;
	}

	.qyx-footer__list--split {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 1.5rem;
	}
}

/* Homepage Smart Templates carousel: once a template page is live its title
   becomes a link that covers the whole card, so the tile and the text are
   one tap target (Flickity still swallows the click after a drag). */
.qyx-templates__cell {
	position: relative;
}

.qyx-templates__link {
	color: inherit;
	text-decoration: none;
}

.qyx-templates__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.qyx-templates__link:focus-visible {
	outline: none;
}

.qyx-templates__cell:has(.qyx-templates__link:focus-visible) {
	outline: 2px solid #7c3aed;
	outline-offset: 4px;
	border-radius: 1rem;
}

.qyx-templates__cell:has(.qyx-templates__link) .qyx-templates__tile {
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.qyx-templates__cell:has(.qyx-templates__link):hover .qyx-templates__tile {
	transform: translateY(-2px);
	box-shadow: 0 10px 24px -12px rgba(15, 23, 42, 0.25);
}