/* ==========================================================================
   Quality Immigration — design system
   Premium editorial 2026. Peacock-teal jewel palette, Montserrat + Inter.
   Frosted glass is used ONLY over photography (hero trust strip, stats cards,
   CTA panel, image-break panel, photo-tile captions, scrolled header). Never
   on a plain ivory band — a blurred panel over flat colour reads as a grey box.

   Naming: every custom class is prefixed .qi-
   Sections:  0 tokens · 1 base · 2 typography · 3 layout & sections
              4 buttons · 5 eyebrow & rules · 6 cards · 7 components
              8 header / footer · 9 motion

   Caveats that must not be re-broken
   ----------------------------------
   1. Chromium raster bug — a view()-timeline animation that uses scale() or the
      `translate` property on an element containing a large raster stops the
      image rasterising, page-wide. All scroll-driven motion here is limited to
      opacity + transform:translateY(), and never runs on an <img> itself; the
      parallax rides on the .qi-parallax wrapper.
   2. Because the reveal animation owns `transform` with fill-mode both, hover
      lifts must use the separate `translate` property or they are overridden.
   3. Cover blocks use dimRatio:0 with the teal wash painted by ::after at
      z-index 0. Do not raise the inner container's z-index above 1.
   4. Blocksy heading overrides need the `body.qi` selector prefix.
   5. Header/footer are CSS-driven, not Blocksy header-builder configuration.
   6. Cover blocks are saved with layout "default". With "constrained",
      WordPress injects `is-layout-constrained` onto the inner container and
      global styles apply `margin-left/right:auto !important` to every child —
      which centres any child with a max-width (hero h1, hero lead) while
      full-width children stay on the rail. That was the two-rail hero bug; the
      guard in §7a keeps it fixed even if the block attribute regresses.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Tokens
   -------------------------------------------------------------------------- */

:root {
	/* Palette */
	--qi-teal-900: #062F30;   /* deepest section background */
	--qi-teal-800: #0B4444;   /* primary deep teal — headings, dark sections */
	--qi-teal-700: #0D5254;   /* CTA hover */
	--qi-teal-600: #116466;   /* rich peacock — interactive / CTA */
	--qi-turquoise: #2E9E8F;  /* sparing highlight only */
	--qi-gold: #C6A15B;       /* thin rules, numerals, gold ON DARK */
	/* The peacock gold is 2.3:1 on ivory — fine for a hairline, a contrast
	   failure for any text. Gold TEXT on a light band uses this deepened tone
	   instead (4.98:1 on the tint, the worst light background). Decorative
	   rules and borders keep --qi-gold. */
	--qi-gold-ink: #7E6023;
	--qi-gold-soft: rgba(198, 161, 91, .38);
	--qi-ivory: #FAF7F2;      /* page background */
	--qi-ivory-deep: #F3EEE6; /* alternate warm band */
	--qi-tint: #E4EFEC;       /* soft teal tint — cards, alt sections */
	--qi-ink: #14181A;        /* near-black text */
	--qi-ink-muted: #4A5456;
	--qi-ink-soft: #5C6567;  /* was #6B7476 — 4.48:1 on ivory, under AA */
	--qi-white: #FFFFFF;

	/* Lines */
	--qi-hairline: rgba(11, 68, 68, .14);
	--qi-hairline-strong: rgba(11, 68, 68, .24);
	--qi-hairline-light: rgba(250, 247, 242, .22);

	/* Type */
	--qi-font-head: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
	--qi-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

	/* Montserrat sets appreciably wider than the Fraunces these were tuned for,
	   so both display steps come down: at 375px the home H1 was running to four
	   ragged lines. */
	--qi-h1: clamp(2.0625rem, 1.15rem + 3.7vw, 3.875rem);  /* 33 → 62 */
	--qi-h2: clamp(1.75rem, 1.2rem + 2.2vw, 2.75rem);      /* 28 → 44 */
	--qi-h3: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);   /* 22 → 28 */
	--qi-h4: clamp(1.125rem, 1rem + .5vw, 1.3125rem);  /* 18 → 21 */
	--qi-lead: clamp(1.0625rem, 1rem + .45vw, 1.3125rem);
	--qi-body: 1.0625rem;
	--qi-small: .9375rem;
	--qi-eyebrow-size: .8125rem;
	--qi-stat: clamp(3rem, 2rem + 5vw, 5.5rem);

	/* Space */
	--qi-space-section: clamp(4.5rem, 3rem + 6vw, 8.5rem);
	--qi-space-section-sm: clamp(3rem, 2rem + 4vw, 5.5rem);
	--qi-gutter: clamp(1.25rem, .6rem + 2vw, 2.5rem);
	--qi-max: 1200px;
	--qi-max-wide: 1400px;
	--qi-max-prose: 62ch;

	--qi-radius: 12px;
	--qi-radius-lg: 16px;
	--qi-radius-btn: 10px;

	--qi-ease: cubic-bezier(.22, .61, .36, 1);

	/* Sticky rail — the header height plus breathing room. The header shrinks
	   from --qi-header-h to --qi-header-h-scrolled once the page moves, so the
	   rail is measured against the *scrolled* height: that is the height any
	   sticky element actually has to clear. */
	/* min-height values; the 1px bottom rule sits outside the box, so the
	   rendered bar is 72px at rest and 64px scrolled. */
	--qi-header-h: 71px;
	--qi-header-h-scrolled: 63px;
	--qi-sticky-top: calc(var(--qi-header-h-scrolled) + 1.75rem);

	/* Frosted glass (photography only) */
	--qi-glass-blur: 14px;
	--qi-glass-bg: rgba(255, 255, 255, .10);
	--qi-glass-bg-strong: rgba(255, 255, 255, .13);
	--qi-glass-border: rgba(255, 255, 255, .20);
	--qi-glass-header: rgba(250, 247, 242, .72);
}

@media (max-width: 700px) {
	:root {
		--qi-header-h: 59px;
		--qi-header-h-scrolled: 55px;
	}
}

/* Align Blocksy's own tokens with the palette so theme chrome matches. */
:root {
	--theme-palette-color-1: #116466;
	--theme-palette-color-2: #0D5254;
	--theme-palette-color-3: #0B4444;
	--theme-palette-color-4: #2B3334;
	--theme-palette-color-5: #E4EFEC;
	--theme-palette-color-6: #F3EEE6;
	--theme-palette-color-7: #FAF7F2;
	--theme-palette-color-8: #FFFFFF;

	--theme-font-family: var(--qi-font-body);
	--theme-text-color: var(--qi-ink);
	--theme-headings-color: var(--qi-teal-800);
	--theme-link-initial-color: var(--qi-teal-600);
	--theme-link-hover-color: var(--qi-teal-700);
	--theme-border-color: var(--qi-hairline);

	--theme-block-max-width: 1200px;
	--theme-block-wide-max-width: 1400px;
	--theme-button-border-radius: var(--qi-radius-btn);
	--theme-button-min-height: 52px;
	--theme-content-vertical-spacing: 0px;
}

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

body.qi {
	background-color: var(--qi-ivory);
	color: var(--qi-ink);
	font-family: var(--qi-font-body);
	font-size: var(--qi-body);
	line-height: 1.68;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	font-synthesis-weight: none;
}

body.qi ::selection {
	background: var(--qi-teal-800);
	color: var(--qi-ivory);
}

body.qi a {
	color: var(--qi-teal-600);
	text-underline-offset: .18em;
	text-decoration-thickness: 1px;
}

body.qi a:hover {
	color: var(--qi-teal-700);
}

body.qi :focus-visible {
	outline: 2px solid var(--qi-gold);
	outline-offset: 3px;
	border-radius: 3px;
}

body.qi img {
	max-width: 100%;
	height: auto;
}

/* The front page is one long editorial canvas: no theme container padding. */
body.qi.home #main-container .ct-container,
body.qi.qi-canvas #main-container .ct-container {
	max-width: none;
	padding-left: 0;
	padding-right: 0;
}

body.qi.home .entry-content > *,
body.qi.qi-canvas .entry-content > * {
	margin-block: 0;
}

body.qi.home article.post,
body.qi.qi-canvas article.post {
	padding: 0;
}

/* The hero carries the page title on the front page. */
body.qi.home .entry-header,
body.qi.home .hero-section,
body.qi.qi-canvas .entry-header {
	display: none;
}

/* Our sections manage their own width; core's constrained layout must not
   re-narrow them. */
body.qi.home .entry-content > *,
body.qi.qi-canvas .entry-content > * {
	max-width: none;
}

body.qi.home .entry-content,
body.qi.qi-canvas .entry-content {
	padding: 0;
}

body.qi.home .ct-container-full,
body.qi.qi-canvas .ct-container-full {
	padding-top: 0;
	padding-bottom: 0;
}

/* --------------------------------------------------------------------------
   2. Typography
   -------------------------------------------------------------------------- */

body.qi h1,
body.qi h2,
body.qi h3,
body.qi h4,
body.qi h5,
body.qi .qi-display {
	font-family: var(--qi-font-head);
	font-weight: 700;
	color: var(--qi-teal-800);
	letter-spacing: -.015em;
	text-wrap: balance;
}

body.qi h1 {
	font-size: var(--qi-h1);
	font-weight: 700;
	line-height: 1.08;
	letter-spacing: -.02em;
}

body.qi h2 {
	font-size: var(--qi-h2);
	font-weight: 700;
	line-height: 1.14;
	letter-spacing: -.018em;
}

body.qi h3 {
	font-size: var(--qi-h3);
	line-height: 1.26;
	font-weight: 600;
	letter-spacing: -.012em;
}

body.qi h4 {
	font-size: var(--qi-h4);
	line-height: 1.34;
	font-weight: 600;
	letter-spacing: -.01em;
}

body.qi p {
	margin: 0 0 1.15em;
}

/* Blocksy gives headings a large top margin; our sections control their own
   rhythm, so neutralise it inside every qi- container. */
