/*
 * Pure Air and Heating — site layer
 *
 * Two jobs:
 *   1. Accessibility rules theme.json cannot express (sections 1-12).
 *   2. The visual design layer: bands, header row, cards, data scale (13+).
 *
 * Every rule in 1-12 exists because of a stated constraint in CLAUDE.md.
 * Nothing in 13+ is allowed to trade one away.
 */

/* ---------------------------------------------------------------------------
 * 1. Tokens CSS needs but theme.json does not emit
 * ------------------------------------------------------------------------- */

:root {
	--pa-focus-ring: var( --wp--custom--focus-ring-width, 3px );
	--pa-min-tap: var( --wp--custom--min-tap-target, 48px );
	--pa-hero-col: var( --wp--custom--hero-column, 620px );
}

/* ---------------------------------------------------------------------------
 * 2. Skip link — first tab stop on every page
 * ------------------------------------------------------------------------- */

.pa-skip-link {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 1000;
	padding: 0.85rem 1.25rem;
	background-color: var( --wp--preset--color--ink );
	color: var( --wp--preset--color--base );
	font-size: var( --wp--preset--font-size--medium );
	font-weight: 700;
	text-decoration: underline;
	transform: translateY( -120% );
}

.pa-skip-link:focus {
	transform: translateY( 0 );
}

/* ---------------------------------------------------------------------------
 * 3. Focus states — every interactive element has a visible one
 *
 * Outline, so it never shifts layout.
 * ------------------------------------------------------------------------- */

:where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible {
	outline: var( --pa-focus-ring ) solid var( --wp--preset--color--ink );
	outline-offset: 2px;
	border-radius: 3px;
}

/* Navy disappears on navy, so dark bands switch to gold (10.18:1 on navy). */
.has-ink-background-color :where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible,
.pa-band--dark :where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible,
.pa-call-bar :where( a, button ):focus-visible {
	outline-color: var( --wp--preset--color--gold );
}

@supports not selector( :focus-visible ) {
	:where( a, button, input, select, textarea, summary, [tabindex] ):focus {
		outline: var( --pa-focus-ring ) solid var( --wp--preset--color--ink );
		outline-offset: 2px;
	}
}

/* ---------------------------------------------------------------------------
 * 4. Tap targets — 48px minimum for controls
 * ------------------------------------------------------------------------- */

.wp-block-button__link,
.wp-block-navigation .wp-block-navigation-item__content,
.pa-phone a {
	min-height: var( --pa-min-tap );
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
}

/*
 * Core ships the nav toggles at ~24px and the submenu chevron at ~10px. The
 * chevron carries aria-expanded, so it is the control a keyboard or switch
 * user operates. Neither can stay at finger-miss size.
 */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: var( --pa-min-tap );
	min-height: var( --pa-min-tap );
}

.wp-block-navigation__responsive-container-open svg,
.wp-block-navigation__responsive-container-close svg {
	width: 28px;
	height: 28px;
}

.wp-block-navigation-submenu__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 0.4rem;
}

.wp-block-navigation-submenu__toggle svg {
	width: 16px;
	height: 16px;
}

.wp-block-navigation__submenu-container {
	border-width: 1.5px;
	border-color: var( --wp--preset--color--line );
	box-shadow: var( --wp--preset--shadow--hover );
}

/* ---------------------------------------------------------------------------
 * 5. Phone — readable text, every page, every breakpoint
 * ------------------------------------------------------------------------- */

.pa-phone {
	margin: 0;
	line-height: 1.1;
}

.pa-phone a {
	font-size: 1.25rem; /* 20px, per the design spec */
	font-weight: 700;
	line-height: 1.1;
	text-decoration: none;
	color: var( --wp--preset--color--ink );
	white-space: nowrap;
}

.pa-phone a:hover,
.pa-phone a:focus {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
}

/* ---------------------------------------------------------------------------
 * 5a. Logo
 *
 * Height is capped so an oversized upload cannot push the header around, and
 * intrinsic width/height on the <img> reserve the box to hold CLS at 0.
 * ------------------------------------------------------------------------- */

.pa-logo-link {
	display: inline-block;
	line-height: 0;
}

.pa-logo {
	width: auto;
	height: auto;
	max-width: 100%;
}

.pa-logo--header {
	height: 44px;
}

.pa-logo--footer {
	height: 40px;
	margin-bottom: 0.25rem;
}

@media ( max-width: 480px ) {
	.pa-logo--header {
		height: 36px;
	}
}

/* When the wordmark is present it is the site name; drop the text duplicate. */
.wp-block-group:has( .pa-logo--header ) .wp-block-site-title,
.wp-block-group:has( .pa-logo--footer ) > .wp-block-heading {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------------
 * 5b. Text on dark bands
 *
 * theme.json pins headings and links to navy, which is correct on light and
 * invisible on navy. Both flip here. Body copy inherits white from the band.
 * ------------------------------------------------------------------------- */

.has-ink-background-color :is( h1, h2, h3, h4, h5, h6 ),
.pa-band--dark :is( h1, h2, h3, h4, h5, h6 ) {
	color: var( --wp--preset--color--base );
}

.has-ink-background-color a:not( .wp-block-button__link ),
.pa-band--dark a:not( .wp-block-button__link ) {
	color: var( --wp--preset--color--gold );
}

.has-ink-background-color .wp-block-button__link,
.pa-band--dark .wp-block-button__link {
	color: var( --wp--preset--color--base );
}

/* ---------------------------------------------------------------------------
 * 5c. Secondary button on dark
 *
 * Orange is reserved for the primary action. The secondary action on a navy
 * band is an outline, never a second orange.
 * ------------------------------------------------------------------------- */

.pa-button-on-dark .wp-block-button__link {
	color: var( --wp--preset--color--base );
	border: 2px solid var( --wp--preset--color--base );
	background-color: transparent;
}

.pa-button-on-dark .wp-block-button__link:hover,
.pa-button-on-dark .wp-block-button__link:focus {
	color: var( --wp--preset--color--ink );
	background-color: var( --wp--preset--color--base );
	border-color: var( --wp--preset--color--base );
}

/* ---------------------------------------------------------------------------
 * 6. Fixed mobile call bar — under 640px, visible at all times
 * ------------------------------------------------------------------------- */

.pa-call-bar {
	display: none;
}

@media ( max-width: 639.98px ) {
	.pa-call-bar {
		position: fixed;
		inset: auto 0 0 0;
		z-index: 900;
		display: block;
		padding: 0.6rem 0.75rem calc( 0.6rem + env( safe-area-inset-bottom, 0px ) );
		background-color: var( --wp--preset--color--ink );
		box-shadow: var( --wp--preset--shadow--bar );
	}

	.pa-call-bar .wp-block-button__link {
		width: 100%;
		min-height: 56px;
	}

	body {
		padding-bottom: calc( 84px + env( safe-area-inset-bottom, 0px ) );
	}
}

/* ---------------------------------------------------------------------------
 * 7. Photography scrim — RETAINED, CURRENTLY UNUSED
 *
 * No photographs are available, and the design is typography-only by
 * decision (2026-08-16). This utility stays so that when photography does
 * arrive it can be reintroduced without rebuilding the hero pattern: add
 * .pa-photo-backing to the hero group and set a background image on it.
 * See the RESTORING PHOTOGRAPHY notes in patterns/hero-call.php.
 * ------------------------------------------------------------------------- */

.pa-photo-backing {
	position: relative;
	isolation: isolate;
}

.pa-photo-backing::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba( 11, 42, 69, 0.92 );
}

/* ---------------------------------------------------------------------------
 * 8. Borders and rules — 1.5px minimum
 * ------------------------------------------------------------------------- */

hr.wp-block-separator:not( .is-style-dots ) {
	border-top-width: 1.5px;
	border-bottom-width: 0;
	opacity: 1;
}

.wp-block-table :where( td, th ) {
	border-width: 1.5px;
}

/* ---------------------------------------------------------------------------
 * 9. Text floor — nothing below 14px, including legal copy
 * ------------------------------------------------------------------------- */

small,
.pa-legal,
.wp-block-post-date,
figcaption,
.wp-element-caption {
	font-size: var( --wp--preset--font-size--x-small );
	line-height: 1.6;
	color: var( --wp--preset--color--muted );
}

/* ---------------------------------------------------------------------------
 * 10. Motion — transform and opacity only, and only when allowed
 * ------------------------------------------------------------------------- */

.wp-block-button__link,
.pa-skip-link,
a {
	transition: background-color 120ms ease, border-color 120ms ease,
		color 120ms ease, box-shadow 120ms ease;
}

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

/* ---------------------------------------------------------------------------
 * 11. Increased contrast preference
 * ------------------------------------------------------------------------- */

@media ( prefers-contrast: more ) {
	:root {
		--wp--preset--color--muted: #22262C;
		--wp--preset--color--line: #14161F;
	}

	.wp-block-post-content a,
	main a {
		text-decoration: underline;
		text-underline-offset: 2px;
	}

	.wp-block-button__link {
		border-width: 2px;
	}
}

@media ( forced-colors: active ) {
	.wp-block-button__link {
		border: 2px solid ButtonText;
	}

	.pa-call-bar {
		border-top: 2px solid ButtonText;
	}
}

/* ---------------------------------------------------------------------------
 * 12. Screen-reader-only utility
 * ------------------------------------------------------------------------- */

.pa-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	white-space: nowrap;
	border: 0;
}


/* ===========================================================================
 * 13. DESIGN LAYER — Claude Design mockup (homepage-target.html)
 *
 * Values are lifted from the mockup's inline styles, not approximated.
 * Where a value conflicts with a CLAUDE.md floor the mockup wins, per
 * instruction, and the conflict is recorded in CONFLICTS.md with its
 * measured number.
 * ======================================================================== */

:root {
	--pa-ff-display: var( --wp--preset--font-family--display );
	--pa-ff-body: var( --wp--preset--font-family--body );
	--pa-ff-mono: var( --wp--preset--font-family--mono );
	--pa-ink: #14161B;
	--pa-cream: #FBF7F1;
	--pa-sand: #F1EAE0;
	--pa-orange: #C2410C;
	--pa-hair-light: rgba( 20, 22, 27, 0.18 );
	--pa-hair-dark: rgba( 251, 247, 241, 0.16 );
	/*
	 * THE SITE-WIDE CONTAINER (2026-10-23). Every section's content, the header
	 * row and the heroes use these two values, so every left edge is the same.
	 *
	 *   --pa-gutter  the space between the screen edge and the content: 40px up to
	 *                1280px wide, growing 1px per 13px of width to 64px at 1600px
	 *                and above. (It was a fixed 40px, in 206 places.)
	 *   --pa-shell   the widest the content column gets, 2048px. Up to 2176px of
	 *                screen the column is fluid (screen - 2 x gutter); beyond that
	 *                it is centred. It was 1280px.
	 *
	 * Only the OUTER container widens. Running text keeps its own measure
	 * (max-width in em or ch on each paragraph), so a line never gets longer than
	 * it was.
	 */
	--pa-gutter: clamp( 40px, calc( 40px + ( 100vw - 1280px ) * 0.075 ), 64px );
	--pa-shell: 2048px;
	--pa-measure: 680px;

	/*
	 * These five were used in rules before they were ever defined, so they
	 * silently resolved to nothing and the colour fell back to inherited. It is
	 * why the mobile menu's section labels rendered ink instead of tan. Values
	 * mirror the theme.json palette; keep them in step with it.
	 */
	--pa-muted: #4A505C;   /* body copy on cream — 7.59:1 */
	--pa-dim: #646A76;     /* legal and micro copy on cream — 5.09:1 */
	--pa-tan: #74644F;     /* eyebrows on sand — 4.78:1 */
	--pa-ondark: #B9BDC6;  /* body copy on ink */
	--pa-ondark-dim: #8B909B; /* labels on ink — 5.65:1 */
	--pa-tint: #F5A97F;    /* warm accent on ink */

	/*
	 * Orange comes in two values and they are not interchangeable.
	 *   --pa-orange     #C2410C — FILLS only. White on it measures 5.18:1.
	 *   --pa-orange-ink #A5350A — orange TEXT on a light background.
	 * #C2410C as text measures 4.34:1 on sand, which is an AA failure, and only
	 * 4.85:1 on cream. The darker value clears AA on every surface we use
	 * (5.65:1 sand, 6.32:1 cream). Never set text to --pa-orange on light.
	 */
	--pa-orange-ink: #A5350A;
}