body.qi .qi-hero :is(h1, h2, h3, h4),
body.qi .qi-cta-banner :is(h1, h2, h3, h4),
body.qi [class*="qi-section"] :is(h1, h2, h3, h4),
body.qi .qi-card :is(h2, h3, h4),
body.qi .qi-step :is(h2, h3, h4),
body.qi .qi-tile :is(h2, h3, h4) {
	margin-top: 0;
}

body.qi .qi-section-head > * { margin-top: 0; }
body.qi .qi-section-head > :is(h1, h2, h3) { margin-bottom: 1.1rem; }
body.qi .qi-section-head > :last-child { margin-bottom: 0; }

body.qi p:last-child {
	margin-bottom: 0;
}

.qi-lead {
	font-size: var(--qi-lead);
	line-height: 1.6;
	color: var(--qi-ink-muted);
}

.qi-prose {
	max-width: var(--qi-max-prose);
}

/* Named "serif" for historic reasons — the class is referenced across the build
   files and page content, so it keeps its name. Since the Montserrat swap it is
   a heavy display statement rather than a serif one. Do not rename. */
.qi-serif-statement {
	font-family: var(--qi-font-head);
	font-weight: 600;
	font-size: clamp(1.625rem, 1.05rem + 2.2vw, 2.5rem);
	line-height: 1.26;
	letter-spacing: -.018em;
	color: var(--qi-teal-800);
	/* `balance` equalises line lengths, which on a four-line statement left a
	   very short opening line and a stepped rag. `pretty` fills each line and
	   only guards the last one against an orphan. */
	text-wrap: pretty;
}

.qi-muted {
	color: var(--qi-ink-muted);
}

.qi-small {
	font-size: var(--qi-small);
}

.qi-center {
	text-align: center;
}

.qi-center .qi-eyebrow,
.qi-eyebrow.qi-center {
	justify-content: center;
	text-align: center;
}

.qi-center .qi-eyebrow::before,
.qi-eyebrow.qi-center::before {
	display: none;
}

.qi-center .qi-prose {
	margin-inline: auto;
}

/* --------------------------------------------------------------------------
   3. Layout & sections
   -------------------------------------------------------------------------- */

.qi-section,
.qi-section-alt,
.qi-section-dark,
.qi-section-tint {
	position: relative;
	padding-block: var(--qi-space-section);
	padding-inline: var(--qi-gutter);
}

.qi-section { background: var(--qi-ivory); }
.qi-section-alt { background: var(--qi-ivory-deep); }
.qi-section-tint { background: var(--qi-tint); }

.qi-section-dark {
	background: var(--qi-teal-900);
	color: rgba(250, 247, 242, .82);
}

.qi-section-sm {
	padding-block: var(--qi-space-section-sm);
}

body.qi .qi-section-dark h1,
body.qi .qi-section-dark h2,
body.qi .qi-section-dark h3,
body.qi .qi-section-dark h4,
body.qi .qi-section-dark .qi-serif-statement,
body.qi .qi-section-dark .qi-stat-figure,
body.qi .is-dark h1,
body.qi .is-dark h2,
body.qi .is-dark h3,
body.qi .is-dark h4 {
	color: var(--qi-ivory);
}

body.qi .qi-section-dark p,
body.qi .qi-section-dark .qi-lead,
body.qi .qi-section-dark .qi-muted {
	color: rgba(250, 247, 242, .78);
}

body.qi .qi-section-dark a { color: var(--qi-ivory); }

/* Hairline that separates stacked light sections. */
.qi-rule-top { border-top: 1px solid var(--qi-hairline); }
.qi-rule-bottom { border-bottom: 1px solid var(--qi-hairline); }

/* Inner constrained wrapper — use on the group directly inside a section. */
.qi-inner,
.qi-section > .wp-block-group__inner-container,
.qi-section-alt > .wp-block-group__inner-container,
.qi-section-tint > .wp-block-group__inner-container,
.qi-section-dark > .wp-block-group__inner-container {
	max-width: var(--qi-max);
	margin-inline: auto;
	width: 100%;
}

.qi-inner-wide {
	max-width: var(--qi-max-wide);
	margin-inline: auto;
}

.qi-stack-sm > * + * { margin-top: 1rem; }
.qi-stack > * + * { margin-top: 1.6rem; }
.qi-stack-lg > * + * { margin-top: 2.75rem; }

/* Section head: eyebrow + heading + optional intro, with a hairline above. */
.qi-section-head {
	max-width: 44rem;
	margin-bottom: clamp(2.5rem, 1.5rem + 2.5vw, 4rem);
}

.qi-section-head.qi-center {
	margin-inline: auto;
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */

.qi-btn,
.qi-btn-outline,
.qi-btn-gold,
.qi-btn-ivory,
body.qi .wp-block-button.qi-btn > .wp-block-button__link,
body.qi .wp-block-button.qi-btn-outline > .wp-block-button__link,
body.qi .wp-block-button.qi-btn-gold > .wp-block-button__link,
body.qi .wp-block-button.qi-btn-ivory > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .55em;
	font-family: var(--qi-font-body);
	font-size: .9375rem;
	font-weight: 600;
	letter-spacing: .01em;
	line-height: 1;
	padding: 1.05rem 1.85rem;
	border-radius: var(--qi-radius-btn);
	border: 1px solid transparent;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .25s var(--qi-ease), color .25s var(--qi-ease),
		border-color .25s var(--qi-ease), transform .25s var(--qi-ease);
}

/* Primary — peacock solid */
.qi-btn,
body.qi .wp-block-button.qi-btn > .wp-block-button__link {
	background-color: var(--qi-teal-600);
	color: var(--qi-ivory);
	border-color: var(--qi-teal-600);
}

.qi-btn:hover,
.qi-btn:focus-visible,
body.qi .wp-block-button.qi-btn > .wp-block-button__link:hover,
body.qi .wp-block-button.qi-btn > .wp-block-button__link:focus-visible {
	background-color: var(--qi-teal-700);
	border-color: var(--qi-teal-700);
	color: var(--qi-ivory);
	transform: translateY(-1px);
}

/* Secondary — 1px outline */
.qi-btn-outline,
body.qi .wp-block-button.qi-btn-outline > .wp-block-button__link {
	background-color: transparent;
	color: var(--qi-teal-800);
	border-color: var(--qi-hairline-strong);
}

.qi-btn-outline:hover,
.qi-btn-outline:focus-visible,
body.qi .wp-block-button.qi-btn-outline > .wp-block-button__link:hover,
body.qi .wp-block-button.qi-btn-outline > .wp-block-button__link:focus-visible {
	border-color: var(--qi-teal-600);
	color: var(--qi-teal-600);
	background-color: transparent;
}

/* Outline on dark backgrounds */
.qi-section-dark .qi-btn-outline,
.qi-on-dark .qi-btn-outline,
body.qi .qi-on-dark .wp-block-button.qi-btn-outline > .wp-block-button__link {
	color: var(--qi-ivory);
	border-color: rgba(250, 247, 242, .45);
}

.qi-section-dark .qi-btn-outline:hover,
.qi-on-dark .qi-btn-outline:hover,
body.qi .qi-on-dark .wp-block-button.qi-btn-outline > .wp-block-button__link:hover {
	background-color: rgba(250, 247, 242, .1);
	border-color: var(--qi-ivory);
	color: var(--qi-ivory);
}

/* Gold — reserved for the single strongest call to action per screen */
.qi-btn-gold,
body.qi .wp-block-button.qi-btn-gold > .wp-block-button__link {
	background-color: var(--qi-gold);
	color: #16181A;
	border-color: var(--qi-gold);
}

.qi-btn-gold:hover,
.qi-btn-gold:focus-visible,
body.qi .wp-block-button.qi-btn-gold > .wp-block-button__link:hover,
body.qi .wp-block-button.qi-btn-gold > .wp-block-button__link:focus-visible {
	background-color: #B8914A;
	border-color: #B8914A;
	color: #16181A;
	transform: translateY(-1px);
}

/* Ivory — solid light button on photography */
.qi-btn-ivory,
body.qi .wp-block-button.qi-btn-ivory > .wp-block-button__link {
	background-color: var(--qi-ivory);
	color: var(--qi-teal-800);
	border-color: var(--qi-ivory);
}

.qi-btn-ivory:hover,
body.qi .wp-block-button.qi-btn-ivory > .wp-block-button__link:hover {
	background-color: var(--qi-white);
	color: var(--qi-teal-700);
	transform: translateY(-1px);
}

body.qi .wp-block-buttons {
	gap: .75rem 1rem;
	align-items: stretch;
}

/* When a qi-btn class sits on core's .wp-block-button wrapper, only the inner
   anchor may look like a button. Without this the wrapper draws a second
   border/background around the link. */
body.qi .wp-block-button[class*="qi-btn"] {
	display: inline-block;
	background: none;
	background-color: transparent;
	border: 0;
	padding: 0;
	border-radius: 0;
	transform: none;
}

body.qi .wp-block-button[class*="qi-btn"]:hover {
	background: none;
	background-color: transparent;
	transform: none;
}

body.qi .wp-block-button[class*="qi-btn"] > .wp-block-button__link {
	min-height: 52px;
	width: 100%;
}

/* Text link with an arrow */
.qi-link-arrow {
	display: inline-flex;
	align-items: center;
	gap: .45em;
	font-weight: 600;
	font-size: .9375rem;
	letter-spacing: .01em;
	color: var(--qi-teal-600);
	text-decoration: none;
	border-bottom: 1px solid var(--qi-gold-soft);
	padding-bottom: .2em;
	transition: color .22s var(--qi-ease), border-color .22s var(--qi-ease), gap .22s var(--qi-ease);
}

.qi-link-arrow:hover {
	color: var(--qi-teal-800);
	border-color: var(--qi-gold);
	gap: .8em;
}

/* --------------------------------------------------------------------------
   5. Eyebrow labels & hairline flourishes
   -------------------------------------------------------------------------- */