body { background: var( --pa-cream ); -webkit-font-smoothing: antialiased; }
::selection { background: var( --pa-orange ); color: #fff; }

.pa-shell { max-width: var( --pa-shell ); margin: 0 auto; }

/* Mono eyebrow / data label */
.pa-mono {
	font-family: var( --pa-ff-mono );
	text-transform: uppercase;
	margin: 0;
}
/*
 * Two classes each on purpose. Section rules like `.pa-price__cell p` and
 * `.pa-svc__aside p` are (0,1,1) and would otherwise beat a single-class
 * utility, which silently left every eyebrow at body size.
 */
.pa-mono.pa-eyebrow { font-size: 14px; letter-spacing: 0.16em; }
.pa-mono.pa-label   { font-size: 14px; letter-spacing: 0.14em; }
.pa-mono.pa-micro   { font-size: 14px; letter-spacing: 0.1em; }

/* --- 13a. Header ---------------------------------------------------------- */

.pa-hdr {
	position: sticky; top: 0; z-index: 40;
	background: rgba( 251, 247, 241, 0.95 );
	backdrop-filter: blur( 12px );
	border-bottom: 1px solid rgba( 20, 22, 27, 0.1 );
}
.pa-hdr__row {
	max-width: 1400px; margin: 0 auto; padding: 10px 24px; min-height: 82px;
	display: flex; align-items: center; flex-wrap: wrap; row-gap: 8px; column-gap: 12px;
}
/*
 * LOGO AND PAGE CONTENT SHARE ONE LEFT EDGE, AND THE RIGHT GROUP THE RIGHT EDGE
 * (2026-10-23). Every section's content sits in a column of --pa-shell with a
 * --pa-gutter either side (40px up to 1280, 64px from 1600). From 1263px up the
 * header row is the same column with the same gutter on both sides, so the logo
 * is on the content's left edge and the right-hand buttons on its right edge at
 * every width: 40 at 1280, 52 at 1440, 64 from 1600. (It used to be 16px
 * narrower on the right, putting the buttons 16px past the content edge.)
 * Below 1263px the compact header keeps its own 24px / 20px gutters.
 *
 * The mockups themselves do not line up (1400px / 32px header, 1280px / 40px
 * content); this is a decision to make them agree, not a copy of the mockup.
 */
@media ( min-width: 1263px ) {
	/* Same gutter both sides: the logo on the content's left edge, the buttons on its right edge. */
	.pa-hdr__row { max-width: var( --pa-shell ); padding-left: var( --pa-gutter ); padding-right: var( --pa-gutter ); }
}
/*
 * THREE ZONES (2026-10-23): logo pinned left, primary nav centred, phone + Start
 * your quote + Book now pinned right, as on sunrun.com. The row is a grid.
 *
 * TWO MODES, because the right group (403px) is wider than the logo (159px) and
 * the nav cannot be centred on the PAGE until there is room for the right group
 * on both sides of it:
 *   BETWEEN (default, 1263px up): columns `auto 1fr auto`, nav centred in the
 *     space between the logo and the right group. It sits ( R - L ) / 2 = 122px
 *     left of the page centre, which is the price of not collapsing early.
 *   PAGE-CENTRED (1600px up): columns `1fr auto 1fr`, nav on the page's centre
 *     line. 1600 is where the nav clears the phone number by 24px or more
 *     (measured: 1560 -> 10px, 1580 -> 18px, 1600 -> 27px); below it the nav
 *     would touch the right group.
 * `1fr auto 1fr` ALONE is not enough: when the right group does not fit on both
 * sides, the grid shoves the nav against it instead of centring between. Hence
 * two modes and a measured switch-over.
 *
 * ZONE GAP 4px (it was 12px). The right group now ends on the content's right
 * edge (gutter 40 at 1280), not 16px past it, which costs the row 16px:
 * requirement 1263 -> 1279. The two column gaps (12 -> 4) pay it back exactly,
 * so the single-row requirement is 1263 and the collapse is still 1262. The nav
 * links carry 6px of padding on each side, so label-to-logo and label-to-phone
 * are never closer than 10px.
 *
 * MEASURED 2026-10-23 (bisection with collapse forced off; fits = no overlap,
 * gaps >= 4px, right group inside the content edge):
 *   English     requirement 1263   collapse <= 1262   page-centred from 1600
 *   Spanish     requirement 1414   compact <= 1432    page-centred from 1770
 *   Portuguese  requirement 1411   compact <= 1432    page-centred from 1770
 * (es/pt: nav shown from 1433 = requirement + ~19px; page-centring measured at
 * 1759 and 1766, 1770 is the round number above both.)
 * Re-measure all of these if a label, an item, a type size or a gap changes.
 */
@media ( min-width: 1263px ) {
	body:not( .pa-lang-es ):not( .pa-lang-pt ) .pa-hdr__row { display: grid; grid-template-columns: auto 1fr auto; column-gap: 4px; }
	body:not( .pa-lang-es ):not( .pa-lang-pt ) .pa-wordmark { justify-self: start; }
	body:not( .pa-lang-es ):not( .pa-lang-pt ) .pa-nav { flex-wrap: nowrap; justify-self: center; }
	body:not( .pa-lang-es ):not( .pa-lang-pt ) .pa-hdr__actions { margin-left: 0; justify-self: end; flex-wrap: nowrap; }
}
@media ( min-width: 1600px ) {
	body:not( .pa-lang-es ):not( .pa-lang-pt ) .pa-hdr__row { grid-template-columns: 1fr auto 1fr; }
}
/* Spanish and Portuguese: the same two modes, starting where their nav starts (1433px; the compact menu is used below, see the es/pt header note). */
@media ( min-width: 1433px ) {
	.pa-lang-es .pa-hdr__row, .pa-lang-pt .pa-hdr__row { display: grid; grid-template-columns: auto 1fr auto; column-gap: 4px; }
	.pa-lang-es .pa-wordmark, .pa-lang-pt .pa-wordmark { justify-self: start; }
	.pa-lang-es .pa-nav, .pa-lang-pt .pa-nav { flex-wrap: nowrap; justify-self: center; }
	.pa-lang-es .pa-hdr__actions, .pa-lang-pt .pa-hdr__actions { margin-left: 0; justify-self: end; flex-wrap: nowrap; }
}
@media ( min-width: 1770px ) {
	.pa-lang-es .pa-hdr__row, .pa-lang-pt .pa-hdr__row { grid-template-columns: 1fr auto 1fr; }
}
.pa-wordmark {
	display: flex; align-items: center; gap: 12px; text-decoration: none; flex-shrink: 0;
}
.pa-wordmark__text {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 25px;
	letter-spacing: 0.22em; color: var( --pa-ink );
}
.pa-wordmark__rule { width: 1px; height: 26px; background: rgba( 20, 22, 27, 0.2 ); }

.pa-nav { display: flex; align-items: center; flex-wrap: wrap; min-width: 0;
	font-size: 16px; font-weight: 500; }
.pa-nav__item { position: relative; display: flex; align-items: center; }
.pa-nav__link {
	padding: 12px 6px; min-height: var( --pa-min-tap ); box-sizing: border-box;
	color: #3A3F49; text-decoration: none;
	display: flex; align-items: center; gap: 6px; white-space: nowrap;
	background: none; border: 0; font: inherit; cursor: pointer;
}
.pa-nav__link:hover, .pa-nav__item:focus-within > .pa-nav__link { color: var( --pa-orange-ink ); }
.pa-nav__caret { font-size: 14px; opacity: 0.55; }

/* CSS-only dropdown: hover and focus-within, no script. */
.pa-menu {
	position: absolute; top: 100%; left: 8px; min-width: 268px;
	background: var( --pa-ink ); padding: 10px 0;
	box-shadow: 0 18px 44px rgba( 20, 22, 27, 0.28 );
	opacity: 0; visibility: hidden; transform: translateY( -4px );
	transition: opacity 120ms ease, transform 120ms ease;
}
.pa-nav__item:hover > .pa-menu,
.pa-nav__item:focus-within > .pa-menu { opacity: 1; visibility: visible; transform: none; }

/*
 * ESCAPE DISMISSAL. assets/js/nav.js sets data-pa-dismissed on the item; this
 * closes the panel while focus is still inside it, which the rule above would
 * otherwise keep open.
 *
 * (0,2,0) — exactly the same weight as `.pa-nav__item:focus-within > .pa-menu`
 * — so it wins only by being declared after it. Do not move it above, and do
 * not "tidy" it with !important; the equal-specificity-later-wins arrangement
 * is deliberate so a future state rule can still override this one the same
 * way.
 */
.pa-nav__item[data-pa-dismissed] > .pa-menu { opacity: 0; visibility: hidden; transform: translateY( -4px ); }
.pa-menu a {
	display: block; padding: 12px 22px; color: #DFE2E7; text-decoration: none;
	font-size: 16px; white-space: nowrap;
}
.pa-menu a:hover { color: #fff; background: rgba( 251, 247, 241, 0.08 ); text-decoration: none; }
.pa-menu--wide { min-width: 470px; column-count: 2; column-gap: 0; padding: 14px 0; }
.pa-menu__note {
	display: block; padding: 12px 22px 4px; color: #8B909B;
	font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase;
}
/*
 * Mockup spacing: 10px between the actions, with the phone given a little extra
 * breathing room before the first button.
 */
.pa-hdr__actions {
	margin-left: auto; display: flex; align-items: center;
	flex-wrap: wrap; gap: 8px; flex-shrink: 0;
}
/* Tap-to-call: 28px tall was well under the control floor on touch screens. */
.pa-hdr__tel {
	display: inline-flex; align-items: center;
	min-height: var( --pa-min-tap ); margin-right: 0;
}

/*
 * Secondary action: outlined ink, so "Book now" keeps the only filled orange
 * in the header and stays the highest-contrast thing in it.
 * Font size is 16px rather than the mockup's 14.5px, to match the nav size
 * raised for legibility. Padding, radius, weight and gap are the mockup's.
 */
/*
 * .pa-hdr__quote WAS gone and is back. The desktop header carried a "Start
 * Your Quote" button until 2026-08-24, when it was removed to buy 171px of
 * header width. It was restored on 2026-09-03 on instruction, as "Start your
 * quote", and the width was bought back by geometry instead — see the
 * breakpoint history further down. It is hidden below 900px, where the mobile
 * menu panel carries it.
*/
.pa-hdr__tel {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 18px;
	color: var( --pa-ink ); text-decoration: none; white-space: nowrap;
}
.pa-hdr__cta {
	display: inline-flex; align-items: center; justify-content: center;
	min-height: var( --pa-min-tap ); box-sizing: border-box;
	background: var( --pa-orange ); color: #fff; padding: 13px 16px; border-radius: 2px;
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 16px;
	text-decoration: none; white-space: nowrap;
}
.pa-hdr__cta:hover { background: #A5350A; color: #fff; text-decoration: none; }
/*
 * The outlined sibling, restored 2026-09-03. Same box as .pa-hdr__cta so the
 * two sit on one baseline; outlined rather than filled so the orange one stays
 * the single primary action in the row.
 */
.pa-hdr__quote {
	display: inline-flex; align-items: center; justify-content: center;
	min-height: var( --pa-min-tap ); box-sizing: border-box;
	/*
	 * INK ON CREAM, not the on-dark pair. This shipped for about ten minutes
	 * as `--pa-hair-dark` border + `--pa-cream` text, which is cream on a cream
	 * header: measured 1.00:1, text AND border, i.e. an invisible button. The
	 * check that missed it asked whether the element had a box, not whether it
	 * could be seen — the header is a LIGHT surface and every other control in
	 * it uses ink.
	 */
	/*
	 * The border is its OWN value, not --pa-hair-light. That token is a hairline
	 * for dividers, and at 0.18 alpha it measured 1.46:1 against the header —
	 * below the 3:1 that WCAG 1.4.11 asks of a control boundary, and visibly
	 * the button read as a plain text link beside the filled one. The outline is
	 * the only thing that says "button" here, so it has to clear the floor.
	 */
	border: 1px solid rgba( 20, 22, 27, 0.46 ); color: var( --pa-ink );
	padding: 13px 15px; border-radius: 2px;
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 16px;
	text-decoration: none; white-space: nowrap;
}
.pa-hdr__quote:hover { background: rgba( 20, 22, 27, 0.06 ); color: var( --pa-ink ); text-decoration: none; }

/*
 * Header collapse. This was missing entirely — the rule that hid the nav below
 * 900px belonged to the previous design layer and went with it, so the nav had
 * been wrapping onto a second row instead of collapsing.
 *
 * Below 900px: logo, phone and Book now. The secondary button goes first
 * because /pricing/ is reachable from the footer and from the price band on
 * every page.
 * Below 420px: Book now goes too — the fixed call bar owns the bottom of the
 * screen at that width and is the better action anyway.
 */
/* --- Booking modal buttons ------------------------------------------------
 * Any [data-pa-book] anchor opens the Housecall Pro modal. Class is pa-bookbtn:
 * .pa-book is taken by the CTA call band. The spinner shows
 * while the embed script is being fetched on first click, so the click never
 * feels dead. It inherits currentColor, so the same rule serves the outlined
 * header button and the hero ghost button.
 */
.pa-bookbtn {
	display: inline-flex; align-items: center; justify-content: center; gap: 9px;
	min-height: var( --pa-min-tap ); box-sizing: border-box;
}
.pa-bookbtn__spin {
	display: none; width: 14px; height: 14px; flex: none;
	border: 2px solid currentColor; border-right-color: transparent;
	border-radius: 50%; opacity: 0.75;
}
.pa-bookbtn.is-loading .pa-bookbtn__spin { display: block; animation: pa-spin 0.6s linear infinite; }
.pa-bookbtn.is-loading .pa-bookbtn__label { opacity: 0.8; }
.pa-bookbtn.is-loading { cursor: progress; }

@keyframes pa-spin { to { transform: rotate( 360deg ); } }

@media ( prefers-reduced-motion: reduce ) {
	.pa-bookbtn.is-loading .pa-bookbtn__spin { animation: pa-fade 1s ease-in-out infinite alternate; }
	@keyframes pa-fade { from { opacity: 0.25; } to { opacity: 0.9; } }
}

/* --- Mobile menu ----------------------------------------------------------
 * <details>-based, so it works without script. Hidden where the desktop nav is
 * shown (1263px up in English, 1433px up on /es/ and /pt/).
 */
.pa-mnav { display: none; }
.pa-mnav__btn {
	list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 9px;
	min-height: var( --pa-min-tap ); box-sizing: border-box;
	padding: 10px 14px; border: 1px solid var( --pa-ink ); border-radius: 2px;
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 16px; color: var( --pa-ink );
}
.pa-mnav__btn::-webkit-details-marker { display: none; }
.pa-mnav__bars {
	width: 17px; height: 11px; flex: none;
	border-top: 2px solid currentColor; border-bottom: 2px solid currentColor;
	position: relative;
}
.pa-mnav__bars::after {
	content: ""; position: absolute; left: 0; right: 0; top: 50%;
	margin-top: -1px; height: 2px; background: currentColor;
}
.pa-mnav[open] .pa-mnav__word::after { content: " ×"; }

/*
 * Belt and braces: a closed <details> still gave its children layout boxes
 * here, and the absolutely-positioned panel pushed the document 1px wide at
 * 900px. Hiding it outright when closed removes the box entirely.
 */
.pa-mnav:not( [open] ) .pa-mnav__panel { display: none; }

/*
 * THE PANEL, WITHOUT SCRIPT: the old dropdown under the header with every
 * section stacked (section name as a small label, links under it). The
 * drill-down controls (close, back, chevron rows) need script and are hidden.
 * Everything below `html.pa-js` is the enhanced version.
 */
.pa-mnav__panel {
	position: absolute; left: 0; right: 0; top: 100%;
	max-height: calc( 100vh - 82px ); overflow-y: auto;
	background: var( --pa-cream ); border-top: 1px solid var( --pa-hair-light );
	border-bottom: 1px solid var( --pa-ink );
	padding: 22px 32px 28px; box-shadow: 0 18px 30px rgba( 20, 22, 27, 0.12 );
}
.pa-mnav__stage { display: flex; flex-direction: column; }
.pa-mnav__screen--root { display: contents; }
.pa-mnav__foot { order: 99; display: grid; gap: 10px; margin-top: 24px; }
.pa-mnav__list { list-style: none; margin: 0; padding: 0; }
.pa-mnav__title {
	font-family: var( --pa-ff-body ); font-weight: 400; font-size: 14px; letter-spacing: 0.12em;
	text-transform: uppercase; color: var( --pa-tan ); margin: 20px 0 8px;
}
.pa-mnav__row {
	display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; box-sizing: border-box;
	padding: 11px 0; font-family: var( --pa-ff-display ); font-weight: 600; font-size: 17px; line-height: 1.3;
	color: var( --pa-ink ); text-decoration: none; text-align: left;
	background: none; border: 0; border-bottom: 1px solid var( --pa-hair-light ); border-radius: 0; cursor: pointer;
}
.pa-mnav__row:hover, .pa-mnav__row:focus-visible { color: var( --pa-orange-ink ); }
.pa-mnav__note { font-size: 15px; color: var( --pa-muted ); margin: 10px 0 0; }
.pa-mnav__head, .pa-mnav__back, .pa-mnav__drill { display: none; }
.pa-mnav__tel {
	display: block; text-align: center; background: var( --pa-orange ); color: #fff;
	padding: 15px 20px; border-radius: 2px; font-family: var( --pa-ff-display );
	font-weight: 700; font-size: 17px; text-decoration: none;
}
.pa-mnav__tel:hover { background: #A5350A; color: #fff; text-decoration: none; }
.pa-mnav__wa {
	display: flex; align-items: center; justify-content: center; gap: 9px; background: #0E7569; color: #fff;
	padding: 14px 20px; border-radius: 2px; font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px; text-decoration: none;
}
.pa-mnav__wa:hover { background: #0A5A51; color: #fff; }

/*
 * THE PANEL, ENHANCED (assets/js/menu.js adds html.pa-js): a full-screen dialog.
 * Header (close left, quote right); below it a stage in which each screen is
 * absolutely positioned and slides on the X axis. A screen is .is-active (on
 * screen), .is-behind (the one you came from: nudged left, hidden once the
 * slide ends) or neither (parked off to the right, hidden). The JS sets `inert`
 * on everything but the active screen so Tab and screen readers stay inside it.
 *
 * html.pa-menu-open locks page scroll. The header loses its backdrop-filter
 * while the menu is open (a filter makes a fixed child position against the
 * header instead of the viewport) and takes a z-index above the call bar.
 */
html.pa-menu-open { overflow: hidden; }
html.pa-menu-open .pa-hdr { z-index: 1100; }
.pa-hdr:has( .pa-mnav[open] ) { backdrop-filter: none; -webkit-backdrop-filter: none; }

html.pa-js .pa-mnav__panel {
	position: fixed; inset: var( --wp-admin--admin-bar--height, 0px ) 0 0 0; z-index: 1;
	max-height: none; padding: 0; border: 0; box-shadow: none; overflow: hidden;
	display: flex; flex-direction: column; background: var( --pa-cream ); color: var( --pa-ink );
}
html.pa-js .pa-mnav__head {
	display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: none;
	padding: 14px 20px; box-sizing: border-box; width: 100%; max-width: 640px; margin: 0 auto; min-height: 76px;
}
.pa-mnav__close {
	display: inline-flex; align-items: center; justify-content: center; flex: none;
	width: 48px; height: 48px; margin-left: -12px; padding: 0; border: 0; background: none; color: var( --pa-ink ); cursor: pointer; border-radius: 2px;
}
.pa-mnav__qbtn {
	display: inline-flex; align-items: center; justify-content: center; min-height: 44px; box-sizing: border-box; padding: 0 20px;
	background: var( --pa-ink ); color: var( --pa-cream ); border: 1px solid var( --pa-ink ); border-radius: 999px;
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 16px; line-height: 1.1; text-align: center; text-decoration: none;
}
.pa-mnav__qbtn:hover { background: var( --pa-orange-ink ); border-color: var( --pa-orange-ink ); color: #fff; }
html.pa-js .pa-mnav__head { border-bottom: 1px solid transparent; }
html.pa-js .pa-mnav__stage { position: relative; display: block; flex: 1 1 auto; min-height: 0; overflow: clip; border-top: 1px solid var( --pa-hair-light ); }
html.pa-js .pa-mnav__screen--root { display: block; }
html.pa-js .pa-mnav__screen {
	position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain; background: var( --pa-cream );
	padding: 0 20px 32px; box-sizing: border-box;
	transform: translateX( 100% ); visibility: hidden;
	transition: transform 0.3s cubic-bezier( 0.4, 0, 0.2, 1 ), visibility 0s linear 0.3s;
}
html.pa-js .pa-mnav__screen > * { max-width: 600px; margin-left: auto; margin-right: auto; }
html.pa-js .pa-mnav__screen.is-active { transform: none; visibility: visible; transition-delay: 0s; }
html.pa-js .pa-mnav__screen.is-behind { transform: translateX( -28% ); }
html.pa-js .pa-mnav__screen--root { transform: none; visibility: hidden; }
html.pa-js .pa-mnav__screen--root.is-active { visibility: visible; }
html.pa-js .pa-mnav__screen--root.is-behind { transform: translateX( -28% ); }
html.pa-js .pa-mnav__drill, html.pa-js .pa-mnav__back { display: flex; }
html.pa-js .pa-mnav__foot { order: 0; margin-top: 28px; }
html.pa-js .pa-mnav__row {
	min-height: 60px; padding: 14px 4px; font-size: 20px; border-bottom-color: var( --pa-hair-light );
}
html.pa-js .pa-mnav__list { border-top: 0; }
html.pa-js .pa-mnav__chev { flex: none; color: var( --pa-muted ); }
html.pa-js .pa-mnav__back {
	align-items: center; gap: 10px; min-height: 52px; padding: 0; margin-top: 4px; margin-bottom: 4px;
	background: none; border: 0; cursor: pointer; font-family: var( --pa-ff-body ); font-size: 17px; font-weight: 500; color: var( --pa-orange-ink );
}
html.pa-js .pa-mnav__back:hover, html.pa-js .pa-mnav__back:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
html.pa-js .pa-mnav__title {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 30px; line-height: 1.1; letter-spacing: -0.02em;
	text-transform: none; color: var( --pa-ink ); margin: 8px auto 14px;
}
html.pa-js .pa-mnav__note { padding: 0 4px; }
.pa-mnav__panel :focus-visible { outline: 2px solid var( --pa-orange-ink ); outline-offset: 2px; }
html.pa-js .pa-mnav__tel, html.pa-js .pa-mnav__wa { min-height: 52px; box-sizing: border-box; }
@media ( prefers-reduced-motion: reduce ) {
	html.pa-js .pa-mnav__screen { transition: none; }
}

/* The language switcher in the panel: the same three buttons as the bar above the header, left-aligned under the contact buttons. */

/*
 * Header collapse. This was missing entirely — the rule that hid the nav below
 * 900px belonged to the previous design layer and went with it, so the nav had
 * been wrapping onto a second row instead of collapsing, and there was no
 * mobile menu behind it.
 *
 * Below 900px: logo, phone, Book now and the menu button. "Start your quote"
 * moves into the menu panel rather than competing for width in the bar.
 * Below 480px: the phone number becomes the menu's job too — the fixed call
 * bar already owns the bottom of the screen at that width.
 */
/*
 * 1179px. The full header (wordmark + six top-level items + phone + Book Now)
 * sits on ONE row from 1180px and wraps to two at 1179. Measured by bisection
 * with the collapse temporarily forced off, not guessed.
 *
 * HISTORY, because this number has moved five times and every move was
 * invisible on screen — the nav simply looked slightly tall inside a band
 * where it had already wrapped:
 *   1240  original, matched to a 1238px header.
 *   1370  a sixth top-level item (Heating) took the requirement to 1371px.
 *   1395  "About" became "Company", +25px on the row.
 *   1350  "Commercial HVAC" became "Commercial" in the nav only, -45px.
 *   1179  the desktop "Start Your Quote" button was removed, -171px.
 *   1262  "Start your quote" was PUT BACK on instruction 2026-09-03. The
 *         August note predicted this would push the requirement over 1280 and
 *         it did — the button costs 149px and the bare requirement went to
 *         1341px. It was bought back down by geometry alone, with no label or
 *         design change:
 *           sentence-case top-level labels     .pa-nav 666 -> 660
 *           button side padding cta 22->16, quote 20->15   -22px
 *           nav link side padding 10 -> 6, x6 items        -48px  (.pa-nav 660 -> 612)
 *           header row column gap 20 -> 16                 -12px
 *         Net: 1341 -> 1263. The desktop header survives at 1280 WITH both
 *         buttons, which is the outcome the brief wanted.
 *
 * There is deliberately NO band in which the desktop nav is shown wrapped: the
 * requirement is 1263px and the breakpoint is 1262px. That alignment is the
 * whole point of this comment — every past regression was the two drifting
 * apart, and none of them was visible on screen.
 *
 *   1262  (2026-10-23) The WhatsApp icon that briefly sat beside the phone number
 *         was REMOVED again on instruction; the number went 1263 -> 1297 -> 1263.
 *         In the same change the header row gained 16px on its LEFT so that the
 *         logo lines up with the page content (see .pa-hdr__row below), and that
 *         16px was paid for with three small gap changes, so the requirement is
 *         unchanged at 1263:
 *           header row column gap 16 -> 12 (two gaps)        -8px
 *           actions gap 10 -> 8 (two gaps)                   -4px
 *           phone link margin-right 4 -> 0                   -4px
 *         Measured by bisection with the collapse forced off, after the change.
 *
 * HEADROOM IS 18px at 1280, not 100px. Anything added to this row — a seventh nav
 * item, a longer label, a third button — will exceed it immediately. Measure
 * before, not after.
 *
 *   - Only TOP-LEVEL label widths matter. Dropdown children sit in an
 *     absolutely positioned panel and contribute nothing to this row.
 *
 * Count rows by comparing vertical centres, not top values — with
 * align-items:center, children on one flex line have different tops. See
 * HANDOFF SS3, where that measurement was wrong the first time it was tried.
 *
 * Renaming About to Company also REMOVED "All Services" from that dropdown,
 * which sounds like it should have bought width back and bought none: dropdown
 * children live in an absolutely positioned panel and never contributed to the
 * header row. Only top-level label widths matter here. Do not reason about
 * this from the item count.
 *
 * Each time the failure mode was the same — the desktop nav still showing
 * inside a band where it had already wrapped, reported by nothing, looking
 * only slightly tall.
 *
 * Rows are counted by comparing VERTICAL CENTRES. With align-items:center,
 * children on a single flex line have different top values, so counting
 * distinct tops reports phantom wrapping — see HANDOFF SS3, where that
 * measurement was wrong the first time it was tried.
 *
 * Re-measure if the nav labels, the item count or the type sizes change.
 */
@media ( max-width: 1262px ) {
	.pa-nav { display: none; }
	.pa-mnav { display: block; }
}

@media ( max-width: 900px ) {
	.pa-hdr__row { column-gap: 12px; }
	.pa-hdr__actions { gap: 10px; }
	/*
	 * Only Book now stays in the bar below 900. "Start your quote" moves into
	 * the mobile menu panel rather than competing for width — the same rule
	 * that applied before it was removed in August, restored with it. Without
	 * this the header wrapped to two rows at 375.
	 */
	.pa-hdr__quote { display: none; }
}

/*
 * At 375px the wordmark, Book now and the menu button need 416px between them,
 * so the menu button was dropping to a second row. The label is hidden rather
 * than removed — the icon alone is the control, but <summary> still needs its
 * accessible name — and the row padding and gap tighten. Measured: 358px
 * needed against 375 available.
 */
/*
 * 320px (iPhone SE 1st gen, folded Galaxy covers). Wordmark + Book now + the
 * menu button need 352px, so the row wrapped. Book now steps aside: the fixed
 * call bar is on screen below 640px and the menu panel carries both actions.
 * Kept below 360 only, so a 375px phone still gets the header CTA.
 */
@media ( max-width: 360px ) {
	.pa-hdr__cta, .pa-hdr__quote { display: none; }
}

@media ( max-width: 480px ) {
	.pa-hdr__cta { padding: 11px 15px; font-size: 15px; min-height: var( --pa-min-tap ); }
	.pa-hdr__row { padding-left: 20px; padding-right: 20px; column-gap: 10px; }
	.pa-mnav__btn { padding: 10px 13px; }
	.pa-mnav__word {
		position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
		overflow: hidden; clip: rect( 0, 0, 0, 0 ); white-space: nowrap; border: 0;
	}
	.pa-mnav__panel { padding: 20px 20px 24px; }
}

/* --- 13b. Hero ------------------------------------------------------------ */

/*
 * FULL-BLEED PHOTOGRAPH, not a two-column split.
 *
 * The re-exported mockup lays the panorama across the whole section and puts
 * the copy on top of it. The old grid gave the photo its own 0.8fr column on
 * the right; nothing about that survives here except the 660px floor.
 */
.pa-hero {
	position: relative; background: var( --pa-ink ); color: var( --pa-cream );
	min-height: 660px; display: flex; overflow: hidden;
}
.pa-hero__bgimg {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; object-position: 34% 50%; display: block;
}
/*
 * The mockup's five stops. It keeps easing all the way out to 0.24 at the
 * right edge, where there is no copy to protect — the same shape as About and
 * Careers, and it needs the same care below, because at narrow widths the copy
 * stops being left-anchored and runs into the thin end.
 */
.pa-hero__bgscrim {
	position: absolute; inset: 0; pointer-events: none;
	background: linear-gradient(
		90deg,
		var( --pa-ink ) 0%,
		rgba( 20, 22, 27, 0.94 ) 34%,
		rgba( 20, 22, 27, 0.7 ) 52%,
		rgba( 20, 22, 27, 0.34 ) 74%,
		rgba( 20, 22, 27, 0.24 ) 100%
	);
}
.pa-hero__col {
	position: relative; padding: 92px 44px 76px 0; max-width: var( --pa-shell ); width: 100%;
	/* Above the container's width the copy follows the page column (and the logo) instead of hugging the left edge: ( width - shell ) / 2, less the gutter that .pa-hero__inner adds. */
	margin-left: max( 0px, calc( ( 100% - var( --pa-shell ) ) / 2 - var( --pa-gutter ) ) );
	box-sizing: border-box; display: flex; flex-direction: column; justify-content: center;
}
.pa-hero__inner { padding-left: var( --pa-gutter ); }
.pa-hero__flag { display: flex; align-items: center; gap: 12px; margin-bottom: 30px; }
.pa-dot {
	width: 8px; height: 8px; border-radius: 50%; background: #F97316;
	box-shadow: 0 0 0 4px rgba( 249, 115, 22, 0.22 );
}
.pa-hero__flag .pa-mono { font-size: 12.5px; letter-spacing: 0.16em; color: #F5A97F; }
/*
 * text-wrap: balance is OFF here. The mockup sets its own three lines with
 * explicit <br>, and balance re-breaks them.
 */
.pa-hero h1 { margin: 0 0 26px; color: var( --pa-cream ); line-height: 0.96; max-width: 15em; }
.pa-hero__lede {
	font-size: 18.5px; line-height: 1.6; color: #B9BDC6; margin: 0 0 40px; max-width: 500px;
}
.pa-hero__lede strong { color: var( --pa-cream ); font-weight: 600; }
.pa-btns { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 48px; }
.pa-btn {
	padding: 17px 30px; border-radius: 2px; font-family: var( --pa-ff-display );
	font-weight: 700; font-size: 17px; text-decoration: none; display: inline-block;
}
.pa-btn--primary { background: var( --pa-orange ); color: #fff; }
.pa-btn--primary:hover { background: #A5350A; color: #fff; text-decoration: none; }
.pa-btn--ghost { border: 1px solid rgba( 251, 247, 241, 0.3 ); color: var( --pa-cream ); font-weight: 600; }
.pa-btn--ghost:hover { background: rgba( 251, 247, 241, 0.08 ); color: var( --pa-cream ); text-decoration: none; }
/*
 * flex-wrap matters here: without it this row's min-content is 332px, which
 * plus the hero column's 48px of padding forced the hero's 1fr track to
 * 380px inside a 375px screen. Every child of the hero then sat 5px wider
 * than the viewport and got clipped on the right edge.
 */
.pa-hero__stats {
	display: flex; flex-wrap: wrap; gap: 40px; align-items: flex-start; padding-top: 26px;
	border-top: 1px solid rgba( 251, 247, 241, 0.14 );
}
.pa-stat__row { display: flex; align-items: baseline; gap: 8px; }
.pa-stat__num {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 26px; color: var( --pa-cream );
}
/* line-height normal, as in both mockups — the glyphs set their own metrics. */
.pa-stars { color: #F59E0B; font-size: 14px; letter-spacing: 2px; line-height: normal; }

/*
 * STAR METER — the glyph row filled to the real rating.
 *
 * Two stacked copies of the same five glyphs: a ghost at low opacity showing
 * the full five, and an overlay clipped to a percentage width showing what was
 * actually earned. The overlay is an exact positional copy, so it inherits
 * font-size and letter-spacing from the wrapper and stays in register at any
 * size — both call-site overrides go on .pa-stars--meter, never on a child.
 *
 * The ghost is a translucent tint of the same amber rather than a grey, so it
 * reads as "unfilled star" on the ink band and on cream alike. It is decorative
 * and aria-hidden, so no contrast floor applies to it; the rating it describes
 * is always rendered as a number beside it.
 *
 * The fill's WIDTH is set inline by pure_air_star_meter(), not here, and it is
 * a calc() rather than a plain percentage: letter-spacing adds a space after
 * the fifth glyph too, so a percentage of this box overshoots the glyph run
 * and paints the last star solid at ratings below 5. The helper documents the
 * arithmetic. If you restyle this, do not replace that calc with a percentage.
 *
 * Do not add overflow to .pa-stars--meter itself. It sits in a baseline-aligned
 * flex row (.pa-stat__row), and an inline-block with a clipped overflow takes
 * its bottom margin edge as its baseline instead of its text baseline, which
 * drops the row out of alignment with the number next to it.
 */
.pa-stars--meter { position: relative; display: inline-block; white-space: nowrap; }
.pa-stars--meter .pa-stars__ghost { color: rgba( 245, 158, 11, 0.26 ); }
.pa-stars--meter .pa-stars__fill {
	position: absolute; top: 0; left: 0;
	overflow: hidden; white-space: nowrap;
	color: #F59E0B;
}
.pa-hero__stats .pa-mono.pa-micro { color: #8B909B; margin-top: 6px; font-size: 11.5px; }


@media ( max-width: 1024px ) {
	/*
	 * Same problem as the About and Careers heroes: the 90deg ramp is built for
	 * copy anchored to the left of a wide section. Once the column goes full
	 * width the copy runs straight into the 0.24 tail, so the ramp is replaced
	 * by an even veil. The value is measured — see the contrast pass in TODO.md.
	 */
	.pa-hero__bgscrim {
		background: linear-gradient(
			180deg,
			rgba( 20, 22, 27, 0.88 ) 0%,
			rgba( 20, 22, 27, 0.86 ) 60%,
			rgba( 20, 22, 27, 0.9 ) 100%
		);
	}
}
@media ( max-width: 900px ) {
	.pa-hero { min-height: 0; }
	.pa-hero__stats { gap: 24px 32px; }
	.pa-hero__col { padding: 56px 24px 48px; margin: 0; max-width: none; }
	.pa-hero__inner { padding-left: 0; }
	/*
	 * The photo no longer has a column of its own to sit in, so there is no
	 * aspect-ratio to set and nothing to reorder. It is the section's
	 * background at every width now.
	 */
}

/* --- 13c. Sections -------------------------------------------------------- */

.pa-sec { padding: 96px var( --pa-gutter ); }
.pa-sec--pricing { padding: 104px var( --pa-gutter ) 96px; background: var( --pa-cream ); }
.pa-sec--services { background: var( --pa-sand ); position: relative; overflow: hidden; }
.pa-sec--reviews { padding: 104px var( --pa-gutter ); background: var( --pa-ink ); color: var( --pa-cream ); }
.pa-sec--areas { background: var( --pa-cream ); }
.pa-sec--book { padding: 110px var( --pa-gutter ); background: var( --pa-orange ); color: #FFF7F1; }

.pa-sec h2 { margin: 0; }
.pa-sec--reviews h2, .pa-sec--book h2 { color: var( --pa-cream ); }
.pa-sec--book h2 { color: #FFF7F1; }

.pa-head {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 340px, 100% ), 1fr ) );
	gap: 40px 64px; align-items: end; margin-bottom: 64px;
}
.pa-head h2 { max-width: 12em; }
.pa-head p { font-size: 18px; line-height: 1.6; color: #4A505C; margin: 0; max-width: 34em; }

/*
 * NOTE ON THE auto-fit GRIDS BELOW
 *
 * Every one uses minmax( min( Npx, 100% ), 1fr ), never minmax( Npx, 1fr ).
 * A bare pixel floor cannot collapse: at 375px the section has ~295px of room,
 * so a 320px or 340px floor forced the track wider than the screen and pushed
 * the whole document sideways. The min() lets the floor give way when the
 * container is narrower than it. Do not drop the min() back out.
 */

/* --- 13d. Pricing --------------------------------------------------------- */

.pa-price { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 230px, 100% ), 1fr ) );
	border-top: 1px solid var( --pa-ink ); }
.pa-price__cell { padding: 40px 44px; border-right: 1px solid rgba( 20, 22, 27, 0.14 ); }
.pa-price__cell:first-child { padding-left: 0; }
.pa-price__cell:last-child { padding-right: 0; border-right: 0; }
.pa-price__cell .pa-mono.pa-label { color: #646A76; margin-bottom: 10px; }
.pa-price__fig {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 58px, 7.3vw, 92px ); line-height: 0.88; letter-spacing: -0.045em; color: var( --pa-ink );
}
/* Tracking is normal on the suffix in both mockups; the figure's -0.045em must not inherit. */
.pa-price__fig span { font-size: 30px; font-weight: 600; letter-spacing: normal; color: #646A76; }
.pa-price__kind { color: var( --pa-orange-ink ) !important; margin: 22px 0 12px; }
.pa-price__cell p { font-size: 16.5px; line-height: 1.55; color: #4A505C; margin: 0 0 14px; max-width: 30em; }
.pa-price__note { color: var( --pa-orange-ink ) !important; font-weight: 600; line-height: 1.5; margin: 0 !important; }
.pa-price__foot { margin-top: 40px; font-size: 16px; line-height: 1.6; color: #646A76; }
/*
 * Explicit colour: these links inherit the theme's cta orange (#C2410C), which
 * is 4.34:1 on the sand band — an AA failure. --pa-orange-ink is 5.65:1 there.
 *
 * .pa-price__cell a was added 2026-08-24 when the band moved from cream to
 * sand. On cream that link measured 4.85:1 and passed; sand pushed it to
 * 4.34:1. Nothing about the link changed — the ground moved under it. Any
 * cream-to-sand change has to re-measure the orange text on the band, because
 * #C2410C sits either side of the 4.5 line depending only on what is behind
 * it.
 */
.pa-price__foot a,
.pa-price__cell a { font-weight: 500; color: var( --pa-orange-ink ); }
/* Beats `.pa-price__cell p`, which would otherwise impose 1.55. */
.pa-price__cell .pa-price__note { line-height: 1.5; }

@media ( max-width: 780px ) {
	.pa-price__cell { padding: 32px 0; border-right: 0; border-bottom: 1px solid rgba( 20,22,27,0.14 ); }
	.pa-price__cell:last-child { border-bottom: 0; }
}

/* --- 13e. Services -------------------------------------------------------- */

.pa-svc {
	position: relative;
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 320px, 100% ), 1fr ) );
	gap: 56px 72px; align-items: start;
}
/*
 * THE INTRO IS A DARK CARD OVER THE PHOTOGRAPH, not text on the sand band.
 * Rebuilt to the mockup 2026-09-03. It was a sticky text column with the photo
 * cropped into a 340px rail beneath it.
 */
.pa-svc__card {
	position: sticky; top: 116px; background: var( --pa-ink ); color: var( --pa-cream );
	padding: 40px 38px 34px; max-width: 460px;
	/*
	 * content-box DELIBERATELY. The mockup's 460px cap is on the content, and
	 * with its 38px side padding the card renders 536px wide. Setting
	 * border-box here caps the whole card at 460 and the panel comes out 76px
	 * narrower than drawn. There is no global border-box reset in this theme,
	 * so the default is what the mockup is measured in.
	 */
}
.pa-svc__card .pa-mono.pa-eyebrow { color: #F5A97F; margin-bottom: 18px; font-size: 12px; }
.pa-svc__card h2 { margin: 0 0 18px; color: var( --pa-cream ); line-height: 1.04; }
.pa-svc__lede {
	font-size: 17.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 28px; max-width: 24em;
}
.pa-svc__facts {
	display: grid; gap: 12px; margin: 0; padding-top: 22px;
	border-top: 1px solid rgba( 251, 247, 241, 0.16 );
}
.pa-svc__fact { display: flex; justify-content: space-between; gap: 18px; }
.pa-svc__facts dt { font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var( --pa-ondark-dim ); }
.pa-svc__facts dd { margin: 0; font-size: 15.5px; color: var( --pa-cream ); text-align: right; }
/*
 * The backdrop. width is min(62%, 1100px) so it can never outgrow the source,
 * and it is pinned top-to-bottom rather than given a height, so it tracks the
 * list's length instead of the 340px the old rail was cropped to.
 */
.pa-svc__bg { position: absolute; left: 0; top: 0; bottom: 0; width: min( 62%, 1100px ); }
.pa-svc__bgimg { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; display: block; }
.pa-svc__scrim { position: absolute; inset: 0; pointer-events: none; }
.pa-svc__scrim--y {
	background: linear-gradient(
		180deg,
		rgba( 241, 234, 224, 0.35 ) 0%,
		rgba( 241, 234, 224, 0.18 ) 40%,
		rgba( 241, 234, 224, 0.1 ) 100%
	);
}
.pa-svc__scrim--x {
	background: linear-gradient(
		90deg,
		rgba( 241, 234, 224, 0 ) 0%,
		rgba( 241, 234, 224, 0.1 ) 40%,
		rgba( 241, 234, 224, 0.75 ) 72%,
		var( --pa-sand ) 88%,
		var( --pa-sand ) 100%
	);
}
.pa-svc__list { border-top: 1px solid rgba( 20, 22, 27, 0.16 ); }
.pa-svc__row {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 210px, 100% ), 1fr ) );
	gap: 10px 32px; padding: 30px 8px;
	border-bottom: 1px solid rgba( 20, 22, 27, 0.16 );
	color: var( --pa-ink ); text-decoration: none; align-items: baseline;
	transition: background 150ms ease;
}
.pa-svc__row:hover { background: rgba( 255, 255, 255, 0.55 ); color: var( --pa-ink ); text-decoration: none; }
.pa-svc__row h3 { margin: 0; }
.pa-svc__row p { font-size: 16.5px; line-height: 1.55; color: #4A505C; margin: 0; }

@media ( max-width: 900px ) {
	.pa-svc__card { position: static; max-width: none; }
	/*
	 * Single column: the 90deg ramp is protecting a right-hand column that no
	 * longer exists, and the list would sit straight on the photograph. The
	 * backdrop goes full width and the ramp becomes an even sand veil heavy
	 * enough for 16.5px body copy — measured, not guessed.
	 */
	.pa-svc__bg { width: 100%; }
	.pa-svc__scrim--x { background: rgba( 241, 234, 224, 0.93 ); }
	.pa-svc__scrim--y { background: none; }
}

/* --- 13f. Reviews --------------------------------------------------------- */

.pa-rev__head {
	display: grid; grid-template-columns: minmax( min( 340px, 100% ), 1fr ) auto; gap: 40px 48px;
	align-items: end; padding-bottom: 40px; border-bottom: 1px solid var( --pa-hair-dark );
}
.pa-rev__head .pa-mono.pa-eyebrow { color: #8B909B; margin-bottom: 18px; }
@media ( max-width: 700px ) { .pa-rev__head { grid-template-columns: 1fr; } }
.pa-rev__stats { display: flex; flex-wrap: wrap; gap: 28px 44px; align-items: flex-start; }
.pa-rev__big { font-family: var( --pa-ff-display ); font-weight: 700; font-size: 54px;
	line-height: 1; letter-spacing: -0.04em; }
.pa-rev__stats .pa-mono.pa-micro { color: #8B909B; margin-top: 8px; }
.pa-rev__verify {
	display: flex; align-items: center; gap: 10px; border: 1px solid rgba( 251,247,241,0.28 );
	padding: 13px 18px; color: var( --pa-cream ); text-decoration: none; margin-top: 4px;
}
.pa-rev__verify:hover { background: rgba( 251,247,241,0.08 ); color: var( --pa-cream ); text-decoration: none; }
.pa-rev__verify span { display: flex; flex-direction: column; line-height: 1.3; }
.pa-rev__verify strong { font-weight: 600; font-size: 16px; }
/*
 * TRACKS COME FROM THE QUOTE COUNT, via --pa-rev-cols set inline by
 * patterns/proof-reviews.php. Not auto-fit: auto-fit lays tracks out by
 * available width, and at 1280 it gave three quotes a FOUR-track grid
 * (400px 400px 400px 0px). The dead track displaced nothing, so nothing ever
 * reported it.
 */
.pa-rev__quotes { display: grid; grid-template-columns: repeat( var( --pa-rev-cols, 3 ), minmax( 0, 1fr ) ); }
.pa-rev__q {
	margin: 0; padding: 44px; border-right: 1px solid var( --pa-hair-dark );
	display: flex; flex-direction: column; gap: 20px;
}
.pa-rev__q:first-child { padding-left: 0; }
.pa-rev__q:last-child { padding-right: 0; border-right: 0; }
/*
 * 24px/500, not 17px/400. Both mockups specify the pull-quote at the display
 * scale — it is the reason the reviews band reads as proof rather than as more
 * body copy. Measured from city-target.html and homepage-target.html:
 * 24px, weight 500, -0.36px tracking, 32.6px leading.
 */
.pa-rev__q p {
	font-size: 24px; font-weight: 500; letter-spacing: -0.015em;
	line-height: 1.36; margin: 0; color: var( --pa-cream );
}
.pa-rev__q footer { font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.1em;
	text-transform: uppercase; color: #8B909B; }

/*
 * ONE COLUMN AT 768 AND BELOW.
 *
 * Three columns were held to 768 briefly and the measurement is why they are
 * not: the tracks land at 229px and the 24px pull quote sets to 12.5-15.4
 * characters a line over six to eight lines. Nothing overflowed and no word
 * left its box, so every mechanical check passed — it was simply a tighter
 * measure than the two-column layout that had already been rejected as
 * unreadable at ten characters. Passing the overflow check is not the same as
 * setting.
 *
 * Above 768 the tracks are 314px at 1024 (~21 characters) and 400px at 1280
 * (~30), both of which set.
 */
@media ( max-width: 768px ) {
	.pa-rev__quotes { grid-template-columns: minmax( 0, 1fr ); }
	.pa-rev__q { padding: 32px 0; border-right: 0; border-bottom: 1px solid var( --pa-hair-dark ); }
	.pa-rev__q:last-child { border-bottom: 0; }
}

/* --- 13g. Areas ----------------------------------------------------------- */

.pa-areas { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 330px, 100% ), 1fr ) );
	gap: 48px 72px; align-items: center; }
.pa-areas .pa-mono.pa-eyebrow { color: #74644F; margin-bottom: 18px; }
.pa-areas h2 { margin: 0 0 20px; }
.pa-areas__lede { font-size: 17.5px; line-height: 1.6; color: #4A505C; margin: 0 0 32px; max-width: 30em; }
/*
 * .pa-chips / .pa-chip / .pa-areas__note DELETED 2026-08-25.
 *
 * They styled the homepage's 42-city chip run and its "Not on the list?" note.
 * The homepage band became county rows plus the map on 2026-08-24 and nothing
 * has used them since. Zero users confirmed immediately before deletion in
 * theme source, rendered output on all 57 pages, wp_posts, wp_options,
 * wp_postmeta and Additional CSS.
 *
 * The chip rule carried one measurement worth keeping even though the rule is
 * gone: 7px vertical padding left those links 38px tall, so it ran min-height
 * 44px. If a chip-like control ever comes back, that is the floor.
 */

/* --- 13g1. Photography ---------------------------------------------------- *
 *
 * `display: contents` is the whole trick. Every photo below ships as a
 * <picture> so it can carry a WebP srcset with a JPG fallback, but a <picture>
 * is a real element and would otherwise sit in the layout as an inline box —
 * which matters enormously here, because several of these images are
 * absolutely positioned, object-fit: cover, or inside a grid cell.
 *
 * With display: contents the wrapper vanishes from layout entirely and the
 * <img> lays out exactly as a bare <img> would. That means every existing rule
 * that targets the image class (.pa-cityhero__img, .pa-svchero__img and the
 * rest) keeps working untouched, and adding photography changed no layout.
 *
 * If you ever need to style the wrapper, give it its own class — do not remove
 * display: contents, or the absolutely-positioned heroes will reflow.
 */
.pa-shot__pic { display: contents; }



/* --- 13g2. Legal documents ------------------------------------------------ *
 *
 * /privacy-policy/ and /terms-of-use/. A reading layout, not a marketing one:
 * one column, no aside, no band alternation. The measure is capped at 720px
 * because these are read in sequence rather than scanned, and the site's
 * 1280px shell would put legal body copy at roughly 150 characters a line.
 *
 * The cap is on the TEXT, not the section, so the band still spans full width
 * and the closing CTA below it lines up with every other page.
 */

.pa-sec--legal { background: var( --pa-cream ); }
.pa-legal { max-width: 720px; }
/*
 * The 720px reading column used to be centred (the shell's auto margins), which
 * put the title 240-280px to the right of the logo on a wide screen. The shell
 * is now the full 1280px and each block inside it is held to 720px, so the
 * column starts on the page's left edge, the same as every other page.
 */
.pa-shell.pa-legal { max-width: var( --pa-shell ); }
.pa-shell.pa-legal > * { max-width: 720px; box-sizing: border-box; }
.pa-legal h1 { margin: 0 0 14px; }
/*
 * `.pa-legal p.pa-legal__meta` — (0,2,1). Two goes at this, both instructive:
 *
 *   .pa-legal__meta        (0,1,0)  loses to `.pa-legal p` (0,1,1)
 *   p.pa-legal__meta       (0,1,1)  TIES with it, and loses on source order
 *   .pa-legal p.pa-legal__meta (0,2,1)  wins
 *
 * The dateline IS a <p>, so the element rule below matches it too. While it
 * lost, the 44px separating the dateline from the first heading collapsed to
 * 18px and the colour fell back to body grey instead of tan. This is the
 * recurring fault logged in CONFLICTS.md — a section rule out-specifying a
 * utility class. Beat it on specificity, not by reordering or !important.
 */
.pa-legal p.pa-legal__meta { color: var( --pa-tan ); margin: 0 0 44px; }
.pa-legal h2 {
	font-size: 25px; line-height: 1.2; letter-spacing: -0.01em;
	margin: 44px 0 14px;
}
.pa-legal h2:first-of-type { margin-top: 0; }
.pa-legal p { font-size: 17.5px; line-height: 1.65; color: #4A505C; margin: 0 0 18px; }
.pa-legal__list { margin: 0 0 18px; padding-left: 22px; }
.pa-legal__list li {
	font-size: 17.5px; line-height: 1.65; color: #4A505C; margin-bottom: 8px;
}
.pa-legal a { color: var( --pa-orange-ink ); }
.pa-legal a:hover { color: #7C2D12; }

/*
 * The NAP block. Same strings as the footer and the schema, byte for byte —
 * a second spelling of the address in a legal document is a real problem, not
 * a cosmetic one.
 */
.pa-legal__contact {
	border-left: 2px solid var( --pa-hair-light ); padding-left: 22px; margin: 0 0 18px;
}
.pa-legal__nap { margin: 0 0 12px; }
.pa-legal__nap:last-child { margin-bottom: 0; }

@media ( max-width: 620px ) {
	.pa-legal h2 { font-size: 22px; margin-top: 36px; }
}

/* --- 13h. Book (orange) --------------------------------------------------- */

.pa-book { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 320px, 100% ), 1fr ) );
	gap: 40px 64px; align-items: center; }
.pa-book .pa-mono.pa-eyebrow { color: #FFF7F1; margin-bottom: 20px; }
.pa-book h2 { font-size: clamp( 36px, 4.6vw, 58px ); line-height: 1.0; letter-spacing: -0.035em; margin: 0 0 20px; }
.pa-book__lede { font-size: 18.5px; line-height: 1.55; color: rgba( 255,247,241,0.88 ); margin: 0; max-width: 32em; }
.pa-book__lede strong { color: #fff; font-weight: 600; }
.pa-book__side { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.pa-book__tel {
	background: var( --pa-ink ); color: var( --pa-cream ); padding: 22px 34px;
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 26px;
	letter-spacing: -0.01em; text-decoration: none; border-radius: 2px;
}
.pa-book__tel:hover { color: var( --pa-cream ); text-decoration: none; background: #000; }
/* A real CTA, so it gets the full 48px control target, not the 44px link one. */
.pa-book__alt { display: inline-flex; align-items: center; min-height: var( --pa-min-tap );
	color: #FFF7F1; font-size: 16px; font-weight: 500; text-decoration: underline;
	text-underline-offset: 3px; }
.pa-book__alt:hover { color: #fff; }
.pa-book__trust { font-size: 14px; color: #FFF7F1; margin: 10px 0 0; }

/* --- 13i. Footer ---------------------------------------------------------- */

.pa-foot { background: var( --pa-ink ); color: var( --pa-cream ); padding: 72px var( --pa-gutter ) 36px; }
.pa-foot__grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 220px, 100% ), 1fr ) ); gap: 48px; }
/*
 * The footer grid reports 41px of phantom scroll overflow whenever column-gap
 * is non-zero and the 1fr tracks land on a fractional width (241.328px at
 * 900px wide). Nothing actually overflows — no descendant's right edge passes
 * the container — but it was enough to make the whole document scroll 1px
 * sideways on tablet widths. Confirmed by setting gap to 0, which takes the
 * document straight back to 900. Pre-existing; found while measuring the
 * header collapse. Clip contains it without creating a scroll container the
 * way overflow:hidden would.
 */
.pa-foot { overflow-x: clip; }
.pa-foot .pa-mono.pa-micro { color: #8B909B; margin-bottom: 16px; }
/*
 * FOOTER LINK ROWS — WCAG 2.2 AA, not AAA.
 *
 * The target criterion here is 2.5.8 Target Size (Minimum): 24x24 CSS px.
 * NOT 2.5.5 Enhanced (44x44), which is AAA and which this project does not
 * claim. An earlier pass padded every anchor to 44px tall to chase the AAA
 * figure; that padding set the row pitch, so a 15px link sat in a 48px box and
 * the columns read triple spaced against the mockup.
 *
 * The hit area is bought HORIZONTALLY instead: each anchor is a full-width
 * block, so the clickable box spans the entire column. Vertically it takes
 * line-height 1.5 plus a small padding-block, which lands well over the 24px
 * minimum while holding the mockup's 30px row pitch.
 *
 * 15px x 1.5 = 22.5px, + 3.75px top and bottom = 30px. If a row ever measures
 * under 24px, raise padding-block one step — do not go back to a 44px box.
 */
.pa-foot__col a {
	display: block;
	width: 100%;
	box-sizing: border-box;
	min-height: 0;
	padding-block: 3.75px;
	padding-inline: 0;
	line-height: 1.5;
	font-size: 15px;
	color: #DFE2E7;
	text-decoration: none;
}
.pa-foot__col a:hover { color: #fff; text-decoration: underline; }

/* The phone is the point of the column: bold, and a size above its neighbours. */
/*
 * Archivo, not the body font. The mockup sets the footer phone in the display
 * family; without an explicit font-family it inherited IBM Plex Sans and read
 * a weight lighter than intended. It is NOT a mono utility — mono is for the
 * eyebrows and column labels only.
 */
.pa-foot .pa-foot__tel {
	font-family: var( --pa-ff-display );
	color: var( --pa-cream ); font-weight: 700; font-size: 18px;
	line-height: 1.5; padding-block: 0 3.75px;
}
.pa-foot .pa-foot__all { font-size: 15px; font-weight: 600; color: var( --pa-tint ); }
.pa-foot__hours { font-size: 15px; font-weight: 600; line-height: 1.5; color: var( --pa-cream ); margin: 10px 0 0; }


.pa-foot a { color: #DFE2E7; text-decoration: none; }
.pa-foot a:hover { color: #fff; text-decoration: underline; }

/* Full lockup: PURE over AIR AND HEATING, matching the header treatment. */
.pa-foot__lockup { display: flex; flex-direction: column; gap: 4px; margin-bottom: 20px; }
.pa-foot__mark {
	font-family: var( --pa-ff-display ); font-weight: 400; font-size: 34px;
	line-height: 0.92; letter-spacing: 0.005em; color: var( --pa-cream );
}
.pa-foot__sub {
	font-family: var( --pa-ff-mono ); font-size: 14px; line-height: 1;
	letter-spacing: 0.22em; text-transform: uppercase; color: var( --pa-cream );
}
.pa-foot__blurb { font-size: 15px; line-height: 1.6; color: #B9BDC6; margin: 0 0 14px; max-width: 26em; }
.pa-foot .pa-foot__note { font-size: 14px; line-height: normal; color: var( --pa-ondark-dim ); margin: 14px 0 0; }
.pa-foot__addr {
	font-style: normal; font-size: 15px; line-height: 1.55;
	color: var( --pa-ondark ); margin: 8px 0 0;
}

.pa-foot__legal { margin-top: 48px; padding-top: 24px; border-top: 1px solid var( --pa-hair-dark );
	font-size: 14px; line-height: 1.5; }

/* --- 13j. Floating call chip ---------------------------------------------
 *
 * Mockup values: ink background, 2px radius, dot + number + microline, and it
 * turns orange on hover. Hidden below 640px where the fixed call bar that
 * CLAUDE.md requires already owns the bottom of the screen — two fixed call
 * controls would collide.
 */

.pa-sticky-cta {
	position: fixed; right: 24px; bottom: 24px; z-index: 50;
	display: none; align-items: center; gap: 12px;
	background: var( --pa-ink ); color: var( --pa-cream );
	padding: 13px 20px; border-radius: 2px; text-decoration: none;
	box-shadow: 0 8px 28px rgba( 20, 22, 27, 0.28 );
}
@media ( min-width: 640px ) { .pa-sticky-cta { display: inline-flex; } }
.pa-sticky-cta:hover, .pa-sticky-cta:focus {
	background: var( --pa-orange ); color: #fff; text-decoration: none;
}
.pa-sticky-cta__dot {
	width: 8px; height: 8px; border-radius: 50%; background: #F97316;
	box-shadow: 0 0 0 4px rgba( 249, 115, 22, 0.25 ); flex: 0 0 auto;
}
.pa-sticky-cta__stack { display: flex; flex-direction: column; line-height: 1.25; }
.pa-sticky-cta-number { font-family: var( --pa-ff-display ); font-weight: 700; font-size: 18px; }
.pa-sticky-cta-micro { font-size: 14px; color: #B9BDC6; }
.pa-sticky-cta:hover .pa-sticky-cta-micro { color: #FFE8DA; }

/* Footer label colour to match the mockup. */
.pa-foot .pa-mono.pa-micro { color: #8B909B; letter-spacing: 0.14em; margin-bottom: 14px; }
.pa-foot__legal { color: #8B909B; }

/* --- 13k. Header lockup ---------------------------------------------------
 *
 * Wordmark image plus the rest of the name as live text. Widths are tuned so
 * the two lines read as one block rather than a mark with a caption.
 */
.pa-wordmark { flex-direction: column; align-items: flex-start; gap: 4px; }
.pa-wordmark__img { height: 40px; width: auto; display: block; }
.pa-wordmark__sub {
	font-family: var( --pa-ff-mono ); font-size: 14px; font-weight: 500;
	letter-spacing: 0.155em; text-transform: uppercase; color: var( --pa-ink );
	line-height: 1; white-space: nowrap;
}
@media ( max-width: 640px ) {
	.pa-wordmark__img { height: 32px; }
	.pa-wordmark__sub { font-size: 14px; letter-spacing: 0.1em; }
}

/* Verify-on-Google chip in the reviews band. */
.pa-rev__dot {
	width: 7px; height: 7px; border-radius: 50%; background: #F59E0B; flex: 0 0 auto;
}

/* --- 13l. Contrast hardening ----------------------------------------------
 *
 * 1. The orange band's lede was rgba(255,247,241,0.88). Composited over
 *    #C2410C that resolves to #F8E1D6 = 4.12:1, an AA failure. My own sweep
 *    missed it because it compared the un-composited RGB. Now solid #FFF7F1
 *    (4.89:1), visually near-identical and passing AA.
 *
 * 2. The reviews-band micro labels sit on ink and measure 5.65:1, but axe
 *    resolves their background to the sticky header's cream and reports
 *    2.99:1. Declaring the background explicitly makes the computation
 *    unambiguous. No visual change — it is the colour already behind them.
 */

.pa-book__lede { color: #FFF7F1; }

.pa-sec--reviews .pa-mono.pa-micro,
.pa-rev__verify .pa-mono.pa-micro {
	background-color: var( --pa-ink );
}

/* ===========================================================================
 * 14. INNER PAGE COMPONENTS
 *
 * The service and location pages were built before the mockup and their stored
 * content still references these classes. Replacing the old design layer
 * orphaned them — they rendered unstyled until this section was added. Restyled
 * to the mockup's language: 2px radius, hairline rules, sand panels.
 * ======================================================================== */

/*
 * Body copy on inner pages. NO max-width here: constrained layout centres every
 * child, so a narrower max-width renders as an indent against the headings
 * rather than a tighter measure. contentSize (680px) is the measure.
 */
.wp-block-post-content > p,
.wp-block-post-content > ul,
.wp-block-post-content > ol {
	font-size: 16.5px;
	line-height: 1.6;
	color: #4A505C;
}
.wp-block-post-content > h2 { margin-top: 2.5rem; }
.wp-block-post-content > h3 { margin-top: 2rem; }
.wp-block-post-content li { margin-bottom: 0.4rem; }

/* Photo beside copy. */
.pa-media-split {
	display: grid;
	grid-template-columns: minmax( min( 280px, 100% ), 420px ) 1fr;
	gap: clamp( 1.5rem, 3vw, 2.5rem );
	align-items: start;
	margin: 2.5rem 0;
}
@media ( max-width: 900px ) {
	.pa-media-split { grid-template-columns: 1fr; }
	.pa-media-split .pa-photo { margin-inline: auto; }
}

.pa-photo {
	display: block;
	width: 100%;
	max-width: 440px;
	height: auto;
	border-radius: 2px;
}

/* Trane product photography. */
.pa-product {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 2px;
}

.pa-product-row {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 15rem, 100% ), 1fr ) );
	gap: clamp( 1rem, 2vw, 1.5rem );
	margin: 2rem 0 1rem;
}

.pa-product-cell {
	background-color: var( --pa-sand );
	border-radius: 2px;
	padding: 1.25rem;
}

.pa-product-cell figcaption,
.pa-product-caption {
	margin-top: 0.75rem;
	font-family: var( --pa-ff-mono );
	font-size: 14px;
	line-height: 1.5;
	color: #646A76;
}

/*
 * Bands embedded in page content must bleed to the viewport, not sit as an
 * inset box. Done with left + transform rather than negative inline margins:
 * core's constrained-layout rule forces margin-inline on every child and wins
 * regardless of specificity, which is why the orange band rendered as a
 * floating rectangle on /404/ and every service page.
 */
/*
 * Painted outward with box-shadow rather than sized with 100vw. 100vw includes
 * the scrollbar, so the vw version overflowed the viewport by the scrollbar
 * width on every page. box-shadow does not participate in layout, so the band
 * reads full width with no overflow; clip-path stops it bleeding vertically.
 *
 * On the homepage main is a flow container and the sections are already full
 * width, so this is a no-op there — the shadow paints off-screen.
 */
main .pa-sec {
	box-shadow: 0 0 0 100vmax var( --pa-band-bg, transparent );
	clip-path: inset( 0 -100vmax );
}
.pa-sec--pricing  { --pa-band-bg: var( --pa-cream ); }
.pa-sec--services { --pa-band-bg: var( --pa-sand ); }
.pa-sec--reviews  { --pa-band-bg: var( --pa-ink ); }
.pa-sec--areas    { --pa-band-bg: var( --pa-cream ); }
.pa-sec--book     { --pa-band-bg: var( --pa-orange ); }
.pa-hero          { --pa-band-bg: var( --pa-ink ); }

/* Inner-page headings are not hero headings. */
main h1 { font-size: clamp( 34px, 3.6vw, 52px ); }
.pa-hero h1 { font-size: clamp( 40px, 5.4vw, 76px ); }

/* Breathing room under the sticky header on pages that open with text. */
.wp-block-post-content { padding-top: 56px; }
main > h1:first-child { margin-top: 56px; }
body:not( .home ) main > .pa-sec:first-child { margin-top: 0; }

/* ---------------------------------------------------------------------------
 * 15. CITY LANDING PAGE
 *
 * Hero with the quote form beside it, the local facts panel, and the
 * what-you-get checklist. Reuses .pa-price, .pa-book and .pa-head from the
 * design layer so a city page and the homepage cannot drift apart.
 *
 * Every grid here uses minmax( min( N, 100% ), 1fr ). See §13 — a bare pixel
 * floor cannot shrink and pushes the page wider than a phone screen.
 * ------------------------------------------------------------------------- */

.pa-sec--local { --pa-band-bg: var( --pa-sand ); background: var( --pa-sand ); }
.pa-cityhero   { --pa-band-bg: var( --pa-ink ); }

/* --- 15a. Hero ------------------------------------------------------------ */

.pa-cityhero {
	position: relative; background: var( --pa-ink ); color: var( --pa-cream );
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 430px, 100% ), 1fr ) );
	align-items: stretch;
}
.pa-cityhero { container-type: inline-size; }
.pa-cityhero__col {
	/* The copy column starts on the page's left edge ( width - shell ) / 2 (less the gutter .pa-cityhero__inner adds), not against the middle of the hero. */
	padding: 88px 44px 76px 0; max-width: 760px; margin-left: max( 0px, calc( ( 100cqw - var( --pa-shell ) ) / 2 - var( --pa-gutter ) ) );
	box-sizing: border-box; display: flex; flex-direction: column; justify-content: center;
}
.pa-cityhero__inner { padding-left: var( --pa-gutter ); }
.pa-cityhero__flag { display: flex; align-items: center; gap: 12px; margin-bottom: 28px; flex-wrap: wrap; }
.pa-cityhero__eyebrow { font-size: 14px; letter-spacing: 0.16em; text-transform: uppercase; color: var( --pa-tint ); margin: 0; }
.pa-cityhero h1 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 38px, 5vw, 70px ); line-height: 0.98; letter-spacing: -0.035em;
	margin: 0 0 24px; color: var( --pa-cream ); text-wrap: balance;
}
.pa-cityhero__lede {
	font-size: 18.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 38px; max-width: 34em;
}
.pa-cityhero__lede strong { color: var( --pa-cream ); font-weight: 600; }

/*
 * The photo sits behind the form. The scrim is a separate element rather than
 * a gradient on the container so the form is never inside a stacking context
 * that dims it.
 */
/*
 * 620px, the mockup's figure — was 520 while the aside held the quote form.
 * The form moved to its own section (see patterns/city-quote.php) so this is
 * now the photograph panel and the mockup's height applies directly.
 */
.pa-cityhero__aside {
	position: relative; display: flex; align-items: center; justify-content: center;
	padding: 56px 40px; min-height: 620px; overflow: hidden;
}
.pa-cityhero__img {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; object-position: 50% 40%;
}
.pa-cityhero__scrim {
	position: absolute; inset: 0;
	background: linear-gradient( 90deg, var( --pa-ink ) 0%, rgba( 20, 22, 27, 0.72 ) 34%, rgba( 20, 22, 27, 0.58 ) 100% );
}

/* A centred figure under a section's cards. */

/* --- 14w. Tranche 4 section padding, from each mockup --------------------- *
 *
 * Every value below is measured off that page's own .dc.html. They do not
 * agree with one another — the pricing band is 88 on seven pages and 92 on
 * /services/, the hero runs 84, 88 or 92 — which is why this is per page
 * rather than a shared rule.
 *
 * The 900px block repeats them because a site-wide query drops several of
 * these bands to 64px, and none of these mockups has a breakpoint.
 */

.pa-page-services #top { padding: 88px var( --pa-gutter ) 80px; }
.pa-page-services #services { padding: 92px var( --pa-gutter ); }
.pa-page-services #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-services #how-it-goes { padding: 92px var( --pa-gutter ); }
.pa-page-services #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-services #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-services #book { padding: 104px var( --pa-gutter ); }

.pa-page-ac-repair #top { padding: 92px var( --pa-gutter ); }
.pa-page-ac-repair #diagnosis { padding: 92px var( --pa-gutter ); }
.pa-page-ac-repair #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-ac-repair #how-it-goes { padding: 92px var( --pa-gutter ); }
.pa-page-ac-repair #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-ac-repair #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-ac-repair #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-ac-repair #book { padding: 104px var( --pa-gutter ); }

.pa-page-ac-installation #top { padding: 84px var( --pa-gutter ) 0; }
.pa-page-ac-installation #decision { padding: 92px var( --pa-gutter ); }
.pa-page-ac-installation #the-work { padding: 92px var( --pa-gutter ); }
.pa-page-ac-installation #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-ac-installation #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-ac-installation #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-ac-installation #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-ac-installation #book { padding: 104px var( --pa-gutter ); }

.pa-page-heating #top { padding: 84px var( --pa-gutter ) 76px; }
.pa-page-heating #systems { padding: 92px var( --pa-gutter ); }
.pa-page-heating #symptoms { padding: 92px var( --pa-gutter ); }
.pa-page-heating #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-heating #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-heating #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-heating #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-heating #book { padding: 104px var( --pa-gutter ); }

.pa-page-ductwork #top { padding: 84px var( --pa-gutter ); }
.pa-page-ductwork #duct-faults { padding: 92px var( --pa-gutter ); }
.pa-page-ductwork #symptoms { padding: 88px var( --pa-gutter ); }
.pa-page-ductwork #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-ductwork #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-ductwork #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-ductwork #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-ductwork #book { padding: 104px var( --pa-gutter ); }

.pa-page-indoor-air-quality #top { padding: 84px var( --pa-gutter ) 0; }
.pa-page-indoor-air-quality #levers { padding: 92px var( --pa-gutter ); }
.pa-page-indoor-air-quality #symptoms { padding: 88px var( --pa-gutter ); }
.pa-page-indoor-air-quality #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-indoor-air-quality #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-indoor-air-quality #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-indoor-air-quality #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-indoor-air-quality #book { padding: 104px var( --pa-gutter ); }

.pa-page-commercial-hvac #top { padding: 88px var( --pa-gutter ); }
.pa-page-commercial-hvac #coverage-matrix { padding: 92px var( --pa-gutter ); }
.pa-page-commercial-hvac #operational-signs { padding: 88px var( --pa-gutter ); }
.pa-page-commercial-hvac #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-commercial-hvac #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-commercial-hvac #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-commercial-hvac #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-commercial-hvac #book { padding: 104px var( --pa-gutter ); }

.pa-page-about #top { padding: 88px var( --pa-gutter ); }
.pa-page-about #how-we-work { padding: 92px var( --pa-gutter ); }
.pa-page-about #licensed-and-local { padding: 88px var( --pa-gutter ); }
.pa-page-about #reviews { padding: 96px var( --pa-gutter ); }
.pa-page-about #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-about #book { padding: 104px var( --pa-gutter ); }

.pa-page-careers #top { padding: 88px var( --pa-gutter ); }
.pa-page-careers #open-roles { padding: 92px var( --pa-gutter ); }
.pa-page-careers #working-here { padding: 92px var( --pa-gutter ); }
.pa-page-careers #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-careers #book { padding: 104px var( --pa-gutter ); }

.pa-page-faq #top { padding: 88px var( --pa-gutter ); }
.pa-page-faq #pricing-questions { padding: 78px var( --pa-gutter ); }
.pa-page-faq #repairs-and-installs { padding: 78px var( --pa-gutter ); }
.pa-page-faq #scheduling-and-service { padding: 78px var( --pa-gutter ); }
.pa-page-faq #plans-and-financing { padding: 78px var( --pa-gutter ); }
.pa-page-faq #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-faq #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-faq #coverage { padding: 92px var( --pa-gutter ); }
.pa-page-faq #book { padding: 104px var( --pa-gutter ); }

.pa-page-financing #top { padding: 84px var( --pa-gutter ) 0; }
.pa-page-financing #lenders { padding: 92px var( --pa-gutter ); }
.pa-page-financing #how-it-works { padding: 92px var( --pa-gutter ); }
.pa-page-financing #pricing { padding: 88px var( --pa-gutter ); }
.pa-page-financing #quote-band { padding: 92px var( --pa-gutter ); }
.pa-page-financing #book { padding: 104px var( --pa-gutter ); }

@media ( max-width: 900px ) {
	.pa-page-services #top { padding: 88px var( --pa-gutter ) 80px; }
	.pa-page-services #services { padding: 92px var( --pa-gutter ); }
	.pa-page-services #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-services #how-it-goes { padding: 92px var( --pa-gutter ); }
	.pa-page-services #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-services #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-services #book { padding: 104px var( --pa-gutter ); }
	.pa-page-ac-repair #top { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-repair #diagnosis { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-repair #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-ac-repair #how-it-goes { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-repair #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-ac-repair #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-repair #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-repair #book { padding: 104px var( --pa-gutter ); }
	.pa-page-ac-installation #top { padding: 84px var( --pa-gutter ) 0; }
	.pa-page-ac-installation #decision { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-installation #the-work { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-installation #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-ac-installation #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-ac-installation #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-installation #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-ac-installation #book { padding: 104px var( --pa-gutter ); }
	.pa-page-heating #top { padding: 84px var( --pa-gutter ) 76px; }
	.pa-page-heating #systems { padding: 92px var( --pa-gutter ); }
	.pa-page-heating #symptoms { padding: 92px var( --pa-gutter ); }
	.pa-page-heating #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-heating #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-heating #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-heating #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-heating #book { padding: 104px var( --pa-gutter ); }
	.pa-page-ductwork #top { padding: 84px var( --pa-gutter ); }
	.pa-page-ductwork #duct-faults { padding: 92px var( --pa-gutter ); }
	.pa-page-ductwork #symptoms { padding: 88px var( --pa-gutter ); }
	.pa-page-ductwork #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-ductwork #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-ductwork #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-ductwork #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-ductwork #book { padding: 104px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #top { padding: 84px var( --pa-gutter ) 0; }
	.pa-page-indoor-air-quality #levers { padding: 92px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #symptoms { padding: 88px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-indoor-air-quality #book { padding: 104px var( --pa-gutter ); }
	.pa-page-commercial-hvac #top { padding: 88px var( --pa-gutter ); }
	.pa-page-commercial-hvac #coverage-matrix { padding: 92px var( --pa-gutter ); }
	.pa-page-commercial-hvac #operational-signs { padding: 88px var( --pa-gutter ); }
	.pa-page-commercial-hvac #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-commercial-hvac #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-commercial-hvac #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-commercial-hvac #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-commercial-hvac #book { padding: 104px var( --pa-gutter ); }
	.pa-page-about #top { padding: 88px var( --pa-gutter ); }
	.pa-page-about #how-we-work { padding: 92px var( --pa-gutter ); }
	.pa-page-about #licensed-and-local { padding: 88px var( --pa-gutter ); }
	.pa-page-about #reviews { padding: 96px var( --pa-gutter ); }
	.pa-page-about #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-about #book { padding: 104px var( --pa-gutter ); }
	.pa-page-careers #top { padding: 88px var( --pa-gutter ); }
	.pa-page-careers #open-roles { padding: 92px var( --pa-gutter ); }
	.pa-page-careers #working-here { padding: 92px var( --pa-gutter ); }
	.pa-page-careers #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-careers #book { padding: 104px var( --pa-gutter ); }
	.pa-page-faq #top { padding: 88px var( --pa-gutter ); }
	.pa-page-faq #pricing-questions { padding: 78px var( --pa-gutter ); }
	.pa-page-faq #repairs-and-installs { padding: 78px var( --pa-gutter ); }
	.pa-page-faq #scheduling-and-service { padding: 78px var( --pa-gutter ); }
	.pa-page-faq #plans-and-financing { padding: 78px var( --pa-gutter ); }
	.pa-page-faq #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-faq #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-faq #coverage { padding: 92px var( --pa-gutter ); }
	.pa-page-faq #book { padding: 104px var( --pa-gutter ); }
	.pa-page-financing #top { padding: 84px var( --pa-gutter ) 0; }
	.pa-page-financing #lenders { padding: 92px var( --pa-gutter ); }
	.pa-page-financing #how-it-works { padding: 92px var( --pa-gutter ); }
	.pa-page-financing #pricing { padding: 88px var( --pa-gutter ); }
	.pa-page-financing #quote-band { padding: 92px var( --pa-gutter ); }
	.pa-page-financing #book { padding: 104px var( --pa-gutter ); }
}

/* --- 14x. Company hero: full-bleed backdrop + paired stat rail ------------ */

.pa-svc2hero--shotbg { position: relative; overflow: hidden; }
.pa-svc2hero--shotbg .pa-shell { position: relative; }
.pa-svc2hero__bgimg {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; display: block;
}
/*
 * One 90deg scrim, as the mockup draws. Heaviest at the left where the h1 and
 * lede sit, easing to the right where the form card sits on its own ground.
 */
.pa-svc2hero__bgscrim {
	position: absolute; inset: 0;
	background: linear-gradient( 90deg, var( --pa-ink ) 0%, rgba( 20, 22, 27, 0.9 ) 30%, rgba( 20, 22, 27, 0.72 ) 100% );
}

/*
 * The scrim above is Maintenance Plans' — it eases right-to-left under a form
 * card. About.dc.html and Careers.dc.html draw a DIFFERENT five-stop ramp that
 * keeps easing all the way out to 0.28 at the right edge, because neither has
 * a card over there to protect: the photograph is meant to read as a
 * photograph on that side. Scoped per page rather than changed globally.
 */
.pa-page-about .pa-svc2hero__bgscrim,
.pa-page-careers .pa-svc2hero__bgscrim {
	background: linear-gradient(
		90deg,
		var( --pa-ink ) 0%,
		rgba( 20, 22, 27, 0.93 ) 34%,
		rgba( 20, 22, 27, 0.68 ) 56%,
		rgba( 20, 22, 27, 0.36 ) 80%,
		rgba( 20, 22, 27, 0.28 ) 100%
	);
}
/*
 * BOTH SOURCES ARE 1080x1350 PORTRAIT in a wide band, so object-fit: cover
 * discards most of the height. These two values are the mockups' framing and
 * they are what keeps the equipment in frame rather than the sky.
 */
.pa-page-about .pa-svc2hero__bgimg { object-position: 55% 45%; }
.pa-page-careers .pa-svc2hero__bgimg { object-position: 60% 40%; }
/*
 * Mockup hero padding. About runs its stat rail flush to the section's bottom
 * edge (0), Careers closes at 76px. Both were 88px from the tranche-4 pass,
 * which predates the photograph.
 */
.pa-page-about #top { padding-bottom: 0; }
.pa-page-careers #top { padding-bottom: 76px; }
/*
 * CONTRAST FIX OVER THE PHOTOGRAPH — this deviates from the mockups, on
 * purpose, and the measurement is in TODO.md.
 *
 * Both mockups ease their scrim out to alpha 0.28 at the right edge. That is
 * fine behind the h1, which is 40px+ cream and only needs 3:1. It is NOT fine
 * behind two other things the mockups place in that same tail:
 *
 *   - About's stat rail, which spans the FULL 1280px and labels its rows in
 *     #8B909B at 14px. Measured against the actual photo pixels, "A person
 *     answers" resolved 1.88:1 at x=1084. The mockup has the same defect; it
 *     was drawn, not rendered.
 *   - Every hero at <=1024px, where the column stops being left-anchored and
 *     the copy runs the full width straight into the thin end of the ramp.
 *     The lede measured 1.83:1 at 375.
 *
 * A flat veil heavy enough to fix About measured alpha 0.86, which is very
 * nearly solid ink and throws the photograph away. So the veil is placed where
 * the text is instead: a bottom band under the rail on wide screens, and a
 * full veil only once the layout goes single-column.
 */
.pa-page-about .pa-svc2hero__bgscrim::after,
.pa-page-careers .pa-svc2hero__bgscrim::after {
	content: ""; position: absolute; inset: 0; pointer-events: none;
	background: linear-gradient(
		180deg,
		rgba( 20, 22, 27, 0 ) 46%,
		rgba( 20, 22, 27, 0.62 ) 72%,
		rgba( 20, 22, 27, 0.84 ) 100%
	);
}
/* Careers' rail lives inside its own panel, so it needs far less. */
.pa-page-careers .pa-svc2hero__bgscrim::after {
	background: linear-gradient(
		180deg,
		rgba( 20, 22, 27, 0 ) 52%,
		rgba( 20, 22, 27, 0.42 ) 100%
	);
}
@media ( max-width: 1024px ) {
	/*
	 * Single column: the horizontal ramp protects nothing, so it is replaced
	 * by an even veil. The photograph still reads as texture behind the copy.
	 */
	.pa-page-about .pa-svc2hero__bgscrim {
		background: linear-gradient(
			180deg,
			rgba( 20, 22, 27, 0.9 ) 0%,
			rgba( 20, 22, 27, 0.9 ) 60%,
			rgba( 20, 22, 27, 0.93 ) 100%
		);
	}
	/*
	 * Careers can run lighter and still clear AA — its rail is inside the
	 * glance panel, so the only copy on bare photo is the h1 and lede. About
	 * cannot: its stat rail is out in the open in 14px #8B909B, and 0.84/0.86
	 * was measured at 4.11 on "Areas, five counties". These two numbers are
	 * measured, not matched — do not unify them.
	 */
	.pa-page-careers .pa-svc2hero__bgscrim {
		background: linear-gradient(
			180deg,
			rgba( 20, 22, 27, 0.84 ) 0%,
			rgba( 20, 22, 27, 0.86 ) 60%,
			rgba( 20, 22, 27, 0.89 ) 100%
		);
	}
	.pa-page-about .pa-svc2hero__bgscrim::after,
	.pa-page-careers .pa-svc2hero__bgscrim::after { background: none; }
}
/*
 * Careers' glance card sits ON the photograph, so it needs the translucent
 * panel the mockup draws around it. Without a ground the dl was legible only
 * because the hero was flat ink.
 */
.pa-page-careers .pa-svc2hero__aside {
	border: 1px solid rgba( 251, 247, 241, 0.24 );
	background: rgba( 20, 22, 27, 0.93 );
	-webkit-backdrop-filter: blur( 8px );
	backdrop-filter: blur( 8px );
	padding: 28px 30px 24px;
	box-sizing: border-box;
}

/*
 * The paired rail — label above value — as against the default rating-and-
 * licence rail. Same row rhythm, different content shape.
 */
.pa-hero__stats--pairs { display: flex; flex-wrap: wrap; gap: 26px 44px; }
.pa-stat__key { color: var( --pa-ondark-dim ); margin: 0 0 6px; }
.pa-stat__val {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 19px;
	letter-spacing: -0.01em; color: var( --pa-cream );
}

/* The quote form as a hero card, and the CTA that replaces it further down. */
/*
 * The mockup's card: a TRANSLUCENT DARK panel over the hero photograph, not a
 * cream one. Values are the mockup's own.
 */
.pa-heroform {
	background: rgba( 20, 22, 27, 0.82 ); backdrop-filter: blur( 8px );
	border: 1px solid rgba( 251, 247, 241, 0.24 ); color: var( --pa-cream );
	/*
	 * NO max-width. It was capped at 460px inside a 604px column — my own
	 * number, not the mockup's, which gives this card only border, background,
	 * blur and padding and lets it fill its column. The cap wasted 144px of
	 * width and kept the form under the 520px pairing threshold, so this was
	 * the one instance on the site still stacking its select and message.
	 */
	padding: 32px 30px 28px; width: 100%; margin-inline: auto;
	box-sizing: border-box;
}
.pa-heroform__eyebrow { color: var( --pa-tint ); margin: 0 0 10px; }
.pa-heroform__title {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 23px;
	line-height: 1.15; letter-spacing: -0.015em; margin: 0 0 20px;
	color: var( --pa-cream );
}
/*
 * ONE heading, as the mockup draws. pure_air_quote_form() carries its own
 * "Start your quote" h2 and lede, which stacked under the card's title and
 * read as a doubled heading. Hidden here rather than removed from the
 * component — the component is off-limits, and display:none also takes it out
 * of the accessibility tree, so it is not announced twice either.
 */
.pa-heroform .pa-qf__title,
.pa-heroform .pa-qf__lede { display: none; }
/*
 * The form sits directly on the dark card, so its own panel chrome comes off
 * and its text flips to the on-dark palette.
 */
.pa-heroform .pa-qf__form { background: transparent; padding: 0; border: 0; }
.pa-heroform .pa-qf__label { color: var( --pa-ondark ); }
.pa-heroform .pa-qf__input {
	background: rgba( 251, 247, 241, 0.06 ); border-color: rgba( 251, 247, 241, 0.28 );
	color: var( --pa-cream );
}
.pa-heroform .pa-qf__input::placeholder { color: var( --pa-ondark-dim ); }
/*
 * ON-DARK OVERRIDES for the hero form card (/maintenance-plans/).
 *
 * .pa-qf__consent USED to be the paragraph itself, so colouring it was enough.
 * It is now a grid WRAPPER and the text lives in .pa-qf__consent-text, so the
 * override has to name the child or it inherits nothing and the consent block
 * renders --pa-muted on ink: measured 2.23:1, with its links at 2.68:1. That
 * is the block least able to afford it.
 */
.pa-heroform .pa-qf__urgent,
.pa-heroform .pa-qf__consent,
.pa-heroform .pa-qf__consent-text { color: var( --pa-ondark ); }
.pa-heroform .pa-qf__consent-text a { color: var( --pa-tint ); }
.pa-heroform .pa-qf__urgent a { color: var( --pa-tint ); }
.pa-quotecta { display: flex; flex-direction: column; justify-content: center; }
.pa-quotecta__lede { font-size: 17.5px; line-height: 1.6; margin: 0 0 24px; }
.pa-quotecta__foot { font-size: 15.5px; line-height: 1.6; margin: 22px 0 0; }

/* --- 14y. Maintenance Plans components ------------------------------------ *
 * From Maintenance Plans.dc.html. Four shapes the other company pages do not
 * use: a ticked list, a three-column visit checklist, a one-line call strip
 * and a grid of linked service cards.
 */

.pa-ticks { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 340px, 100% ), 1fr ) ); gap: 28px 56px; }
.pa-tick { display: flex; gap: 14px; align-items: flex-start; }
/*
 * --pa-orange-ink is for orange text on a LIGHT ground. These ticks also render
 * on the ink "Why it is worth doing at all" band, where it measured 2.68:1 —
 * effectively invisible. The ink case gets the on-dark tint instead.
 */
.pa-tick__mark { flex: 0 0 auto; color: var( --pa-orange-ink ); font-size: 17px; line-height: 1.5; }
.pa-sec--svc2ink .pa-tick__mark,
.pa-sec--svc2ink .pa-checklist li::before { color: var( --pa-tint ); }
.pa-tick h3 { font-family: var( --pa-ff-display ); font-weight: 600; font-size: 19px; margin: 0 0 6px; }
.pa-tick p { font-size: 16.5px; line-height: 1.6; margin: 0; }
.pa-ticks__foot { font-size: 16.5px; line-height: 1.6; margin: 34px 0 0; max-width: 46em; }

.pa-checkcols { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 300px, 100% ), 1fr ) ); gap: 40px 56px; }
.pa-checkcol h3 { font-family: var( --pa-ff-display ); font-weight: 700; font-size: 21px; margin: 0 0 6px; }
.pa-checkcol__label {
	font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase;
	color: var( --pa-tan ); margin: 0 0 16px; padding-bottom: 14px;
	border-bottom: 1px solid var( --pa-hair-light );
}
.pa-checklist { list-style: none; margin: 0; padding: 0; }
.pa-checklist li {
	position: relative; padding-left: 26px; margin-bottom: 12px;
	font-size: 16.5px; line-height: 1.55;
}
.pa-checklist li::before {
	content: "\2713"; position: absolute; left: 0; top: 0;
	color: var( --pa-orange-ink ); font-size: 15px;
}
.pa-checkcols__foot { font-size: 16.5px; line-height: 1.6; margin: 34px 0 0; }
.pa-checkcols__foot a { color: var( --pa-orange-ink ); font-weight: 600; }

/* The call strip is one line: heading, number, reassurance. No grid. */
.pa-callstrip { text-align: center; }
.pa-callstrip__tel {
	display: inline-block; font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 34px, 4.4vw, 52px ); letter-spacing: -0.03em;
	color: var( --pa-orange-ink ); text-decoration: none; margin: 6px 0 10px;
}
.pa-callstrip__tel:hover { color: #7C2D12; }
.pa-callstrip__note { font-size: 16.5px; line-height: 1.6; color: #4A505C; margin: 0; }

.pa-related { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 300px, 100% ), 1fr ) ); gap: 2px; }
.pa-related__card {
	display: block; padding: 26px 28px 28px; background: var( --pa-cream );
	color: var( --pa-ink ); text-decoration: none; transition: background 150ms ease;
	min-height: var( --pa-min-tap ); box-sizing: border-box;
}
.pa-related__card:hover, .pa-related__card:focus-visible { background: #fff; text-decoration: none; }
.pa-related__name {
	display: block; font-family: var( --pa-ff-display ); font-weight: 600;
	font-size: 20px; letter-spacing: -0.015em; margin-bottom: 8px;
}
.pa-related__arrow { color: var( --pa-orange-ink ); }
.pa-related__desc { display: block; font-size: 16px; line-height: 1.55; color: #4A505C; }

/* --- 14z. Per-page section padding, from each mockup --------------------- *
 *
 * Every mockup sets its own vertical rhythm and they do not agree with one
 * another. These follow each mockup exactly, scoped by the pa-page-{slug} body
 * class so one page's values never move another's.
 *
 * /contact/ — Contact.dc.html: 104 / 72 / 92 / 92 / 92 / 104.
 */
.pa-page-contact .pa-svc2hero { padding: 104px var( --pa-gutter ) 96px; }
.pa-page-contact #contact { padding: 72px var( --pa-gutter ); }
.pa-page-contact .pa-sec--areas { padding: 92px var( --pa-gutter ); }
.pa-page-contact .pa-sec--book { padding: 104px var( --pa-gutter ); }
/*
 * Held at 92px below 900 too. A site-wide media query drops these two bands to
 * 64px; Contact.dc.html has no breakpoints and holds 92 at every width.
 */
@media ( max-width: 900px ) {
	.pa-page-contact #quote-band,
	.pa-page-contact #what-happens-next { padding: 92px var( --pa-gutter ); }
}

/*
 * /maintenance-plans/ — Maintenance Plans.dc.html: 88/92/92/92/72/88/92/92/104.
 */
.pa-page-maintenance-plans .pa-svc2hero { padding: 88px var( --pa-gutter ) 84px; }
.pa-page-maintenance-plans #call-strip { padding: 72px var( --pa-gutter ); }
.pa-page-maintenance-plans #related-services { padding: 88px var( --pa-gutter ); }
.pa-page-maintenance-plans .pa-sec--areas { padding: 92px var( --pa-gutter ); }
.pa-page-maintenance-plans .pa-sec--book { padding: 104px var( --pa-gutter ); }
/*
 * Held against the site-wide 900px query that drops .pa-sec--svc2 bands to
 * 64px. Maintenance Plans.dc.html has no breakpoints and holds these values at
 * every width.
 */
@media ( max-width: 900px ) {
	.pa-page-maintenance-plans .pa-sec--svc2,
	.pa-page-maintenance-plans .pa-sec--svc2quote { padding: 92px var( --pa-gutter ); }
	.pa-page-maintenance-plans #call-strip { padding: 72px var( --pa-gutter ); }
	.pa-page-maintenance-plans #related-services { padding: 88px var( --pa-gutter ); }
	.pa-page-maintenance-plans .pa-sec--areas { padding: 92px var( --pa-gutter ); }
	.pa-page-maintenance-plans .pa-sec--book { padding: 104px var( --pa-gutter ); }
}

/* --- 15a2. City quote section --------------------------------------------- *
 *
 * From City Landing Page.dc.html. The mockup's own values, not invented:
 * section padding 92px 40px, a two-column grid on a 360px floor (wrapped in
 * min() so it collapses on a phone), and the form in an ink card at
 * 38px 36px 34px.
 */
.pa-sec--cityquote { background: var( --pa-cream ); padding: 92px var( --pa-gutter ); scroll-margin-top: 110px; }
.pa-cityquote {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 360px, 100% ), 1fr ) );
	gap: 48px 72px; align-items: start;
}
.pa-cityquote .pa-mono.pa-eyebrow { color: var( --pa-tan ); margin-bottom: 18px; }
.pa-cityquote h2 { margin: 0 0 20px; }
.pa-cityquote__lede { font-size: 17.5px; line-height: 1.6; color: #4A505C; margin: 0 0 30px; max-width: 32em; }
.pa-cityquote__rows { border-top: 1px solid var( --pa-hair-light ); }
.pa-cityquote__row {
	display: flex; gap: 18px; padding: 18px 0;
	border-bottom: 1px solid var( --pa-hair-light ); align-items: baseline;
}
.pa-cityquote__key {
	flex: 0 0 auto; min-width: 104px; font-size: 14px; letter-spacing: 0.12em;
	text-transform: uppercase; color: var( --pa-tan );
}
.pa-cityquote__val { font-size: 16.5px; line-height: 1.55; color: var( --pa-ink ); }
.pa-cityquote__foot { font-size: 16.5px; line-height: 1.6; color: #4A505C; margin: 24px 0 0; }
.pa-cityquote__foot a { color: var( --pa-orange-ink ); font-weight: 600; }
/*
 * The card is ink, so the form inside it inherits the on-dark treatment the
 * quote form already ships. No new form styling — the working form is dropped
 * in as-is, which is the point of the backend-preservation rule.
 */
.pa-cityquote__card {
	background: var( --pa-ink ); color: var( --pa-cream ); padding: 38px 36px 34px;
	display: flex; flex-direction: column; justify-content: center;
}
.pa-cityquote__cardlede { font-size: 17.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 24px; }
.pa-cityquote__cta { align-self: flex-start; }
.pa-cityquote__cardfoot { font-size: 15.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 22px 0 0; }
.pa-cityquote__cardfoot a { color: var( --pa-cream ); font-weight: 600; }

/*
 * MOCKUP PADDING, applied on the city template only. The build carried
 * 104/104/110; the mockup draws 100/100/104 and 92 for the new quote section.
 * Scoped to .page-template-page-city so no other page's rhythm moves.
 */
.page-template-page-city .pa-sec--pricing { padding: 100px var( --pa-gutter ) 96px; }
.page-template-page-city .pa-sec--reviews { padding: 100px var( --pa-gutter ); }
.page-template-page-city .pa-sec--book { padding: 104px var( --pa-gutter ); }

/* --- 15b. Quote form ------------------------------------------------------ */

/*
 * THE FORM SIZES ITSELF FROM ITS OWN WIDTH, not the viewport.
 *
 * It renders in containers of three very different widths — 604px in the
 * quote section, 440px in a city hero, 398px in the maintenance-plans hero
 * card — so a viewport media query gets it wrong in at least two of them. A
 * container query asks the only question that matters: how much room does THIS
 * copy of the form have.
 */
/*
 * NO max-width HERE. It was 440px, and that default caused the same bug three
 * times: every container it renders in had to remember to lift it, and two of
 * them never did. The city hero sat at 440 inside a 720px column, the city
 * card at 440 inside 604, and the maintenance-plans hero card at 440 inside
 * 604 — each wasting width and paying for it in height, and each staying under
 * the pairing threshold as a result.
 *
 * The cap is unnecessary: every one of the five call sites puts the form in a
 * grid column or a card that already bounds it. A default that must be
 * overridden everywhere is not a default, it is a trap.
 */
.pa-qf { position: relative; width: 100%; container-type: inline-size; }
.pa-qf__form, .pa-qf__done {
	background: var( --pa-cream ); color: var( --pa-ink );
	padding: 30px 30px 26px; box-shadow: 0 24px 60px rgba( 0, 0, 0, 0.4 );
}
.pa-qf__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pa-qf__title {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 25px;
	letter-spacing: -0.025em; margin: 0; color: var( --pa-ink );
}
.pa-qf__city { font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase; color: var( --pa-orange-ink ); margin: 0; }
.pa-qf__lede { font-size: 15px; line-height: 1.5; color: var( --pa-muted ); margin: 6px 0 14px; }

.pa-qf__row { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 150px, 100% ), 1fr ) ); gap: 8px; }
.pa-qf__field { margin: 0 0 8px; display: flex; flex-direction: column; }
.pa-qf__label {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 14px;
	color: var( --pa-ink ); margin-bottom: 5px;
}
.pa-qf__input {
	width: 100%; box-sizing: border-box; padding: 12px 14px; min-height: var( --pa-min-tap );
	border: 1px solid rgba( 20, 22, 27, 0.34 ); background: #fff; border-radius: 0;
	font-family: var( --pa-ff-body ); font-size: 16px; color: var( --pa-ink );
}
/* 16px, not the mockup's 15.5: iOS Safari zooms the page on focus below 16px. */
.pa-qf__textarea { min-height: 62px; resize: vertical; }
.pa-qf__input:focus {
	outline: none; border-color: var( --pa-orange-ink );
	box-shadow: 0 0 0 3px rgba( 194, 65, 12, 0.28 );
}
.pa-qf__input[aria-invalid="true"] { border-color: #A5350A; border-width: 2px; }

.pa-qf__err:empty { display: none; }
.pa-qf__err {
	display: block; font-size: 14px; line-height: 1.4; color: #8F2D08;
	margin-top: 5px; font-weight: 500;
}
.pa-qf__alert {
	font-size: 15px; line-height: 1.45; color: #8F2D08; font-weight: 600;
	border: 1px solid #8F2D08; background: rgba( 194, 65, 12, 0.07 );
	padding: 11px 13px; margin-bottom: 14px;
}

/* Hidden from sight and from assistive technology, and out of the tab order. */
.pa-qf__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.pa-qf__submit {
	width: 100%; background: var( --pa-orange ); color: #fff; border: none;
	padding: 16px 20px; min-height: var( --pa-min-tap );
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px;
	cursor: pointer; border-radius: 0;
	display: inline-flex; align-items: center; justify-content: center; gap: 10px;
}
.pa-qf__submit:hover { background: #A5350A; }
.pa-qf__submit[disabled] { cursor: progress; }
.pa-qf__spin { display: none; width: 15px; height: 15px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; }
.pa-qf__submit.is-loading .pa-qf__spin { display: block; animation: pa-spin 0.6s linear infinite; }
@media ( prefers-reduced-motion: reduce ) {
	.pa-qf__submit.is-loading .pa-qf__spin { animation: pa-fade 1s ease-in-out infinite alternate; }
}

/*
 * HEIGHT. The form was 851px tall in a 604px column and 958px in a 440px one,
 * which left an awkward hole beside it on the wide pages and a very long
 * scroll on the city pages. The height sat in three places: three field rows,
 * the select and textarea stacked full-width, and the consent block wrapping
 * to seven lines.
 *
 * Once the form has ~560px of its own, the select and the message sit side by
 * side — the select needs no width and the message is optional, so pairing
 * them costs nothing and removes a whole row. Below that they stack, because
 * a 200px-wide select next to a 200px textarea helps nobody.
 */
/*
 * 520px, not 560. The city quote card lands at 532px, so a 560 threshold left
 * that one instance stacked and 100px taller than its twin in the hero for no
 * reason a reader could see. At 520 the two tracks are ~256px each, which a
 * select and a two-row textarea both carry.
 */
@container ( min-width: 520px ) {
	.pa-qf__pair { display: grid; grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr ); gap: 8px; align-items: start; }
	.pa-qf__pair .pa-qf__field { margin-bottom: 8px; }
	.pa-qf__pair .pa-qf__textarea { min-height: 96px; }
}
.pa-qf__urgent {
	display: flex; align-items: flex-start; gap: 10px; margin: 14px 0 0;
	padding-top: 14px; border-top: 1px solid rgba( 20, 22, 27, 0.16 );
	font-size: 15px; line-height: 1.45; color: var( --pa-muted );
}
.pa-qf__urgent a { color: var( --pa-orange-ink ); font-weight: 600; }
.pa-qf__dot { width: 7px; height: 7px; border-radius: 50%; background: #F97316; flex: none; margin-top: 7px; }
/*
 * TCPA CONSENT BLOCK. It was a single line of text under the button until
 * 2026-09-03; it is now a checkbox and a long disclosure, so it needs a real
 * layout.
 *
 * COLOUR IS --pa-muted, NOT --pa-dim. --pa-dim is the token for legal and
 * micro copy and it does clear AA at 5.09:1 on cream, so this is not a
 * contrast fix. It is a legibility one: this is the smallest type on the page
 * AND the paragraph a consent record rests on, so it gets the body-copy token
 * at 7.59:1 rather than the quietest one available. Measured after the change
 * on every surface the form sits on — see TODO.md.
 */
.pa-qf__consent {
	display: grid; grid-template-columns: auto minmax( 0, 1fr ); gap: 10px;
	align-items: start; margin: 16px 0 0;
}
.pa-qf__check {
	width: 18px; height: 18px; margin: 2px 0 0; flex-shrink: 0;
	accent-color: var( --pa-orange ); cursor: pointer;
}
.pa-qf__consent-text {
	font-size: 13.5px; line-height: 1.5; color: var( --pa-muted ); cursor: pointer;
}
.pa-qf__consent-text a { color: var( --pa-orange-ink ); text-decoration: underline; }
/*
 * The tap target is the LABEL, which is the whole paragraph, so the 18px box
 * is not the only thing a thumb can hit. No min-height is forced on the box
 * itself — enlarging the checkbox to 44px would put a huge control beside
 * small text and look broken.
 */

.pa-qf__done { padding: 40px 30px; }
.pa-qf__done-eyebrow { font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-orange-ink ); margin: 0 0 14px; }
.pa-qf__done-title {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 27px;
	line-height: 1.1; letter-spacing: -0.025em; margin: 0 0 14px; color: var( --pa-ink );
}
.pa-qf__done-body { font-size: 16px; line-height: 1.55; color: var( --pa-muted ); margin: 0 0 20px; }
.pa-qf__done-tel {
	display: inline-flex; align-items: center; min-height: var( --pa-min-tap );
	background: var( --pa-ink ); color: var( --pa-cream ); padding: 12px 22px;
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px; text-decoration: none;
}
.pa-qf__done-tel:hover { background: #000; color: var( --pa-cream ); text-decoration: none; }

/* --- 15c. Local facts panel ----------------------------------------------- */

/*
 * Two columns at desktop, stacked below 900px — the mockup's layout.
 * Explicit tracks rather than auto-fit: auto-fit was emitting a third, empty
 * 0px track, and its collapse point landed near 790px rather than the 900px
 * the rest of the page breaks at.
 */
.pa-local {
	display: grid; grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr );
	gap: 56px 72px;
}
@media ( max-width: 900px ) {
	.pa-local { grid-template-columns: minmax( 0, 1fr ); }
}
.pa-local__facts h2, .pa-local__gets h2 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 31px, 3.4vw, 44px ); line-height: 1.03; letter-spacing: -0.03em;
	margin: 0 0 28px; max-width: 16em;
}

.pa-facts { background: var( --pa-ink ); color: var( --pa-cream ); }
.pa-facts__row { padding: 28px 32px; border-bottom: 1px solid var( --pa-hair-dark ); }
.pa-facts__row:last-child { border-bottom: 0; }
.pa-facts__label {
	font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase;
	color: var( --pa-ondark-dim ); margin: 0 0 10px;
}
.pa-facts__label--warm { color: var( --pa-tint ); }
.pa-facts__value {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 26px, 2.6vw, 34px ); line-height: 1.05; letter-spacing: -0.025em;
	color: var( --pa-cream ); margin: 0 0 10px;
}
.pa-facts__detail { font-size: 16px; line-height: 1.55; color: var( --pa-ondark ); margin: 0; }