.qi-eyebrow {
	display: flex;
	align-items: center;
	gap: .75rem;
	font-family: var(--qi-font-body);
	font-size: var(--qi-eyebrow-size);
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--qi-gold-ink);
	margin: 0 0 1.15rem;
	line-height: 1.4;
}

.qi-eyebrow::before {
	content: "";
	flex: 0 0 auto;
	width: 28px;
	height: 1px;
	background: currentColor;
	opacity: .75;
}

.qi-eyebrow-teal { color: var(--qi-teal-600); }

/* body.qi prefix required: `body.qi .qi-section-dark p` is more specific and
   would otherwise repaint the eyebrow ivory. */
body.qi .qi-section-dark .qi-eyebrow,
body.qi .qi-on-dark .qi-eyebrow,
/* On a deep-teal band the bright peacock gold is the legible one (5.9:1), so
   the dark contexts opt back out of --qi-gold-ink. */
body.qi .is-dark .qi-eyebrow,
body.qi .qi-section-dark .qi-eyebrow,
body.qi .qi-section-dark .qi-step-num,
body.qi .is-dark .qi-step-num,
body.qi .qi-section-dark .qi-timeline-year,
body.qi .qi-cta-banner .qi-step-num { color: var(--qi-gold); }


.qi-hairline {
	border: 0;
	border-top: 1px solid var(--qi-hairline);
	margin: 0;
	height: 0;
}

.qi-hairline-gold {
	border-top-color: var(--qi-gold-soft);
}

/* --------------------------------------------------------------------------
   6. Cards
   -------------------------------------------------------------------------- */

.qi-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: .9rem;
	background: var(--qi-white);
	border: 1px solid var(--qi-hairline);
	border-radius: var(--qi-radius-lg);
	padding: clamp(1.5rem, 1rem + 1.4vw, 2.25rem);
	height: 100%;
	/* Hover lift uses `translate`, not `transform`: the scroll reveal owns
	   `transform` with fill-mode both and would otherwise cancel the lift. */
	transition: border-color .3s var(--qi-ease), translate .3s var(--qi-ease),
		box-shadow .3s var(--qi-ease), background-color .3s var(--qi-ease);
}

.qi-card:hover {
	border-color: var(--qi-teal-600);
	translate: 0 -3px;
}

body.qi .qi-card h3,
body.qi .qi-card h4 {
	margin: 0;
	font-size: clamp(1.1875rem, 1.05rem + .45vw, 1.375rem);
	line-height: 1.24;
	text-wrap: pretty;
}

.qi-card p {
	color: var(--qi-ink-muted);
	font-size: var(--qi-small);
	margin: 0;
}

.qi-card .qi-link-arrow { margin-top: auto; align-self: flex-start; padding-top: .35rem; }

.qi-card-tint { background: var(--qi-tint); border-color: transparent; }
.qi-card-plain { background: transparent; border-color: transparent; padding-inline: 0; }

/* Card grids */
.qi-grid {
	display: grid;
	gap: clamp(1rem, .6rem + 1.2vw, 1.75rem);
}

.qi-grid-2 { grid-template-columns: 1fr; }

@media (min-width: 780px) {
	.qi-grid-2 { grid-template-columns: repeat(2, 1fr); }
}
.qi-grid-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.qi-grid-4 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

@media (min-width: 1000px) {
	.qi-grid-3 { grid-template-columns: repeat(3, 1fr); }
	.qi-grid-4 { grid-template-columns: repeat(4, 1fr); }
}

/* WordPress columns inside our sections behave as a grid on small screens. */
body.qi .qi-grid > .wp-block-column,
body.qi .qi-grid > .wp-block-group {
	flex-basis: auto !important;
}

/* Line icons */
.qi-icon {
	display: block;
	width: 30px;
	height: 30px;
	color: var(--qi-teal-600);
	margin-bottom: .35rem;
}

.qi-icon svg {
	display: block;
	width: 100%;
	height: 100%;
	stroke: currentColor;
	stroke-width: 1.4;
	stroke-linecap: round;
	stroke-linejoin: round;
	fill: none;
}

/* Audience tiles — hairline separated, no boxes */
.qi-tile {
	border-top: 1px solid var(--qi-hairline-strong);
	padding-top: 1.35rem;
	display: flex;
	flex-direction: column;
	gap: .5rem;
}

body.qi .qi-tile h3 {
	font-size: var(--qi-h4);
	margin: 0;
}

.qi-tile p {
	margin: 0;
	color: var(--qi-ink-muted);
	font-size: var(--qi-small);
}

/* 6b. Image-led cards ------------------------------------------------------
   The photograph is the top of the card; text sits below it. Used by the
   homepage services grid and available to any page. */

.qi-card-media {
	padding: 0;
	overflow: hidden;
	gap: 0;
}

.qi-card-figure {
	display: block;
	position: relative;
	margin: 0;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--qi-tint);
	border-bottom: 1px solid var(--qi-hairline);
}

body.qi .qi-card-figure img {
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	/* `scale` (not transform) so the reveal animation keeps ownership of
	   transform; a hover transition is not a scroll-driven animation, so the
	   raster caveat does not apply. */
	transition: scale .7s var(--qi-ease);
}

.qi-card-media:hover .qi-card-figure img { scale: 1.045; }

.qi-card-body {
	display: flex;
	flex-direction: column;
	gap: .75rem;
	flex: 1 1 auto;
	padding: clamp(1.35rem, 1rem + 1vw, 1.85rem);
}

body.qi .qi-card-media h3 { margin: 0; }

body.qi .qi-card-media h3 a {
	color: inherit;
	text-decoration: none;
}

body.qi .qi-card-media:hover h3 a { color: var(--qi-teal-600); }

.qi-card-media .qi-link-arrow {
	margin-top: auto;
	align-self: flex-start;
	padding-top: .35rem;
}

/* Checklist of sub-areas inside a card body. */
.qi-card-checklist {
	list-style: none;
	margin: .35rem 0 0;
	padding: 0;
	display: grid;
	gap: .5rem;
}

.qi-card-checklist li {
	position: relative;
	padding-left: 1.65rem;
	font-size: var(--qi-small);
	line-height: 1.45;
	color: var(--qi-ink);
}

.qi-card-checklist li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .32em;
	width: 1.05em;
	height: 1.05em;
	border-radius: 50%;
	background: var(--qi-tint);
}

.qi-card-checklist li::after {
	content: "";
	position: absolute;
	left: .29em;
	top: .58em;
	width: .46em;
	height: .24em;
	border-left: 1.6px solid var(--qi-teal-600);
	border-bottom: 1.6px solid var(--qi-teal-600);
	transform: rotate(-45deg);
}

/* Feature card: wider photograph, larger headline, denser text column. */
@media (min-width: 1000px) {
	.qi-grid-feature > :first-child { grid-column: span 2; }

	.qi-card-feature { flex-direction: row; }

	.qi-card-feature .qi-card-figure {
		flex: 0 0 46%;
		aspect-ratio: auto;
		border-bottom: 0;
		border-right: 1px solid var(--qi-hairline);
	}

	.qi-card-feature .qi-card-body {
		justify-content: center;
		gap: .85rem;
		padding: clamp(1.75rem, 1.2rem + 1.6vw, 2.5rem);
	}

	body.qi .qi-card-feature h3 {
		font-size: clamp(1.5rem, 1.2rem + .9vw, 1.95rem);
	}

	.qi-card-feature p { font-size: var(--qi-small); }

	/* The feature card sets the row height; let the neighbour's photograph
	   absorb the difference instead of leaving a slab of empty card. */
	.qi-grid-feature > :nth-child(2) .qi-card-figure {
		aspect-ratio: auto;
		flex: 1 1 auto;
		min-height: 220px;
	}

	.qi-card-feature .qi-link-arrow { margin-top: .35rem; }
}

/* 6c. Photographic tiles — caption on a frosted strip ---------------------- */

.qi-photo-tile {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--qi-radius-lg);
	aspect-ratio: 3 / 4;
	background: var(--qi-teal-800);
	isolation: isolate;
	transition: translate .3s var(--qi-ease);
}

.qi-photo-tile:hover { translate: 0 -3px; }

.qi-photo-tile-media {
	position: absolute;
	inset: 0;
	display: block;
	background:
		repeating-linear-gradient(135deg, rgba(250, 247, 242, .05) 0 12px, transparent 12px 24px),
		var(--qi-teal-800);
}

body.qi .qi-photo-tile-media img {
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	transition: scale .7s var(--qi-ease);
}

.qi-photo-tile:hover .qi-photo-tile-media img { scale: 1.05; }

.qi-photo-tile::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient(180deg, rgba(6, 47, 48, .10) 0%, rgba(6, 47, 48, .30) 42%, rgba(6, 47, 48, .78) 100%);
}

/* The caption is bottom-anchored, so a one-line title sat 20px lower than a
   two-line one and the row of tiles read as ragged. A floor equal to the
   tallest caption lines every top up; the content still hangs off the bottom
   edge, so nothing moves for the tall ones. */
.qi-photo-tile-body {
	position: absolute;
	inset: auto .6rem .6rem;
	z-index: 1;
	min-height: 7.5rem;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	padding: 1rem 1.1rem 1.05rem;
	border: 1px solid var(--qi-glass-border);
	border-radius: var(--qi-radius);
	background: rgba(255, 255, 255, .11);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.qi-photo-tile-body {
		-webkit-backdrop-filter: blur(12px) saturate(130%);
		backdrop-filter: blur(12px) saturate(130%);
		background: rgba(255, 255, 255, .09);
	}
}

body.qi .qi-photo-tile-body h3 {
	margin: 0 0 .3rem;
	color: var(--qi-ivory);
	font-size: 1.0625rem;
	line-height: 1.25;
}

.qi-photo-tile-body p {
	margin: 0;
	color: rgba(250, 247, 242, .86);
	font-size: .8125rem;
	line-height: 1.5;
}

/* --------------------------------------------------------------------------
   7. Components
   -------------------------------------------------------------------------- */

/* 7a. Hero ---------------------------------------------------------------- */

.qi-hero {
	position: relative;
	min-height: min(88vh, 820px);
	display: flex;
	align-items: center;
	isolation: isolate;
	padding-inline: var(--qi-gutter);
	background-color: var(--qi-teal-900);
	background-size: cover;
	background-position: center;
	color: var(--qi-ivory);
}

body.qi .qi-hero.wp-block-cover {
	min-height: min(88vh, 820px);
	padding: clamp(5rem, 3rem + 8vw, 9rem) var(--qi-gutter);
}

/* Deep-teal duotone wash over the photography. Sits at z-index 0, above the
   background image, below core's inner container (z-index 1). */
.qi-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background:
		linear-gradient(100deg, rgba(6, 47, 48, .88) 0%, rgba(6, 47, 48, .68) 46%, rgba(11, 68, 68, .34) 100%),
		linear-gradient(180deg, rgba(6, 47, 48, .18) 0%, rgba(6, 47, 48, .42) 100%);
}

body.qi .qi-hero .qi-eyebrow { color: var(--qi-gold); }

body.qi .qi-hero > .wp-block-cover__background,
body.qi .qi-hero > .wp-block-cover__gradient-background {
	display: none;
}

body.qi .qi-hero > .wp-block-cover__inner-container,
.qi-hero > .qi-hero-inner {
	position: relative;
	z-index: 1;
	max-width: var(--qi-max);
	margin-inline: auto;
	width: 100%;
}

/* ONE LEFT RAIL. See caveat 6 in the file header: if the cover ever renders
   with `is-layout-constrained`, core's global styles push `margin-left:auto
   !important; margin-right:auto !important` onto every child and any child with
   a max-width (h1 at 17ch, lead at 54ch) is centred while the eyebrow, buttons
   and trust row stay left. This neutralises it whatever the block attribute
   says. Never delete without re-testing the hero rail at 1440px. */
body.qi .qi-hero > .wp-block-cover__inner-container > *,
body.qi .qi-cta-banner > .wp-block-cover__inner-container > *,
body.qi .qi-stats > .wp-block-cover__inner-container > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

body.qi .qi-hero h1,
body.qi .qi-hero h2,
body.qi .qi-hero p { color: var(--qi-ivory); }

body.qi .qi-hero h1 { max-width: 17ch; margin: 0 0 1.5rem; }

body.qi .qi-hero .qi-lead {
	max-width: 54ch;
	color: rgba(250, 247, 242, .86);
	margin-bottom: 2.25rem;
}

/* Trust row — one frosted pill per claim, on the hero's left rail. */
.qi-trustrow {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 14px;
	margin: clamp(2.25rem, 1.5rem + 2.5vw, 3.25rem) 0 0;
	padding: 0;
	list-style: none;
	font-size: .8125rem;
	font-weight: 500;
	letter-spacing: .1em;
	text-transform: uppercase;
}

.qi-trustrow > li {
	display: inline-flex;
	align-items: center;
	padding: 14px 22px;
	border: 1px solid var(--qi-glass-border);
	border-radius: 999px;
	background: var(--qi-glass-bg);
	color: rgba(250, 247, 242, .9);
	line-height: 1.25;
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.qi-trustrow > li {
		-webkit-backdrop-filter: blur(var(--qi-glass-blur)) saturate(130%);
		backdrop-filter: blur(var(--qi-glass-blur)) saturate(130%);
		background: rgba(255, 255, 255, .09);
	}
}

/* 2 x 2 on tablet, full-width stack on phones. */
@media (max-width: 1099px) and (min-width: 561px) {
	.qi-trustrow > li { flex: 0 1 calc(50% - 7px); }
}

@media (max-width: 560px) {
	.qi-trustrow {
		gap: 10px;
	}

	.qi-trustrow > li {
		flex: 1 1 100%;
		padding: 12px 18px;
	}
}

/* 7a-2. Parallax wrapper --------------------------------------------------
   The background photograph of every cover / full-bleed band lives inside this
   wrapper so the scroll-driven translate never touches the <img> (caveat 1).
   The wrapper is taller than its container so the drift cannot expose an edge;
   the container's own overflow does the clipping. */

.qi-parallax {
	position: absolute;
	left: 0;
	right: 0;
	top: -10%;
	bottom: -10%;
	z-index: 0;
	pointer-events: none;
	overflow: hidden;
}

.qi-parallax > img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	border: 0;
	margin: 0;
	padding: 0;
}

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.qi-parallax {
			animation: qi-parallax-drift linear both;
			animation-timeline: view();
			animation-range: cover 0% cover 100%;
		}
	}
}

@keyframes qi-parallax-drift {
	from { transform: translateY(-6%); }
	to { transform: translateY(6%); }
}

/* 7a-3. Hero entrance — time based, so the fold is never blank ------------- */

@media (prefers-reduced-motion: no-preference) {
	body.qi .qi-hero > .wp-block-cover__inner-container > * {
		animation: qi-rise .9s var(--qi-ease) both;
	}

	body.qi .qi-hero > .wp-block-cover__inner-container > :nth-child(1) { animation-delay: .05s; }
	body.qi .qi-hero > .wp-block-cover__inner-container > :nth-child(2) { animation-delay: .14s; }
	body.qi .qi-hero > .wp-block-cover__inner-container > :nth-child(3) { animation-delay: .23s; }
	body.qi .qi-hero > .wp-block-cover__inner-container > :nth-child(4) { animation-delay: .32s; }
	body.qi .qi-hero > .wp-block-cover__inner-container > :nth-child(5) { animation-delay: .41s; }

	/* The trust pills arrive one after another rather than as one block. */
	body.qi .qi-hero .qi-trustrow { animation: none; }

	body.qi .qi-hero .qi-trustrow > li {
		animation: qi-rise .8s var(--qi-ease) both;
	}

	body.qi .qi-hero .qi-trustrow > li:nth-child(1) { animation-delay: .44s; }
	body.qi .qi-hero .qi-trustrow > li:nth-child(2) { animation-delay: .52s; }
	body.qi .qi-hero .qi-trustrow > li:nth-child(3) { animation-delay: .60s; }
	body.qi .qi-hero .qi-trustrow > li:nth-child(4) { animation-delay: .68s; }
}

@keyframes qi-rise {
	from { opacity: 0; transform: translateY(18px); }
	to { opacity: 1; transform: none; }
}

/* 7b. Editorial two-column strip ------------------------------------------ */

.qi-split {
	display: grid;
	gap: clamp(1.75rem, 1rem + 3vw, 4.5rem);
	align-items: start;
}

/* core/columns sets `align-items:normal !important`, which stretches grid items
   to the row height and kills any position:sticky inside them. align-self on
   the item itself is not overridden. */
body.qi .qi-split > .wp-block-column { align-self: start; }

@media (min-width: 900px) {
	.qi-split { grid-template-columns: 1.05fr .95fr; }
	.qi-split-media { grid-template-columns: 1fr 1fr; align-items: center; }
	.qi-split-sticky { grid-template-columns: .92fr 1.08fr; }
}

/* Sticky prose column beside the taller scrolling headline+image column.
   Gated on viewport height as well as width: if the pinned column cannot fit
   under the header it must scroll normally rather than overlap. */
@media (min-width: 900px) {
	body.qi .qi-sticky-col > p { max-width: 46ch; }
	body.qi .qi-sticky-col > p + p { margin-top: 1.6rem; }
	body.qi .qi-flow-col .qi-figure-reveal { max-width: 420px; }
}

@media (min-width: 900px) and (min-height: 700px) {
	body.qi .qi-sticky-col {
		position: sticky;
		top: var(--qi-sticky-top);
	}
}

@media (prefers-reduced-motion: reduce) {
	body.qi .qi-sticky-col { position: static; }
}

/* 7b-2. Editorial figure with a scroll-driven settle + drift ---------------
   Fully visible without the animation: the effect is layered on only where
   scroll-driven animations are supported and motion is welcome. */

body.qi .qi-figure-reveal {
	margin: clamp(2rem, 1.2rem + 2vw, 3rem) 0 0;
	max-width: 440px;
}

body.qi .qi-figure-reveal img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 14px;
}

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		/* The animation rides on the <figure>, never on the <img>. A
		   `translate`-based parallax drift and a scaled settle were both tried
		   and broke image rasterisation, so the effect is a fade and slide. */
		body.qi .qi-figure-reveal {
			animation: qi-figure-settle linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 85%;
		}
	}
}

/* Note: no scale() here. A scroll-driven animation that scales an element
   containing a large raster stops the image rasterising in current Chromium
   (the whole page can lose its photographs), so the settle is a fade + slide. */