/* .pa-facts__flag was removed 2026-08-19 — the panel no longer disclaims. */

.pa-local__ask { font-size: 16px; line-height: 1.55; color: var( --pa-muted ); margin: 20px 0 0; }
.pa-local__ask a { color: var( --pa-orange-ink ); font-weight: 500; }

/* --- 15d. What-you-get checklist ------------------------------------------ */

.pa-checks { list-style: none; margin: 0; padding: 0; border-top: 1px solid var( --pa-hair-light ); }
.pa-checks__row {
	display: flex; gap: 18px; padding: 20px 0;
	border-bottom: 1px solid var( --pa-hair-light );
}
.pa-checks__tick {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px;
	color: var( --pa-orange-ink ); flex: none; line-height: 1.5;
}
.pa-checks__title {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 19px;
	letter-spacing: -0.015em; margin: 0 0 5px; color: var( --pa-ink );
}
.pa-checks__body { font-size: 16px; line-height: 1.55; color: var( --pa-muted ); margin: 0; }

.pa-local__nearby {
	padding: 22px 24px; margin-top: 28px;
	border: 1px solid var( --pa-hair-light ); background: rgba( 255, 255, 255, 0.5 );
}
.pa-local__nearby p:last-child { font-size: 16px; line-height: 1.55; color: var( --pa-muted ); margin: 8px 0 0; }
.pa-local__nearby a { color: var( --pa-orange-ink ); font-weight: 500; }