@keyframes qi-figure-settle {
	from {
		opacity: .4;
		transform: translateY(40px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}


/* 7c. Media & text (About preview) ---------------------------------------- */

body.qi .qi-mediatext.wp-block-media-text {
	grid-template-columns: 44% 1fr;
	gap: clamp(1.75rem, 1rem + 3vw, 4rem);
	align-items: center;
}

body.qi .qi-mediatext .wp-block-media-text__media img {
	border-radius: var(--qi-radius-lg);
	aspect-ratio: 4 / 5;
	object-fit: cover;
	width: 100%;
}

body.qi .qi-mediatext .wp-block-media-text__content {
	padding: 0;
}

@media (max-width: 780px) {
	body.qi .qi-mediatext.wp-block-media-text {
		grid-template-columns: 1fr;
	}
}

.qi-portrait-frame {
	position: relative;
	border-radius: var(--qi-radius-lg);
	overflow: hidden;
}

/* 7d. Process steps -------------------------------------------------------- */

.qi-steps {
	display: grid;
	gap: clamp(1.75rem, 1rem + 2.5vw, 3rem);
	counter-reset: qi-step;
}

@media (min-width: 900px) {
	.qi-steps { grid-template-columns: repeat(4, 1fr); }
}

.qi-step {
	border-top: 1px solid var(--qi-gold-soft);
	padding-top: 1.5rem;
}

.qi-step-num {
	display: block;
	font-family: var(--qi-font-head);
	font-weight: 700;
	font-size: clamp(2.25rem, 1.6rem + 2vw, 3.25rem);
	line-height: 1;
	color: var(--qi-gold-ink);
	margin-bottom: .85rem;
	letter-spacing: -.03em;
}

body.qi .qi-step h3 {
	font-size: var(--qi-h4);
	margin: 0 0 .55rem;
}

.qi-step p {
	margin: 0;
	color: var(--qi-ink-muted);
	font-size: var(--qi-small);
}

body.qi .qi-section-dark .qi-step p { color: rgba(250, 247, 242, .78); }

/* 7d-2. Sticky stacked process cards ---------------------------------------
   Opt-in modifier so the plain .qi-steps grid used elsewhere is untouched.
   Each card sticks a little lower than the one before it, so the next card
   scrolls up and overlaps it. Cards need an opaque background to do that. */

.qi-steps-stack { counter-reset: qi-step; }

@media (min-width: 900px) {
	.qi-steps-stack {
		grid-template-columns: minmax(0, 62rem);
		gap: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
	}

	.qi-steps-stack > .qi-step {
		position: sticky;
		border-top: 0;
		border: 1px solid var(--qi-hairline);
		border-radius: var(--qi-radius-lg);
		background: var(--qi-ivory);
		padding: clamp(1.75rem, 1.2rem + 1.6vw, 2.5rem);
		display: grid;
		grid-template-columns: auto 1fr;
		column-gap: clamp(1.5rem, 1rem + 2vw, 3rem);
		align-items: start;
		box-shadow: 0 24px 60px -46px rgba(6, 47, 48, .55);
	}

	.qi-steps-stack > .qi-step:nth-child(1) { top: calc(var(--qi-sticky-top) + 0px); }
	.qi-steps-stack > .qi-step:nth-child(2) { top: calc(var(--qi-sticky-top) + 18px); }
	.qi-steps-stack > .qi-step:nth-child(3) { top: calc(var(--qi-sticky-top) + 36px); }
	.qi-steps-stack > .qi-step:nth-child(4) { top: calc(var(--qi-sticky-top) + 54px); }

	.qi-steps-stack > .qi-step > .qi-step-num {
		grid-row: 1 / span 2;
		margin: 0;
		padding-right: clamp(1.5rem, 1rem + 2vw, 3rem);
		border-right: 1px solid var(--qi-gold-soft);
		min-width: 4.5rem;
	}

	body.qi .qi-steps-stack > .qi-step h3 {
		font-size: var(--qi-h3);
		margin: .2rem 0 .55rem;
	}

	.qi-steps-stack > .qi-step p {
		font-size: var(--qi-body);
		max-width: 54ch;
	}

	/* Trailing room so the last card is read before the section releases. */
	.qi-steps-stack::after {
		content: "";
		display: block;
		height: clamp(2rem, 1rem + 4vw, 5rem);
	}
}

@media (prefers-reduced-motion: reduce) {
	.qi-steps-stack > .qi-step { position: static; }
}

/* 7e. Stats ---------------------------------------------------------------- */

body.qi .qi-stats.wp-block-cover,
body.qi .qi-stats.wp-block-group {
	position: relative;
	background-color: var(--qi-teal-900);
	padding: var(--qi-space-section) var(--qi-gutter);
	min-height: 0;
	isolation: isolate;
	overflow: hidden;
}

/* Let a little of the photograph read through the deep-teal dim. */
body.qi .qi-stats.wp-block-cover > .wp-block-cover__background {
	opacity: .7;
}

body.qi .qi-stats > .wp-block-cover__inner-container,
body.qi .qi-stats > .wp-block-group__inner-container {
	position: relative;
	z-index: 1;
	max-width: var(--qi-max);
	margin-inline: auto;
	width: 100%;
}

.qi-stats-grid {
	display: grid;
	gap: clamp(1rem, .6rem + 1.2vw, 1.75rem);
}

@media (min-width: 800px) {
	.qi-stats-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Each figure sits in its own frosted card over the teal-velvet photograph. */
.qi-stat {
	position: relative;
	text-align: center;
	padding: clamp(2rem, 1.4rem + 2vw, 3rem) 1.25rem;
	border: 1px solid var(--qi-glass-border);
	border-radius: var(--qi-radius-lg);
	background: var(--qi-glass-bg);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.qi-stat {
		-webkit-backdrop-filter: blur(var(--qi-glass-blur)) saturate(130%);
		backdrop-filter: blur(var(--qi-glass-blur)) saturate(130%);
		background: rgba(255, 255, 255, .07);
	}
}

.qi-stat-figure {
	display: block;
	font-family: var(--qi-font-head);
	font-weight: 700;
	font-size: var(--qi-stat);
	line-height: 1;
	letter-spacing: -.035em;
	color: var(--qi-ivory);
	margin-bottom: .85rem;
}

.qi-stat-figure em {
	font-style: normal;
	color: var(--qi-gold);
}

.qi-stat-label {
	display: block;
	font-family: var(--qi-font-body);
	font-size: .8125rem;
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: rgba(250, 247, 242, .72);
}

/* 7f. FAQ accordion (native <details>) ------------------------------------- */

/* Left rail, like every other section — a centred accordion beside left-aligned
   section heads is the misalignment the client flagged. */
.qi-faq {
	max-width: 60rem;
	margin-inline: 0;
	border-top: 1px solid var(--qi-hairline);
}

.qi-faq details {
	border-bottom: 1px solid var(--qi-hairline);
	background: transparent;
}

/* Compact accordion. The rows were on 24px vertical padding with a 20px
   summary and a 26px answer margin, which read as a stack of tall cards rather
   than a list. 17px of padding keeps every row comfortably past the 44px tap
   minimum (17px text x 1.35 + 34 = ~57px) while halving the whitespace. */
.qi-faq summary {
	list-style: none;
	cursor: pointer;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1.25rem;
	padding: 1.0625rem 0;
	font-family: var(--qi-font-head);
	font-weight: 600;
	font-size: clamp(1.0625rem, 1.02rem + .18vw, 1.125rem);
	line-height: 1.4;
	letter-spacing: -.01em;
	color: var(--qi-teal-800);
	transition: color .22s var(--qi-ease);
}

.qi-faq summary::-webkit-details-marker { display: none; }
.qi-faq summary::marker { content: ""; }

.qi-faq summary:hover { color: var(--qi-teal-600); }

.qi-faq summary::after {
	content: "";
	flex: 0 0 auto;
	width: 13px;
	height: 13px;
	/* Centres the glyph on the cap height of the first summary line. */
	margin-top: .46em;
	background:
		linear-gradient(var(--qi-gold), var(--qi-gold)) center/100% 1.5px no-repeat,
		linear-gradient(var(--qi-gold), var(--qi-gold)) center/1.5px 100% no-repeat;
	transition: transform .3s var(--qi-ease);
}

.qi-faq details[open] > summary::after {
	transform: none;
	background:
		linear-gradient(var(--qi-gold), var(--qi-gold)) center/100% 1.5px no-repeat;
}

body.qi .qi-faq details > *:not(summary) {
	margin-block: 0 .55rem;
	margin-inline: 0;
	max-width: 58ch;
	color: var(--qi-ink-muted);
	font-size: 1rem;
	line-height: 1.62;
}

/* The answer sits under the summary, so it only needs a floor of its own. */
body.qi .qi-faq details > *:not(summary):last-child {
	margin-bottom: 1.0625rem;
}

@media (prefers-reduced-motion: no-preference) {
	.qi-faq details[open] > *:not(summary) {
		animation: qi-faq-open .28s var(--qi-ease) both;
	}
}

@keyframes qi-faq-open {
	from { opacity: 0; transform: translateY(-4px); }
	to { opacity: 1; transform: none; }
}

/* 7g. CTA banner ----------------------------------------------------------- */

body.qi .qi-cta-banner.wp-block-cover {
	background-color: var(--qi-teal-800);
	padding: clamp(4.5rem, 3rem + 6vw, 8rem) var(--qi-gutter);
	min-height: 0;
	isolation: isolate;
}

body.qi .qi-cta-banner.wp-block-cover > .wp-block-cover__background {
	display: none;
}

body.qi .qi-cta-banner::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: linear-gradient(105deg, rgba(6, 47, 48, .9) 0%, rgba(11, 68, 68, .8) 55%, rgba(17, 100, 102, .68) 100%);
}

body.qi .qi-cta-banner .qi-eyebrow { color: var(--qi-gold); }
body.qi .qi-cta-banner h2,
body.qi .qi-cta-banner p { color: var(--qi-ivory); }
body.qi .qi-cta-banner .qi-lead { color: rgba(250, 247, 242, .84); }

/* The inner container IS the frosted panel. */
body.qi .qi-cta-banner > .wp-block-cover__inner-container,
body.qi .qi-cta-banner > .wp-block-group__inner-container {
	position: relative;
	z-index: 1;
	max-width: 58rem;
	margin-inline: auto;
	text-align: center;
	width: 100%;
	padding: clamp(2.25rem, 1.5rem + 3vw, 3.75rem) clamp(1.5rem, 1rem + 2.5vw, 3.5rem);
	border: 1px solid var(--qi-glass-border);
	border-radius: 20px;
	background: var(--qi-glass-bg-strong);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	body.qi .qi-cta-banner > .wp-block-cover__inner-container,
	body.qi .qi-cta-banner > .wp-block-group__inner-container {
		-webkit-backdrop-filter: blur(16px) saturate(135%);
		backdrop-filter: blur(16px) saturate(135%);
		background: rgba(255, 255, 255, .09);
	}
}

/* The rail guard above zeroes the auto margins on cover children; inside the
   CTA panel the composition is deliberately centred, so give them back. */
body.qi .qi-cta-banner > .wp-block-cover__inner-container > * {
	margin-left: auto !important;
	margin-right: auto !important;
}

body.qi .qi-cta-banner .wp-block-buttons { justify-content: center; }

/* 7h. Editorial image break — full-bleed photograph + frosted statement ---- */

.qi-imagebreak {
	position: relative;
	display: flex;
	/* Panel rides high, in the sky band of the photograph, where the type has
	   the most contrast to work with. */
	align-items: flex-start;
	min-height: min(62vh, 560px);
	padding: clamp(3rem, 2rem + 4vw, 5rem) var(--qi-gutter);
	background-color: var(--qi-teal-900);
	isolation: isolate;
	overflow: hidden;
}

.qi-imagebreak::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background:
		linear-gradient(90deg, rgba(6, 47, 48, .66) 0%, rgba(6, 47, 48, .44) 42%, rgba(6, 47, 48, .10) 100%),
		linear-gradient(180deg, rgba(6, 47, 48, .28) 0%, rgba(6, 47, 48, .18) 45%, rgba(6, 47, 48, .58) 100%);
}

.qi-imagebreak-panel {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 46rem;
	padding: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
	border: 1px solid var(--qi-glass-border);
	border-radius: var(--qi-radius-lg);
	background: var(--qi-glass-bg-strong);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.qi-imagebreak-panel {
		-webkit-backdrop-filter: blur(16px) saturate(135%);
		backdrop-filter: blur(16px) saturate(135%);
		background: rgba(255, 255, 255, .09);
	}
}

body.qi .qi-imagebreak-panel .qi-eyebrow { color: var(--qi-gold); }

body.qi .qi-imagebreak-panel .qi-serif-statement {
	color: var(--qi-ivory);
	margin: 0 0 .9rem;
	font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.4rem);
}