/* --- 15e. (removed) -------------------------------------------------------
 * The researched prose section was deleted from the location pages on
 * 2026-08-19 — it restated the fact panel, so the utility difference appeared
 * twice on one page. Its styles (.pa-citybody, .pa-prose*) went with it.
 * The writing is archived in inc/research-archive.php.
 * ------------------------------------------------------------------------- */

/* --- 15f. Service-areas mega-menu, grouped by county ----------------------- */

/*
 * Sized for growth. At 45 cities the menu still shows a capped set per county
 * and defers to /service-areas/, so it never becomes taller than the viewport.
 */
/*
 * ANCHORED TO ITS TRIGGER'S RIGHT EDGE, not its left.
 *
 * The panel is 620px wide and absolutely positioned. Left-anchored, its right
 * edge sits at (trigger left + 8 + 620); when a sixth top-level item was added
 * to the nav on 2026-08-21 the Service Areas trigger moved ~78px right and
 * that put the panel's edge at 1307px in a 1280px viewport — 27px of
 * horizontal document scroll on every page, from a panel that is
 * visibility:hidden and that nobody had opened.
 *
 * That is the failure mode HANDOFF SS3 describes: it was invisible on screen,
 * the header looked perfect, and only a scrollWidth comparison caught it.
 * visibility:hidden does not remove a box from layout, so a hidden dropdown
 * still extends the scrollable area.
 *
 * Right-anchoring makes the panel grow leftwards from the trigger, so its
 * right edge can never pass the trigger's — which is inside the nav by
 * definition. It survives another nav item being added; left-anchoring would
 * break again silently.
 */
.pa-menu--areas { min-width: 620px; padding: 22px 0 0; left: auto; right: 0; }
/*
 * HEIGHT IS CAPPED AGAINST THE VIEWPORT, not at a fixed pixel value.
 *
 * The panel is 916px of content. In a 900px window its bottom landed at 991px
 * with overflow visible, so the last county column and the "All N Service
 * Areas" footer sat below the fold with no way to reach them except closing
 * the menu and scrolling the page.
 *
 * The subtrahend is the sticky header (82px min-height) plus a 24px breathing
 * gap, so the cap follows the header rather than a number that silently stops
 * matching it. dvh first for mobile browsers whose toolbars make vh lie, with
 * vh underneath for anything that does not support it — declaration order is
 * the fallback, so do not reorder these two.
 */
.pa-menu--areas {
	max-height: calc( 100vh - 106px );
	max-height: calc( 100dvh - 106px );
	overflow-y: auto;
	overscroll-behavior: contain;
}
.pa-menu__cols {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 180px, 100% ), 1fr ) );
	gap: 4px 12px; padding: 0 10px;
}
.pa-menu__head {
	font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase;
	color: var( --pa-ondark-dim ); margin: 0 0 4px; padding: 0 12px;
}
.pa-menu__col a { padding: 9px 12px; font-size: 16px; }
.pa-menu__more { color: var( --pa-tint ) !important; }
.pa-menu__foot {
	display: flex; align-items: center; justify-content: space-between; gap: 16px;
	flex-wrap: wrap; margin-top: 14px; padding: 14px 22px;
	border-top: 1px solid var( --pa-hair-dark );
}
.pa-menu__all {
	color: var( --pa-cream ) !important; font-weight: 600; font-size: 16px;
	padding: 0 !important;
}
.pa-menu__all:hover { color: var( --pa-tint ) !important; }
.pa-menu__foot .pa-menu__note { padding: 0; }

@media ( max-width: 1262px ) { .pa-menu--areas { min-width: 0; } }


/* --- 16. SERVICE AREAS PAGE -------------------------------------------------
 * Matches service-areas-target.html. Counts and lists are data-driven — see
 * patterns/service-areas-index.php.
 * ------------------------------------------------------------------------- */

.pa-cov { background: var( --pa-ink ); color: var( --pa-cream ); padding: 84px var( --pa-gutter ) 76px; --pa-band-bg: var( --pa-ink ); }
.pa-cov__grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 400px, 100% ), 1fr ) ); gap: 56px 72px; }
.pa-cov h1 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 40px, 5.9vw, 72px ); line-height: 0.96; letter-spacing: -0.035em;
	margin: 0 0 24px; color: var( --pa-cream );
}
.pa-cov__lede { font-size: 18.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 38px; max-width: 34em; }
.pa-cov__lede strong { color: var( --pa-cream ); font-weight: 600; }

/*
 * 1px gaps on a light ground draw the grid rules without borders.
 *
 * The 163px floor is sized to the longest word these labels contain.
 * "neighborhoods" sets to 127.4px at 14px with 0.1em tracking; a 150px floor
 * gave a 107px content box at 375, so the word painted 20px outside its own
 * cell. It never scrolled the document and no rect left the viewport, which is
 * why the old rect-based check reported nothing for it on every run it ever
 * made. 163px = 127.4 rounded up plus the 28px x2 padding, less the 20px of
 * slack the track already had.
 */
/*
 * FOUR COLUMNS, ALWAYS, ABOVE 1024. Not auto-fit.
 *
 * This was `repeat( auto-fit, minmax( min( 163px, 100% ), 1fr ) )` and the
 * fourth stat wrapped to a second row on every desktop width, leaving an empty
 * cell beside it. The arithmetic: the hero is a two-column grid inside a
 * 1280px shell, so this column is (1280 - 80 padding - 72 gap) / 2 = 564px.
 * Four tracks with a 163px floor need 4 x 163 + 3 x 1px gap = 655px, so
 * auto-fit dropped to three and pushed the fourth down. The column does not
 * get wider above 1280 either — the shell is capped — so no amount of viewport
 * fixed it. THE MOCKUP HAS THE SAME DEFECT, at minmax(150px, 1fr).
 *
 * minmax( 0, 1fr ) rather than 1fr: a bare 1fr keeps min-width:auto, so a
 * track can still refuse to shrink below its content and re-create the
 * overflow this is meant to remove. The floor has to be 0.
 */
.pa-cov__stats {
	display: grid; grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	gap: 1px; background: var( --pa-hair-dark ); align-self: start;
}
/*
 * Side padding drops with the track width. At four columns in 564px each cell
 * is 140px, and the mockup's 28px sides leave 84px of content for a 51px
 * "24/7" — which overflows. Measured, not guessed.
 */
.pa-cov__stat { background: var( --pa-ink ); padding: 26px 14px; }
@media ( min-width: 1440px ) {
	.pa-cov__stat { padding: 30px 20px; }
}
/*
 * Below 1024 the hero is one column, so the stats get the full width and go
 * 2x2 — which is what the brief allows and what the mockup would do if it had
 * a narrow view.
 */
@media ( max-width: 1023px ) {
	.pa-cov__stats { grid-template-columns: repeat( 2, minmax( 0, 1fr ) ); }
	.pa-cov__stat { padding: 26px 20px; }
}
.pa-cov__statnum {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 40px, 4.6vw, 54px ); line-height: 1; letter-spacing: -0.04em; color: var( --pa-cream );
}
.pa-cov__statlabel { font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; color: var( --pa-ondark-dim ); margin: 8px 0 0; overflow-wrap: anywhere; }

/* --- 16b. County lists ---------------------------------------------------- */

.pa-county { margin-top: 52px; }
.pa-county__head {
	display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
	padding-bottom: 14px; border-bottom: 1px solid var( --pa-ink ); margin-bottom: 6px;
}
.pa-county__head h3 {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 25px;
	letter-spacing: -0.02em; margin: 0; color: var( --pa-ink );
}
.pa-county__count { font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-tan ); margin: 0; }
.pa-county__grid { display: grid; grid-template-columns: repeat( auto-fill, minmax( min( 215px, 100% ), 1fr ) ); }
.pa-county__grid a, .pa-county__soon {
	display: flex; align-items: center; min-height: 48px; padding: 12px 14px 12px 0;
	border-bottom: 1px solid rgba( 20, 22, 27, 0.14 );
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 17px;
	color: var( --pa-ink ); text-decoration: none;
}
.pa-county__grid a:hover { color: var( --pa-orange-ink ); }
.pa-county__soon { color: var( --pa-dim ); font-weight: 500; }
.pa-county__soon::after { content: " — page coming"; font-family: var( --pa-ff-body ); font-size: 14px; font-weight: 400; }
.pa-county__note { font-size: 16px; line-height: 1.55; color: var( --pa-muted ); margin: 18px 0 0; max-width: 34em; }

.pa-fallback {
	margin-top: 56px; padding: 26px 30px; border: 1px solid var( --pa-hair-light );
	background: var( --pa-sand );
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 280px, 100% ), 1fr ) );
	gap: 20px 40px; align-items: center;
}
.pa-fallback__title { font-family: var( --pa-ff-display ); font-weight: 700; font-size: 21px; letter-spacing: -0.02em; margin: 0 0 6px; color: var( --pa-ink ); }
.pa-fallback p { font-size: 16.5px; line-height: 1.55; color: var( --pa-muted ); margin: 0; }
.pa-fallback__cta {
	justify-self: start; display: inline-flex; align-items: center; min-height: var( --pa-min-tap );
	background: var( --pa-orange ); color: #fff; padding: 15px 26px; border-radius: 2px;
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px; text-decoration: none;
}
.pa-fallback__cta:hover { background: #A5350A; color: #fff; text-decoration: none; }

/* --- 16c. Photo band ------------------------------------------------------ */

/* --- 16c. Photo band ------------------------------------------------------ *
 *
 * Rebuilt 2026-08-25 to Service Areas.dc.html. The mockup makes this a
 * full-bleed photograph under two scrims, with the coverage copy on the left
 * and the STATIC coverage map in a bordered card on the right.
 *
 * The previous version was two portrait install photographs side by side. Those
 * files are no longer in the theme, so that band had been rendering empty; this
 * rebuild replaces it rather than restoring it.
 */
/*
 * MOCKUP PADDING for /service-areas/. The build carried 96/110 where the
 * mockup draws 92/104, and the coverage hero drops to 56px below 900 where the
 * mockup holds 84. Scoped so no other page moves.
 */
.page-template-page-service-areas .pa-sec--areas { padding: 92px var( --pa-gutter ); }
.page-template-page-service-areas .pa-sec--book  { padding: 104px var( --pa-gutter ); }

.pa-photoband {
	position: relative; overflow: hidden;
	background: var( --pa-ink ); color: var( --pa-cream ); --pa-band-bg: var( --pa-ink );
	padding: 96px var( --pa-gutter ) 92px;
}
.pa-photoband__bg {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; display: block;
}
.pa-photoband__scrim { position: absolute; inset: 0; }
.pa-photoband__scrim--x {
	background: linear-gradient( 90deg, var( --pa-ink ) 0%, rgba( 20, 22, 27, 0.94 ) 42%, rgba( 20, 22, 27, 0.72 ) 100% );
}
.pa-photoband__scrim--y {
	background: linear-gradient( 180deg, rgba( 20, 22, 27, 0.42 ) 0%, rgba( 20, 22, 27, 0.2 ) 50%, rgba( 20, 22, 27, 0.55 ) 100% );
}
.pa-photoband__grid {
	position: relative;
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 360px, 100% ), 1fr ) );
	gap: 48px 64px; align-items: center;
}
.pa-photoband__eyebrow { color: var( --pa-tint ); margin-bottom: 18px; }
.pa-photoband h2 { margin: 0 0 20px; color: var( --pa-cream ); }
.pa-photoband__lede { font-size: 18px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 30px; max-width: 30em; }
.pa-photoband__stats {
	display: grid; gap: 12px; padding-top: 24px;
	border-top: 1px solid var( --pa-hair-dark ); max-width: 420px;
}
.pa-photoband__stat { display: flex; justify-content: space-between; gap: 18px; }
.pa-photoband__statkey {
	font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase; color: var( --pa-ondark-dim );
}
.pa-photoband__statval { font-size: 15.5px; color: var( --pa-cream ); }
/*
 * The map card. backdrop-filter is the mockup's; it degrades to the flat
 * translucent fill where unsupported, which is why the background colour is
 * set as well rather than relying on the blur.
 */
.pa-photoband__mapcard {
	border: 1px solid rgba( 251, 247, 241, 0.24 );
	background: rgba( 20, 22, 27, 0.72 ); backdrop-filter: blur( 6px );
	padding: 14px; min-width: 0;
}
/*
 * 11px, the mockup's value (client decision 2026-08-25). This joins the mono
 * micro-labels already recorded in CONFLICTS.md section 2, where the mockup's
 * typography was allowed to win over the size floor for exactly this reason.
 */
.pa-photoband__mapcap {
	font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
	color: var( --pa-ondark-dim ); margin: 12px 0 2px; text-align: center;
}

/* --- 16d. Price promise --------------------------------------------------- */

.pa-sec--promise { background: var( --pa-sand ); --pa-band-bg: var( --pa-sand ); padding: 88px var( --pa-gutter ); }
.pa-sec--promise .pa-price__fig { font-size: clamp( 52px, 6.4vw, 80px ); }

@media ( max-width: 900px ) {
	/*
	 * .pa-cov's padding override is GONE (2026-08-25). It dropped this band to
	 * 56px/24px below 900 while Service Areas.dc.html holds 84px/40px at every
	 * width — and 40px is the site's own gutter everywhere else, so the 24px
	 * was the outlier, not the convention.
	 *
	 * The .pa-photoband__cell rule is gone too: that element no longer exists
	 * since the photo band was rebuilt as a full-bleed photograph.
	 */
	.pa-cov__grid { grid-template-columns: minmax( 0, 1fr ); gap: 40px; }
	.pa-sec--promise { padding-left: 24px; padding-right: 24px; }
}

/* ---------------------------------------------------------------------------
 * 17. FULL-BLEED SECTIONS SIT FLUSH
 *
 * THE BUG: a 24px cream band rendered between every adjacent full-width
 * section, and between the header, main and footer.
 *
 * CAUSE: the block-theme defaults
 *     :where(.wp-site-blocks) > *        { margin-block-start: 1.5rem }
 *     :root :where(.is-layout-flow) > *  { margin-block-start: 1.5rem }
 * both resolve --wp--style--block-gap, which theme.json sets to 1.5rem. The
 * margin is transparent, so what showed through was BODY's background —
 * #FBF7F1 — which is why it read as a cream band rather than a border.
 *
 * WHY NOT FIX IT IN theme.json: setting styles.spacing.blockGap to 0 would
 * zero the same variable everywhere, and it is doing real work inside post
 * content — measured at 24px between paragraphs and 40px above h2 on the
 * service pages and /pricing/. Collapsing those to fix a section boundary
 * would trade one bug for a worse one. theme.json cannot scope a style to a
 * component class emitted inside a core/html block, so this is the one case
 * where a stylesheet rule is the correct instrument.
 *
 * WHY NOT NEGATIVE MARGINS: they would overlap the sections rather than
 * remove the gap, and every subsequent layout question would inherit the lie.
 *
 * The selectors below are :where()-wrapped to specificity (0,0,0) — the same
 * weight as the rules they neutralise — so nothing here can out-specify a
 * deliberate margin set later on any of these components.
 * ------------------------------------------------------------------------- */

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

/*
 * The :root prefix is REQUIRED and is not decoration. The rule being
 * neutralised is `:root :where(.is-layout-flow) > *`, which is (0,1,0) — the
 * :root sits outside the :where(), so it counts. A plain
 * `:where(...) > :where(...)` selector is (0,0,0) and loses silently: the
 * first version of this fix zeroed the header/main/footer gaps and left every
 * section-to-section gap at 24px, with nothing reported anywhere.
 *
 * Matching at (0,1,0) and arriving later in the cascade is what wins it. The
 * inner :where() keeps the component list itself weightless, so a deliberate
 * margin on any one of these components still overrides this.
 */
:root :where( .is-layout-flow, .is-layout-constrained ) > :where(
	.pa-sec, .pa-hero, .pa-cityhero, .pa-svchero, .pa-svc2hero, .pa-cov, .pa-photoband
) {
	margin-block-start: 0;
}


/* --- 17. SERVICES HUB (/services/) ------------------------------------------
 *
 * Built from AC_Services_dc.html. Most of the page reuses the existing
 * components — .pa-sec, .pa-head, .pa-price, .pa-svc__list, .pa-rev, .pa-book,
 * .pa-areas — so what follows is only what the mockup adds: its own hero, the
 * form-beside-list intro, the four-step grid, and the two coverage/quote
 * adjustments.
 * ------------------------------------------------------------------------- */

/* --- 17a. Services hero --------------------------------------------------- */

/*
 * Contained, not full-bleed. The homepage and city heroes run edge to edge;
 * this one puts its content on .pa-shell at 1280 with the ink background
 * running the full width behind it, which is what the mockup draws. Reusing
 * .pa-hero would have given the wrong geometry, so it gets its own grid.
 *
 * The 430px track floor is written min( 430px, 100% ). A bare 430px cannot
 * collapse: at 375px the section has ~295px of usable width and the track
 * would force the page 135px wider than the screen. See HANDOFF SS3.
 */
.pa-svchero { position: relative; overflow: hidden; background: var( --pa-ink ); color: var( --pa-cream ); padding: 88px var( --pa-gutter ) 80px; }
/* Photograph: right 52% (900px cap), full height, one ink scrim over the whole band. */
.pa-svchero__photo { position: absolute; top: 0; right: 0; bottom: 0; width: min( 52%, 900px ); }
.pa-svchero__img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 58% 50%; }
/*
 * The mockup's scrim stops are ink solid to 40%, 0.86 at 56%, 0.42 at 80% and
 * 0.30 at 100%. The legibility floor on top is the same device as /heating/:
 * 0.93 ink up to the right edge of the copy column (660px, or 56% of the
 * shell), fading over 120px, so the lede and buttons keep contrast on a narrow
 * window where the column runs under the photograph. A second, bottom-up veil
 * sits behind the fact row: its 11.5px grey captions run straight across the
 * photograph (the mockup's own scrim leaves them 2.5:1 to 3.6:1 on the light
 * grass and siding), so the foot of the band darkens to carry them.
 */
.pa-svchero__scrim {
	position: absolute; inset: 0; pointer-events: none;
	background:
		linear-gradient( 0deg, rgba( 20, 22, 27, 0.82 ) 0, rgba( 20, 22, 27, 0.82 ) 150px, rgba( 20, 22, 27, 0 ) 300px ),
		linear-gradient( 90deg, rgba( 20, 22, 27, 0.93 ) 0, rgba( 20, 22, 27, 0.93 ) calc( max( var( --pa-gutter ), ( 100% - var( --pa-shell ) ) / 2 ) + min( 660px, 56% ) ), rgba( 20, 22, 27, 0 ) calc( max( var( --pa-gutter ), ( 100% - var( --pa-shell ) ) / 2 ) + min( 660px, 56% ) + 120px ) ),
		linear-gradient( 90deg, #14161B 0%, #14161B 40%, rgba( 20, 22, 27, 0.86 ) 56%, rgba( 20, 22, 27, 0.42 ) 80%, rgba( 20, 22, 27, 0.3 ) 100% );
}
.pa-svchero__inner { position: relative; }
.pa-svchero__col { max-width: min( 660px, 56% ); }
.pa-svchero__flag { display: flex; align-items: center; gap: 12px; margin-bottom: 26px; flex-wrap: wrap; }
.pa-svchero__eyebrow {
	font-size: 12.5px; letter-spacing: 0.16em; text-transform: uppercase; line-height: normal;
	color: var( --pa-tint ); margin: 0;
}
.pa-svchero h1 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 38px, 5vw, 68px ); line-height: 0.96; letter-spacing: -0.035em;
	margin: 0 0 24px; color: var( --pa-cream ); text-wrap: balance;
}
.pa-svchero__lede { font-size: 18.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 36px; }
.pa-svchero__lede strong { color: var( --pa-cream ); font-weight: 600; }
.pa-svchero .pa-btns { margin-bottom: 0; }
.pa-svchero .pa-btn { line-height: normal; }
.pa-svchero .pa-btn--ghost { border-color: rgba( 251, 247, 241, 0.3 ); }
/* Four fact cells under an ink-on-cream rule, each with its own hairline below. */
.pa-svchero__facts {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 190px, 100% ), 1fr ) );
	margin-top: 62px; border-top: 1px solid rgba( 251, 247, 241, 0.4 );
}
.pa-svchero__fact { padding: 28px 34px 26px 0; border-bottom: 1px solid rgba( 251, 247, 241, 0.16 ); }
.pa-svchero__fact .pa-stat__row { gap: 10px; }
.pa-svchero__val {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: clamp( 26px, 2.6vw, 32px );
	line-height: 1; letter-spacing: -0.03em; color: var( --pa-cream );
}
.pa-svchero__cap { font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: #8B909B; margin: 12px 0 0; line-height: normal; }
/* The dot stays beside the first line when the eyebrow wraps (same as /heating/). */
.pa-svchero__flag { flex-wrap: nowrap; align-items: flex-start; }
.pa-svchero__flag .pa-dot { flex: none; margin-top: 4px; }
/*
 * PHONE. The mockup squeezes the copy into 56% of the width at every size, which
 * at 375 leaves a 150px lede column running down the page over the photograph.
 * Under 700px the column takes the full width and the photograph becomes a
 * washed-out ground behind the whole band (0.9 ink).
 */
@media ( max-width: 700px ) {
	.pa-svchero__col { max-width: none; }
	.pa-svchero__scrim { background: rgba( 20, 22, 27, 0.9 ); }
}

/*
 * VERTICAL padding only. The horizontal gutter stays 40px at every width
 * because .pa-sec does — there is no sitewide 24px mobile gutter for these
 * bands, and the first version of this rule used 24px, which put the hero and
 * the intro 16px left of every other band on the page at 768. Measured, not
 * spotted: the bands look fine in isolation and only disagree with each other.
 */
@media ( max-width: 900px ) {
	.pa-svchero { padding: 64px var( --pa-gutter ) 56px; }
}

/* --- 17b. Intro: quote form beside the service list ----------------------- */

.pa-sec--svcintro { background: var( --pa-cream ); padding: 92px var( --pa-gutter ) 88px; }
.pa-svcintro {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 400px, 100% ), 1fr ) );
	gap: 56px 72px; align-items: start;
}
/* The form ships with its own max-width for the hero; here it owns the column. */
.pa-svcintro__body .pa-mono.pa-eyebrow { color: #74644F; margin-bottom: 18px; }
.pa-svcintro__body h2 { margin: 0 0 20px; max-width: 16em; }
.pa-svcintro__lede { font-size: 17.5px; line-height: 1.6; color: #4A505C; margin: 0 0 34px; max-width: 34em; }

/*
 * The rows are anchors, so the heading and the meta label are spans rather
 * than a grid of block children — .pa-svc__row's own auto-fit grid would put
 * the body copy in a second column beside the title at this width, which is
 * not what the mockup draws here.
 */
.pa-svcintro .pa-svcrow { display: block; padding: 26px 8px; }
.pa-svcrow__head {
	display: flex; align-items: baseline; justify-content: space-between;
	gap: 20px; flex-wrap: wrap; margin-bottom: 8px;
}
.pa-svcrow__head h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 25px;
	letter-spacing: -0.02em; margin: 0;
}
/*
 * --pa-orange-ink, not --pa-orange. #C2410C is 4.34:1 on sand and 4.85:1 on
 * cream; this label is 14px, so it needs the 4.5:1 floor for normal text and
 * #C2410C does not clear it on either ground.
 */
.pa-svcrow__meta {
	font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase;
	color: var( --pa-orange-ink ); white-space: nowrap;
}
.pa-svcrow__body {
	display: block; font-size: 16.5px; line-height: 1.55; color: #4A505C; max-width: 38em;
}
.pa-svcintro .pa-svcrow:hover { background: var( --pa-sand ); }

.pa-svcalso {
	margin-top: 30px; padding: 24px 26px;
	border: 1px solid rgba( 20, 22, 27, 0.18 ); background: var( --pa-sand );
}
.pa-svcalso__label { color: #74644F !important; margin-bottom: 10px; }
.pa-svcalso p { font-size: 16.5px; line-height: 1.6; color: #4A505C; margin: 0; }
.pa-svcalso a { font-weight: 500; color: var( --pa-orange-ink ); }

@media ( max-width: 900px ) {
	.pa-sec--svcintro { padding: 64px var( --pa-gutter ); }
}

/* --- 17c. How a service call goes ----------------------------------------- */

/*
 * The 1px gap on an ink background is the hairline: the cells paint their own
 * cream, and the grid gap shows through between them. It is one rule instead
 * of four border declarations that have to be undone at each edge.
 */
.pa-steps {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 240px, 100% ), 1fr ) );
	gap: 1px; background: rgba( 20, 22, 27, 0.14 ); border-top: 1px solid var( --pa-ink );
}
.pa-step { background: var( --pa-cream ); padding: 32px 30px 30px; }
.pa-step:first-child { padding-left: 0; }
.pa-step:last-child { padding-right: 0; }
.pa-step__num {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 15px;
	letter-spacing: 0.14em; color: var( --pa-orange-ink ); margin: 0 0 16px;
}
.pa-step h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 21px;
	letter-spacing: -0.02em; margin: 0 0 10px;
}
.pa-step__body { font-size: 16px; line-height: 1.55; color: #4A505C; margin: 0; }

/*
 * :first-child / :last-child only identify the row edges while the grid is a
 * SINGLE row. At two columns the edge cells are odd/even, not first/last, so
 * the zeroed padding lands on the wrong side and the second column's text sits
 * hard against the hairline. The column count is pinned here rather than left
 * to auto-fit so the nth-child rules and the track count cannot disagree.
 */
@media ( max-width: 1000px ) and ( min-width: 561px ) {
	.pa-steps { grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr ); }
	.pa-step, .pa-step:first-child, .pa-step:last-child { padding: 30px 24px; }
	.pa-step:nth-child( odd ) { padding-left: 0; }
	.pa-step:nth-child( even ) { padding-right: 0; }
}

@media ( max-width: 560px ) {
	.pa-steps { grid-template-columns: minmax( 0, 1fr ); }
	.pa-step, .pa-step:first-child, .pa-step:last-child { padding: 28px 0; }
}

/* --- 17d. Coverage band ---------------------------------------------------
 *
 * Built to "Coverage Section.html". Four departures from that mockup, all
 * deliberate, all recorded in patterns/services-coverage.php:
 *
 *   - no Leaflet (the map is a static export)
 *   - minmax( min( 400px, 100% ), 1fr ), not the mockup's uncollapsible 400px
 *   - every failing colour swapped for a token this site already has
 *   - the county counts are counted, not typed
 *
 * COLOUR SUBSTITUTIONS. Eleven of the mockup's thirteen text colours fail AA
 * on sand. Measured on #F1EAE0:
 *
 *   #98846D  3.00:1  eyebrow, county count, arrow, legend, credit, region
 *   #6E7480  3.93:1  "Not listed?" sentence, pricing note
 *   #C2410C  4.34:1  "Coverage area", "See all service areas", "Call and ask"
 *
 * Replaced by --pa-tan (4.78:1), #4A505C (6.78:1) and --pa-orange-ink
 * (5.65:1) respectively. Nothing new was invented and nothing here is below
 * 4.5:1. If you paste a colour out of that mockup, measure it first.
 */

/*
 * TWO MODIFIERS, DELIBERATELY SPLIT (2026-08-24, when the homepage adopted
 * this band):
 *
 *   .pa-sec--covband  LAYOUT. County rows beside the map panel. Homepage and
 *                     the 12 service/company pages.
 *   .pa-sec--svccov   GROUND ONLY. Sand. The 12 pages, NOT the homepage.
 *
 * They were one class for a day and that was a bug waiting: putting the band
 * on the homepage by reusing .pa-sec--svccov silently turned #areas sand, and
 * homepage-target.html draws it cream. Layout and ground are separate
 * decisions here — the homepage alternates cream/sand/ink down the page and
 * its coverage band is a cream beat in that run.
 *
 * Do not merge these back together. If a third page adopts the band, give it
 * --covband and decide its ground on its own evidence.
 *
 * The mockup's floor is minmax( 400px, 1fr ) — a bare pixel floor, which
 * cannot collapse and overflows a 375px phone. Wrapped in min( , 100% ).
 * Consequence worth knowing: a 400px floor plus the 72px gap needs 872px of
 * content, so this band goes single-column below a 952px viewport rather than
 * the 812px the base 330px floor gives .pa-areas elsewhere.
 *
 * Still scoped rather than changed at the base: .pa-areas is also used by the
 * /service-areas/ index band, which is a stacked county directory and wants
 * none of this.
 */
.pa-sec--covband .pa-areas {
	grid-template-columns: repeat( auto-fit, minmax( min( 400px, 100% ), 1fr ) );
	gap: 56px 72px; align-items: start;
}
/*
 * COLUMN, not row. The helper returns two siblings — the framed <figure> and
 * the "same published pricing" note that sits under it. As a flex row they
 * shared the 564px cell and the map rendered at 285px.
 */
.pa-svccov__aside { display: flex; flex-direction: column; align-items: stretch; }

/* County rows ------------------------------------------------------------- */

/*
 * The five county rows jump to #orange … #lake on /service-areas/. Those IDs
 * already existed and already resolved — but .pa-hdr is position:sticky at
 * 103px, and the site has no scroll-margin anywhere, so every one of those
 * jumps landed the county heading EXACTLY under the header: top=0, hidden by
 * the full 103px. The link worked and the destination was invisible.
 *
 * 103px header + 21px of air. Header height is 103px at 1280, 768 and 375
 * alike, so one value covers every width. Re-measure if the header changes.
 */
.pa-county > .pa-county__head > h3[id],
h3[id="orange"], h3[id="seminole"], h3[id="brevard"], h3[id="osceola"], h3[id="lake"] {
	scroll-margin-top: 124px;
}

.pa-covrows { border-top: 1px solid var( --pa-ink ); }
.pa-covrow {
	display: grid; grid-template-columns: 1fr auto auto; gap: 20px;
	align-items: baseline; padding: 17px 16px 17px 0;
	border-bottom: 1px solid var( --pa-hair-light );
	color: var( --pa-ink ); text-decoration: none;
}
.pa-covrow:hover, .pa-covrow:focus-visible { background: var( --pa-cream ); text-decoration: none; }
.pa-covrow:hover .pa-covrow__arrow, .pa-covrow:focus-visible .pa-covrow__arrow { color: var( --pa-orange-ink ); }
.pa-covrow__name {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 19px; letter-spacing: -0.015em;
}
.pa-covrow__count {
	font-family: var( --pa-ff-mono ); font-size: 11.5px; letter-spacing: 0.12em;
	text-transform: uppercase; color: var( --pa-tan );
}
.pa-covrow__arrow { color: var( --pa-tan ); font-size: 15px; }

.pa-covfoot {
	display: flex; flex-wrap: wrap; gap: 18px 40px; align-items: center; margin-top: 30px;
}
.pa-covfoot__ask { font-size: 15.5px; line-height: 1.6; color: #4A505C; }
.pa-covfoot__ask a { color: var( --pa-orange-ink ); font-weight: 500; }

.pa-svccov__all {
	display: inline-flex; align-items: center; min-height: var( --pa-min-tap );
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 17px;
	color: var( --pa-orange-ink ); text-decoration: none;
}
.pa-svccov__all:hover { color: #7C2D12; }

/* The framed map panel ---------------------------------------------------- */

/*
 * box-sizing is REQUIRED here, not decorative. This theme has no global
 * border-box reset — it is applied per component — so `width: 100%` plus a
 * 1px border each side put 2px of overflow on .pa-svccov__aside and another
 * 2px on .pa-shell. No horizontal scrollbar appeared and zero rect offenders
 * were reported; only the scrollWidth check saw it.
 */
.pa-covmap {
	margin: 0; width: 100%; box-sizing: border-box;
	border: 1px solid var( --pa-ink ); background: var( --pa-sand );
}
.pa-covmap__head {
	display: flex; justify-content: space-between; align-items: center;
	gap: 16px; flex-wrap: wrap; padding: 15px 18px;
}
.pa-covmap__label {
	font-family: var( --pa-ff-mono ); font-size: 11px; letter-spacing: 0.14em;
	text-transform: uppercase; color: var( --pa-orange-ink );
}
.pa-covmap__region {
	font-family: var( --pa-ff-mono ); font-size: 11px; letter-spacing: 0.1em;
	text-transform: uppercase; color: var( --pa-tan );
}
.pa-covmap__frame {
	display: block;
	border-top: 1px solid var( --pa-hair-light );
	border-bottom: 1px solid var( --pa-hair-light );
}

/*
 * MEASURED, do not scale the source down instead.
 *
 * The source render is 2360px wide for the map rectangle alone, and its bold
 * city labels have a 20px cap height in it. Scaling that whole render into
 * this panel puts them at 4.8px on desktop and 2.5px at 375.
 *
 * The shipped file is cropped to the five served counties, 1300x1050 of the
 * source, which is 1.8x the magnification at the same display width. In this
 * panel that gives roughly 8.6px on desktop and 4.4px at a 375px viewport.
 *
 * So: legible on desktop, NOT legible at 375. Known and accepted, not an
 * oversight. A tighter mobile crop was considered and rejected — the only way
 * to make the labels readable at that width is to cut coverage out of a
 * coverage map. At 375 the image carries shape and extent while the county
 * ROWS directly above it carry the names and the counts. Widen the slot
 * before you re-crop the image.
 */
.pa-covmap__img { display: block; width: 100%; height: auto; }

.pa-covmap__legend {
	display: flex; flex-wrap: wrap; gap: 12px 26px; align-items: center; padding: 14px 18px;
}
.pa-covmap__key {
	display: flex; align-items: center; gap: 9px;
	font-family: var( --pa-ff-mono ); font-size: 10.5px; letter-spacing: 0.12em;
	text-transform: uppercase; color: var( --pa-tan );
}
.pa-covmap__swatch {
	width: 20px; height: 11px; flex: 0 0 auto;
	background: rgba( 194, 65, 12, 0.3 ); border: 1.5px solid var( --pa-orange );
}
.pa-covmap__pin {
	width: 14px; height: 14px; flex: 0 0 auto; border-radius: 50%;
	background: var( --pa-ink ); border: 2.5px solid var( --pa-cream );
	box-shadow: 0 1px 4px rgba( 20, 22, 27, 0.4 );
}
.pa-covmap__pin--hq {
	width: 16px; height: 16px; border-width: 2px; background: var( --pa-orange );
	display: flex; align-items: center; justify-content: center;
}
.pa-covmap__pin--hq::after {
	content: ""; width: 5px; height: 5px; border-radius: 50%; background: var( --pa-cream );
}
/*
 * #4A505C, not the mockup's #98846D at 10px. A legal credit is the last place
 * to ship 3.00:1, and the credit is the one line in this band that is not
 * optional. It sits at margin-left:auto on a wide row and drops onto its own
 * line when the legend wraps.
 */
.pa-covmap__credit {
	margin-left: auto; font-family: var( --pa-ff-mono ); font-size: 10.5px;
	letter-spacing: 0.06em; color: #4A505C;
}
.pa-covmap__credit a { color: inherit; text-decoration: underline; }
.pa-covmap__credit a:hover { color: var( --pa-ink ); }

/*
 * The map panel on /service-areas/ only. Capped at 860px and centred rather
 * than filling the 1200px shell: the largest export is 1300w because that is
 * the native width of the crop, so a 1200px panel would be served at 1.08x on
 * a 1x screen and visibly soft on a 2x one. 860 keeps it at 1.5x on 2x, which
 * is the best this source can do. Widen it only by re-exporting from a looser
 * crop, which costs magnification and therefore label legibility.
 */
/*
 * Map beside photograph, per the mockup's minmax( 360px, 1fr ) pair. The 860px
 * cap moved off .pa-cov__map and onto the pair, because the map is now one
 * column of two rather than a centred block on its own.
 */
.pa-cov__pair {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 360px, 100% ), 1fr ) );
	gap: 2px; margin: 0 0 56px; align-items: stretch;
}
.pa-cov__map { min-width: 0; }
/*
 * min-height is REQUIRED, not decorative. The only child is absolutely
 * positioned, so this column has no content height of its own. Paired with the
 * map it stretches to the map's height and the min-height never applies; once
 * the grid drops to one column it becomes its own row and collapsed to ZERO
 * without it — the photograph vanished at 375 and 768 with no error.
 */
.pa-cov__shot {
	position: relative; overflow: hidden; min-width: 0; min-height: 320px;
	background: var( --pa-ink );
}
/*
 * The photograph matches the map panel's height rather than its own aspect —
 * they are a pair and a ragged bottom edge reads as a mistake. object-fit
 * crops instead of distorting.
 */
.pa-cov__shotimg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

.pa-covmap__note {
	font-size: 15px; line-height: 1.6; color: #4A505C; margin: 16px 0 0;
}

@media ( max-width: 620px ) {
	/* The legend is four items on one row at desktop; at phone width it needs
	   to wrap without the credit pinned to a far-right edge. */
	.pa-covmap__credit { margin-left: 0; }
	.pa-covrow { grid-template-columns: 1fr auto; gap: 4px 16px; }
	.pa-covrow__arrow { grid-column: 2; grid-row: 1; }
	.pa-covrow__count { grid-column: 1; grid-row: 2; }
}

/* --- 17e. Two-quote reviews grid ------------------------------------------ */

/*
 * The .pa-rev__quotes--two modifier that lived here is GONE. It existed only
 * while /services/ and the service pages rendered two quotes; the track count
 * now comes from --pa-rev-cols, which handles any length, and nothing filters
 * the array any more. Removed rather than left in place — an unreachable
 * modifier reads as live code to the next person.
 */


/* --- 18. SERVICE PAGES (the seven) -----------------------------------------
 *
 * Built from the seven Claude Design exports. The shared bands — pricing,
 * reviews, coverage, closing band — reuse the components already defined
 * above; what follows is the hero variants and the eight body layouts the
 * mockups add.
 *
 * BANDS: each mockup alternates cream / sand / INK in its own order, and the
 * ink sections are the reason this section carries a colour-inversion block.
 * Two of the seven heroes are cream rather than ink. All of it was read off
 * the mockups' section backgrounds — see inc/services-data.php.
 * ------------------------------------------------------------------------- */

/* --- 18a. Hero ------------------------------------------------------------ */

.pa-svc2hero { background: var( --pa-ink ); color: var( --pa-cream ); padding: 84px var( --pa-gutter ) 76px; }
.pa-svc2hero__grid {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 420px, 100% ), 1fr ) );
	gap: 48px 72px; align-items: start;
}
.pa-svc2hero--solo .pa-svc2hero__grid { grid-template-columns: minmax( 0, 1fr ); }
.pa-svc2hero__flag { display: flex; align-items: center; gap: 12px; margin-bottom: 26px; flex-wrap: wrap; }
/* 14px, not the mockups' 12.5px — the project minimum wins over the export. */
.pa-svc2hero__eyebrow {
	font-size: 14px; letter-spacing: 0.16em; text-transform: uppercase;
	color: var( --pa-tint ); margin: 0;
}
.pa-svc2hero h1 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 38px, 5vw, 64px ); line-height: 0.98; letter-spacing: -0.035em;
	margin: 0 0 22px; color: var( --pa-cream ); text-wrap: balance;
}
.pa-svc2hero__lede {
	font-size: 18.5px; line-height: 1.6; color: var( --pa-ondark ); margin: 0 0 34px; max-width: 34em;
}
.pa-svc2hero__lede strong { color: var( --pa-cream ); font-weight: 600; }
.pa-svc2hero .pa-btns { margin-bottom: 40px; }
.pa-svc2hero__note {
	margin: 30px 0 0; padding-top: 24px; border-top: 1px solid var( --pa-hair-dark );
	font-size: 17px; line-height: 1.6; color: var( --pa-ondark ); max-width: 46em;
}
.pa-svc2hero__img { display: block; width: 100%; max-width: 460px; height: auto; margin-inline: auto; }