.qi-imagebreak-note {
	margin: 0;
	font-size: .8125rem;
	font-weight: 500;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: rgba(250, 247, 242, .7);
}

/* Keep the panel on the page rail rather than against the viewport edge. */
.qi-imagebreak { justify-content: flex-start; }

.qi-imagebreak > .qi-imagebreak-panel {
	margin-left: max(0px, calc((100% - var(--qi-max)) / 2));
}

/* 7i. Why-us split — value props on the rail, sticky photograph beside ----- */

.qi-whysplit {
	display: grid;
	gap: clamp(1.75rem, 1rem + 3vw, 4rem);
	align-items: start;
}

@media (min-width: 900px) {
	.qi-whysplit { grid-template-columns: 1.08fr .92fr; }
}

.qi-whylist {
	display: grid;
	gap: clamp(1.5rem, 1rem + 1.4vw, 2.25rem);
}

.qi-why-item {
	border-top: 1px solid var(--qi-hairline-strong);
	padding-top: 1.35rem;
}

body.qi .qi-why-item h3 {
	font-size: var(--qi-h4);
	margin: 0 0 .5rem;
}

.qi-why-item p {
	margin: 0;
	color: var(--qi-ink-muted);
	font-size: var(--qi-small);
	max-width: 50ch;
}

.qi-why-media {
	margin: 0;
	border-radius: var(--qi-radius-lg);
	overflow: hidden;
}

body.qi .qi-why-media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

/* Pinned only when it can be seen whole; the cap stops a tall portrait crop
   from having its lower half clipped off the bottom of a short viewport. */
@media (min-width: 900px) and (min-height: 700px) {
	.qi-why-media {
		position: sticky;
		top: var(--qi-sticky-top);
		max-height: calc(100vh - var(--qi-sticky-top) - 2rem);
	}

	body.qi .qi-why-media img { height: 100%; }
}

@media (prefers-reduced-motion: reduce) {
	.qi-why-media { position: static; }
}

/* Spacing for the link that follows a card grid. */
body.qi .qi-after-grid { margin-top: clamp(2rem, 1.4rem + 1.6vw, 3rem); }

/* Missing-image placeholder (wired later by the image agent). */
.qi-img-placeholder {
	background:
		repeating-linear-gradient(135deg, rgba(250, 247, 242, .045) 0 12px, transparent 12px 24px),
		var(--qi-teal-900);
}

/* --------------------------------------------------------------------------
   8. Header & footer
   -------------------------------------------------------------------------- */

body.qi header#header {
	position: sticky;
	top: 0;
	z-index: 60;
	background-color: var(--qi-ivory);
	border-bottom: 1px solid transparent;
	will-change: background-color;
}

/* Blocksy sets `overflow:hidden;overflow:clip` on #main-container. `clip` is
   not a scroll container, so sticky still resolves against the viewport in
   modern engines; the declaration below is only a guard for the `hidden`
   fallback path. */
body.qi #main-container { overflow: clip; }

/* Once the page has scrolled the bar settles into a SOLID ivory rail: hairline
   rule plus a whisper of shadow for separation. It is deliberately NOT
   translucent — a see-through bar with body copy and photography sliding
   underneath was unreadable on both desktop and mobile. The only frosted state
   left is the resting one at the very top of a photographic hero, where there
   is nothing behind the bar yet. Scroll-driven CSS — no scroll listener. */
@supports (animation-timeline: scroll()) {
	body.qi header#header {
		animation: qi-header-frost linear both;
		animation-timeline: scroll(root block);
		animation-range: 40px 150px;
	}

	/* The bar also compacts slightly as it sticks. 8px over a 110px scroll
	   range is sub-pixel per frame, so the reflow is imperceptible. */
	body.qi header#header [data-row="middle"] > .ct-container {
		animation: qi-header-compact linear both;
		animation-timeline: scroll(root block);
		animation-range: 40px 150px;
	}
}

@keyframes qi-header-frost {
	from {
		background-color: rgba(250, 247, 242, 1);
		border-bottom-color: rgba(11, 68, 68, 0);
		box-shadow: 0 1px 0 rgba(6, 47, 48, 0);
	}
	to {
		background-color: var(--qi-ivory);
		border-bottom-color: var(--qi-hairline);
		box-shadow: 0 6px 18px -14px rgba(6, 47, 48, .55);
	}
}

@keyframes qi-header-compact {
	from { min-height: var(--qi-header-h); }
	to   { min-height: var(--qi-header-h-scrolled); }
}

/* Without scroll-driven animations the bar stays solid ivory with its rule. */
@supports not (animation-timeline: scroll()) {
	body.qi header#header { border-bottom-color: var(--qi-hairline); }
}

@media (prefers-reduced-motion: reduce) {
	body.qi header#header {
		animation: none;
		background-color: var(--qi-ivory);
		border-bottom-color: var(--qi-hairline);
	}

	body.qi header#header [data-row="middle"] > .ct-container {
		animation: none;
		min-height: var(--qi-header-h);
	}
}

body.qi header#header [data-row="middle"] {
	background-color: transparent;
}

body.qi header#header .ct-container {
	max-width: var(--qi-max-wide);
	padding-inline: var(--qi-gutter);
}

body.qi header#header [data-row="middle"] > .ct-container {
	min-height: var(--qi-header-h);
}

body.qi .site-branding .site-title a {
	font-family: var(--qi-font-head);
	font-weight: 600;
	font-size: 1.4rem;
	letter-spacing: -.02em;
	color: var(--qi-teal-800);
	text-decoration: none;
}

/* The v3 crest badge needs more height than the old flat seal for its ring
   text to resolve: 50px inside the 64px scrolled desktop rail (7px air each
   side), 40px inside the 56px mobile one. */
body.qi .site-logo-container img,
body.qi .site-branding img {
	height: 50px;
	width: auto;
	max-height: 50px;
	/* Kill the inline baseline gap — it pushes the logo ~2px above the bar's
	   true centreline. */
	display: block;
}

/* Blocksy's logo anchor is a few px taller than the img (its --logo-max-height
   box) with the img top-anchored; centre the img inside it so the logo's
   midline matches the hamburger's. */
body.qi .site-logo-container {
	display: flex;
	align-items: center;
	justify-content: flex-start;
}

@media (max-width: 700px) {
	body.qi .site-logo-container img,
	body.qi .site-branding img {
		height: 46px;
		max-height: 46px;
		/* Wide lockup must never collide with the hamburger (~56px + padding
		   each side): cap the width and let the height follow. */
		max-width: calc(100vw - 128px);
		width: auto;
		object-fit: contain;
	}

	/* Keep the lockup on the left rail but centre it VERTICALLY in the bar —
	   it was riding the top edge after the bar compaction. The row needs a
	   real height: with the branding absolutely positioned the row collapses
	   to 0 and top:50% degenerates to the bar's top edge. */
	body.qi header#header [data-row="middle"] {
		position: relative;
		min-height: 56px;
	}
	body.qi header#header [data-row="middle"] .site-branding {
		position: absolute;
		left: 20px;
		top: 50%;
		transform: translateY(-50%);
		margin: 0;
		z-index: 1;
	}
	body.qi .site-branding .site-title a { font-size: 1.15rem; }
}

/* Blocksy pads the branding column for its own default bar height; the compact
   rail supplies its own rhythm. */
body.qi header#header [data-row="middle"] .site-branding,
body.qi header#header [data-row="middle"] .site-logo-container {
	padding-block: 0;
}

/* Anchor targets must clear the sticky bar. */
body.qi :target,
body.qi [id]:not(body):not(html) {
	scroll-margin-top: calc(var(--qi-header-h-scrolled) + 1rem);
}

/* The wordmark already carries the name — no duplicate text title. */
body.qi.wp-custom-logo .site-title-container,
body.qi.has-custom-logo .site-title-container { display: none; }

/* Nav */
body.qi header#header .menu-container > ul > li > a,
body.qi #header-menu-1 .menu > li > a {
	font-family: var(--qi-font-body);
	font-size: .9375rem;
	font-weight: 500;
	letter-spacing: .01em;
	text-transform: none;
	color: var(--qi-ink);
}

body.qi header#header .menu-container > ul > li > a:hover,
body.qi header#header .menu-container > ul > li.current-menu-item > a {
	color: var(--qi-teal-600);
}

body.qi header#header .sub-menu {
	background-color: var(--qi-white);
	border: 1px solid var(--qi-hairline);
	border-radius: var(--qi-radius);
	padding-block: .5rem;
	box-shadow: 0 18px 40px -28px rgba(6, 47, 48, .45);
}

body.qi header#header .sub-menu a {
	font-size: .9rem;
	color: var(--qi-ink);
}

body.qi header#header .sub-menu a:hover { color: var(--qi-teal-600); }

/* Search icon is not part of the design language. */
body.qi header#header .ct-header-search { display: none; }

/* Menu CTA item — a pill, not a full-height column. */
body.qi li.qi-nav-cta {
	display: flex;
	align-items: center;
	margin-left: .85rem;
}

body.qi li.qi-nav-cta > a,
body.qi li.qi-nav-cta > a.ct-menu-link {
	height: auto;
	min-height: 44px;
	align-self: center;
	background-color: var(--qi-teal-600);
	color: var(--qi-ivory) !important;
	border-radius: var(--qi-radius-btn);
	padding: 0 1.4rem !important;
	font-weight: 600;
	line-height: 1;
	transition: background-color .25s var(--qi-ease);
}

body.qi .qi-nav-cta > a:hover {
	background-color: var(--qi-teal-700);
	color: var(--qi-ivory) !important;
}

body.qi .qi-nav-cta > a .ct-menu-link-inner { color: inherit; }

/* Offcanvas / mobile menu — deep teal panel, ivory type, gold accents.
   The Primary menu is assigned to Blocksy's `menu_mobile` location, so this
   panel carries Home / Services (+5 children) / About / Contact / CTA. */
body.qi #offcanvas {
	--theme-palette-color-8: var(--qi-teal-900);
	--theme-palette-color-1: var(--qi-gold);
	--theme-palette-color-2: var(--qi-gold);
	--theme-link-initial-color: var(--qi-ivory);
	--theme-link-hover-color: var(--qi-gold);
	background-color: var(--qi-teal-900);
	color: var(--qi-ivory);
}

body.qi #offcanvas .ct-panel-inner {
	display: flex;
	flex-direction: column;
	min-height: 100%;
	background-color: transparent;
}

body.qi #offcanvas .ct-panel-actions {
	padding: .6rem .75rem;
	border-bottom: 1px solid rgba(244, 239, 230, .12);
}

body.qi #offcanvas .ct-toggle-close {
	color: var(--qi-ivory);
	min-width: 48px;
	min-height: 48px;
}

body.qi #offcanvas .ct-toggle-close .ct-icon {
	fill: currentColor;
	width: 14px;
	height: 14px;
}

body.qi #offcanvas .ct-panel-content {
	flex: 1 1 auto;
	display: flex;
}

/* Blocksy renders an empty desktop-device panel alongside the mobile one; left
   in place it grows and pushes the menu into the middle of the drawer. */
body.qi #offcanvas .ct-panel-content:has(> .ct-panel-content-inner:empty) {
	display: none;
}

/* Blocksy centres the panel body; the menu should start at the top and let
   the CTA hold the bottom. */
body.qi #offcanvas .ct-panel-content-inner {
	display: flex;
	flex-direction: column;
	width: 100%;
	margin: 0;
	padding: .5rem 1.35rem 1.75rem;
}

body.qi #offcanvas nav.mobile-menu {
	flex: 1 1 auto;
	display: flex;
}

body.qi #offcanvas nav.mobile-menu > ul {
	display: flex;
	flex-direction: column;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

body.qi #offcanvas nav.mobile-menu > ul > li {
	border-bottom: 1px solid rgba(244, 239, 230, .12);
}

body.qi #offcanvas .menu-item a.ct-menu-link {
	display: flex;
	align-items: center;
	min-height: 48px;
	padding: .35rem 0;
	font-family: var(--qi-font-body);
	font-size: 1.0625rem;
	font-weight: 500;
	letter-spacing: .005em;
	color: var(--qi-ivory);
	text-decoration: none;
	transition: color .2s var(--qi-ease);
}

body.qi #offcanvas .menu-item a.ct-menu-link:hover,
body.qi #offcanvas .menu-item a.ct-menu-link:focus-visible,
body.qi #offcanvas .current-menu-item > a.ct-menu-link,
body.qi #offcanvas .ct-sub-menu-parent > a.ct-menu-link:hover {
	color: var(--qi-gold);
}

body.qi #offcanvas .ct-sub-menu-parent {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: .5rem;
}

body.qi #offcanvas .ct-toggle-dropdown-mobile {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 48px;
	min-height: 48px;
	color: var(--qi-ivory);
	background: none;
	border: 0;
}

body.qi #offcanvas .ct-toggle-dropdown-mobile .ct-icon { fill: currentColor; }

body.qi #offcanvas .sub-menu {
	margin: 0 0 .5rem;
	padding: 0 0 0 1rem;
	list-style: none;
	border-left: 1px solid rgba(244, 239, 230, .18);
}

body.qi #offcanvas .sub-menu a.ct-menu-link {
	min-height: 44px;
	font-size: .9375rem;
	color: rgba(244, 239, 230, .82);
}

/* Free consultation sits at the foot of the panel as a full-width gold button */
body.qi #offcanvas li.qi-nav-cta {
	display: block;
	margin: auto 0 0;
	padding-top: 1.75rem;
	border-bottom: 0;
}

body.qi #offcanvas li.qi-nav-cta > a.ct-menu-link {
	justify-content: center;
	min-height: 52px;
	padding: 0 1.4rem !important;
	border-radius: var(--qi-radius-btn);
	background-color: var(--qi-gold);
	color: #16181A !important;
	font-weight: 600;
}

body.qi #offcanvas li.qi-nav-cta > a.ct-menu-link:hover {
	background-color: #B8914A;
	color: #16181A !important;
}

/* Brand footer (rendered from functions.php into blocksy:footer:before) */
.qi-footer {
	background: var(--qi-teal-900);
	color: rgba(250, 247, 242, .74);
	padding: clamp(3.5rem, 2.5rem + 4vw, 6rem) var(--qi-gutter) clamp(2.5rem, 2rem + 2vw, 3.5rem);
}

.qi-footer-inner {
	max-width: var(--qi-max);
	margin-inline: auto;
	display: grid;
	gap: clamp(2rem, 1.2rem + 2.5vw, 3.5rem);
	grid-template-columns: 1fr;
}

@media (min-width: 760px) {
	.qi-footer-inner { grid-template-columns: 1.4fr 1fr 1fr; }
}

@media (min-width: 1040px) {
	.qi-footer-inner { grid-template-columns: 1.6fr 1fr .8fr 1fr; }
}

.qi-footer-mark {
	font-family: var(--qi-font-head);
	font-weight: 600;
	font-size: 1.35rem;
	letter-spacing: -.02em;
	color: var(--qi-ivory);
	margin: 0 0 .85rem;
}

.qi-footer-line {
	max-width: 34ch;
	font-size: var(--qi-small);
	line-height: 1.65;
	margin: 0 0 1.5rem;
}

body.qi .qi-footer-mark-link {
	display: inline-block;
	margin: 0 0 .85rem;
	line-height: 0;
}

body.qi img.qi-footer-logo {
	display: block;
	width: 210px;
	max-width: 100%;
	height: auto;
	aspect-ratio: 370 / 64;
}

body.qi .qi-footer h2.qi-footer-head {
	font-family: var(--qi-font-body);
	font-size: .75rem;
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--qi-gold);
	margin: 0 0 1.1rem;
}

.qi-footer ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: .6rem;
}

/* Social icon buttons — hand-drawn inline SVGs, no icon font. */
.qi-footer-social {
	flex-direction: row !important;
	flex-wrap: wrap;
	gap: 12px !important;
}

body.qi .qi-footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border: 1px solid rgba(244, 239, 230, .25);
	border-radius: 12px;
	background-color: transparent;
	color: rgba(250, 247, 242, .85);
	transition: border-color .25s var(--qi-ease), background-color .25s var(--qi-ease),
		color .25s var(--qi-ease);
}

body.qi .qi-footer-social a:hover,
body.qi .qi-footer-social a:focus-visible {
	border-color: var(--qi-gold);
	background-color: rgba(198, 161, 91, .14);
	color: var(--qi-gold);
}

.qi-footer-social svg {
	display: block;
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

body.qi .qi-footer a {
	color: rgba(250, 247, 242, .8);
	font-size: var(--qi-small);
	text-decoration: none;
	transition: color .22s var(--qi-ease);
}

body.qi .qi-footer a:hover { color: var(--qi-gold); }

.qi-footer-note {
	margin: 1.1rem 0 0;
	font-size: .8125rem;
	color: rgba(250, 247, 242, .55);
}

/* Blocksy's copyright row becomes our bottom bar. */
body.qi footer#footer [data-row="bottom"] {
	background-color: var(--qi-teal-900);
	border-top: 1px solid var(--qi-hairline-light);
}

body.qi .ct-footer-copyright {
	font-size: .8125rem;
	color: rgba(250, 247, 242, .6);
	padding-block: 1.4rem;
}

body.qi .ct-footer-copyright a { color: rgba(250, 247, 242, .78); text-decoration: none; }
body.qi .ct-footer-copyright a:hover { color: var(--qi-gold); }
body.qi .ct-footer-copyright .qi-sep { color: var(--qi-gold); opacity: .7; padding-inline: .35rem; }

body.qi footer#footer {
	background-color: var(--qi-teal-900);
	color: rgba(250, 247, 242, .74);
	border-top: 0;
}

body.qi footer#footer .ct-container {
	max-width: var(--qi-max);
	padding-inline: var(--qi-gutter);
}

body.qi footer#footer a { color: rgba(250, 247, 242, .82); text-decoration: none; }
body.qi footer#footer a:hover { color: var(--qi-gold); }

body.qi footer#footer h3,
body.qi footer#footer h4,
body.qi footer#footer .widget-title {
	color: var(--qi-ivory);
	font-family: var(--qi-font-head);
	font-size: 1rem;
	letter-spacing: .02em;
}

/* --------------------------------------------------------------------------
   9. Motion — CSS only, content never depends on it
   -------------------------------------------------------------------------- */