/*
 * CREAM HERO. /ac-installation/ and /indoor-air-quality/ open on cream in
 * their mockups, not on ink. Every colour in the hero has to invert with it —
 * this is the block that would be missed, because the ink version looks
 * perfectly fine right up until the background changes underneath it.
 */
.pa-svc2hero--cream { background: var( --pa-cream ); color: var( --pa-ink ); }
.pa-svc2hero--cream h1 { color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-svc2hero__lede { color: #4A505C; }
.pa-svc2hero--cream .pa-svc2hero__lede strong { color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-svc2hero__eyebrow { color: #74644F; }
.pa-svc2hero--cream .pa-stat__num { color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-hero__stats { border-top-color: var( --pa-hair-light ); }
.pa-svc2hero--cream .pa-mono.pa-micro { color: #646A76; }
.pa-svc2hero--cream .pa-btn--ghost { border-color: rgba( 20, 22, 27, 0.28 ); color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-btn--ghost:hover { background: rgba( 20, 22, 27, 0.06 ); color: var( --pa-ink ); }

@media ( max-width: 900px ) {
	.pa-svc2hero { padding: 64px var( --pa-gutter ) 56px; }
}

/* --- 18b. Hero asides ----------------------------------------------------- */

/* The symptom picker on /ac-repair/. Real links to the form anchor. */
.pa-pick__label { font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-ondark-dim ); margin: 0 0 14px; }
.pa-pick { border-top: 1px solid var( --pa-hair-dark ); }
.pa-pick__row {
	display: block; padding: 16px 4px; border-bottom: 1px solid var( --pa-hair-dark );
	color: var( --pa-cream ); text-decoration: none; transition: background 150ms ease;
	/* A real control, so the full 48px target, not the 44px link one. */
	min-height: var( --pa-min-tap ); box-sizing: border-box;
}
.pa-pick__row:hover, .pa-pick__row:focus { background: rgba( 251, 247, 241, 0.07 ); color: var( --pa-cream ); text-decoration: none; }
.pa-pick__name { display: block; font-weight: 600; font-size: 17px; margin-bottom: 3px; }
.pa-pick__desc { display: block; font-size: 15px; line-height: 1.5; color: var( --pa-ondark ); }
.pa-pick__foot { font-size: 15px; line-height: 1.6; color: var( --pa-ondark ); margin: 18px 0 0; }

/* --- 18a1. Hero photo variants -------------------------------------------- *
 *
 * BACKDROP (AC Installation). The photograph runs down the right 44% of the
 * hero with a left-to-right scrim over it, and the existing two-column grid
 * sits on top. The figure component keeps its column — the mockup keeps it too.
 *
 * The scrim goes cream-to-transparent because this hero is the one CREAM
 * service hero; on the ink heroes it would be the opposite direction.
 */
.pa-svc2hero--backdrop { position: relative; overflow: hidden; }
.pa-svc2hero--backdrop .pa-svc2hero__grid { position: relative; }
.pa-svc2hero__backdrop {
	position: absolute; top: 0; right: 0; bottom: 0;
	width: 44%; min-width: min( 300px, 100% );
}
.pa-svc2hero__backimg { width: 100%; height: 100%; object-fit: cover; display: block; }
/*
 * PANEL fit. Indoor Air Quality.dc.html sizes its hero photograph
 * min(46%, 740px) by 560px — a panel down the right, not a full-height bleed.
 * The scrim is skipped for this fit: the mockup runs no gradient over it
 * because the copy does not overlap the image.
 */
.pa-svc2hero--panel .pa-svc2hero__backdrop {
	width: min( 46%, 740px ); height: 560px; bottom: auto;
}
.pa-svc2hero--panel .pa-svc2hero__backscrim { display: none; }
.pa-svc2hero__backscrim {
	position: absolute; inset: 0;
	background: linear-gradient( 90deg, var( --pa-cream ) 0%, var( --pa-cream ) 46%, rgba( 251, 247, 241, 0.95 ) 62%, rgba( 251, 247, 241, 0.88 ) 100% );
}

/*
 * ASIDE PHOTO (Ductwork). Stacked above the aside component, capped at the
 * mockup's 400px and held at the source's own 624x500 so it never upscales —
 * 624px is this file's native width and there is nothing above it to export.
 */
/*
 * DUCTWORK HERO PHOTOGRAPH — the mockup's geometry, not an approximation.
 *
 *   position: absolute; top: 50%; right: 0; transform: translateY(-50%);
 *   width: min(46%, 620px); aspect-ratio: 620 / 496;
 *
 * Three things this is NOT, all of which look plausible and are wrong:
 *   - it does not run to the top and bottom of the band. It is vertically
 *     CENTRED at a fixed aspect ratio, which is what the mockup draws;
 *   - it is not a grid child. It has to escape the 1280px shell to reach the
 *     viewport edge, so it is pinned to the section;
 *   - the 620px cap is not styling. air-handler-indoor is 624px native, so
 *     anything wider upscales.
 *
 * The card overlapping it is a consequence of this geometry, not a nudge: the
 * grid's right column starts at 676px in a 1280 viewport and the photo's left
 * edge lands at 691px, so the card is 15px over it. Both numbers move together
 * with the viewport, so the overlap holds without a magic offset.
 */
.pa-svc2hero__shotbox {
	/*
	 * FULL HEIGHT OF THE BAND, top to bottom, and off the right edge.
	 *
	 * This was `top: 50%; transform: translateY(-50%); aspect-ratio: 620/496`,
	 * copied from the mockup. In the mockup canvas that lands close to the band
	 * height so it reads as a bleed; in the real page the band is 651px and the
	 * photo is 496px, which left 77px of dead ink above and below and made the
	 * photograph read as a floating rectangle. The mockup has the same gap —
	 * 53px, 82% coverage — so this is one of the places the mockup is not
	 * self-consistent and the brief's words are the better spec.
	 *
	 * COST, and it is real: air-handler-indoor is 624x500 native with nothing
	 * larger to export. Covering a 651px-tall box scales it 1.30x, so the photo
	 * is upscaled. Flagged rather than hidden — a taller source is the only
	 * actual fix.
	 */
	position: absolute; top: 0; bottom: 0; right: 0;
	width: min( 46%, 620px );
	overflow: hidden; background: #22252C;
}
.pa-svc2hero__shotimg { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; display: block; }
/* The mockup's five-stop ramp: solid ink to 40%, easing to 0.4 at the right. */
.pa-svc2hero__shotscrim {
	position: absolute; inset: 0; pointer-events: none;
	background: linear-gradient(
		90deg,
		var( --pa-ink ) 0%,
		var( --pa-ink ) 40%,
		rgba( 20, 22, 27, 0.82 ) 54%,
		rgba( 20, 22, 27, 0.5 ) 72%,
		rgba( 20, 22, 27, 0.4 ) 100%
	);
}
/*
 * The SECTION is the containing block, and the grid must stay STATIC so the
 * photo resolves against the section and reaches the viewport edge rather than
 * the 1280px shell's edge. The copy and the card get their own stacking
 * instead, so they still sit above the scrim.
 */
.pa-svc2hero:has( .pa-svc2hero__shotbox ) { position: relative; overflow: hidden; }
.pa-svc2hero:has( .pa-svc2hero__shotbox ) .pa-svc2hero__grid { position: static; }
/*
 * PAINT ORDER: photo, then scrim, then content.
 *
 * All three are positioned with z-index auto, and the scrim sits BEFORE the
 * grid in the DOM while the photo sits inside it — so DOM order put the photo
 * ON TOP OF THE SCRIM and the photograph was never dimmed at all. It read as a
 * bright rectangle with a hard left edge instead of easing into the band, and
 * nothing in a geometry check can see that.
 */
.pa-svc2hero:has( .pa-svc2hero__shotbox ) .pa-svc2hero__shotbox { z-index: 0; }
.pa-svc2hero:has( .pa-svc2hero__shotbox ) .pa-svc2hero__shotscrim { z-index: 1; }
.pa-svc2hero:has( .pa-svc2hero__shotbox ) .pa-svc2hero__col,
.pa-svc2hero:has( .pa-svc2hero__shotbox ) .pa-svc2card { position: relative; z-index: 2; }
/*
 * BELOW 1024 the hero is one column, so the photo stops being a right-hand
 * bleed and becomes a normal block ABOVE the card — the stack the brief asks
 * for. Absolute positioning is dropped entirely rather than nudged, and the
 * scrim goes with it: there is nothing beside the photo to scrim any more.
 */
@media ( max-width: 1023px ) {
	/*
	 * Static again, so it flows where it sits in the markup: after the copy,
	 * directly above the card. Photo and card stack as a pair.
	 */
	.pa-svc2hero__shotbox {
		position: static; transform: none; width: 100%;
		max-width: min( 620px, 100% ); aspect-ratio: 620 / 496;
		margin: 0 0 22px; height: auto;
	}
	.pa-svc2hero__shotscrim { display: none; }
	.pa-svc2hero:has( .pa-svc2hero__shotbox ) { overflow: visible; }
}
/*
 * The orange row in the airflow card. Data-driven from the third element of
 * the row, never nth-child — the mockup paints the FAILING room, and which
 * row that is would move if the list ever changed.
 */
.pa-bars__row--bad .pa-bars__pct { color: var( --pa-tint ); }
.pa-bars__row--bad .pa-bars__fill { background: var( --pa-orange ); }

/* --- 18a2. The "shot" hero (AC Repair) ------------------------------------ *
 *
 * The mockup restructures this hero rather than adding a photo to it: the text
 * centres over a full-bleed photograph and the symptom picker moves out from
 * beside the copy to a full-width row underneath, six across.
 *
 * The picker keeps .pa-pick and every row style it already had. Only the
 * container changes from a stacked list to a grid, via .pa-pick--row — so the
 * 48px control height, the hover and the focus ring all still apply.
 */
.pa-svc2hero--shot {
	position: relative; overflow: hidden; padding: 92px var( --pa-gutter ) 0;
	background: var( --pa-ink );
}
.pa-svc2hero__shot {
	position: absolute; inset: 0; width: 100%; height: 100%;
	object-fit: cover; object-position: 50% 42%; display: block;
}
/*
 * Top-to-bottom, matching the mockup's 180deg. It is heaviest at the top where
 * the h1 sits and lightest at the bottom where the picker rows are, which is
 * why the picker's own contrast is measured separately.
 */
.pa-svc2hero__scrim {
	position: absolute; inset: 0;
	background: linear-gradient( 180deg, rgba( 20, 22, 27, 0.82 ) 0%, rgba( 20, 22, 27, 0.7 ) 42%, rgba( 20, 22, 27, 0.86 ) 100% );
}
.pa-svc2hero__centre {
	position: relative; max-width: 1080px; margin: 0 auto; text-align: center;
}
.pa-svc2hero__centre .pa-svc2hero__flag { justify-content: center; }
.pa-svc2hero--shot h1 { font-size: clamp( 40px, 6.2vw, 92px ); }
.pa-svc2hero__centre .pa-svc2hero__lede { margin-inline: auto; max-width: 640px; }
.pa-svc2hero__centre .pa-btns { justify-content: center; }

.pa-svc2hero__below {
	position: relative; max-width: var( --pa-shell ); margin: 0 auto;
	border-top: 1px solid var( --pa-hair-dark ); padding-top: 26px;
}
/*
 * minmax( min( 215px, 100% ), 1fr ) — the mockup's 215px floor, wrapped so it
 * can collapse. Six across at 1280 and above, and it steps down on its own.
 * A bare 215px floor would overflow a 375px phone.
 */
.pa-pick--row {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 215px, 100% ), 1fr ) );
	border-top: 0; padding-bottom: 8px; column-gap: 30px;
}
.pa-pick--row .pa-pick__row { padding: 26px 0; }
.pa-svc2hero__below .pa-pick__foot { padding: 0 0 60px; margin: 26px 0 0; }

/* The card used by the financing figure, the at-a-glance list and the charts. */
.pa-svc2card { border: 1px solid var( --pa-hair-dark ); padding: 28px 30px; background: rgba( 251, 247, 241, 0.04 ); }
.pa-svc2hero--cream .pa-svc2card { border-color: var( --pa-hair-light ); background: var( --pa-sand ); }
.pa-svc2card__label { color: var( --pa-ondark-dim ) !important; margin-bottom: 12px; }
.pa-svc2hero--cream .pa-svc2card__label { color: #646A76 !important; }
.pa-svc2card__body { font-size: 16px; line-height: 1.6; color: var( --pa-ondark ); margin: 18px 0 0; }
.pa-svc2hero--cream .pa-svc2card__body { color: #4A505C; }
.pa-svc2hero--cream .pa-svc2card .pa-price__fig { color: var( --pa-ink ); }
.pa-svc2card .pa-price__fig { font-size: clamp( 52px, 5.6vw, 76px ); color: var( --pa-cream ); }

/* Label / value pairs — the at-a-glance list and the compare panels. */
.pa-glance { margin: 0; display: grid; grid-template-columns: minmax( 0, 128px ) minmax( 0, 1fr ); gap: 0 18px; }
.pa-glance dt {
	font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.12em;
	text-transform: uppercase; color: var( --pa-ondark-dim );
	padding: 14px 0; border-top: 1px solid var( --pa-hair-dark );
}
/*
 * overflow-wrap: anywhere is LOAD-BEARING, not tidiness.
 *
 * These lists carry the email address, a single 34-character token with no
 * break opportunity in it. In a 149px cell on a 375px screen its min-content
 * width is 291px, and a grid track cannot shrink below the min-content of what
 * it holds — so the dd pushed .pa-glance to 437px, which pushed .pa-shell, the
 * section, and finally the document to a scrollWidth of 477px in a 375px
 * viewport.
 *
 * The reason that was hard to see: NO ELEMENT'S RECT EXCEEDED THE VIEWPORT.
 * Every getBoundingClientRect().right came back inside 375, because the rects
 * were clamped while the scroll box was not. The standing overflow check —
 * compare every right edge against clientWidth — reported zero while the page
 * scrolled sideways. Comparing scrollWidth against clientWidth, element by
 * element, is what found it.
 */
.pa-glance dd {
	margin: 0; font-size: 16.5px; line-height: 1.5; color: var( --pa-cream );
	padding: 14px 0; border-top: 1px solid var( --pa-hair-dark );
	overflow-wrap: anywhere;
}
.pa-glance dt:first-of-type, .pa-glance dd:first-of-type { border-top: 0; padding-top: 0; }
.pa-glance--light dt { color: #74644F; border-top-color: var( --pa-hair-light ); }
/*
 * PHONE: STACK THE PAIRS.
 *
 * The 128px dt track is fixed and does not collapse, so on a narrow screen it
 * takes its 128px and leaves the dd whatever remains. Measured inside the
 * Careers glance panel: dd was 64px wide at 414, 25px at 375, and 0px at 320,
 * where "Company vehicle and diagnostic equipment" rendered as a 920px-tall
 * ribbon one character wide.
 *
 * The reason no existing check caught it: `overflow-wrap: anywhere` above lets
 * the dd wrap to any width, so it never forces a scrollWidth and never trips
 * the overflow check, and the contrast check passed it because a one-character
 * column still has perfectly good contrast. It is only visibly wrong.
 *
 * All five .pa-glance usages get this — it is the component that is fragile,
 * not the Careers panel.
 */
@media ( max-width: 600px ) {
	.pa-glance { grid-template-columns: minmax( 0, 1fr ); }
	.pa-glance dt { padding: 14px 0 2px; }
	.pa-glance dd { padding: 0 0 14px; border-top: 0; }
	.pa-glance dd:first-of-type { padding-top: 0; }
}

.pa-glance--light dd { color: var( --pa-ink ); border-top-color: var( --pa-hair-light ); }

/* The illustrative airflow chart on /ductwork/. */
.pa-bars__sub { font-size: 15px; line-height: 1.5; color: var( --pa-ondark ); margin: 0 0 20px; }
.pa-bars__row { margin-bottom: 14px; }
.pa-bars__head { display: flex; justify-content: space-between; gap: 12px; font-size: 15px; margin-bottom: 6px; color: var( --pa-cream ); }
.pa-bars__pct { font-family: var( --pa-ff-mono ); font-size: 14px; color: var( --pa-ondark-dim ); }
/*
 * THE DEFAULT FILL IS LIGHT GREY, NOT ORANGE. It was orange for every row,
 * which made all four bars read as alarming and destroyed the only thing the
 * graphic says: three rooms are fine and one is not. The mockup's values are
 * a 0.12 track with a 0.55 fill, and orange strictly on the failing row.
 * Height is the mockup's 8px, not 6.
 */
.pa-bars__track { height: 8px; background: rgba( 251, 247, 241, 0.12 ); }
.pa-bars__fill { height: 8px; background: rgba( 251, 247, 241, 0.55 ); }
/*
 * The caption is part of the claim, not decoration: these are made-up numbers
 * and the page says so. Do not drop it, and do not restyle it to look like a
 * footnote nobody reads.
 */
.pa-bars__foot { font-size: 14px; line-height: 1.5; color: var( --pa-ondark-dim ); margin: 18px 0 0; }

/*
 * .pa-bars is an ON-DARK component, but two service heroes are ground: cream
 * (/indoor-air-quality/ and /ac-installation/). On cream, --pa-ondark #B9BDC6
 * measured 1.58:1 on the 15px sub copy — real body text, failing badly.
 * Pre-existing; found during the 2026-08-25 mockup rebuild, not caused by it.
 *
 * Scoped to the cream hero so the ink usages are untouched.
 */
.pa-svc2hero--cream .pa-bars__sub { color: #4A505C; }
.pa-svc2hero--cream .pa-bars__head { color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-bars__pct { color: var( --pa-tan ); }
.pa-svc2hero--cream .pa-bars__track { background: rgba( 20, 22, 27, 0.12 ); }
.pa-svc2hero--cream .pa-bars__foot { color: #4A505C; }


/* The humidity band on /indoor-air-quality/. */
.pa-hum { margin: 4px 0 20px; }
.pa-hum__scale {
	position: relative; height: 10px;
	background: linear-gradient( 90deg, #6E7480 0%, #A8B0A0 30%, #C2410C 100% );
}
.pa-hum__band {
	position: absolute; left: 22%; width: 26%; top: -4px; bottom: -4px;
	border: 2px solid var( --pa-ink );
}
.pa-svc2hero--cream .pa-hum__band { border-color: var( --pa-cream ); }
.pa-hum__ticks {
	display: flex; justify-content: space-between; margin-top: 8px;
	font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.1em;
	text-transform: uppercase; color: #646A76;
}

/* --- 18c. Body sections --------------------------------------------------- */

.pa-sec--svc2 { padding: 92px var( --pa-gutter ); }
.pa-sec--svc2ink { background: var( --pa-ink ); color: var( --pa-cream ); }
.pa-sec--svc2 .pa-head { margin-bottom: 52px; }
.pa-sec--svc2 .pa-head h2 { max-width: 13em; }
.pa-sec--svc2 .pa-mono.pa-eyebrow { color: #74644F; margin-bottom: 18px; }
.pa-sec--svc2ink .pa-mono.pa-eyebrow { color: var( --pa-ondark-dim ); }
.pa-sec--svc2ink h2, .pa-sec--svc2ink h3 { color: var( --pa-cream ); }
/*
 * EVERY component that sets its own body colour has to be named here.
 *
 * `.pa-sec--svc2ink p` is (0,1,1) and so is `.pa-card p`, `.pa-fig p` and the
 * rest — same weight, and the component rules are declared later, so they win.
 * The first version of this block relied on the generic selector and shipped
 * #4A505C body copy onto the ink bands: **2.23:1 at 16px**, an outright AA
 * failure, on /heating/, /ac-installation/, /ac-maintenance/ and
 * /indoor-air-quality/. Nothing errored and the text was legible enough to
 * look intentional; it was caught by compositing every text colour against its
 * walked backdrop and filtering for dark grounds.
 *
 * The list is explicit rather than clever on purpose. If you add a component
 * to section 18 that sets a colour, add it here too — and then measure, rather
 * than assuming the generic rule underneath covers it.
 */
.pa-sec--svc2ink .pa-head p,
.pa-sec--svc2ink .pa-card p,
.pa-sec--svc2ink .pa-fig p,
.pa-sec--svc2ink .pa-row2__body p,
.pa-sec--svc2ink .pa-panel__body,
.pa-sec--svc2ink .pa-panel__item p,
.pa-sec--svc2ink .pa-panel__itemhead,
.pa-sec--svc2ink .pa-checks__body,
.pa-sec--svc2ink .pa-matrix td,
.pa-sec--svc2ink p { color: var( --pa-ondark ); }
.pa-sec--svc2ink .pa-fig__num,
.pa-sec--svc2ink .pa-matrix tbody th { color: var( --pa-cream ); }
.pa-sec--svc2ink .pa-matrix thead th { color: var( --pa-ondark-dim ); border-bottom-color: rgba( 251, 247, 241, 0.4 ); }
.pa-sec--svc2ink .pa-matrix th, .pa-sec--svc2ink .pa-matrix td { border-bottom-color: var( --pa-hair-dark ); }

/*
 * overflow-wrap here for the same reason as .pa-glance dd: the careers
 * footnote prints the email address, which is one 34-character token with no
 * break opportunity. At 375 it ran 7px past the column. Any prose block that
 * can contain an address or a URL needs this — the token does not care that
 * the paragraph around it wraps perfectly well.
 */
.pa-svc2foot {
	margin: 34px 0 0; padding-top: 22px; border-top: 1px solid var( --pa-hair-light );
	font-size: 16.5px; line-height: 1.6; color: #4A505C; max-width: 46em;
	overflow-wrap: anywhere;
}
.pa-sec--svc2ink .pa-svc2foot { border-top-color: var( --pa-hair-dark ); color: var( --pa-ondark ); }
.pa-svc2foot a, .pa-card a, .pa-checks__body a, .pa-panel__rows a { font-weight: 500; color: var( --pa-orange-ink ); }
/*
 * On ink, --pa-orange-ink (#A5350A) is 2.3:1 and fails outright. The tint is
 * the link colour that works on this ground — the same one the hero eyebrows
 * use. This is the pair of rules that a "just use the orange token" cleanup
 * would collapse and break.
 */
.pa-sec--svc2ink .pa-svc2foot a, .pa-sec--svc2ink .pa-card a,
.pa-sec--svc2ink .pa-checks__body a, .pa-sec--svc2ink .pa-panel__rows a { color: var( --pa-tint ); }

/* cards + numbered — a hairline grid of heading and paragraph. */
.pa-cards {
	/* The 22% floor caps it at 4 columns however wide the container gets (the old 1200px column topped out at 4 too); without it 6 cards go 5 + 1 at 1600. */
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( max( 280px, 22% ), 100% ), 1fr ) );
	border-top: 1px solid var( --pa-ink );
}
.pa-sec--svc2ink .pa-cards { border-top-color: rgba( 251, 247, 241, 0.4 ); }
.pa-card { padding: 30px 34px 28px 0; border-bottom: 1px solid var( --pa-hair-light ); }
.pa-sec--svc2ink .pa-card { border-bottom-color: var( --pa-hair-dark ); }
.pa-card h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 21px;
	letter-spacing: -0.02em; margin: 0 0 10px;
}
.pa-card p { font-size: 16px; line-height: 1.55; color: #4A505C; margin: 0; }
.pa-card__num {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 15px;
	letter-spacing: 0.14em; color: var( --pa-orange-ink ); margin: 0 0 14px;
}
.pa-sec--svc2ink .pa-card__num { color: var( --pa-tint ); }
/*
 * THE NUMBER HAS NEVER RENDERED AS ITS OWN RULE INTENDED. The number is a <p>,
 * and `.pa-card p` (0,1,1) out-ranks `.pa-card__num` (0,1,0), so every numbered
 * card on the site showed its "01" as 16px body grey instead of a small tinted
 * label — and the 11.5px label is also shorter than a 16px line, so it moved
 * every heading beneath it. Every mockup draws it the same way: IBM Plex Mono,
 * 11.5px, 0.14em, tinted on ink and orange on light.
 *
 * (0,2,1) here beats `.pa-card p`. Affects every page using the numbered card:
 * /indoor-air-quality/, /about/, /contact/ and any other company page with one.
 */
.pa-card p.pa-card__num {
	font-family: var( --pa-ff-mono ); font-weight: 400; font-size: 11.5px; line-height: normal;
	letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-orange-ink ); margin: 0 0 14px;
}
.pa-sec--svc2ink .pa-card p.pa-card__num { color: var( --pa-tint ); }

/* rows — the number sits in the left gutter, full width. */
.pa-rows { border-top: 1px solid var( --pa-ink ); }
.pa-sec--svc2ink .pa-rows { border-top-color: rgba( 251, 247, 241, 0.4 ); }
.pa-row2 {
	display: grid; grid-template-columns: 72px minmax( 0, 1fr ); gap: 8px 24px;
	padding: 28px 0; border-bottom: 1px solid var( --pa-hair-light );
}
.pa-sec--svc2ink .pa-row2 { border-bottom-color: var( --pa-hair-dark ); }
.pa-row2__num {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: 15px;
	letter-spacing: 0.14em; color: var( --pa-orange-ink ); margin: 4px 0 0;
}
.pa-sec--svc2ink .pa-row2__num { color: var( --pa-tint ); }
.pa-row2__body h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 22px;
	letter-spacing: -0.02em; margin: 0 0 8px;
}
.pa-row2__body p { font-size: 16.5px; line-height: 1.55; color: #4A505C; margin: 0; max-width: 46em; }

/* figures — a large value above each heading. */
.pa-figs {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 260px, 100% ), 1fr ) );
	border-top: 1px solid var( --pa-ink );
}
.pa-fig { padding: 30px 34px 28px 0; border-bottom: 1px solid var( --pa-hair-light ); }
.pa-fig__num {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 26px, 2.6vw, 34px ); line-height: 1.05; letter-spacing: -0.028em;
	color: var( --pa-ink ); margin: 0 0 12px;
}
.pa-fig h3 {
	font-family: var( --pa-ff-mono ); font-weight: 500; font-size: 14px;
	letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-orange-ink ); margin: 0 0 10px;
}
.pa-fig p { font-size: 16px; line-height: 1.55; color: #4A505C; margin: 0; }

/* compare + decision — two panels under an orange rule. */
.pa-panels {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 340px, 100% ), 1fr ) );
	gap: 48px 72px;
}
.pa-panel { border-top: 2px solid var( --pa-orange ); padding-top: 26px; }
.pa-panel__tag {
	font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase;
	color: var( --pa-orange-ink ) !important; margin-bottom: 12px;
}
.pa-sec--svc2ink .pa-panel__tag { color: var( --pa-tint ) !important; }
.pa-panel__tag--under { margin-top: 10px; }
.pa-panel h3 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 26px, 2.8vw, 34px ); line-height: 1.05; letter-spacing: -0.028em; margin: 0 0 12px;
}
.pa-panel__body { font-size: 17px; line-height: 1.6; color: #4A505C; margin: 0 0 24px; max-width: 30em; }
.pa-panel__rows { margin: 0; display: grid; grid-template-columns: minmax( 0, 128px ) minmax( 0, 1fr ); gap: 0 18px; }
.pa-panel__rows dt {
	font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.12em;
	text-transform: uppercase; color: #74644F; padding: 16px 0;
	border-bottom: 1px solid var( --pa-hair-light );
}
.pa-panel__rows dd {
	margin: 0; font-size: 16.5px; line-height: 1.55; color: var( --pa-ink );
	padding: 16px 0; border-bottom: 1px solid var( --pa-hair-light );	overflow-wrap: anywhere;
}
.pa-sec--svc2ink .pa-panel__rows dt { color: var( --pa-ondark-dim ); border-bottom-color: var( --pa-hair-dark ); }
.pa-sec--svc2ink .pa-panel__rows dd { color: var( --pa-cream ); border-bottom-color: var( --pa-hair-dark ); }
.pa-panel__item { padding: 16px 0; border-bottom: 1px solid var( --pa-hair-light ); }
.pa-sec--svc2ink .pa-panel__item { border-bottom-color: var( --pa-hair-dark ); }
.pa-panel__itemhead { font-weight: 600; font-size: 16.5px; margin: 0 0 4px; }
.pa-panel__item p { font-size: 16px; line-height: 1.5; color: #4A505C; margin: 0; }

/* checks — a note column beside a ticked list. */
.pa-checks {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 320px, 100% ), 1fr ) );
	gap: 40px 72px; align-items: start;
}
.pa-checks__list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var( --pa-ink ); }
.pa-sec--svc2ink .pa-checks__list { border-top-color: rgba( 251, 247, 241, 0.4 ); }
.pa-checks__list li {
	display: grid; grid-template-columns: 26px minmax( 0, 1fr ); gap: 14px;
	padding: 20px 0; border-bottom: 1px solid var( --pa-hair-light );
}
.pa-sec--svc2ink .pa-checks__list li { border-bottom-color: var( --pa-hair-dark ); }
.pa-checks__tick { color: var( --pa-orange-ink ); font-size: 16px; line-height: 1.5; }
.pa-sec--svc2ink .pa-checks__tick { color: var( --pa-tint ); }
.pa-checks__head { display: block; font-weight: 600; font-size: 17px; margin-bottom: 4px; }
.pa-checks__body { display: block; font-size: 16px; line-height: 1.55; color: #4A505C; }
.pa-sec--svc2ink .pa-checks__body { color: var( --pa-ondark ); }

/* matrix — a real table, scrollable inside its own box rather than the page. */
.pa-matrix__scroll { overflow-x: auto; }
.pa-matrix { width: 100%; border-collapse: collapse; }
.pa-matrix th, .pa-matrix td {
	text-align: left; padding: 18px 20px 18px 0; vertical-align: top;
	border-bottom: 1px solid var( --pa-hair-light ); font-size: 16px; line-height: 1.5;
}
.pa-matrix thead th {
	font-family: var( --pa-ff-mono ); font-size: 14px; letter-spacing: 0.12em;
	text-transform: uppercase; color: #74644F; font-weight: 500;
	border-bottom: 1px solid var( --pa-ink );
}
.pa-matrix tbody th { font-weight: 600; color: var( --pa-ink ); }
.pa-matrix td { color: #4A505C; }

/* --- 18d. Quote band ------------------------------------------------------ */

/*
 * NO background here. It used to set cream, and because this rule is declared
 * after .pa-sec--services — both (0,1,0) — it beat the sand band modifier and
 * the quote band rendered cream on /contact/ and /maintenance-plans/ where
 * their mockups draw sand. Cream is the body ground: every other "cream"
 * section in this system simply declares no background. Do not add one back.
 */
.pa-sec--svc2quote { padding: 92px var( --pa-gutter ); }
/*
 * The form column takes the larger share above 1024. The copy beside it is a
 * short lede and a detail list and does not need half the shell; the form does,
 * because every 60px of width it gains takes a line off the consent block.
 */
.pa-svc2quote {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 400px, 100% ), 1fr ) );
	gap: 48px 72px; align-items: start;
}
@media ( min-width: 1024px ) {
	.pa-svc2quote { grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1.3fr ); }
}
.pa-svc2quote__col .pa-mono.pa-eyebrow { color: #74644F; margin-bottom: 18px; }
.pa-svc2quote__col h2 { margin: 0 0 18px; max-width: 14em; }
.pa-svc2quote__lede { font-size: 17.5px; line-height: 1.6; color: #4A505C; margin: 0 0 30px; max-width: 34em; }
.pa-svc2quote__alt { font-size: 16px; line-height: 1.6; color: #4A505C; margin: 26px 0 0; }
.pa-svc2quote__alt a { font-weight: 600; color: var( --pa-orange-ink ); }
/*
 * THE CITY FORMS WERE CAPPED AT 440px INSIDE 604-720px COLUMNS.
 *
 * `.pa-qf` has max-width: 440px as its default, and only the quote-section and
 * services-intro containers ever lifted it — so on a city page the form sat at
 * 440 in a 720px hero column and a 604px card, wasting a third of the width
 * and paying for it in height: the consent block wrapped to TEN lines and the
 * form measured 958px. It also kept the form under the 560px container-query
 * threshold, so the select and message could not pair.
 *
 * Lifting the cap fixes both at once. The card and the hero column already
 * bound the width, so nothing runs away.
 */
/*
 * THE FORM'S OWN TITLE IS HIDDEN IN THE QUOTE SECTION, and only there.
 *
 * That section's h2 already addresses the form directly — "Tell us what it is
 * doing and we will get you a time", "Sign up for a plan" — so "Start your
 * quote / No cost, no obligation" immediately beside it is the same
 * instruction twice, and it costs 49px of height in the column that was
 * already the taller of the two.
 *
 * NOT hidden in the city hero or the maintenance-plans hero card: there the
 * heading above is the PAGE's, about the city or the plans, and the form's own
 * title is the only thing naming it.
 *
 * The <form> carries aria-label="Start your quote" in every case, so hiding
 * the visible title never leaves the form without an accessible name, and
 * display:none keeps it out of the accessibility tree rather than announcing
 * it twice where it is shown.
 */
.pa-svc2quote__form .pa-qf__head,
.pa-svc2quote__form .pa-qf__lede { display: none; }

@media ( max-width: 900px ) {
	.pa-sec--svc2, .pa-sec--svc2quote { padding: 64px var( --pa-gutter ); }
	.pa-card, .pa-fig { padding-right: 0; }
	.pa-row2 { grid-template-columns: minmax( 0, 1fr ); gap: 6px; }
}


/* --- 19. COMPANY PAGES ------------------------------------------------------
 *
 * /about/, /contact/, /faq/, /financing/, /maintenance-plans/, /careers/.
 * Most of these pages are section-18 components; what follows is only the
 * four shapes the company mockups add.
 * ------------------------------------------------------------------------- */

/* --- 19a. Hero stat rail (/about/) ---------------------------------------- */

/*
 * A <dl>, not a grid of divs: each cell is a value and its label, which is
 * what a description list is. The .pa-statrail__cell wrapper is what lets
 * dt/dd pair up inside a grid — a bare dl puts every dt and dd on its own
 * track and the pairs come apart.
 */
/*
 * STAT RAIL — /about/. Built to the mockup: a single row of tracks spanning
 * the full content width, one rule above the whole rail and one under each
 * cell. No gap grid and no per-cell background.
 *
 * The earlier version painted hairlines with `gap: 1px` over a container
 * background. With auto-fit and five items in a six-track row, the leftover
 * track showed that background as a solid block — the "empty sixth cell".
 * Rules on the cells themselves cannot do that.
 *
 * The 190px floor is the mockup's own, and it is also sized to the longest
 * UNBREAKABLE value the rail holds: "CAC1820635" is 135px at this display
 * size and a licence number has no break opportunity in it. It was never the
 * cause of the wrap — the rail was being laid out inside a half-width aside,
 * where five 190px tracks cannot fit. It sits at full width now.
 *
 * overflow-wrap on the dt stays as the net: a value longer than the floor
 * should degrade to an ugly wrap, not to a page that scrolls sideways.
 */
.pa-statrail {
	margin: 62px 0 0; display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 190px, 100% ), 1fr ) );
	border-top: 1px solid rgba( 251, 247, 241, 0.4 );
}
.pa-statrail__cell { padding: 30px 34px 28px 0; border-bottom: 1px solid var( --pa-hair-dark ); }
.pa-svc2hero--cream .pa-statrail { border-top-color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-statrail__cell { border-bottom-color: var( --pa-hair-light ); }
.pa-statrail dt {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 26px, 2.6vw, 34px ); line-height: 1; letter-spacing: -0.03em;
	color: var( --pa-cream ); margin: 0;
	overflow-wrap: anywhere;
}
.pa-svc2hero--cream .pa-statrail dt { color: var( --pa-ink ); }
.pa-statrail dd {
	margin: 12px 0 0; font-family: var( --pa-ff-mono ); font-size: 14px;
	letter-spacing: 0.1em; text-transform: uppercase; color: var( --pa-ondark-dim );
	line-height: 1.4;
}
.pa-svc2hero--cream .pa-statrail dd { color: #646A76; }

/* --- 19a-ii. Full-width hero (/about/) ------------------------------------- */

/*
 * One column, not two. The aside is still a sibling in the markup; collapsing
 * the grid to a single track drops it below the column at the section's full
 * width, which is where the mockup puts the stat rail. No markup branch.
 */
/*
 * FAQ.dc.html bottom-aligns its two hero columns, so the paragraph and the
 * jump links sit level with the foot of the h1 rather than level with its top.
 */
.pa-svc2hero--bottom .pa-svc2hero__grid { align-items: end; }
.pa-svc2hero--bottom .pa-svc2hero__aside { min-height: 0; }
.pa-svc2hero__lede--aside { margin: 0 0 26px; max-width: 500px; }
/* h1 caps to the value the page declares, on the standard hero too. */
.pa-svc2hero h1 { font-size: clamp( 38px, 5.6vw, var( --pa-hero-h1-max, 68px ) ); }
.pa-svc2hero--full .pa-svc2hero__grid { grid-template-columns: minmax( 0, 1fr ); gap: 0; }
.pa-svc2hero--full .pa-svc2hero__col { max-width: 900px; }
.pa-svc2hero--full .pa-svc2hero__aside { min-height: 0; }
/*
 * The mockup sets this hero larger than the shared one — 84px against 64px at
 * the cap, and a 19px lede in a 620px measure. Scoped to the variant rather
 * than changed globally: it is this page's hero, not the site's.
 */
.pa-svc2hero--full h1 { font-size: clamp( 40px, 5.6vw, 84px ); line-height: 0.93; letter-spacing: -0.04em; }
.pa-svc2hero--full .pa-svc2hero__lede { font-size: 19px; max-width: 620px; margin-bottom: 36px; }
.pa-svc2hero--full .pa-btns { margin-bottom: 0; }

/*
 * /financing/ HERO, to Financing.dc.html — scoped by the page's body class
 * because every value here is this page's and none should leak into the shared
 * hero, the shared price figure, or the price bands that reuse .pa-price__fig.
 *
 * What the mockup draws that the build did not:
 *   - the band CLOSES on a 1px ink rule under the content (the hero has no
 *     bottom padding; the grid carries 52px and the rule);
 *   - the figure is a free-standing $58/mo, not a boxed card: a hairline on
 *     the left, 44px of padding, no ground, no other borders;
 *   - the figure is clamp(72px, 9vw, 132px), nearly twice the shared 92px cap;
 *   - h1 76px cap, 0.94 leading, -0.038em, 24px beneath.
 */
.pa-page-financing .pa-svc2hero__grid {
	padding-bottom: 52px; border-bottom: 1px solid var( --pa-ink );
}
.pa-page-financing .pa-svc2hero h1 {
	font-size: clamp( 40px, 5.4vw, 76px ); line-height: 0.94; letter-spacing: -0.038em; margin: 0 0 24px;
}
/*
 * VERTICAL RHYTHM. Measured against the rendered mockup, the build's hero was
 * 59px taller at 1440 and the whole of it was inherited body leading plus two
 * margins the mockup does not have:
 *   - the eyebrow block: line-height 1.6 instead of `normal` (+4px) and a 26px
 *     gap to the h1 instead of 18px (+8px);
 *   - the buttons: line-height 1.6 gives a 62px button where the mockup's is
 *     55px (+7px) — this is a GLOBAL difference in .pa-btn, scoped here only
 *     because changing it everywhere would move every hero on the site;
 *   - .pa-btns carries a 48px bottom margin; the mockup has none (+40px net,
 *     the rest being absorbed by the row gap).
 */
.pa-page-financing .pa-svc2hero__flag { margin-bottom: 18px; line-height: normal; }
.pa-page-financing .pa-svc2hero__eyebrow { font-size: 12px; letter-spacing: 0.16em; line-height: normal; }
.pa-page-financing .pa-svc2hero .pa-btns { margin-bottom: 0; }
.pa-page-financing .pa-svc2hero .pa-btn { line-height: normal; }
.pa-page-financing .pa-svc2hero__lede { margin: 0 0 36px; max-width: 520px; }
.pa-page-financing .pa-svc2hero .pa-btn--ghost { border-color: rgba( 20, 22, 27, 0.35 ); }
.pa-page-financing .pa-svc2hero .pa-svc2card {
	border: 0; border-left: 1px solid rgba( 20, 22, 27, 0.16 );
	background: none; padding: 0 0 0 44px;
}
.pa-page-financing .pa-svc2hero .pa-svc2card__label {
	font-size: 12px; letter-spacing: 0.14em; margin-bottom: 10px; line-height: normal;
}
.pa-page-financing .pa-svc2hero .pa-price__fig {
	font-size: clamp( 72px, 9vw, 132px ); line-height: 0.82; letter-spacing: -0.05em;
}
/*
 * The suffix is 0.3em of the figure, NOT the shared 30px. At 132px that is
 * ~40px and at 72px it is ~22px, so it stays in proportion instead of looking
 * like a footnote next to a giant number.
 */
.pa-page-financing .pa-svc2hero .pa-price__fig span {
	font-size: 0.3em; letter-spacing: 0; font-weight: 600; color: #6E7480;
}
.pa-page-financing .pa-svc2hero .pa-svc2card__body {
	font-size: 16.5px; line-height: 1.55; margin: 24px 0 0; max-width: 26em;
}
/* Stacked, the hairline still divides the figure from the copy above it. */
@media ( max-width: 600px ) {
	.pa-page-financing .pa-svc2hero .pa-svc2card { padding-left: 24px; }
}

/*
 * /contact/ TOP OF PAGE, to Contact.dc.html — hero photograph, the three-card
 * strip, and the dark form card. All scoped by .pa-page-contact or by the
 * opt-in .pa-sec--qdark / .pa-qf--ph classes, so nothing here reaches another
 * page's hero, rails or form.
 */

/* --- hero -------------------------------------------------------------- */
.pa-page-contact .pa-svc2hero__bgimg { object-position: 40% 50%; }
.pa-page-contact .pa-svc2hero__bgscrim {
	background: linear-gradient(
		90deg,
		var( --pa-ink ) 0%,
		rgba( 20, 22, 27, 0.92 ) 32%,
		rgba( 20, 22, 27, 0.66 ) 54%,
		rgba( 20, 22, 27, 0.34 ) 78%,
		rgba( 20, 22, 27, 0.26 ) 100%
	);
}
/*
 * CONTRAST BELOW 1280. The mockup's ramp eases out to 0.26 at the right edge,
 * which is fine while the 760px copy column sits inside the heavy left 70% —
 * measured 5.4 to 6.5:1 for the lede from 1280 up. Below that the column
 * reaches into the thin end and the lede falls to 3.7:1 at 1100, 2.0:1 at 768
 * and 2.5:1 at 375, sampled against the real photo pixels. Same failure, same
 * fix as the About, Careers and homepage heroes: an evener, heavier veil.
 */
@media ( max-width: 1279px ) {
	.pa-page-contact .pa-svc2hero__bgscrim {
		background: linear-gradient(
			90deg,
			var( --pa-ink ) 0%,
			rgba( 20, 22, 27, 0.94 ) 40%,
			rgba( 20, 22, 27, 0.88 ) 70%,
			rgba( 20, 22, 27, 0.84 ) 100%
		);
	}
}
.pa-page-contact .pa-svc2hero--full .pa-svc2hero__col { max-width: 760px; }
.pa-page-contact .pa-svc2hero__flag { margin-bottom: 18px; line-height: normal; }
.pa-page-contact .pa-svc2hero__eyebrow { font-size: 12px; letter-spacing: 0.16em; line-height: normal; }
.pa-page-contact .pa-svc2hero h1 { margin: 0 0 22px; }
.pa-page-contact .pa-svc2hero__lede { font-size: 19px; max-width: 620px; margin: 0; }

/* --- the three-card strip ---------------------------------------------- */
/*
 * SPECIFICITY NOTE: every selector below is `.pa-page-contact .pa-rails .pa-rail`
 * (0,3,0) on purpose. The shared rule `.pa-rail:first-child { padding-left: 0 }`
 * is (0,2,0) and sits LATER in the file, so a (0,2,0) override here loses the
 * tie on source order — which is exactly what happened first time: the ink card
 * lost its left padding, its copy re-wrapped and the whole strip came out 32px
 * short. Beat it on specificity, not by reordering.
 *
 * It was a full-width row of identical cream cells under an ink rule. The
 * mockup is a 1040px strip of THREE different cards — ink, cream with a
 * hairline, sand — held together by a 2px gap over a hairline ground.
 */
.pa-page-contact #contact { padding: 72px var( --pa-gutter ) 88px; }
.pa-page-contact .pa-rails {
	max-width: 1040px; margin: 0 auto; gap: 2px; border-top: 0;
	background: rgba( 20, 22, 27, 0.14 );
}
.pa-page-contact .pa-rails .pa-rail { padding: 36px 30px 32px; box-sizing: border-box; }
/*
 * Margins are set PER ELEMENT, never by a blanket `.pa-rail p { margin: 0 }`.
 * The blanket rule was (0,3,1) and out-ranked the (0,3,0) per-element margins
 * below it, which zeroed the label and value margins and left every card 32px
 * short. The <p> tags are the component's; give each one its own margin.
 */
.pa-page-contact .pa-rails .pa-rail__label {
	font-size: 11.5px; letter-spacing: 0.14em; line-height: normal; margin: 0 0 18px;
}
.pa-page-contact .pa-rails .pa-rail__value {
	font-size: clamp( 20px, 2vw, 26px ); line-height: 1.15; letter-spacing: -0.025em; margin: 0 0 14px;
}
.pa-page-contact .pa-rails .pa-rail__body { margin: 0; }
.pa-page-contact .pa-rails .pa-rail__note {
	font-size: 11.5px; letter-spacing: 0.1em; line-height: normal; margin: 0; color: #74644F;
}
/* 1: Call — ink */
.pa-page-contact .pa-rails .pa-rail:nth-child( 1 ) { background: var( --pa-ink ); color: var( --pa-cream ); }
.pa-page-contact .pa-rails .pa-rail:nth-child( 1 ) .pa-rail__label { color: var( --pa-tint ) !important; }
.pa-page-contact .pa-rails .pa-rail:nth-child( 1 ) .pa-rail__value {
	color: var( --pa-cream ); font-size: clamp( 30px, 3.2vw, 42px ); line-height: 1; letter-spacing: -0.035em;
}
.pa-page-contact .pa-rails .pa-rail:nth-child( 1 ) .pa-rail__body { color: var( --pa-ondark ); }
.pa-page-contact .pa-rails a.pa-rail:nth-child( 1 ):hover { background: #1C1F26; color: var( --pa-cream ); }
/* 2: Email — cream with a hairline */
.pa-page-contact .pa-rails .pa-rail:nth-child( 2 ) { background: var( --pa-cream ); border: 1px solid rgba( 20, 22, 27, 0.14 ); }
.pa-page-contact .pa-rails .pa-rail:nth-child( 2 ) .pa-rail__label,
.pa-page-contact .pa-rails .pa-rail:nth-child( 3 ) .pa-rail__label { color: #74644F !important; }
/* 3: Office — sand, a touch roomier */
.pa-page-contact .pa-rails .pa-rail:nth-child( 3 ) { background: var( --pa-sand ); padding: 40px 36px 36px; }
.pa-page-contact .pa-rails .pa-rail:nth-child( 3 ) .pa-rail__value { line-height: 1.2; }
.pa-page-contact .pa-rails .pa-rail:nth-child( 3 ) .pa-rail__body { margin-bottom: 10px; }

/* --- the quote section: dark form card --------------------------------- */
/*
 * EQUAL columns. The shared quote grid gives the form the larger share above
 * 1024 (1fr 1.3fr) to keep the form short; the Contact mockup draws two equal
 * halves around the dark card, so this section opts out.
 */
@media ( min-width: 1024px ) {
	.pa-sec--qdark .pa-svc2quote { grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr ); }
}
.pa-sec--qdark .pa-svc2quote__col .pa-mono.pa-eyebrow { font-size: 12px; letter-spacing: 0.16em; line-height: normal; }
.pa-sec--qdark .pa-svc2quote__col h2 { font-size: clamp( 31px, 3.4vw, 44px ); line-height: 1.04; letter-spacing: -0.03em; margin: 0 0 20px; max-width: 15em; }
.pa-sec--qdark .pa-svc2quote__lede { font-size: 17.5px; line-height: 1.6; margin: 0 0 30px; max-width: 32em; }
/*
 * NAMED .pa-qfacts, NOT .pa-facts. `.pa-facts` is the ink facts panel on all 42
 * city pages (patterns/city-facts.php), and this block sat later in the file
 * with the same class names, so it silently restyled every one of them: rows
 * went from 28px 32px padding to 18px 0 and flex. Every structural check
 * passed, because none of them measure spacing on the city pages.
 */
.pa-qfacts { margin: 0; border-top: 1px solid rgba( 20, 22, 27, 0.16 ); }
.pa-qfacts__row {
	display: flex; gap: 18px; padding: 18px 0; align-items: baseline;
	border-bottom: 1px solid rgba( 20, 22, 27, 0.16 );
}
.pa-qfacts dt { font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase; color: #74644F; min-width: 92px; }
.pa-qfacts dd { margin: 0; font-size: 16.5px; line-height: normal; color: var( --pa-ink ); }
.pa-sec--qdark .pa-svc2quote__alt { margin: 24px 0 0; font-size: 16.5px; line-height: 1.6; }
@media ( max-width: 480px ) {
	.pa-qfacts__row { flex-direction: column; gap: 4px; }
}

.pa-sec--qdark .pa-svc2quote__form {
	background: var( --pa-ink ); color: var( --pa-cream ); padding: 38px 36px 34px; box-sizing: border-box;
}
/*
 * Visually hidden labels. The standard pattern — NOT display:none, which would
 * take them out of the accessibility tree and leave every field unnamed.
 */
.pa-qf--ph .pa-qf__label {
	position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip: rect( 0, 0, 0, 0 ); white-space: nowrap; border: 0;
}
/*
 * NO select+message pairing in this mode. The container query that pairs them
 * is for the light form; the Contact mockup stacks them, each full width.
 */
.pa-qf--ph .pa-qf__pair { display: block; }
.pa-qf--ph .pa-qf__field { margin: 0 0 10px; }
/*
 * 12px, not 8: the mockup's textarea is an inline-block, so it sits on the
 * text baseline and carries ~4px of descender gap beneath its 18px margin. The
 * gap is an artefact, but the button lands 4px lower in the mockup because of
 * it, so it is reproduced here (10px field margin + 12px = 22px).
 */
.pa-qf--ph .pa-qf__textarea { min-height: 90px; margin-bottom: 12px; }
.pa-qf--ph .pa-qf__submit { padding: 18px 24px; line-height: normal; }
.pa-qf--ph .pa-qf__row { gap: 10px; }
.pa-qf--ph .pa-qf__err:empty { display: none; }
.pa-qf--ph .pa-qf__input {
	/*
	 * BORDER ALPHA 0.36, NOT THE MOCKUP'S 0.22. At 0.22 the field boundary
	 * measures 2.00:1 against the dark card, under the 3:1 WCAG 1.4.11 asks of a
	 * control's edge — and here the edge is essentially all there is, because the
	 * 0.06 fill is nearly invisible on ink. Solved for, not guessed: 0.36 gives
	 * 3.14:1 (3.0 needs 0.345). Visually a touch firmer than drawn.
	 */
	background: rgba( 251, 247, 241, 0.06 ); border: 1px solid rgba( 251, 247, 241, 0.36 );
	color: var( --pa-cream ); padding: 14px 15px; font-size: 15.5px; border-radius: 2px;
}
.pa-qf--ph .pa-qf__input::placeholder { color: var( --pa-ondark-dim ); opacity: 1; }
.pa-qf--ph select.pa-qf__input option { color: var( --pa-ink ); background: var( --pa-cream ); }
.pa-qf--ph .pa-qf__input[aria-invalid="true"] { border-color: var( --pa-tint ); }
.pa-qf--ph .pa-qf__err { color: var( --pa-tint ); }
.pa-qf--ph .pa-qf__alert { color: var( --pa-cream ); }
/*
 * The dark card (.pa-svc2quote__form) IS the card. The form inside carries its
 * own ground, padding, border and shadow from the light-card styling, so
 * leaving them on stacked a second frame inside the first and added ~70px.
 */
/*
 * .pa-qf__form AND .pa-qf__done share one card rule (.pa-qf__form, .pa-qf__done
 * at the top of this component), so resetting only the form left the SUCCESS
 * panel with the light-card ground and padding inside the dark card. Its text
 * then measured 1.8:1 — light type on cream — on the most important message
 * the form ever shows. Both panels are reset together.
 */
.pa-qf--ph .pa-qf__form,
.pa-qf--ph .pa-qf__done { background: transparent; padding: 0; border: 0; box-shadow: none; }
/*
 * The "AC out right now? Call..." line is the same instruction the left column
 * already gives ("Rather talk it through? Call..."), a few inches away, and the
 * mockup's form does not have it. Hidden in this dark-card mode only.
 */
.pa-qf--ph .pa-qf__urgent { display: none; }
/*
 * The consent block, to the mockup: 12.5px in --pa-ondark-dim (5.65:1 on ink)
 * under its own hairline — which this block now has to draw itself, because
 * the "AC out right now?" line that used to sit above it carried the rule.
 */
.pa-qf--ph .pa-qf__consent {
	margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba( 251, 247, 241, 0.16 );
	align-items: start; gap: 10px;
}
.pa-qf--ph .pa-qf__check { width: 15px; height: 15px; margin: 4px 0 0; accent-color: var( --pa-orange ); }
.pa-qf--ph .pa-qf__consent-text { font-size: 12.5px; line-height: 1.55; color: var( --pa-ondark-dim ); }
.pa-qf--ph .pa-qf__consent-text a { color: var( --pa-tint ); }
.pa-qf--ph .pa-qf__done { color: var( --pa-cream ); }
/* The title sets its own colour (ink), so the container's colour never reaches it. */
.pa-qf--ph .pa-qf__done-title { color: var( --pa-cream ); }
.pa-qf--ph .pa-qf__done-body { color: var( --pa-ondark ); }
.pa-qf--ph .pa-qf__done-eyebrow { color: var( --pa-tint ); }
.pa-qf--ph .pa-qf__done-tel { background: var( --pa-orange ); color: #fff; }
.pa-qf--ph .pa-qf__done-tel:hover { background: #A5350A; color: #fff; }

/*
 * /indoor-air-quality/ — to Indoor Air Quality.dc.html as it is exported NOW.
 * Two things had moved since this page was built: the humidity meter is a
 * full-width band under the hero rather than a card over the photograph, and
 * the filter cabinet sits in the "Three levers" heading row rather than under
 * the cards.
 */

/* --- hero ----------------------------------------------------------------- */
.pa-svc2hero--meter .pa-svc2hero__col { max-width: min( 640px, 52% ); }
.pa-svc2hero--meter .pa-svc2hero__backimg { object-position: 62% 44%; }
.pa-svc2hero--meter .pa-svc2hero__flag { margin-bottom: 18px; line-height: normal; }
.pa-svc2hero--meter .pa-svc2hero__eyebrow { font-size: 12px; letter-spacing: 0.16em; line-height: normal; }
.pa-svc2hero--meter h1 { font-size: clamp( 40px, 5.6vw, 82px ); line-height: 0.94; letter-spacing: -0.04em; margin: 0 0 24px; }
.pa-svc2hero--meter .pa-svc2hero__lede { font-size: 19px; max-width: none; margin: 0 0 36px; }
.pa-svc2hero--meter .pa-btns { margin-bottom: 0; }
.pa-svc2hero--meter .pa-btn { line-height: normal; }
.pa-svc2hero--meter .pa-btn--ghost { border-color: rgba( 20, 22, 27, 0.35 ); }
/*
 * THE PHOTOGRAPH'S TWO FADES. The panel fit used to hide the scrim outright,
 * on the stated ground that "the mockup runs no gradient over it". That was
 * wrong: Indoor Air Quality.dc.html draws two — a left fade from solid cream
 * to 0.06 over 100% of the width, and a 190px fade to solid cream at the foot
 * — which is the soft edge in the design and the reason the photo reads as
 * part of the page rather than a rectangle pasted onto it.
 */
.pa-svc2hero--panel .pa-svc2hero__backscrim {
	display: block; inset: auto; top: 0; right: 0; left: auto; bottom: auto;
	width: min( 46%, 740px ); height: 560px; pointer-events: none;
	background:
		linear-gradient( 180deg, rgba( 251, 247, 241, 0 ) 0%, #FBF7F1 78% ) bottom / 100% 190px no-repeat,
		linear-gradient( 90deg, #FBF7F1 0%, rgba( 251, 247, 241, 0.62 ) 18%, rgba( 251, 247, 241, 0.12 ) 40%, rgba( 251, 247, 241, 0.06 ) 100% );
}
.pa-svc2hero--meter .pa-svc2hero__grid { position: relative; }
/*
 * NARROW. The mockup is a fixed desktop layout: at phone width it leaves the
 * photograph behind the headline with nothing over it. Built that way this
 * was unreadable (the h1 and lede ran across the thermostat), so below 700px
 * the copy takes the full width and the photo becomes a washed-out ground
 * behind the whole hero. The 0.9 cream veil keeps every pixel under text
 * well past 4.5:1 whatever the photo does beneath it.
 */
@media ( max-width: 700px ) {
	.pa-svc2hero--meter .pa-svc2hero__col { max-width: none; }
	.pa-svc2hero--meter.pa-svc2hero--panel .pa-svc2hero__backdrop,
	.pa-svc2hero--meter.pa-svc2hero--panel .pa-svc2hero__backscrim {
		inset: 0; width: 100%; min-width: 0; height: auto;
	}
	.pa-svc2hero--meter.pa-svc2hero--panel .pa-svc2hero__backscrim { background: rgba( 251, 247, 241, 0.9 ); }
}
.pa-svc2hero__meterwrap { position: relative; }

/* --- the humidity band ------------------------------------------------------ */
.pa-meter { margin-top: 62px; padding: 34px 0 30px; border-top: 1px solid var( --pa-ink ); }
.pa-meter__head { display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap; margin-bottom: 20px; }
/* Colours are the page's tan and grey, darkened where the mockup's fail contrast. */
.pa-meter__label { font-size: 11.5px; letter-spacing: 0.16em; text-transform: uppercase; color: #74644F; line-height: normal; }
.pa-meter__sub { font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; color: #646A76; line-height: normal; }
.pa-meter__bar {
	position: relative; height: 74px; border: 1px solid rgba( 20, 22, 27, 0.2 );
	background: rgba( 255, 255, 255, 0.5 );
}
.pa-meter__ok, .pa-meter__bad {
	position: absolute; top: 0; bottom: 0; display: flex; align-items: center;
	font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; line-height: normal;
}
.pa-meter__ok { left: 40%; width: 20%; justify-content: center; background: var( --pa-ink ); color: var( --pa-cream ); }
.pa-meter__bad { left: 72%; right: 0; border-left: 1px solid var( --pa-orange ); padding-left: 14px; color: var( --pa-orange-ink ); }
.pa-meter__ticks { display: flex; justify-content: space-between; font-size: 11.5px; letter-spacing: 0.1em; color: #646A76; margin-top: 10px; line-height: normal; }
.pa-meter__body { font-size: 16.5px; line-height: 1.6; color: #4A505C; margin: 24px 0 60px; max-width: 46em; }
@media ( max-width: 600px ) {
	/* The bar's in-bar labels cannot fit at phone width; the paragraph carries the meaning. */
	.pa-meter__bad { font-size: 10px; padding-left: 8px; letter-spacing: 0.06em; }
	.pa-meter__ok { font-size: 10px; letter-spacing: 0.06em; }
}
/* At 375 the ink block is 59px wide and "Comfortable" is clipped to "OMFORTABL".
   The bar is aria-hidden and the tick row beneath already reads "Comfortable",
   so the in-bar copy is dropped there instead of being shrunk past legibility. */
@media ( max-width: 520px ) {
	.pa-meter__ok { font-size: 0; letter-spacing: 0; }
}

/* --- the "Three levers" heading row ------------------------------------------ */
.pa-headfig {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 320px, 100% ), 1fr ) );
	gap: 40px 64px; align-items: center; margin-bottom: 56px;
}
.pa-headfig__copy .pa-mono.pa-eyebrow { font-size: 12px; letter-spacing: 0.16em; color: var( --pa-ondark-dim ); margin: 0 0 18px; line-height: normal; }
.pa-headfig__copy h2 { font-size: clamp( 31px, 3.4vw, 46px ); line-height: 1.04; letter-spacing: -0.03em; margin: 0 0 22px; max-width: 13em; color: var( --pa-cream ); }
.pa-headfig__lede { font-size: 18px; line-height: 1.6; color: var( --pa-ondark ); margin: 0; max-width: 32em; }
.pa-headfig__fig { margin: 0 auto; max-width: 400px; width: 100%; } /* centred in its column, as drawn */
.pa-headfig__img { display: block; width: 100%; height: auto; filter: drop-shadow( 0 26px 48px rgba( 0, 0, 0, 0.55 ) ); }
.pa-headfig__fig figcaption {
	font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; line-height: normal;
	color: var( --pa-ondark-dim ); margin-top: 22px; padding-top: 16px;
	border-top: 1px solid rgba( 251, 247, 241, 0.16 ); text-align: center;
}

/* --- symptoms section, to the mockup --------------------------------------- */
/*
 * Scoped to THIS page's #symptoms. The shared .pa-card carries the "levers"
 * values (30/34/28, 16px body, cream rule above); the symptoms grid in the
 * mockup is tighter and draws an INK rule above it. Other pages' plain card
 * grids use the same component and have not been compared, so they are left
 * as they are rather than changed on a guess.
 */
.pa-page-indoor-air-quality #symptoms .pa-head { align-items: end; gap: 32px 64px; margin-bottom: 52px; }
.pa-page-indoor-air-quality #symptoms .pa-head h2 { margin: 0; max-width: 13em; }
.pa-page-indoor-air-quality #symptoms .pa-head p:not(.pa-mono) { font-size: 18px; line-height: 1.6; max-width: 34em; margin: 0; }
.pa-page-indoor-air-quality #symptoms .pa-cards {
	grid-template-columns: repeat( auto-fit, minmax( min( 300px, 100% ), 1fr ) ); border-top: 1px solid var( --pa-ink );
}
.pa-page-indoor-air-quality #symptoms .pa-card { padding: 28px 34px 26px 0; border-bottom: 1px solid rgba( 20, 22, 27, 0.18 ); }
.pa-page-indoor-air-quality #symptoms .pa-card h3 { margin: 0 0 8px; }
.pa-page-indoor-air-quality #symptoms .pa-card p { font-size: 16.5px; }
/* Card headings sit on the font's own line height in the mockup (22px at 21px
   type); the shared .pa-card h3 leading is taller and pushed every row down. */
.pa-page-indoor-air-quality #levers .pa-card h3,
.pa-page-indoor-air-quality #symptoms .pa-card h3 { line-height: normal; }
/* The mockup keeps the 34px right gutter on these cards at every width; the
   shared <=900px rule drops it, which re-wraps the paragraphs at tablet. */
.pa-page-indoor-air-quality #levers .pa-card,
.pa-page-indoor-air-quality #symptoms .pa-card { padding-right: 34px; }
.pa-page-indoor-air-quality #symptoms .pa-head h2 { font-size: clamp( 31px, 3.4vw, 46px ); line-height: 1.04; letter-spacing: -0.03em; }
.pa-page-indoor-air-quality #symptoms .pa-head .pa-mono.pa-eyebrow { font-size: 12px; line-height: normal; }
/* The closing line carries no rule above it on this page. #6A707C is the
   mockup's #6E7480 nudged to clear 4.5:1 on the cream (4.37:1 as exported). */
.pa-page-indoor-air-quality #levers .pa-svc2foot,
.pa-page-indoor-air-quality #symptoms .pa-svc2foot { margin-top: 26px; padding-top: 0; border-top: 0; }
.pa-page-indoor-air-quality #symptoms .pa-svc2foot { max-width: none; line-height: normal; color: #6A707C; }

/* --- /heating/ hero, to Heating.dc.html ------------------------------------- */
/*
 * INK PHOTO HERO. A photograph down the right 46% of an ink hero, full height,
 * with ONE scrim over the whole section (ink solid to 42%, then 0.86 / 0.55 /
 * 0.42). The copy is a single column over the ink on the left. Not a variant of
 * --panel (cream, 560px tall, fades to cream) or of the default backdrop (cream
 * scrim) — both would be wrong colours here.
 *
 * The mockup's scrim is fine where the copy stays left of the photo, but below
 * ~1280px the note line runs out under it and the grey text drops to ~2:1 on
 * the light wall. So the scrim strengthens as the viewport narrows, and is
 * near-flat on phones. Checked against the photo's real brightest pixels.
 */
.pa-svc2hero--inkphoto .pa-svc2hero__backdrop { width: 46%; min-width: min( 320px, 100% ); }
.pa-svc2hero--inkphoto .pa-svc2hero__backimg { object-position: 50% 40%; }
/*
 * Two layers. The bottom one is the mockup's gradient, verbatim. The top one is
 * the legibility floor: 0.93 ink up to the right edge of the note line (the
 * shell's left edge plus its 726px max-width), fading out over 120px after it.
 * On a wide screen the copy ends before the photo starts and the floor is
 * invisible under the mockup's own scrim; as the viewport narrows the copy runs
 * under the photo and the floor is what keeps it readable.
 */
.pa-svc2hero--inkphoto .pa-svc2hero__backscrim {
	background:
		linear-gradient( 90deg, rgba( 20, 22, 27, 0.93 ) 0, rgba( 20, 22, 27, 0.93 ) calc( max( var( --pa-gutter ), ( 100% - var( --pa-shell ) ) / 2 ) + 726px ), rgba( 20, 22, 27, 0 ) calc( max( var( --pa-gutter ), ( 100% - var( --pa-shell ) ) / 2 ) + 846px ) ),
		linear-gradient( 90deg, #14161B 0%, #14161B 42%, rgba( 20, 22, 27, 0.86 ) 58%, rgba( 20, 22, 27, 0.55 ) 78%, rgba( 20, 22, 27, 0.42 ) 100% );
}
.pa-svc2hero--inkphoto .pa-svc2hero__eyebrow { font-size: 12.5px; line-height: normal; }
/* When the eyebrow wraps on a phone the shared flex-wrap dropped the dot onto a
   line of its own above it. Keep it beside the first line (4px = half of the
   16px line minus half of the 8px dot, i.e. still centred when it is one line). */
.pa-svc2hero--inkphoto .pa-svc2hero__flag { flex-wrap: nowrap; align-items: flex-start; }
.pa-svc2hero--inkphoto .pa-svc2hero__flag .pa-dot { flex: none; margin-top: 4px; }
.pa-svc2hero--inkphoto h1 {
	font-size: clamp( 38px, 5.2vw, 74px ); line-height: 0.94; letter-spacing: -0.038em;
	margin: 0 0 26px; max-width: 15em;
}
.pa-svc2hero--inkphoto .pa-svc2hero__lede { max-width: 500px; margin: 0 0 32px; }
.pa-svc2hero--inkphoto .pa-btns { margin-bottom: 0; }
.pa-svc2hero--inkphoto .pa-btn { line-height: normal; }
.pa-svc2hero--inkphoto .pa-svc2hero__note {
	margin: 44px 0 0; padding-top: 26px; border-top: 1px solid rgba( 251, 247, 241, 0.14 );
	font-size: 16.5px; color: #8B909B; max-width: 44em;
}

/* --- /ac-installation/ hero and "The work", to AC Installation.dc.html ------- */
/*
 * The hero's scrim used to end at 0.62 on the right edge; the mockup ends at
 * 0.88 (the base .pa-svc2hero__backscrim above now says so). That is the
 * difference between a condenser you can read and a pale wash, and the
 * client's screenshot shows the wash.
 */
.pa-svc2hero--statsbelow .pa-svc2hero__backimg { object-position: 60% 50%; }
.pa-svc2hero--statsbelow .pa-svc2hero__grid {
	align-items: end; padding-bottom: 54px; border-bottom: 1px solid var( --pa-ink );
}
.pa-svc2hero--statsbelow .pa-svc2hero__eyebrow { font-size: 12px; line-height: normal; }
.pa-svc2hero--statsbelow .pa-svc2hero__flag { margin-bottom: 18px; }
.pa-svc2hero--statsbelow h1 {
	font-size: clamp( 40px, 5.4vw, 76px ); line-height: 0.94; letter-spacing: -0.038em; margin: 0 0 24px;
}
.pa-svc2hero--statsbelow .pa-svc2hero__lede { max-width: 520px; margin: 0 0 36px; }
.pa-svc2hero--statsbelow .pa-btns { margin-bottom: 0; }
.pa-svc2hero--statsbelow .pa-btn { line-height: normal; }
.pa-svc2hero--statsbelow .pa-btn--ghost { border-color: rgba( 20, 22, 27, 0.35 ); }
.pa-svc2hero__statswrap { position: relative; }
.pa-svc2hero--statsbelow .pa-hero__stats { border-top: 0; padding: 30px 0 62px; gap: 40px; }
.pa-svc2hero--statsbelow .pa-stat__num, .pa-svc2hero--statsbelow .pa-hero__stats .pa-mono.pa-micro { line-height: normal; }

/* The financing figure: a plain block on a left rule, not a card. */
.pa-herostat { border-left: 1px solid rgba( 20, 22, 27, 0.16 ); padding-left: 44px; max-width: 340px; } /* content-box on purpose: the mockup's 340 is the text column, rule and padding sit outside it */
.pa-herostat__label { font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: #646A76; margin: 0 0 10px; line-height: normal; }
.pa-herostat__fig {
	font-family: var( --pa-ff-display ); font-weight: 700; font-size: clamp( 72px, 9vw, 132px );
	line-height: 0.82; letter-spacing: -0.05em; color: var( --pa-ink );
}
.pa-herostat__fig span { font-size: 0.3em; letter-spacing: 0; font-weight: 600; color: #646A76; }
.pa-herostat__body { font-size: 16.5px; line-height: 1.55; color: #4A505C; margin: 24px 0 0; max-width: 26em; }

/* "The work": hairline rows, heading left and paragraph right. */
.pa-pairs { border-top: 1px solid var( --pa-ink ); }
.pa-pair {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 240px, 100% ), 1fr ) ); gap: 10px 40px;
	padding: 26px 0; border-bottom: 1px solid rgba( 20, 22, 27, 0.14 );
}
.pa-pair h3 { font-family: var( --pa-ff-display ); font-weight: 600; font-size: 23px; letter-spacing: -0.02em; line-height: normal; margin: 0; }
.pa-pair p { font-size: 16.5px; line-height: 1.55; color: #4A505C; margin: 0; max-width: 38em; }
.pa-pair a { font-weight: 500; color: var( --pa-orange-ink ); }

.pa-page-ac-installation #decision .pa-head,
.pa-page-ac-installation #the-work .pa-head { gap: 32px 64px; margin-bottom: 52px; }
.pa-page-ac-installation #decision .pa-head h2,
.pa-page-ac-installation #the-work .pa-head h2 { font-size: clamp( 31px, 3.4vw, 46px ); line-height: 1.04; letter-spacing: -0.03em; max-width: 13em; }
.pa-page-ac-installation #decision .pa-head .pa-mono.pa-eyebrow,
.pa-page-ac-installation #the-work .pa-head .pa-mono.pa-eyebrow { font-size: 12px; line-height: normal; }
/* No rule above the closing line, and it runs the full width. */
.pa-page-ac-installation #the-work .pa-svc2foot { margin-top: 28px; padding-top: 0; border-top: 0; max-width: none; line-height: normal; color: #6A707C; }

/* --- /vacation-rentals/ -----------------------------------------------------
 *
 * Built from a flattened PDF of the client's design, not from HTML, so these
 * values are read off the picture rather than measured. The PDF is a capture of
 * the page at about 880px wide, scaled up ~1.16x onto the PDF page (its header
 * wraps, its buttons are 63px tall = the usual 55px x 1.16). Fonts and gaps
 * below were back-computed with that factor. When the project HTML arrives,
 * re-measure and replace the guesses.
 */
.pa-svc2hero--tl .pa-svc2hero__eyebrow { font-size: 12px; line-height: normal; }
.pa-svc2hero--tl .pa-svc2hero__flag { margin-bottom: 18px; }
.pa-svc2hero--tl h1 { font-size: clamp( 40px, 5.4vw, 76px ); line-height: 0.96; letter-spacing: -0.038em; margin: 0 0 24px; max-width: 15em; }
.pa-svc2hero--tl .pa-svc2hero__lede { max-width: 520px; margin: 0 0 36px; }
.pa-svc2hero--tl .pa-btns { margin-bottom: 0; }
.pa-svc2hero--tl .pa-btn { line-height: normal; }
.pa-svc2hero--tl .pa-btn--ghost { border-color: rgba( 20, 22, 27, 0.35 ); }
.pa-svc2hero--tl .pa-svc2hero__grid { align-items: center; }
@media ( min-width: 901px ) { .pa-svc2hero--tl { padding: 85px var( --pa-gutter ) 80px; } }

/* The turnover-day timeline: a dark panel, a time column and a sequence of rows. */
.pa-tl { background: var( --pa-ink ); color: var( --pa-cream ); padding: 36px 34px 28px; }
.pa-tl__label { font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var( --pa-tint ); margin: 0 0 10px; line-height: normal; }
.pa-tl__title { font-family: var( --pa-ff-display ); font-weight: 700; font-size: 24px; line-height: 1.1; letter-spacing: -0.025em; margin: 0 0 17px; color: var( --pa-cream ); }
.pa-tl__rows { list-style: none; margin: 0; padding: 0; }
.pa-tl__row:first-child { border-top: 0; } /* the design draws no rule above the first step */
.pa-tl__row {
	display: grid; grid-template-columns: minmax( 0, 90px ) minmax( 0, 1fr ); gap: 6px 24px;
	padding: 15px 0 15px; border-top: 1px solid rgba( 251, 247, 241, 0.16 );
}
.pa-tl__time { font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: #8B909B; padding-top: 4px; line-height: normal; }
.pa-tl__time--hot { color: var( --pa-tint ); }
.pa-tl__row h3 { font-family: var( --pa-ff-display ); font-weight: 600; font-size: 18px; line-height: normal; letter-spacing: -0.01em; margin: 0 0 3px; color: var( --pa-cream ); }
.pa-tl__row p { font-size: 15px; line-height: 1.55; color: var( --pa-ondark ); margin: 0; }
.pa-tl__foot { font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: #8B909B; margin: 17px 0 0; line-height: normal; }
@media ( max-width: 640px ) {
	.pa-tl { padding: 32px 24px 28px; }
	.pa-tl__row { grid-template-columns: minmax( 0, 1fr ); }
}

/* Two-column hairline rows on the ink band. */
.pa-cards--two { grid-template-columns: repeat( 2, minmax( 0, 1fr ) ); column-gap: 64px; }
.pa-cards--two .pa-card { padding: 28px 0 26px; }
.pa-cards--two .pa-card h3 { margin-bottom: 8px; }
.pa-cards--two .pa-card p { font-size: 16.5px; max-width: 26em; }
@media ( max-width: 760px ) { .pa-cards--two { grid-template-columns: minmax( 0, 1fr ); } }

/* A 'checks' section whose heading sits in the left column, above the note. */
/* The grid's own top rule would cross the heading; the list keeps its ink rule. */
.pa-checks--headaside { border-top: 0; }
/* .pa-svcalso p (0,1,1) zeroes the label's margin; this is (0,3,1). */
.pa-checks--headaside .pa-svcalso p.pa-svcalso__label { margin-bottom: 12px; }
.pa-checks__head2 { margin-bottom: 28px; }
.pa-checks__head2 .pa-mono.pa-eyebrow { color: #74644F; font-size: 12px; line-height: normal; margin: 0 0 18px; }
.pa-checks__head2 h2 { font-size: clamp( 31px, 3.4vw, 46px ); line-height: 1.04; letter-spacing: -0.03em; margin: 0 0 22px; max-width: 9em; }
.pa-checks__lede { font-size: 18px; line-height: 1.6; color: #4A505C; margin: 0; max-width: 24em; }

/* --- WhatsApp and the language line (2026-10-23) ----------------------------
 *
 * Colour: #128C7E, one of WhatsApp's own greens, is the only one that clears
 * 3:1 for a graphic on the cream header (#25D366, the brand's light green, is
 * under 2:1 there). White on #128C7E is 4.3:1 on the call bar button.
 */
.pa-wa { display: inline-flex; align-items: center; justify-content: center; color: #128C7E; text-decoration: none; flex: none; }
.pa-wa:hover { color: #075E54; }
.pa-wa__icon { display: block; }

/*
 * Below 640px the header drops the phone number. The fixed call bar is on screen
 * from 639px down and carries Call now, so the header copy was a duplicate, and
 * it was what pushed the menu button onto a second row from 481 to about 560px
 * (wordmark 147 + phone 131 + Book now 107 + Menu 97, plus gaps, is 546px against
 * 433 to 512 available). It used to be 480px and below only.
 */
@media ( max-width: 639.98px ) { .pa-hdr__tel { display: none; } }

/* Contact page: inline, right after the phone number in "Rather talk it through?". */
.pa-svc2quote__alt .pa-wa--inline { vertical-align: -5px; margin: 0 2px 0 4px; }
.pa-sec--qdark .pa-wa--inline { color: var( --pa-tint ); }
.pa-sec--qdark .pa-wa--inline:hover { color: #fff; }

/*
 * Mobile call bar: three equal actions. Colours: Call is the site's orange,
 * WhatsApp #0E7569 (white text 5.4:1; WhatsApp's own #128C7E is 4.1:1, under
 * the 4.5:1 text needs), Quote is outlined cream on the ink bar.
 */
@media ( max-width: 639.98px ) {
	.pa-call-bar__row { display: flex; gap: 8px; align-items: stretch; }
	.pa-cb {
		flex: 1 1 0; min-width: 0; min-height: 56px; box-sizing: border-box;
		display: inline-flex; align-items: center; justify-content: center; gap: 6px;
		padding: 0 4px; border-radius: 2px; border: 1px solid transparent;
		font-family: var( --pa-ff-display ); font-weight: 700; font-size: 15px; line-height: 1.1;
		color: #fff; text-decoration: none; white-space: nowrap;
	}
	.pa-cb--call { flex-grow: 1.15; background: var( --wp--preset--color--cta, #C2410C ); border-color: var( --wp--preset--color--cta, #C2410C ); }
	.pa-cb--wa { background: #0E7569; border-color: #0E7569; }
	.pa-cb--quote { background: rgba( 251, 247, 241, 0.06 ); border-color: rgba( 251, 247, 241, 0.4 ); }
	.pa-cb:hover, .pa-cb:focus-visible { filter: brightness( 1.12 ); color: #fff; }
	.pa-cb svg { flex: none; display: block; width: 20px; height: 20px; }
}
/* 359px and below: three side-by-side buttons are ~90px each, so the icon goes above the label. */
@media ( max-width: 359.98px ) {
	.pa-cb { flex-direction: column; gap: 3px; font-size: 14px; padding: 6px 2px; }
}

/* Language line: the trust row's own micro style; its own line under the pair. */
.pa-hero__stats .pa-hero__langs { flex: 1 0 100%; margin: 0; }
.pa-hero__stats:has( > .pa-hero__langs ) { row-gap: 14px; } /* the row's own 40px gap would float the line away from the pair */
.pa-foot .pa-foot__langs { margin: 4px 0 0; }
.pa-svchero__langs { font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: #8B909B; margin: 14px 0 0; line-height: normal; }

/*
 * Spanish and Portuguese headers. The translated top-level labels are longer
 * ("Aire acondicionado", "Calidad del aire", "Áreas de servicio") and so are the
 * buttons ("Solicite seu orçamento"), so the one-row desktop nav that fits
 * English from 1263px needs MORE room on /es/ and /pt/ pages. Measured 2026-10-23
 * by bisecting with collapse forced off and counting rows by vertical centre:
 * Spanish 1415px, Portuguese 1412px. The full nav shows from 1433px (the
 * requirement plus the same ~18px headroom English has at 1280); below that the
 * compact menu is used, which carries the same links plus the language switcher.
 * Until 2026-10-23 the compact menu was used at EVERY width on these pages,
 * which read as a missing header on a desktop screen. English is untouched.
 * Re-measure if a translated label, the item count or a type size changes.
 */
@media ( max-width: 1432px ) {
	.pa-lang-es .pa-nav, .pa-lang-pt .pa-nav { display: none; }
	.pa-lang-es .pa-mnav, .pa-lang-pt .pa-mnav { display: block; }
}

/* --- Language switcher: footer and Menu panel; only on pages that have a translation ---
 * Muted text, like the rest of the footer line it sits in. Orange is reserved
 * for actions, so the links are underlined, not coloured. The page you are on is
 * bold and not a link. */
.pa-lang { margin: 14px 0 0; font-size: 14px; letter-spacing: 0.04em; color: #8B909B; }
.pa-lang a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.pa-lang a:hover, .pa-lang a:focus-visible { color: var( --pa-cream ); }
.pa-lang__here { color: inherit; font-weight: 700; }

/* Spanish and Portuguese headlines: sized so the three deliberate lines of the
 * homepage h1 each fit on one line, then balanced where a line must wrap. */
.pa-lang-es .pa-hero h1, .pa-lang-pt .pa-hero h1 { font-size: clamp( 34px, 4.3vw, 62px ); text-wrap: balance; }
.pa-lang-es h1, .pa-lang-pt h1 { text-wrap: balance; }

/* --- 19b. FAQ jump links --------------------------------------------------- */

/*
 * The mockup's measurements: 8px gap, 9px/15px padding, 14.5px. They matter
 * because four links have to sit on ONE row in a 604px column. At the previous
 * 10px gap and 10px/16px padding they summed to 629px and the fourth wrapped
 * to a second row on its own, which is what the section looked wrong as.
 *
 * min-height is NOT --pa-min-tap here. These are 38px tall by the mockup's
 * padding, and forcing 44 would both break the drawing and re-introduce the
 * wrap. They sit in a nav beside a phone number and a full-width jump list
 * repeats below, so this is not the only route to any of them.
 */
.pa-jump { display: flex; flex-wrap: wrap; gap: 8px; }
.pa-jump a {
	display: inline-flex; align-items: center;
	border: 1px solid rgba( 251, 247, 241, 0.28 ); padding: 9px 15px;
	font-size: 14.5px; color: var( --pa-cream ); text-decoration: none;
}
.pa-jump a:hover, .pa-jump a:focus { background: rgba( 251, 247, 241, 0.08 ); color: var( --pa-cream ); text-decoration: none; }
.pa-svc2hero--cream .pa-jump a { border-color: var( --pa-hair-light ); color: var( --pa-ink ); }
.pa-svc2hero--cream .pa-jump a:hover { background: var( --pa-sand ); color: var( --pa-ink ); }

/* --- 19c. Contact rails ---------------------------------------------------- */

.pa-rails {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 300px, 100% ), 1fr ) );
	gap: 1px; background: rgba( 20, 22, 27, 0.14 ); border-top: 1px solid var( --pa-ink );
}
.pa-rail {
	background: var( --pa-cream ); padding: 32px 30px 30px 0;
	display: block; color: var( --pa-ink ); text-decoration: none;
	transition: background 150ms ease;
}
.pa-rail:first-child { padding-left: 0; }
a.pa-rail:hover, a.pa-rail:focus { background: var( --pa-sand ); color: var( --pa-ink ); text-decoration: none; }
.pa-rail__label { color: var( --pa-orange-ink ) !important; margin-bottom: 12px; }
.pa-rail__value {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 22px, 2.2vw, 27px ); line-height: 1.2; letter-spacing: -0.02em;
	margin: 0 0 12px; color: var( --pa-ink ); overflow-wrap: anywhere;
}
.pa-rail__body { font-size: 16px; line-height: 1.55; color: #4A505C; margin: 0; }
.pa-rail__note { font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; color: #646A76; margin: 14px 0 0; }

@media ( max-width: 900px ) {
	.pa-rail, .pa-rail:first-child { padding: 28px 0; }
}

/* --- 19d. Split: prose column beside a definition list (/about/) ----------- */

.pa-split {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 340px, 100% ), 1fr ) );
	gap: 48px 72px; align-items: start;
}
/* The left column now carries the whole intro, so it needs the head's rhythm. */
.pa-split__col .pa-mono.pa-eyebrow { color: #98846D; margin: 0 0 18px; }
.pa-split__col h2 { margin: 0 0 20px; max-width: 15em; }
.pa-split__lede { font-size: 17.5px; line-height: 1.6; color: var( --pa-muted ); margin: 0 0 26px; max-width: 32em; }
/*
 * THE VERIFY LIST — one rule per ROW, not one per cell.
 *
 * This was .pa-glance, which borders the dt and the dd separately. With an
 * 18px column gap between them the rule renders as two segments with a visible
 * break in the middle of every line. The mockup puts a single border-bottom on
 * the row and a heavier ink border-top above the first, so the rules read as
 * continuous.
 */
.pa-verify { margin: 0; border-top: 1px solid var( --pa-ink ); }
.pa-verify__row {
	display: grid; grid-template-columns: minmax( 0, 128px ) minmax( 0, 1fr ); gap: 18px;
	padding: 17px 0; border-bottom: 1px solid rgba( 20, 22, 27, 0.16 );
}
.pa-verify dt {
	font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase;
	color: #98846D; padding-top: 3px;
}
.pa-verify dd { margin: 0; font-size: 16.5px; line-height: 1.5; color: var( --pa-ink ); overflow-wrap: anywhere; }
/*
 * Phone: the 128px label track does not collapse, so below 600 the pairs stack
 * — the same fix the .pa-glance list needed, for the same reason.
 */
@media ( max-width: 600px ) {
	.pa-verify__row { grid-template-columns: minmax( 0, 1fr ); gap: 4px; }
}
.pa-split__link {
	display: inline-flex; align-items: center; gap: 10px;
	min-height: var( --pa-min-tap );
	border: 1px solid var( --pa-hair-light ); padding: 12px 18px;
	color: var( --pa-ink ); text-decoration: none; font-weight: 600; font-size: 16px;
}
.pa-split__link:hover { background: var( --pa-ink ); color: var( --pa-cream ); text-decoration: none; }
.pa-split__link:hover .pa-rev__dot { background: var( --pa-cream ); }
.pa-split .pa-rev__dot { width: 7px; height: 7px; border-radius: 50%; background: #F59E0B; flex: 0 0 auto; }

/* --- 19e. Careers roles ---------------------------------------------------- */

.pa-roles { border-top: 1px solid var( --pa-ink ); }
.pa-role {
	display: block; padding: 28px 8px; border-bottom: 1px solid var( --pa-hair-light );
	color: var( --pa-ink ); text-decoration: none; transition: background 150ms ease;
}
.pa-role:hover, .pa-role:focus { background: var( --pa-sand ); color: var( --pa-ink ); text-decoration: none; }
.pa-role__head {
	display: flex; align-items: baseline; justify-content: space-between;
	gap: 20px; flex-wrap: wrap; margin-bottom: 10px;
}
.pa-role__head h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 25px;
	letter-spacing: -0.02em; margin: 0;
}
/* --pa-orange-ink, not --pa-orange: 14px text needs 4.5:1 and #C2410C is 4.34 on sand. */
.pa-role__meta {
	font-size: 14px; letter-spacing: 0.12em; text-transform: uppercase;
	color: var( --pa-orange-ink ); white-space: nowrap;
}
/* nowrap only where there is room. Below 900 the meta shares a narrow column
 * with a 25px heading and was pushing its line past its own box. */
@media ( max-width: 900px ) {
	.pa-role__meta { white-space: normal; }
	.pa-role__head { gap: 6px; }
}
.pa-role__body { display: block; font-size: 16.5px; line-height: 1.55; color: #4A505C; max-width: 46em; }


/* --- 19e-ii. Pricing and coverage bands on sand ---------------------------
 *
 * SAND ON THE SERVICE AND COMPANY PAGES ONLY. Not site-wide, and the
 * difference is the whole point.
 *
 * Every service and company mockup draws these two bands on sand. The
 * HOMEPAGE and CITY mockups draw them on CREAM — homepage-target.html has
 * #pricing cream and #areas cream, city-target.html has Pricing cream — and
 * they do that because their neighbours are already sand. Forcing sand
 * everywhere collides on exactly those two page types:
 *
 *   homepage   pricing | services   both sand, boundary lost
 *   city x42   local   | pricing    both sand, boundary lost
 *
 * Measured by simulating the change before making it, not discovered after.
 *
 * The separation is free because the three pricing bands are already three
 * patterns — pricing-no-trip-charge (homepage), city-pricing (42 cities) and
 * services-pricing (everything else) — and likewise for coverage. Hanging the
 * ground off the service/company modifiers leaves the other two untouched.
 *
 * If you ever want sand on the homepage or a city page, change its NEIGHBOUR
 * first or the section boundary disappears.
 */
.pa-sec--svcprice { background: var( --pa-sand ); }
.pa-sec--svccov { background: var( --pa-sand ); }

/* --- 19f. FAQ groups (/faq/) ----------------------------------------------- */

/*
 * The FAQ group is NOT the shared .pa-head shape. Its mockup puts the heading
 * and the question count on ONE baseline under a rule, caps the heading at
 * 36px rather than the site's 46, and lays the answers out in two wide
 * columns. Built with .pa-cards first, which stacked the head, dropped the
 * rule, and gave four narrow columns instead of two.
 */
.pa-sec--qa { padding: 78px var( --pa-gutter ); }
.pa-qa__head {
	display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap;
	padding-bottom: 16px; border-bottom: 1px solid var( --pa-ink ); margin-bottom: 8px;
}
.pa-sec--svc2ink .pa-qa__head { border-bottom-color: rgba( 251, 247, 241, 0.4 ); }
.pa-qa__head h2 {
	font-family: var( --pa-ff-display ); font-weight: 700;
	font-size: clamp( 27px, 2.8vw, 36px ); letter-spacing: -0.028em; margin: 0;
}
.pa-qa__count { font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase; color: #74644F; }
.pa-sec--svc2ink .pa-qa__count { color: var( --pa-ondark-dim ); }
/*
 * Two columns at 1280 from a 420px floor, written min( 420px, 100% ) so the
 * track can still collapse on a phone. gap 0 72px — the rule under each answer
 * is the separator, so a row gap would double it.
 */
.pa-qa {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 420px, 100% ), 1fr ) );
	gap: 0 72px;
}
.pa-qa__item { padding: 26px 0; border-bottom: 1px solid var( --pa-hair-light ); }
.pa-sec--svc2ink .pa-qa__item { border-bottom-color: var( --pa-hair-dark ); }
.pa-qa__item h3 {
	font-family: var( --pa-ff-display ); font-weight: 600; font-size: 21px;
	line-height: 1.25; letter-spacing: -0.02em; margin: 0 0 10px;
}
.pa-qa__item p { font-size: 16.5px; line-height: 1.6; color: #4A505C; margin: 0; }
.pa-sec--svc2ink .pa-qa__item p { color: var( --pa-ondark ); }
.pa-qa__item a { font-weight: 500; color: var( --pa-orange-ink ); }
.pa-sec--svc2ink .pa-qa__item a { color: var( --pa-tint ); }

/* --- 19g. Careers role: two columns ---------------------------------------- */

/*
 * Each role is its own grid — title and meta left, description right — which
 * is what the mockup draws. It was built as a stacked block with the head
 * above a full-width paragraph.
 */
.pa-role {
	display: grid; grid-template-columns: repeat( auto-fit, minmax( min( 280px, 100% ), 1fr ) );
	gap: 12px 48px; align-items: start;
}
.pa-role__head { display: block; margin-bottom: 0; }
.pa-role__head h3 { margin: 0 0 6px; }
.pa-role__meta { display: block; white-space: normal; }

/* --- 19h. Full-width hero cap ---------------------------------------------- */

/*
 * The h1 cap is per-page data (--pa-hero-h1-max), because /about/ caps at 84px
 * and /contact/ at 82px in their own mockups. Same variant, different number.
 */
.pa-svc2hero--full h1 { font-size: clamp( 40px, 5.6vw, var( --pa-hero-h1-max, 84px ) ); }

/*
 * Reading measure. The container widened (--pa-shell, --pa-gutter), and the text
 * blocks that sit in a column of it widened too: at 1920px the vacation-rentals
 * checklist went from 564px to 860px and the AC-repair footnote was one 1792px
 * line. These cap the TEXT at 680px (about 80 characters) and leave the boxes,
 * rules and grids at the full container width. Measured at 1920 across all
 * pages: nothing else over 760px with more than a line of text.
 */
.pa-checks__body, .pa-checks__head, .pa-tl__row p, .pa-svcalso p, .pa-facts__detail,
.pa-local__nearby p, .pa-pick__foot { max-width: var( --pa-measure ); }

/*
 * Language buttons (the Menu panel's switcher). Three bordered tap targets, 40px
 * high; the current language is the filled one and is not a link. Orange stays
 * for actions, so the fill is ink. A slim bar of the same buttons sat above the
 * header on small screens from 2026-10-23 until it was removed the same day (the
 * switcher stays in the Menu panel and the footer); only the button styling is left.
 */
.pa-lang--bar { margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; box-sizing: border-box; font-size: 14px; letter-spacing: 0.02em; color: var( --pa-ink ); }
.pa-lang--bar > span[aria-hidden] { display: none; }
.pa-lang--bar a, .pa-lang--bar .pa-lang__here {
	display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
	min-height: 40px; min-width: 44px; padding: 0 14px; border: 1px solid rgba( 20, 22, 27, 0.35 ); border-radius: 4px;
	color: var( --pa-ink ); text-decoration: none; font-weight: 500; background: transparent;
}
.pa-lang--bar a:hover, .pa-lang--bar a:focus-visible { background: rgba( 20, 22, 27, 0.08 ); }
.pa-lang--bar .pa-lang__here { background: var( --pa-ink ); border-color: var( --pa-ink ); color: var( --pa-cream ); font-weight: 600; }

/* The language switcher inside the menu panel: the bar's three buttons, flush left under the contact buttons. */
.pa-lang--bar.pa-lang--inpanel { margin-top: 4px; }
.pa-lang--bar.pa-lang--inpanel a, .pa-lang--bar.pa-lang--inpanel .pa-lang__here { min-height: 44px; }