/* Progressive enhancement: only browsers that support scroll-driven
   animations get the reveal. Everything is fully visible otherwise — the
   @supports guard means no element is ever left at opacity 0.

   Two modes:
     .qi-reveal on a single element  → that element fades and rises.
     .qi-reveal on a grid container  → the container stays put and its children
                                       stagger in. Stagger is achieved by
                                       shifting each child's animation-range,
                                       because animation-delay is meaningless on
                                       a scroll timeline.

   Only opacity and transform:translateY() are animated, and never on an <img>
   (caveat 1 in the file header). */

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {

		.qi-reveal,
		body.qi .qi-section-head > *,
		body.qi .qi-mediatext > * {
			animation: qi-reveal-up linear both;
			animation-timeline: view();
			animation-range: entry 5% entry 58%;
		}

		/* Container mode — the wrapper itself must not animate. */
		.qi-reveal.qi-grid,
		.qi-reveal.qi-steps,
		.qi-reveal.qi-stats-grid,
		.qi-reveal.qi-split,
		.qi-reveal.qi-whylist,
		.qi-stagger {
			animation: none;
		}

		.qi-reveal.qi-grid > *,
		.qi-reveal.qi-steps > *,
		.qi-reveal.qi-stats-grid > *,
		.qi-reveal.qi-split > *,
		.qi-reveal.qi-whylist > *,
		.qi-stagger > * {
			animation: qi-reveal-up linear both;
			animation-timeline: view();
			animation-range: entry 4% entry 50%;
		}

		/* Staggered ranges — later children start (and finish) later. */
		.qi-reveal.qi-grid > :nth-child(2),
		.qi-reveal.qi-steps > :nth-child(2),
		.qi-reveal.qi-stats-grid > :nth-child(2),
		.qi-reveal.qi-split > :nth-child(2),
		.qi-reveal.qi-whylist > :nth-child(2),
		.qi-stagger > :nth-child(2),
		body.qi .qi-section-head > :nth-child(2),
		body.qi .qi-mediatext > :nth-child(2) {
			animation-range: entry 10% entry 56%;
		}

		.qi-reveal.qi-grid > :nth-child(3),
		.qi-reveal.qi-steps > :nth-child(3),
		.qi-reveal.qi-stats-grid > :nth-child(3),
		.qi-reveal.qi-whylist > :nth-child(3),
		.qi-stagger > :nth-child(3),
		body.qi .qi-section-head > :nth-child(3) {
			animation-range: entry 16% entry 62%;
		}

		.qi-reveal.qi-grid > :nth-child(4),
		.qi-reveal.qi-steps > :nth-child(4),
		.qi-reveal.qi-whylist > :nth-child(4),
		.qi-stagger > :nth-child(4) {
			animation-range: entry 22% entry 68%;
		}

		.qi-reveal.qi-grid > :nth-child(5),
		.qi-reveal.qi-steps > :nth-child(5),
		.qi-stagger > :nth-child(5) {
			animation-range: entry 28% entry 74%;
		}

		.qi-reveal.qi-grid > :nth-child(n + 6),
		.qi-stagger > :nth-child(n + 6) {
			animation-range: entry 34% entry 80%;
		}

		/* Sticky things must not be transformed: a transform on an ancestor
		   creates a containing block and breaks position:sticky. */
		.qi-reveal.qi-split > .qi-sticky-col,
		.qi-steps-stack > .qi-step,
		.qi-why-media {
			animation: none;
		}
	}
}

@keyframes qi-reveal-up {
	from { opacity: 0; transform: translateY(22px); }
	to { opacity: 1; transform: none; }
}

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

/* --------------------------------------------------------------------------
   10. Small screens
   Everything below is the mobile pass. Three bands:
     · <= 782px  reading floors and touch sizing (phones and portrait tablets)
     · <= 560px  full-width actions and the tightest layout band
     · coarse pointer / short viewport  motion simplification
   Desktop layout is deliberately untouched.
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
	body.qi .qi-hero.wp-block-cover {
		padding-block: clamp(4rem, 3rem + 6vw, 6rem);
		min-height: min(78vh, 680px);
	}
}

/* 10a. Reading floors -------------------------------------------------------
   Nothing that carries a sentence may sit below 16px on a phone. Genuine
   labels keep their designed size and are listed as exceptions at the end. */

@media (max-width: 782px), (max-height: 500px) and (pointer: coarse) {
	:root {
		/* Drives card copy, footer copy, legal dl, FAQ answers, help text. */
		--qi-small: 1rem;
	}

	body.qi .qi-photo-tile-body p,
	body.qi .qi-imagebreak-note,
	body.qi .qi-service-tags li,
	body.qi .qi-footer-note,
	body.qi .ct-footer-copyright,
	body.qi .fluentform .ff-el-help-message,
	body.qi .fluentform .error.text-danger,
	body.qi .fluentform .ff-el-is-error .error {
		font-size: .9375rem;
	}

	body.qi .qi-trustrow {
		font-size: .9375rem;
	}

	body.qi .qi-link-arrow,
	body.qi span.qi-link-arrow,
	body.qi .qi-btn,
	body.qi .qi-btn-outline,
	body.qi .qi-btn-gold,
	body.qi .qi-btn-ivory,
	body.qi .wp-block-button[class*="qi-btn"] > .wp-block-button__link,
	body.qi #offcanvas .sub-menu a.ct-menu-link,
	body.qi .qi-contact-social a,
	body.qi .fluentform .ff-btn-submit,
	body.qi .fluentform .ff-btn.ff-btn-submit {
		font-size: 1rem;
	}

	body.qi .fluentform .ff-el-input--label label {
		font-size: .875rem;
		letter-spacing: .08em;
	}
}

/* 10b. Touch targets --------------------------------------------------------
   Every control a thumb has to find gets 44px in its smaller axis. Inline
   links inside running prose are exempt (WCAG 2.5.8) and are left alone so the
   text rhythm is not broken. */

@media (max-width: 782px), (pointer: coarse) {
	/* The hamburger was an 18px icon with no hit area at all. */
	body.qi header#header .ct-header-trigger,
	body.qi header#header button.ct-header-trigger {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		min-width: 44px;
		min-height: 44px;
		margin-right: -.35rem;
	}

	body.qi .qi-footer-social a {
		width: 44px;
		height: 44px;
	}

	/* Footer columns: turn 19px text rows into 44px list rows. */
	body.qi .qi-footer-col li > a,
	body.qi .qi-footer-col ul > li > a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	body.qi .qi-footer-col li {
		margin-bottom: 0;
	}

	/* Copyright legal links sit on one wrapped row; pad them apart vertically
	   so neighbouring targets do not merge. */
	body.qi .ct-footer-copyright a {
		display: inline-block;
		padding-block: .8rem;
	}

	/* Card headings are the primary target on a card. Vertical padding on an
	   inline anchor grows the hit rectangle without altering the line box, so
	   the card layout is identical while the target clears 44px. */
	body.qi .qi-card h2 > a,
	body.qi .qi-card h3 > a,
	body.qi .qi-card h4 > a,
	body.qi .qi-tile h3 > a,
	body.qi a.qi-contact-value {
		padding-block: .7rem;
	}

	/* Standalone arrow links are calls to action, not prose links. */
	body.qi a.qi-link-arrow {
		min-height: 44px;
		padding-block: .5rem;
		align-items: center;
	}

	/* Consent manager accordion on the cookie policy page. */
	body.qi button.cmplz-category-toggle {
		min-width: 44px;
		min-height: 44px;
	}

	/* Bigger consent box; the label is already the full hit area. */
	body.qi .fluentform .ff-el-form-check-label input[type="checkbox"],
	body.qi .fluentform .ff-el-form-check input[type="checkbox"] {
		width: 22px;
		height: 22px;
	}

	body.qi .fluentform .ff-el-form-check-label {
		min-height: 44px;
		align-items: center;
	}
}

/* 10c. Full-width actions ---------------------------------------------------
   Below 560px a pair of pills side by side leaves each one too narrow to read
   and too close to its neighbour. They stack full width instead. */

@media (max-width: 560px) {
	body.qi .wp-block-buttons {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: .75rem;
		width: 100%;
	}

	body.qi .wp-block-buttons > .wp-block-button {
		width: 100%;
		max-width: none;
		margin: 0;
	}

	body.qi .wp-block-buttons > .wp-block-button > .wp-block-button__link {
		display: flex;
		width: 100%;
		min-height: 52px;
	}

	body.qi .fluentform .ff-btn-submit,
	body.qi .fluentform .ff-btn.ff-btn-submit {
		width: 100%;
	}

	/* Eyebrow tracking at 13px overruns a 335px rail on the longer labels. */
	body.qi .qi-eyebrow {
		letter-spacing: .09em;
		flex-wrap: wrap;
	}
}

/* 10d. Motion on touch ------------------------------------------------------
   Parallax and pinned columns are desktop affordances. On a coarse pointer the
   drift costs raster work for an effect nobody is tracking with a mouse, and a
   pinned column on a short viewport traps the content beside it. */

@media (pointer: coarse) {
	.qi-parallax {
		animation: none !important;
		top: 0;
		bottom: 0;
	}
}

/* The stacked-steps pin had a width guard but no height guard, unlike the
   other two pinned components. A 900x600 window would pin four tall cards
   under the header with nowhere to go. */
@media (min-width: 900px) and (max-height: 759px) {
	.qi-steps-stack > .qi-step {
		position: static;
	}
}

/* 10e. Deliberate exceptions to the 16px floor -----------------------------
   These are labels, not prose: uppercase, tracked, and read as UI furniture.
   Raising them to 16px would make them compete with the copy they caption.
     .qi-eyebrow (13px)        section eyebrows
     .qi-stat-label (13px)     figure captions under stat numerals
     .qi-timeline-year (13px)  timeline rail labels
     .qi-contact-label (12px)  contact list keys
     .qi-footer-head (12px)    footer column headings
     .qi-card-index (12px)     card numerals
   -------------------------------------------------------------------------- */
