/* ==========================================================
   PCRS design system — assembled from the approved mockups.
   Sources: mockups/assets/pcrs-tokens.css, mockups/assets/patterns.css,
   and the per-page <style> blocks of the four mockup pages.
   Global-module annotation styling (.gm / data-gm) is stripped.
   Hard rule preserved: no scroll-behavior:smooth anywhere.
   ========================================================== */


/* ---------- pcrs-tokens.css ---------- */

/**
 * PCRS mockup foundation — flattens what WordPress normally generates
 * (theme.json presets + element styles) so patterns.css runs verbatim in a
 * standalone HTML mockup. Values = Live Clients/PCRS/site/theme.json.
 * Mockup-only file: the real site gets these from theme.json / Divi.
 */

@font-face {
	font-family: 'Archivo';
	font-weight: 100 900;
	font-style: normal;
	src: url('fonts/archivo-variable.woff2') format('woff2');
}
@font-face {
	font-family: 'Zilla Slab';
	font-weight: 400;
	src: url('fonts/zilla-slab-400.woff2') format('woff2');
}
@font-face {
	font-family: 'Zilla Slab';
	font-weight: 600;
	src: url('fonts/zilla-slab-600.woff2') format('woff2');
}
:root {
	/* palette — PCRS StyleGuide 2025 mapped to token roles */
	--wp--preset--color--inkdeep:    #14163f;
	--wp--preset--color--dark:       #272b6f;
	--wp--preset--color--darkalt:    #32377f;
	--wp--preset--color--mid:        #1c75bc;
	--wp--preset--color--accent:     #ed1c24;
	--wp--preset--color--accentsoft: #f4565c;
	--wp--preset--color--onaccent:   #ffffff;
	--wp--preset--color--onbadge:    #7ab8e8;
	--wp--preset--color--support:    #7ab8e8;
	--wp--preset--color--paper:      #ffffff;
	--wp--preset--color--wash:       #f1f5fb;
	--wp--preset--color--ink:        #1d2145;
	--wp--preset--color--soft:       #5c6484;
	--wp--preset--color--line:       #dfe5f0;

	--wp--preset--gradient--accent-btn: linear-gradient(180deg, #f4565c 0%, #ed1c24 100%);
	/* 180deg, not 160deg, and the angle is load-bearing.
	   `.ccmm-sec.is-mid` is a band with a curved dome above it, and the dome is
	   a separate element painted a FLAT colour — the gradient's 0% stop. That
	   only meets the band without a seam if the band's top edge is a single
	   colour, which is true of a vertical gradient and false of a tilted one.
	   At 160deg the top edge already slid from #1c75bc on the left toward
	   #32377f on the right, so the flat dome matched at the left edge and was
	   21/255 of blue adrift by the right — a hard horizontal line across the
	   page under the Sudden Service band. Measured, not guessed.
	   Keep this vertical, or paint the dome with the same gradient. */
	--wp--preset--gradient--mid-band:   linear-gradient(180deg, #1c75bc 0%, #32377f 100%);
	--wp--preset--gradient--dark-band:  linear-gradient(160deg, #32377f 0%, #14163f 100%);

	--wp--preset--font-family--display: 'Archivo','Segoe UI',Arial,sans-serif;
	--wp--preset--font-family--body:    'Segoe UI',-apple-system,Roboto,Arial,sans-serif;
	--wp--preset--font-family--slab:    'Zilla Slab',Georgia,serif;

	--wp--preset--font-size--eyebrow: 0.76rem;
	--wp--preset--font-size--small:   0.92rem;
	--wp--preset--font-size--base:    16.5px;
	--wp--preset--font-size--lead:    1.05rem;
	--wp--preset--font-size--card:    1.05rem;
	--wp--preset--font-size--stat:    clamp(2rem, 4vw, 3rem);
	--wp--preset--font-size--band:    clamp(1.4rem, 2.8vw, 2.1rem);
	--wp--preset--font-size--section: clamp(1.9rem, 4.6vw, 3.4rem);
	--wp--preset--font-size--hero:    clamp(2.1rem, 5.6vw, 4.1rem);

	--wp--preset--spacing--10: 0.6rem;
	--wp--preset--spacing--20: 1rem;
	--wp--preset--spacing--30: clamp(1rem, 2vw, 1.5rem);
	--wp--preset--spacing--40: 1.4rem;
	--wp--preset--spacing--50: clamp(1.5rem, 4vw, 3.2rem);
	--wp--preset--spacing--60: clamp(2.2rem, 4vw, 3.4rem);
	/* Band padding. Measured 2026-08-11: at 7.5vw this produced a 305–362px
	   gap between the last line of one band and the first line of the next
	   (padding-bottom + dome sweep + padding-top + trailing margin). That
	   reads as dead space, not rhythm. Halved to land the same gap near
	   190px, which still separates the bands without stranding them. */
	--wp--preset--spacing--70: clamp(2.4rem, 4vw, 3.6rem);
}
/* ---- base (theme.json styles equivalent) ---- */
* { box-sizing: border-box; }
body {
	margin: 0;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.62;
}
h1, h2, h3, h4 {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 900;
	line-height: 0.98;
	margin: 0 0 var(--wp--preset--spacing--20);
	text-transform: uppercase;
}
h1 { font-size: var(--wp--preset--font-size--hero); letter-spacing: -0.01em; }
h2 { font-size: var(--wp--preset--font-size--section); letter-spacing: 0.005em; }
h3 { font-size: var(--wp--preset--font-size--card); font-weight: 800; }
a { color: var(--wp--preset--color--accent); text-decoration: none; }
img { max-width: 100%; height: auto; }
p { margin: 0 0 var(--wp--preset--spacing--20); }
/* ---- WP class shims patterns.css expects ---- */
.wp-block-button__link, .wp-element-button {
	display: inline-block;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 800;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	border-radius: 999px;
	border: 2px solid transparent;
	padding: 0.9rem 1.7rem;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--onaccent);
	cursor: pointer;
}
.wp-block-buttons { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--20); }
.wp-block-button { margin: 0; }
.has-lead-font-size  { font-size: var(--wp--preset--font-size--lead); }
.has-small-font-size { font-size: var(--wp--preset--font-size--small); }
.alignfull { width: 100%; }
/* ---- secondary-tier plain layout: SINGLE column ----
   Was a two-column grid with a right sidebar. Gus, 2026-08-13: "I dont want to
   see 2 column pages. No side columns." The sidebar carried Contact / Cleaning
   services / Serving on all 20 pages, identical every time, and every item in
   it already appears in the header, the footer or /service-area/ — so removing
   it loses no information.

   The measure is capped rather than released to the full 1200px wrap: with the
   sidebar gone the body text would otherwise run the whole width, and a
   ~150-character line is materially harder to read than the ~85 it replaced.

   Everything shares ONE left edge. An earlier version let the hero and the chip
   clouds bleed wider than the text; the result was a hero starting 170px left
   of its own h1, which reads as a mistake rather than as emphasis. If a block
   genuinely needs more room, widen the column for that page rather than
   breaking the alignment. */
.tier2-wrap {
	max-width: 1200px;
	margin-inline: auto;
	padding: clamp(1.5rem, 4vw, 3rem) clamp(1.1rem, 4vw, 2.4rem);
	display: block;
}
.tier2-main {
	max-width: 860px;
	margin-inline: auto;
}
/* Belt and braces: the sidebar is deleted from page content, but a stray one in
   an un-rebuilt page must not reintroduce a second column. */
.tier2-sidebar { display: none; }
.tier2-main h1, .tier2-main h2, .tier2-main h3 { text-transform: none; letter-spacing: 0; line-height: 1.15; }
.tier2-main h1 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); }
.tier2-main h2 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); }

/* ---------- patterns.css ---------- */

/**
 * Section-pattern stylesheet — the visual half of the Lane A class contract.
 *
 * Interface: ../../CLASS-CONTRACT.md (class names are fixed there — nothing here
 * invents, renames or abbreviates one). Look contract: ../../REFERENCE-SPEC.md —
 * that file wins every conflict with design-spec.md, which stays only as the
 * record of type/spacing constants (still valid and still used below).
 * Every colour/size/spacing value below is a `var(--wp--preset--*)` token from
 * ccmm-starter/theme.json, EXCEPT the translucent-white card fills on dark
 * surfaces (`rgba(255,255,255,.0N)`) — the one exception the design language
 * calls for and no token expresses. Where a design-spec number has no exact
 * matching token, the nearest token is used directly, or derived from one with
 * calc()/color-mix() — never a bare literal colour or size.
 *
 * Loads on the front end AND inside the block editor (see ccmm-blocks.php),
 * so nothing here assumes a front-end-only DOM.
 *
 * Hard rule, non-negotiable: no `scroll-behavior:smooth` anywhere in this file.
 */

/* ==========================================================================
   Motion — keyframes + the three mandatory fallbacks (design-spec §6)
   ========================================================================== */

@keyframes ccmm-fade-up {
	from { opacity: 0; transform: translateY(40px); }
	to   { opacity: 1; transform: translateY(0); }
}
@keyframes ccmm-fade-right {
	from { opacity: 0; transform: translateX(44px); }
	to   { opacity: 1; transform: translateX(0); }
}
@keyframes ccmm-zoom-in {
	from { opacity: 0; transform: scale(.7); }
	to   { opacity: 1; transform: scale(1); }
}
@keyframes ccmm-bounce-in {
	0%   { opacity: 0; transform: scale(.3); }
	55%  { opacity: 1; transform: scale(1.06); }
	80%  { transform: scale(.97); }
	100% { transform: scale(1); }
}
/* Fallback 1 — EVERY motion rule is scoped to html.js, not just the opacity
   one. An unscoped `animation-fill-mode: both` + `paused` freezes elements at
   their keyframe's 0% frame (opacity:0) even without the js flag — which is
   exactly how the editor canvas and no-JS visitors ended up staring at empty
   colour bands. Without JS none of these selectors match, so content is
   simply visible, static. ccmm-blocks.php prints the inline script that adds
   `js` to <html> in <head> (front end only — never the editor iframe). */
html.js .ccmm-a {
	opacity: 0;
	animation-timing-function: cubic-bezier(.22, .7, .3, 1);
	animation-fill-mode: both;
	animation-duration: .75s;
	animation-play-state: paused;
}
html.js .ccmm-a.in { animation-play-state: running; }
html.js .ccmm-a--up     { animation-name: ccmm-fade-up; animation-duration: .75s; }
html.js .ccmm-a--right  { animation-name: ccmm-fade-right; animation-duration: .75s; }
html.js .ccmm-a--zoom   { animation-name: ccmm-zoom-in; animation-duration: .6s; }
html.js .ccmm-a--bounce { animation-name: ccmm-bounce-in; animation-duration: .85s; }
html.js .ccmm-d1 { animation-delay: .1s; }
html.js .ccmm-d2 { animation-delay: .22s; }
html.js .ccmm-d3 { animation-delay: .34s; }
html.js .ccmm-d4 { animation-delay: .46s; }
/* Fallback 2 — reduced motion wins over everything above. */
@media (prefers-reduced-motion: reduce) {
	.ccmm-a,
	html.js .ccmm-a {
		opacity: 1 !important;
		transform: none !important;
		animation: none !important;
	}
}
/* Fallback 3 (the timed reveal) lives in motion.js — a setTimeout(2500) that
   adds `.in` to every .ccmm-a regardless of observer support or scroll
   position, covering old browsers and headless screenshot capture. */

/* ==========================================================================
   Layout — .ccmm-sec / bands / .ccmm-wrap / .ccmm-head
   ========================================================================== */

.ccmm-sec {
	/* NO width declaration here: alignfull resolves its own width against the
	   constrained parent's negative-margin math. A width:100% locks the band to
	   the padded content width and shoves the whole page off-centre. */
	/* Dome depth. Scaled down with --spacing--70 (2026-08-11): the sweep has
	   to stay proportional to the band padding, because a dome deeper than
	   the padding above it reads as the curve eating the content rather than
	   as a transition between bands. Still a committed arc, not a lip. */
	--ccmm-sweep: clamp(2.2rem, 4.4vw, 4rem);
	position: relative;
	padding-block: var(--wp--preset--spacing--70) calc(var(--wp--preset--spacing--70) + var(--ccmm-sweep));
	overflow-x: hidden;
	overflow-x: clip;
}
/* Curved band transitions (REFERENCE-SPEC signature 3, TUP pole): each band
   after the hero domes up into the previous one with a deep half-ellipse of
   its OWN colour. Committed depth — a shallow lip reads as an error. The
   extra block-end padding above is the room the next band's dome borrows. */
.ccmm-sec:not(.ccmm-hero)::before {
	content: '';
	position: absolute;
	left: -8%;
	width: 116%;
	top: calc(-1 * var(--ccmm-sweep) + 1px);
	height: var(--ccmm-sweep);
	border-radius: 50% 50% 0 0 / 100% 100% 0 0;
	pointer-events: none;
}
/* Dome colour = the band's own surface. Gradient bands use their gradient's
   TOP colour so the dome meets the band without a seam. */
.ccmm-sec.is-dark::before    { background: var(--wp--preset--color--dark); }
.ccmm-sec.is-darkalt::before { background: var(--wp--preset--color--darkalt); }
.ccmm-sec.is-light::before   { background: var(--wp--preset--color--paper); }
.ccmm-sec.is-wash::before    { background: var(--wp--preset--color--wash); }
.ccmm-sec.is-mid::before     { background: var(--wp--preset--color--mid); }
.ccmm-sec.is-accent::before  { background: var(--wp--preset--color--accentsoft); }
.ccmm-sec.is-photo::before   { background: var(--wp--preset--color--dark); }
/* The hero's framed team card hangs past the hero's bottom edge — keep the
   hero (and the card with it) painting above the next band's dome. */
.ccmm-sec.ccmm-hero {
	z-index: 2;
}
.ccmm-sec.is-dark {
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--paper);
}
.ccmm-sec.is-darkalt {
	background: var(--wp--preset--color--darkalt);
	color: var(--wp--preset--color--paper);
}
.ccmm-sec.is-mid {
	background: var(--wp--preset--gradient--mid-band);
	color: var(--wp--preset--color--paper);
}
.ccmm-sec.is-light {
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
}
.ccmm-sec.is-accent {
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--dark);
}
/* Photo band — full-bleed image, no section padding, no colour band (the
   image itself is the section). REFERENCE-SPEC signature 3: "no text or
   minimal", height ~40–60vh, straight edges (see the arc note below). */
.ccmm-sec.is-photo {
	padding-block: 0;
	line-height: 0;
}
/* Interstitial phone strip — one line of text, so it must NOT take a full
   band's padding. At the shared --spacing--70 it rendered 342px tall for a
   single sentence and read as a section in its own right instead of as a
   punctuation mark between two sections.
   The block-end still reserves --ccmm-sweep: the following band's dome draws
   up into that space, so the visible height of the accent strip is
   (pad + text + pad) ≈ 100px while the transition stays consistent with
   every other band boundary.
   NOTE the class is `ccmm-strip`, deliberately NOT `ccmm-phone-strip` — that
   older name carries a `p { font-size: small }
` rule which out-ranks
   .ccmm-phone-strip-text and shrinks the headline to 14.7px. */
.ccmm-sec.ccmm-strip {
	--ccmm-strip-pad: var(--wp--preset--spacing--20);
	padding-block: var(--ccmm-strip-pad)
	               calc(var(--ccmm-strip-pad) + var(--ccmm-sweep));
}
/* A strip with no band after it must not reserve dome room — mid-page that
   reservation is invisible (the next band's dome paints over it), but on the
   LAST strip it renders as bare red below the text and the band goes
   bottom-heavy. That rule lives ONLY in pcrs-divi-compat.css, keyed on the
   Divi section wrapper.
   Do NOT express it here as `.ccmm-strip:last-child`. On the built site every
   band is the only child of its own Divi code module, so :last-child matches
   EVERY strip — which removed the dome reservation page-wide and let the next
   band's dome paint straight over the phone number. Whether a strip is "last"
   is a fact about the page, and in Divi only the wrapper knows it. */

/* The strip's OWN dome scales down with it. At full depth the dome is ~60px
   on a ~70px band, so it nearly doubles the red above the text and the band
   reads as uncentred even though the text is exactly centred in its own box.
   40% keeps the curved language proportional to a band this thin.
   Only the ::before is scaled. --ccmm-sweep itself must NOT be overridden on
   the strip: the block-end padding uses it to reserve room for the NEXT
   band's dome, which is still full depth, and shrinking that reservation
   lets the following dome paint straight over the phone number. */
.ccmm-sec.ccmm-strip::before {
	height: calc(var(--ccmm-sweep) * .4);
	top: calc(-1 * var(--ccmm-sweep) * .4 + 1px);
}
/* B2 note (REFERENCE-SPEC signature 3): bands are STRAIGHT edges — a shallow
   arc reads as an error. The old `.has-arc` (a 1.6rem lip) is exactly that
   shallow-arc error, so it is retired rather than carried forward. Nothing
   in the current 11-section build uses a curved edge. */

.ccmm-wrap {
	max-width: 1200px;
	margin-inline: auto;
	padding-inline: clamp(1.1rem, 4vw, 2.4rem);
}
/* Section intro block. REFERENCE-SPEC signature 1, "every section, no
   exceptions": heading FIRST, badge pill BELOW it, lead line last. The old
   eyebrow-above-heading order is abolished — nothing here special-cases
   order, the abolition lives entirely in the pattern markup order. */
.ccmm-head {
	max-width: 48rem;
	margin-inline: auto;
	margin-bottom: var(--wp--preset--spacing--60);
	text-align: center;
}
.ccmm-head > .ccmm-kick {
	margin-top: var(--wp--preset--spacing--20);
	margin-bottom: var(--wp--preset--spacing--20);
}
/* ==========================================================================
   Two-tone heading highlight — signature 1. No background, accent-a text.
   A plain inline element (mark or a bound paragraph standing in for a
   "span"), never a block preset attribute, so it carries no has-* pairing
   obligation.
   ========================================================================== */

.ccmm-hl {
	background: none;
	color: var(--wp--preset--color--accent);
}
/* On the gold (is-accent) band the base heading colour is already dark navy
   (see `.ccmm-sec.is-accent{color:dark}
` above) and the highlight is
   accent-coloured gold by default — indistinguishable from the gold
   background it sits on. Invert to paper there so the two-tone contrast
   survives on every band, not just dark/light ones. */
.ccmm-sec.is-accent .ccmm-hl {
	color: var(--wp--preset--color--paper);
}
/* Same problem, opposite end of the palette: accent red (#ed1c24) on the
   mid-band gradient (#1c75bc → #32377f) measures roughly 2:1, which fails
   even the 3:1 floor for large display text. Keep the two-tone heading, but
   express it as two levels of white so both halves stay legible. */
.ccmm-sec.is-mid h2,
.ccmm-sec.is-mid h3 {
	color: color-mix(in srgb, var(--wp--preset--color--paper) 76%,
	                 var(--wp--preset--color--mid));
}
.ccmm-sec.is-mid .ccmm-hl {
	color: var(--wp--preset--color--paper);
}
/* Body links on the dark-family bands. The global `a { color: accent }
` is
   the same red, and in the pillar cards it lands on small body copy where the
   bar is 4.5:1. On any band whose own text is paper, a link takes the band's
   text colour and earns its affordance from the underline instead.
   Buttons are excluded — they carry their own filled treatment. */
.ccmm-sec.is-dark a:not(.wp-block-button__link),
.ccmm-sec.is-darkalt a:not(.wp-block-button__link),
.ccmm-sec.is-mid a:not(.wp-block-button__link),
.ccmm-sec.is-photo a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--paper);
	text-decoration: underline;
	text-underline-offset: .18em;
	text-decoration-thickness: 1px;
}
/* ==========================================================================
   Grids
   ========================================================================== */

.ccmm-grid3 {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
}
.ccmm-grid2 {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--50);
	align-items: center;
}
/* One 5-up grid shared by why-choose, benefits and process-steps — the card
   itself (not the grid) carries the visual difference between those three
   sections, so one grid definition covers all of them. */
.ccmm-grid5 {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: var(--wp--preset--spacing--30);
}
.ccmm-grid5.is-why  { counter-reset: ccmm-why; }
.ccmm-grid5.is-proc { counter-reset: ccmm-proc; }
/* The process grid is a grid5 for its counter, but MODULE-3A caps the Plan at
   three steps ("Three steps maximum"), and three cards in five columns left
   each one a narrow ribbon of wrapped text. */
.ccmm-grid5.ccmm-three { grid-template-columns: repeat(3, 1fr); }
/* ==========================================================================
   Primary-nav dropdowns — the TUP pattern (REFERENCE-SPEC pole). Section
   parents own a submenu instead of the whole IA sitting flat across the bar.

   Specificity note: the nav's own `.ccmm-nav ul { display: flex }
` is (0,1,1)
   and lives in a per-page <style> block that loads AFTER this file, so the
   submenu rules are written as `.ccmm-nav .ccmm-sub` (0,2,0) to win on
   specificity rather than on order.

   CSS-only: :hover for pointers, :focus-within so the menu is reachable by
   keyboard without script.
   ========================================================================== */
.ccmm-nav li { position: relative; }
.ccmm-nav .ccmm-has-sub > a::after {
	content: '\25BE';
	margin-left: .3em;
	font-size: .78em;
	opacity: .65;
}
.ccmm-nav .ccmm-sub {
	display: block;
	position: absolute;
	top: 100%;
	left: -0.9rem;
	min-width: 17.5rem;   /* "Carpet & Upholstery Cleaning" is the longest item */
	margin: 0;
	padding: .45rem 0;
	list-style: none;
	background: var(--wp--preset--color--paper);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	box-shadow: 0 18px 40px -14px color-mix(in srgb, var(--wp--preset--color--inkdeep) 45%, transparent);
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity .16s ease, transform .16s ease, visibility .16s;
	z-index: 80;
}
.ccmm-nav .ccmm-has-sub:hover > .ccmm-sub,
.ccmm-nav .ccmm-has-sub:focus-within > .ccmm-sub {
	opacity: 1;
	visibility: visible;
	transform: none;
}
.ccmm-nav .ccmm-sub li { display: block; }
.ccmm-nav .ccmm-sub a {
	display: block;
	padding: .48rem 1.05rem;
	font-size: .78rem;
	letter-spacing: .02em;
	text-transform: none;
	white-space: nowrap;
}
.ccmm-nav .ccmm-sub a:hover {
	background: var(--wp--preset--color--wash);
}
@media (prefers-reduced-motion: reduce) {
	.ccmm-nav .ccmm-sub { transition: none; transform: none; }
}
/* Seven top-level items plus a logo and a phone pill is a lot of bar, and
   `.ccmm-header-inner` is `flex-wrap: wrap` — so when the row overflows it
   does not squeeze, it drops the phone pill onto a second line underneath
   the logo. Keep the three parts on one row and let the nav absorb the
   pressure instead: it is the only part that can give.
   Specificity: `.ccmm-nav ul` in the page block is (0,1,1), so the nav rules
   here are written to match or beat it. */
.ccmm-header .ccmm-header-inner {
	flex-wrap: nowrap;
}
.ccmm-header .ccmm-nav { min-width: 0; }
.ccmm-header .ccmm-nav ul { flex-wrap: nowrap; }
.ccmm-header .ccmm-logo img { flex: none; }
.ccmm-header-phone { flex: none; }
@media (max-width: 1440px) {
	.ccmm-header .ccmm-nav ul { gap: var(--wp--preset--spacing--20); }
	.ccmm-header .ccmm-nav a { font-size: .79rem; }
}
@media (max-width: 1240px) {
	.ccmm-header .ccmm-nav ul { gap: .7rem; }
	.ccmm-header .ccmm-nav a { font-size: .72rem; letter-spacing: 0; }
	.ccmm-header .ccmm-logo img { height: 44px; }
}
/* Below this the mobile header global takes over, so the desktop row is
   allowed to wrap again rather than crushing to nothing. */
@media (max-width: 1024px) {
	.ccmm-header .ccmm-header-inner,
	.ccmm-header .ccmm-nav ul { flex-wrap: wrap; }
}
/* Service-areas pill-chip wrap grid — not a fixed column count, chips wrap. */
.ccmm-areas {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--20);
}
/* ==========================================================================
   Eyebrow / badge pill — content unchanged, position in the lockup moves
   below the heading (see pattern markup). Also doubles as a flex wrapper
   when it holds two children (a static label + a bound value) instead of
   a single text node — the hero's "Call us today · <phone>" pill.
   ========================================================================== */

.ccmm-kick {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--10);
	border-radius: 999px;
	border: 1.6px solid var(--wp--preset--color--accent);
	background: color-mix(in srgb, var(--wp--preset--color--dark) 55%, transparent);
	/* `onbadge`, not `accent`: the badge text colour that reads on a dark pill
	   is brand-dependent (gold works, red doesn't) — same reasoning as
	   `onaccent`. Demo maps it to the gold accent; PCRS maps it light blue. */
	color: var(--wp--preset--color--onbadge);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 800;
	letter-spacing: .13em;
	text-transform: uppercase;
	padding: calc(var(--wp--preset--spacing--20) * .5) var(--wp--preset--spacing--20);
	line-height: 1;
}
.ccmm-kick p {
	margin: 0;
	font: inherit;
	color: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
}
.ccmm-sec.is-accent .ccmm-kick,
.ccmm-sec.is-light .ccmm-kick {
	background: color-mix(in srgb, var(--wp--preset--color--dark) 88%, transparent);
}
/* ==========================================================================
   Cards — dark base + "numbered" modifier (why-choose)
   ========================================================================== */

.ccmm-card {
	position: relative;
	border-radius: 16px;
	background: rgba(255, 255, 255, .04);
	border: 1px solid rgba(255, 255, 255, .1);
	padding: var(--wp--preset--spacing--40);
	transition: transform .2s cubic-bezier(.22, .7, .3, 1), background-color .2s, border-color .2s;
}
.ccmm-card:hover {
	transform: translateY(-4px);
	border-color: color-mix(in srgb, var(--wp--preset--color--accent) 55%, transparent);
	background: color-mix(in srgb, var(--wp--preset--color--accent) 6%, transparent);
}
.ccmm-card p {
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.6;
}
/* Why-choose: giant accent-a index number (01…05) above the title, from CSS
   counter() — never in the markup. Parent grid carries `.is-why`. */
.ccmm-card.is-numbered::before {
	counter-increment: ccmm-why;
	content: counter(ccmm-why, decimal-leading-zero);
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: calc(var(--wp--preset--font-size--band) * 1.05);
	font-weight: 900;
	opacity: .55;
	line-height: 1;
	margin-bottom: var(--wp--preset--spacing--20);
	color: var(--wp--preset--color--onbadge);
}
/* 8 Reasons block — MODULE-3A section 9 requires the numbering to be a REAL
   `<ol>`, not images and not counter-styled divs: "Numbered list rendered as
   proper <ol> markup (not images)". So the list semantics live in the
   document while the giant index keeps the .is-numbered look above. */
.ccmm-reasons {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--wp--preset--spacing--30);
}
.ccmm-reasons > li {
	position: relative;
	border-radius: 16px;
	background: rgba(255, 255, 255, .04);
	border: 1px solid rgba(255, 255, 255, .1);
	padding: var(--wp--preset--spacing--40);
	transition: transform .2s cubic-bezier(.22, .7, .3, 1), background-color .2s, border-color .2s;
}
.ccmm-reasons > li:hover {
	transform: translateY(-4px);
	border-color: color-mix(in srgb, var(--wp--preset--color--accent) 55%, transparent);
	background: color-mix(in srgb, var(--wp--preset--color--accent) 6%, transparent);
}
/* The marker is generated from the list's own ordinal, so the printed number
   can never drift out of step with the markup the way a hand-typed one can. */
.ccmm-reasons > li::before {
	content: counter(list-item, decimal-leading-zero);
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: calc(var(--wp--preset--font-size--band) * 1.05);
	font-weight: 900;
	opacity: .55;
	line-height: 1;
	margin-bottom: var(--wp--preset--spacing--20);
	color: var(--wp--preset--color--onbadge);
}
.ccmm-reasons h3 {
	font-size: var(--wp--preset--font-size--card);
	margin-bottom: var(--wp--preset--spacing--10);
}
.ccmm-reasons p {
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.6;
	padding-bottom: 0;
}
/* Project-story cards (MODULE-3A section 8, The Transformation) — a media
   card whose image slot is a labelled placeholder until the real before/after
   photos land. Real photos only: no stock, no AI-generated before/afters. */
.ccmm-story-cards {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
}
.ccmm-story-tag {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	opacity: .7;
	margin-bottom: var(--wp--preset--spacing--10);
}
/* NAP block (MODULE-3A section 12) — must be selectable TEXT, never an image,
   so the entity can be extracted and matched against GBP and citations. */
.ccmm-nap {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--50);
	max-width: 46rem;
	margin-inline: auto;
	text-align: left;
}
.ccmm-nap dt {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	opacity: .65;
}
.ccmm-nap dd {
	margin: 0 0 var(--wp--preset--spacing--20);
}
/* A quieter "we don't have this yet" marker than .ccmm-placeholder.is-strip,
   which draws its own dashed rules and tangled badly with the short lines of
   a definition list. Still visibly unfinished — a missing NAP field must not
   be able to pass for a filled one. */
.ccmm-nap .ccmm-pending {
	display: inline-block;
	border: 1px dashed color-mix(in srgb, currentColor 45%, transparent);
	border-radius: 8px;
	padding: .35em .7em;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
	opacity: .75;
}
@media (max-width: 980px) {
	.ccmm-reasons { grid-template-columns: repeat(2, 1fr); }
	.ccmm-story-cards { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
	.ccmm-reasons { grid-template-columns: 1fr; }
	.ccmm-nap { grid-template-columns: 1fr; }
}
/* ==========================================================================
   Cards — light base + "step" modifier (process steps)
   ========================================================================== */

.ccmm-card-light {
	position: relative;
	border-radius: 18px;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	box-shadow: 0 12px 30px -18px color-mix(in srgb, var(--wp--preset--color--dark) 40%, transparent);
	padding: var(--wp--preset--spacing--40);
	overflow: visible;
	transition: transform .2s cubic-bezier(.22, .7, .3, 1);
}
.ccmm-card-light::before {
	content: '';
	position: absolute;
	inset: 0 auto 0 0;
	width: 5px;
	border-radius: 18px 0 0 18px;
	background: var(--wp--preset--gradient--accent-btn);
}
.ccmm-card-light:hover {
	transform: translateY(-4px);
}
.ccmm-card h3,
.ccmm-card-light h3 {
	font-size: var(--wp--preset--font-size--card);
}
/* Process steps: a circular numbered pill breaking the card's own top edge
   (REFERENCE-SPEC signature 5, "Numbered process", TUP variant — the pole).
   Parent grid carries `.is-proc`. The strip from ::before above is skipped
   here since the pill sits where it would start. */
.ccmm-card-light.is-step::before {
	content: none;
}
.ccmm-card-light.is-step {
	padding-top: calc(var(--wp--preset--spacing--40) + 14px);
}
.ccmm-card-light.is-step::after {
	counter-increment: ccmm-proc;
	content: counter(ccmm-proc, decimal-leading-zero);
	position: absolute;
	top: -22px;
	left: var(--wp--preset--spacing--40);
	width: 44px;
	height: 44px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--dark);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 900;
	font-size: var(--wp--preset--font-size--small);
	box-shadow: 0 8px 18px -6px color-mix(in srgb, var(--wp--preset--color--accent) 70%, transparent);
}
/* ==========================================================================
   Icon badges — round (dark cards / benefits) + squircle (light cards)
   ========================================================================== */

.ccmm-badge {
	width: 66px;
	height: 66px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: conic-gradient(
		from 180deg,
		var(--wp--preset--color--accentsoft),
		var(--wp--preset--color--accent),
		var(--wp--preset--color--accentsoft)
	);
	box-shadow: 0 8px 22px -8px color-mix(in srgb, var(--wp--preset--color--accent) 70%, transparent);
	margin-bottom: var(--wp--preset--spacing--20);
}
.ccmm-badge svg,
.ccmm-badge img {
	width: 1.7rem;
	height: 1.7rem;
	color: var(--wp--preset--color--dark);
	fill: var(--wp--preset--color--dark);
}
/* Benefits band (mid-blue): "circular white icon chips" — same component,
   inverted fill so it reads against the mid band instead of a dark one. */
.ccmm-badge.is-white {
	background: var(--wp--preset--color--paper);
	box-shadow: 0 8px 22px -8px color-mix(in srgb, var(--wp--preset--color--inkdeep) 35%, transparent);
}
.ccmm-badge.is-white svg,
.ccmm-badge.is-white img {
	color: var(--wp--preset--color--mid);
	fill: var(--wp--preset--color--mid);
}
.ccmm-badge-sq {
	width: 56px;
	height: 56px;
	border-radius: 14px;
	display: grid;
	place-items: center;
	background: var(--wp--preset--color--dark);
	margin-bottom: var(--wp--preset--spacing--20);
}
.ccmm-badge-sq svg,
.ccmm-badge-sq img {
	width: 1.5rem;
	height: 1.5rem;
	color: var(--wp--preset--color--accent);
	fill: var(--wp--preset--color--accent);
}
/* The badge groups ship empty (patterns carry structure, not artwork) — a
   generic sparkle glyph is painted via mask so it takes token colour. Real
   per-service icons replace this in CSS, never in the block markup. */
.ccmm-badge::before,
.ccmm-badge-sq::before {
	content: '';
	width: 1.7rem;
	height: 1.7rem;
	background: var(--wp--preset--color--dark);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l2.4 7.6L22 12l-7.6 2.4L12 22l-2.4-7.6L2 12l7.6-2.4z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l2.4 7.6L22 12l-7.6 2.4L12 22l-2.4-7.6L2 12l7.6-2.4z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.ccmm-badge-sq::before {
	width: 1.5rem;
	height: 1.5rem;
	background: var(--wp--preset--color--accent);
}
.ccmm-badge.is-white::before {
	background: var(--wp--preset--color--mid);
}
/* ==========================================================================
   Benefits — circular icon inline with copy
   ========================================================================== */

.ccmm-bnf-item {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--20);
	border-radius: 16px;
	background: rgba(255, 255, 255, .1);
	border: 1px solid rgba(255, 255, 255, .18);
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--20);
	transition: transform .2s cubic-bezier(.22, .7, .3, 1);
}
.ccmm-bnf-item:hover {
	transform: translateY(-4px);
}
.ccmm-bnf-item .ccmm-badge,
.ccmm-bnf-item .ccmm-badge-sq {
	flex: 0 0 auto;
	margin-bottom: 0;
}
.ccmm-bnf-item h3 {
	font-size: var(--wp--preset--font-size--card);
	margin: 0 0 calc(var(--wp--preset--spacing--10) * .5);
}
.ccmm-bnf-item p {
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}
/* ==========================================================================
   Testimonial
   ========================================================================== */

.ccmm-quote {
	max-width: 48rem;
	margin-inline: auto;
	text-align: center;
	border-radius: 20px;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	box-shadow: 0 20px 50px -24px color-mix(in srgb, var(--wp--preset--color--inkdeep) 50%, transparent);
	padding: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-quote p {
	font-size: var(--wp--preset--font-size--lead);
	line-height: 1.6;
}
.ccmm-quote cite,
.ccmm-quote footer {
	display: block;
	margin-top: var(--wp--preset--spacing--20);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 800;
	font-style: normal;
	color: var(--wp--preset--color--accent);
}
/* ==========================================================================
   FAQ — white pill rows on a dark band, circular accent chevron flush right
   (REFERENCE-SPEC signature 6). Native <details>/<summary>, bracket
   selectors allowed here (Lane A only — see CLASS-CONTRACT "Hard rules").
   ========================================================================== */

.ccmm-faq {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
	max-width: 48rem;
	margin-inline: auto;
}
.ccmm-faq-item {
	border-radius: 999px;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	overflow: hidden;
	transition: border-radius .2s cubic-bezier(.22, .7, .3, 1);
}
/* `.is-open` (JS-synced in motion.js), NOT the attribute selector on the
   native open state: square brackets anywhere in CSS trip the Divi shortcode
   parser when this ships inside a code module — including in comments, which
   is why this comment spells it out instead of showing it
   (SERVICE-PAGE-PIPELINE §6, learned the hard way on wizclean). */
.ccmm-faq-item.is-open {
	border-radius: 22px;
}
.ccmm-faq-item summary {
	position: relative;
	display: block;
	list-style: none;
	cursor: pointer;
	padding: var(--wp--preset--spacing--20) calc(var(--wp--preset--spacing--40) + 2.6rem) var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--card);
	text-transform: uppercase;
	letter-spacing: .01em;
}
.ccmm-faq-item summary::-webkit-details-marker { display: none; }
/* Circular accent chevron button, flush right. The circle is ::after (drawn
   first in paint order); the chevron itself is ::before but promoted above
   it with z-index so it reads on top of the circle rather than under it. */
.ccmm-faq-item summary::after {
	content: '';
	position: absolute;
	top: 50%;
	right: var(--wp--preset--spacing--20);
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
	transform: translateY(-50%);
	z-index: 1;
}
.ccmm-faq-item summary::before {
	content: '';
	position: absolute;
	top: 50%;
	right: calc(var(--wp--preset--spacing--20) + 12px);
	width: 9px;
	height: 9px;
	border-right: 2px solid var(--wp--preset--color--dark);
	border-bottom: 2px solid var(--wp--preset--color--dark);
	transform: translateY(-75%) rotate(45deg);
	transition: transform .2s cubic-bezier(.22, .7, .3, 1);
	z-index: 2;
}
.ccmm-faq-item.is-open summary::before {
	transform: translateY(-35%) rotate(225deg);
}
.ccmm-faq-item > :not(summary) {
	padding: 0 var(--wp--preset--spacing--40) var(--wp--preset--spacing--40);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.6;
}
/* ==========================================================================
   Service areas — translucent pill chips on a dark band, accent map-pin dot
   + white label (REFERENCE-SPEC signature 6).
   ========================================================================== */

.ccmm-area-chip {
	position: relative;
	margin: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, .06);
	border: 1px solid rgba(255, 255, 255, .16);
	color: var(--wp--preset--color--paper);
	font-size: var(--wp--preset--font-size--small);
	padding: .6rem 1.2rem .6rem 2.1rem;
}
/* The chip was written for dark bands only: a 6%-white fill with a 16%-white
   border and paper text. On a light band all three vanish and the chip
   renders as nothing but its red dot. Same failure mode as the outlined
   phone pill — a component whose default is the dark-band treatment, used on
   a light band. Any light-family tone must restate all three. */
.ccmm-sec.is-light .ccmm-area-chip,
.ccmm-sec.is-wash .ccmm-area-chip {
	background: var(--wp--preset--color--paper);
	border-color: var(--wp--preset--color--line);
	color: var(--wp--preset--color--ink);
	box-shadow: 0 6px 18px -12px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
}
.ccmm-area-chip::before {
	content: '';
	position: absolute;
	left: .95rem;
	top: 50%;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
	transform: translateY(-50%);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--wp--preset--color--accent) 30%, transparent);
}
/* ==========================================================================
   Photo band — full-bleed section separator, straight edges
   ========================================================================== */

.ccmm-photo-band,
.ccmm-photo-band img {
	display: block;
	width: 100%;
	height: clamp(40vh, 50vw, 60vh);
	object-fit: cover;
}
/* ==========================================================================
   Hero
   ========================================================================== */

.ccmm-hero {
	position: relative;
	overflow: visible;
	isolation: isolate;
	color: var(--wp--preset--color--paper);
	background: var(--wp--preset--color--inkdeep);
	padding-block: var(--wp--preset--spacing--70);
	text-align: center;
}
/* Two-class selector on purpose: inside the editor iframe every block gets
   `.block-editor-block-list__block { position: relative }
` from the editor's
   own stylesheet, which loads after this one — at single-class specificity it
   would win and drop the media into normal flow (a ~900px dark box pushing
   the hero content a full viewport down). */
.ccmm-hero .ccmm-hero-media {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
}
.ccmm-hero-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.ccmm-hero-media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: var(--wp--preset--gradient--dark-band);
	opacity: .72;
}
.ccmm-hero-inner {
	position: relative;
	z-index: 1;
	max-width: 1200px;
	margin-inline: auto;
	padding-inline: clamp(1.1rem, 4vw, 2.4rem);
}
/* An absolutely-positioned sibling paints above static content even at
   z-index:0, so the background photo could still cover the headline despite
   sitting behind it in source order. `.ccmm-hero-inner` fixes this at the
   container level (position:relative + z-index:1 above). This selector is
   the same belt-and-braces rule from the two-column build, kept verbatim
   per CLASS-CONTRACT "Hard rules" even though `.ccmm-hero-media` is now a
   sibling rather than a nested child — it still matches every hero-inner
   child and costs nothing extra. */
.ccmm-hero-inner > *:not(.ccmm-hero-media) {
	position: relative;
	z-index: 1;
}
.ccmm-hero-inner .ccmm-kick {
	margin-bottom: var(--wp--preset--spacing--20);
}
.ccmm-hero-loc {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--10);
	margin-bottom: var(--wp--preset--spacing--10);
}
.ccmm-hero-loc p { margin: 0; }
/* The bound service-area value highlights in accent-b (support), not
   accent-a: a warm accent reads on navy when it's gold, but not when a
   brand's accent is red — the cool accent is legible on dark in both. */
.ccmm-hero-loc .ccmm-hl {
	color: var(--wp--preset--color--support);
}
.ccmm-hero-sub {
	max-width: 34rem;
	margin-inline: auto;
	color: var(--wp--preset--color--support);
	font-size: var(--wp--preset--font-size--lead);
	font-weight: 700;
}
.ccmm-hero-inner .ccmm-cta-row {
	justify-content: center;
	margin-top: var(--wp--preset--spacing--40);
}
/* Framed team-photo card — overlaps the next band's top (REFERENCE-SPEC
   Hero composite). `.ccmm-hero` keeps `overflow:visible` (its media layer
   clips itself independently) so this can spill past the section edge. */
.ccmm-hero-frame {
	width: clamp(220px, 26vw, 320px);
	margin: var(--wp--preset--spacing--50) auto calc(var(--wp--preset--spacing--60) * -1);
	border: 4px solid var(--wp--preset--color--accent);
	border-radius: 16px;
	overflow: hidden;
	box-shadow: 0 20px 40px -16px color-mix(in srgb, var(--wp--preset--color--inkdeep) 60%, transparent);
}
.ccmm-hero-frame img {
	display: block;
	width: 100%;
	height: auto;
}
/* ==========================================================================
   Intro — circular portrait with a badge caption overlapping its corner
   ========================================================================== */

.ccmm-portrait-wrap {
	position: relative;
	max-width: 22rem;
	margin-inline: auto;
}
.ccmm-portrait-badge {
	position: absolute;
	right: -.6rem;
	bottom: -.6rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0;
	width: 84px;
	height: 84px;
	border-radius: 50%;
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--dark);
	box-shadow: 0 10px 24px -8px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
	text-align: center;
	justify-content: center;
}
.ccmm-portrait-badge p {
	margin: 0;
	line-height: 1.1;
}
.ccmm-portrait-badge p:first-child {
	font-size: .62rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	font-weight: 800;
}
.ccmm-portrait-badge p:last-child {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.05rem;
	font-weight: 900;
}
/* ==========================================================================
   Buttons / CTA row — one reusable buttons row (REFERENCE-SPEC signature 2):
   filled accent pill + phone pill, scoped to .ccmm-cta-row so the treatment
   stays inside the patterns rather than bleeding to every button.
   ========================================================================== */

.ccmm-cta-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	/* Both references centre every CTA pair — a left-hung pair reads broken. */
	justify-content: center;
	gap: var(--wp--preset--spacing--20);
}
.ccmm-cta-row .wp-block-button__link {
	background: var(--wp--preset--gradient--accent-btn);
	/* `onaccent`, not `dark`: dark-on-gold works but dark-on-red doesn't —
	   the readable-on-accent colour is a brand decision, so it's a token. */
	color: var(--wp--preset--color--onaccent);
	box-shadow: 0 10px 26px -8px color-mix(in srgb, var(--wp--preset--color--accent) 60%, transparent);
	transition: transform .15s, box-shadow .15s;
}
.ccmm-cta-row .wp-block-button__link:hover {
	transform: translateY(-2px);
}
.ccmm-cta-row .is-style-outline .wp-block-button__link {
	background: rgba(255, 255, 255, .06);
	border: 2px solid rgba(255, 255, 255, .6);
	color: var(--wp--preset--color--paper);
	box-shadow: none;
}
/* Phone icon on the second pill — its label is the phone number itself. */
.ccmm-cta-row .is-style-outline .wp-block-button__link::before {
	content: '\260E';
	margin-right: .5em;
}
/* Light bands: the translucent-white outline pill is invisible on paper —
   the phone pill fills accent-b instead (REFERENCE-SPEC signature 2:
   "outlined-white on dark bands, filled accent-b on light bands").
   `is-wash` was missing from this list. It is the second light tone in the
   palette (#f1f5fb), so a white pill with a 60%-white border on it rendered
   as very nearly nothing — the phone CTA on any wash band was effectively
   invisible. Every light-family tone must be listed here; the default in the
   block above is the DARK-band treatment, so a tone omitted here fails
   silently rather than looking obviously wrong. */
.ccmm-sec.is-light .ccmm-cta-row .is-style-outline .wp-block-button__link,
.ccmm-sec.is-wash .ccmm-cta-row .is-style-outline .wp-block-button__link,
.ccmm-sticky-bar .ccmm-cta-row .is-style-outline .wp-block-button__link {
	background: var(--wp--preset--color--support);
	border-color: var(--wp--preset--color--support);
	color: var(--wp--preset--color--ink);
}
/* ==========================================================================
   Sticky contact bar — the references' "hanging contact us": a fixed white
   bar that slides in once the visitor scrolls past the hero (motion.js
   toggles .is-shown). Static in the editor so it never covers the canvas.
   ========================================================================== */

.ccmm-sticky-bar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	/* The constrained layout parent caps children at contentSize —
	   a fixed full-width bar must escape that. */
	max-width: none;
	z-index: 60;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--30);
	padding: 0.55rem 1rem;
	background: var(--wp--preset--color--paper);
	box-shadow: 0 12px 30px -14px color-mix(in srgb, var(--wp--preset--color--inkdeep) 45%, transparent);
	transform: translateY(-110%);
	transition: transform 0.35s ease;
}
.ccmm-sticky-bar.is-shown {
	transform: translateY(0);
}
.ccmm-sticky-bar .ccmm-sticky-label {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 800;
	color: var(--wp--preset--color--ink);
}
.ccmm-sticky-bar .ccmm-cta-row .wp-block-button__link {
	padding: 0.6rem 1.3rem;
}
@media (prefers-reduced-motion: reduce) {
	.ccmm-sticky-bar {
		transition: none;
	}
}
/* Editor: render in flow, never fixed over the canvas. */
.editor-styles-wrapper .ccmm-sticky-bar {
	position: static;
	transform: none;
}
/* Footer © line — the bound paragraph carries ONLY the company name (a
   binding replaces the whole attribute, partial interpolation isn't a thing),
   so the legal dressing is painted around it here. */
.ccmm-footer-copy::before { content: '\00a9 '; }
.ccmm-footer-copy::after  { content: '. All rights reserved.'; }
/* The final CTA band is full accent (gold) — a gold-on-gold filled button
   would be invisible, so both pills invert to dark-on-gold here. */
.ccmm-sec.is-accent .ccmm-cta-row .wp-block-button__link {
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--paper);
	box-shadow: 0 10px 26px -8px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
}
.ccmm-sec.is-accent .ccmm-cta-row .is-style-outline .wp-block-button__link {
	background: transparent;
	border-color: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--dark);
}
/* ==========================================================================
   Responsive collapses — design-spec §7: 980px, 900px, 560px
   ========================================================================== */

@media (max-width: 980px) {
	.ccmm-grid5 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
	.ccmm-grid2 { grid-template-columns: 1fr; }
	.ccmm-grid3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
	.ccmm-grid5,
	.ccmm-grid3 {
		grid-template-columns: 1fr;
	}
	.ccmm-hero-inner h1 {
		font-size: 2.2rem;
	}
}

/* ---------- page: home.html ---------- */

/* ---- mockup-only: site chrome (header/nav/footer) + the two new
   global-module bands (blog roll cards, service menu list) — none of these
   are part of the Lane A CLASS-CONTRACT, so they get their own scoped rules
   here rather than touching the shared foundation files. The homepage-formula
   pass (fixed top bar, hero form card, phone strips, linked service tiles,
   review cards, dashed placeholders, trust chips) follows the same policy —
   new page furniture, own rules, foundation files untouched. ---- */
/* variant C only: bias the cover-crop to the image's left edge so Adam
   (standing at ~45% of the frame) shifts right, out from under the headline
   copy and into the visible gap beside the form card. */
.ccmm-hero .ccmm-hero-media img { object-position: left center; }
.ccmm-header {
	background: var(--wp--preset--color--paper);
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.ccmm-header-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-block: var(--wp--preset--spacing--20);
}
.ccmm-logo img { display: block; height: 52px; width: auto; }
.ccmm-nav ul {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-nav a {
	font-family: var(--wp--preset--font-family--display);
	font-size: .85rem;
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
}
.ccmm-nav a:hover { color: var(--wp--preset--color--accent); }
.ccmm-header-phone { white-space: nowrap; }
.ccmm-story-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
	align-items: center;
	gap: var(--wp--preset--spacing--60);
}
@media (max-width: 900px) {
	.ccmm-story-grid { grid-template-columns: 1fr; }
}
.ccmm-prose-2col {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 900px) {
	.ccmm-prose-2col { grid-template-columns: 1fr; }
}
.ccmm-prose-2col h3 { margin-bottom: var(--wp--preset--spacing--10); }
.ccmm-svc-menu {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-svc-menu a {
	font-family: var(--wp--preset--font-family--display);
	font-size: .85rem;
	font-weight: 800;
	letter-spacing: .02em;
	color: var(--wp--preset--color--paper);
}
.ccmm-svc-menu a:hover { color: var(--wp--preset--color--support); }
.ccmm-sec.is-svc-menu { padding-block: var(--wp--preset--spacing--40); }
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 700px) {
	.ccmm-footer-grid { grid-template-columns: 1fr; }
}
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin-bottom: var(--wp--preset--spacing--10); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}
/* ==========================================================================
   NEW — fixed top bar (formula #0). Always visible, not scroll-triggered —
   it absorbs the job the old scroll-triggered .ccmm-sticky-bar used to do
   (that bar + its JS toggle are removed below in favour of this one).
   ========================================================================== */
.ccmm-topbar {
	position: sticky;
	top: 0;
	z-index: 70;
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
}
.ccmm-topbar-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-block: 0.55rem;
	font-size: var(--wp--preset--font-size--eyebrow);
}
.ccmm-topbar-marks {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--20);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-topbar-mark {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--wp--preset--color--support);
	white-space: nowrap;
}
.ccmm-topbar-mark:not(.ccmm-placeholder)::before {
	content: '\2713';
	margin-right: .4em;
	color: var(--wp--preset--color--accent);
}
.ccmm-topbar-call {
	display: flex;
	align-items: center;
	gap: .5em;
	white-space: nowrap;
	font-weight: 800;
}
.ccmm-topbar-call-label {
	text-transform: uppercase;
	letter-spacing: .04em;
	opacity: .85;
}
.ccmm-topbar-call a {
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--display);
}
.ccmm-topbar-btn {
	flex: 0 0 auto;
	display: inline-block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--eyebrow);
	text-transform: uppercase;
	letter-spacing: .03em;
	border-radius: 999px;
	padding: .5rem 1.1rem;
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--onaccent);
	white-space: nowrap;
}
@media (max-width: 700px) {
	.ccmm-topbar-marks { display: none; }
}
/* ==========================================================================
   NEW — generic dashed placeholder. Labeled slots for data we don't have
   yet (Google rating, live reviews widget, guarantee badge asset). The
   label IS the content — never filled with an invented number or star
   rating.
   ========================================================================== */
.ccmm-placeholder {
	border: 2px dashed color-mix(in srgb, currentColor 45%, transparent);
	border-radius: 12px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: .03em;
	text-align: center;
}
.ccmm-placeholder.is-pill {
	display: inline-flex;
	align-items: center;
	border-radius: 999px;
	padding: .3rem .8rem;
	font-size: .6rem;
	white-space: nowrap;
}
.ccmm-placeholder.is-strip {
	max-width: 46rem;
	margin: 0 auto var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
	opacity: .85;
}
.ccmm-placeholder.is-badge {
	width: 130px;
	height: 130px;
	border-radius: 50%;
	margin: var(--wp--preset--spacing--40) auto 0;
	padding: 1rem;
	display: flex;
	align-items: center;
	justify-content: center;
	line-height: 1.25;
	font-size: .64rem;
	opacity: .85;
}
/* ==========================================================================
   NEW — hero two-column layout (content left, THE lead form right).
   ========================================================================== */
.ccmm-hero-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(280px, 1fr);
	gap: var(--wp--preset--spacing--60);
	align-items: start;
	text-align: left;
	margin-top: var(--wp--preset--spacing--30);
}
@media (max-width: 900px) {
	.ccmm-hero-grid { grid-template-columns: 1fr; text-align: center; }
}
@media (min-width: 901px) {
	.ccmm-hero-copy .ccmm-hero-loc,
	.ccmm-hero-copy .ccmm-cta-row,
	.ccmm-hero-copy .ccmm-check-list { justify-content: flex-start; }
	.ccmm-hero-copy .ccmm-hero-sub { margin-inline: 0; }
}
.ccmm-check-list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--20);
	margin: var(--wp--preset--spacing--30) 0;
	padding: 0;
	list-style: none;
}
.ccmm-check-list li {
	display: flex;
	align-items: center;
	gap: .5em;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
}
.ccmm-check-list li::before {
	content: '\2713';
	display: inline-grid;
	place-items: center;
	width: 1.3em;
	height: 1.3em;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--onaccent);
	font-size: .68em;
	flex: 0 0 auto;
}
/* ==========================================================================
   NEW — THE lead form card (hero, right column). Static mock of the real
   fields in content/old-site/free-estimate.md — inputs disabled, the live
   build swaps this whole card for the GHL embed.
   ========================================================================== */
.ccmm-form-card {
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	border-radius: 20px;
	padding: var(--wp--preset--spacing--40);
	box-shadow: 0 20px 50px -24px color-mix(in srgb, var(--wp--preset--color--inkdeep) 60%, transparent);
	text-align: left;
}
.ccmm-form-card h3 {
	font-size: var(--wp--preset--font-size--band);
	margin-bottom: var(--wp--preset--spacing--10);
}
.ccmm-form-card > p {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--soft);
}
.ccmm-form-card > p a { color: var(--wp--preset--color--accent); }
.ccmm-form-row { margin-bottom: var(--wp--preset--spacing--20); }
.ccmm-form-row--2col {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--20);
}
@media (max-width: 480px) {
	.ccmm-form-row--2col { grid-template-columns: 1fr; }
}
.ccmm-form-row label,
.ccmm-form-consent {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	margin-bottom: .3rem;
}
.ccmm-form-row input,
.ccmm-form-row select,
.ccmm-form-row textarea {
	display: block;
	width: 100%;
	margin-top: .35rem;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 8px;
	padding: .6rem .8rem;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	background: var(--wp--preset--color--wash);
	color: var(--wp--preset--color--soft);
}
.ccmm-form-row textarea { resize: none; height: 4.5rem; }
.ccmm-form-consent {
	display: flex;
	align-items: flex-start;
	gap: .5em;
	font-weight: 400;
	font-size: .78rem;
	color: var(--wp--preset--color--soft);
	margin-bottom: var(--wp--preset--spacing--20);
}
.ccmm-form-consent input { margin-top: .2rem; }
.ccmm-form-upload {
	border: 1px dashed var(--wp--preset--color--line);
	border-radius: 8px;
	padding: .8rem;
	margin: 0;
	font-size: .78rem;
	color: var(--wp--preset--color--soft);
	text-align: center;
}
.ccmm-form-upload span { display: block; font-size: .7rem; margin-top: .2rem; }
.ccmm-form-card button[disabled] {
	width: 100%;
	opacity: .6;
	cursor: not-allowed;
}
.ccmm-form-embed-note {
	margin: var(--wp--preset--spacing--20) 0 0;
	font-size: .74rem;
	font-style: italic;
	color: var(--wp--preset--color--soft);
	text-align: center;
}
/* ==========================================================================
   NEW — owner-as-guide: trust chips + the team photo moved down from the
   hero (it crowds the hero once the form card takes the right column).
   ========================================================================== */
.ccmm-trust-chips {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--30);
	margin-top: var(--wp--preset--spacing--40);
}
.ccmm-trust-chip {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--10);
}
.ccmm-trust-chip .ccmm-badge-sq { margin-bottom: 0; }
.ccmm-trust-chip p {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: .02em;
}
.ccmm-team-frame {
	display: block;
	max-width: 420px;
	margin: var(--wp--preset--spacing--50) auto 0;
	border: 4px solid var(--wp--preset--color--accent);
	border-radius: 16px;
}
/* ==========================================================================
   NEW — services menu: linked tiles (real photo where staged, icon badge
   otherwise). The whole card is the link; anchor reset so it doesn't pick
   up the global accent-red link colour.
   ========================================================================== */
.ccmm-svc-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--wp--preset--spacing--30);
}
@media (max-width: 900px) { .ccmm-svc-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .ccmm-svc-grid { grid-template-columns: 1fr; } }
a.ccmm-card-light {
	display: block;
	color: inherit;
	text-decoration: none;
}
.ccmm-card-light.is-photo-tile img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: 14px;
	margin-bottom: var(--wp--preset--spacing--20);
}
/* --- real photography, replacing the client-asset placeholders ------------
   The photos are PCRS's own: service shots from their Drive folder, and the
   before/after pairs from the 97 sets published on pcrsofct.com. */
.ccmm-card-photo {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	border-radius: 14px;
	margin-bottom: var(--wp--preset--spacing--20);
	background: color-mix(in srgb, var(--wp--preset--color--inkdeep) 8%, transparent);
}
/* Whole-card link. The two service cards previously linked only from a
   "Learn more" sentence at the bottom; the photo and the heading — the things
   a visitor actually aims at — were dead. */
.ccmm-card-link {
	display: block;
	color: inherit;
	text-decoration: none;
}
.ccmm-card-link h3 { margin-top: 0; }
.ccmm-card-link:hover h3,
.ccmm-card-link:focus-visible h3 { text-decoration: underline; }
/* Before/after pair. Both frames must be the SAME aspect ratio and the same
   height or the comparison lies — a taller "after" reads as more improvement
   than there was. object-fit:cover on a shared aspect-ratio guarantees it
   regardless of the two source files' own proportions. */
.ccmm-ba {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 6px;
	margin-bottom: var(--wp--preset--spacing--20);
}
.ccmm-ba figure {
	position: relative;
	margin: 0;
}
.ccmm-ba img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 10px;
	background: color-mix(in srgb, var(--wp--preset--color--inkdeep) 8%, transparent);
}
.ccmm-ba figcaption {
	position: absolute;
	inset-inline-start: 8px;
	inset-block-start: 8px;
	padding: .18rem .5rem;
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: .62rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	background: color-mix(in srgb, var(--wp--preset--color--inkdeep) 78%, transparent);
	color: var(--wp--preset--color--paper);
}
.ccmm-ba figure.is-after figcaption {
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--onaccent);
}
.ccmm-phone-strip p {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: .03em;
	font-size: var(--wp--preset--font-size--small);
}
.ccmm-phone-strip a { color: inherit; text-decoration: underline; }
/* ==========================================================================
   NEW — reviews: named cards + citation footer (same citation treatment as
   the single-quote card this replaces).
   ========================================================================== */
.ccmm-card.is-review footer {
	margin-top: var(--wp--preset--spacing--20);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--small);
	/* Was accent red. The review cards only ever sit on an is-dark band, where
	   #ed1c24 on #272b6f is about 2.5:1 — under the 4.5:1 bar for text this
	   small. Support blue on the same ground measures about 5.6:1. */
	color: var(--wp--preset--color--support);
}
/* ---- footer v2 (global module, formula #15): 4 columns = contact/legal +
   the old site's real footer link columns (_site-chrome.md) + social +
   office-hours placeholder. Overrides the earlier 2-col footer rules. ---- */
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.6fr 1fr 1fr 1.1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 1000px) { .ccmm-footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px)  { .ccmm-footer-grid { grid-template-columns: 1fr; } }
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin: 0 0 var(--wp--preset--spacing--10); }
.ccmm-footer :is(h2,h3) + p, .ccmm-footer ul + :is(h2,h3) { margin-top: var(--wp--preset--spacing--20); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; margin: 0 0 .4rem; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer ul { list-style: none; margin: 0; padding: 0; }
.ccmm-footer li { margin-bottom: .35rem; }
.ccmm-footer li a { opacity: .85; font-size: .9rem; }
.ccmm-footer li a:hover { opacity: 1; }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}

/* ---------- page: about.html ---------- */

/* Two co-owner cut-outs side by side in the story section (Gus 2026-08-07:
   "second-generation" needs BOTH Amy and Curtis visible) */
.ccmm-portrait-duo {
	display: grid;
	/* Cut-outs are pre-matched on HEAD SIZE, not frame height: each was scaled
	   so hair-to-chin is the same pixel height, then both cropped to 3.37
	   head-heights (see scratchpad/match_owners.py). Columns follow the
	   resulting widths — Amy 629px, Curtis 791px — so no CSS scaling undoes
	   the match; they sit bottom-aligned as a pair. */
	grid-template-columns: 0.8fr 1fr;
	gap: 1rem;
	align-items: end;
}
.ccmm-portrait-duo .ccmm-portrait-wrap { max-width: none; }
.ccmm-portrait-duo img { display: block; width: 100%; height: auto; }
/* Page-specific supplemental rules for this mockup only — never touches
	   pcrs-tokens.css / patterns.css. Prefixed `pcrs-`, not `ccmm-`: the
	   ccmm- vocabulary is the fixed Lane A contract, this page needs a
	   couple of one-off treatments the contract doesn't define (an
	   "archive photo requested" placeholder, no-photo team cards). Every
	   value below is still a var(--wp--preset--*) token, per the hard rule. */

	/* "Then & now" archive slot — real "now" photo beside a clearly-marked
	   placeholder box for the grainy family photo the client will supply. */
	/* The "now" photo is a 3:1 team lineup. Held in one half of the two-column
	   grid it rendered 536px wide and 174px tall — thirteen faces at thumbnail
	   size beside an empty placeholder box twice its height. It spans the full
	   width instead, and the archive placeholder sits under it as a slim bar,
	   which is the right weight for a note about a photo that does not exist
	   yet. */
	.pcrs-now-photo {
		grid-column: 1 / -1;
	}
.pcrs-now-photo img {
		display: block;
		width: 100%;
		height: auto;
		border-radius: 14px;
	}
.ccmm-grid2 > .pcrs-archive-box {
		grid-column: 1 / -1;
		min-height: 0;
		padding-block: var(--wp--preset--spacing--30);
	}
/* Co-owner bio cards. Same 4:5 portrait as the roster below, so the two
	   sections read as one set rather than two treatments of the same people. */
	.pcrs-owner-photo {
		display: block;
		width: 100%;
		max-width: 260px;
		aspect-ratio: 4 / 5;
		object-fit: cover;
		object-position: 50% 22%;
		border-radius: var(--wp--custom--radius--md, 14px);
		margin: 0 auto var(--wp--preset--spacing--30);
		background: var(--wp--preset--color--paper);
		box-shadow: 0 14px 32px -18px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
	}
/* Service menu tiles (global module 5881, on 12 pages).
	   Was six bare text chips. PAGE-FORMULA #6 calls for photo tiles, and this
	   band is where a visitor picks what they came for. The whole tile is the
	   anchor, so the click target is the card rather than the label. */
	.ccmm-svc-tiles {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: var(--wp--preset--spacing--30);
	}
@media (max-width: 900px) { .ccmm-svc-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .ccmm-svc-tiles { grid-template-columns: 1fr; } }

/* Orphan-row fix for 7 ccmm-svc-tiles (added with Dryer Vent Cleaning,
   2026-08-19). At 3-per-row and 2-per-row the 7th tile would be the sole
   item on its own last row; span it full-width in exactly that case rather
   than hardcoding "7". */
.ccmm-svc-tiles > :last-child:nth-child(3n+1) {
	grid-column: 1 / -1;
	max-width: 420px;
	margin-inline: auto;
}
@media (max-width: 900px) {
	.ccmm-svc-tiles > :last-child:nth-child(2n+1) {
		grid-column: 1 / -1;
		max-width: 420px;
		margin-inline: auto;
	}
}

.ccmm-svc-tile {
		display: block;
		text-decoration: none;
		color: inherit;
		border-radius: 14px;
		overflow: hidden;
		background: color-mix(in srgb, var(--wp--preset--color--paper) 8%, transparent);
		transition: transform .18s ease, box-shadow .18s ease;
	}
.ccmm-svc-tile img {
		display: block;
		width: 100%;
		aspect-ratio: 4 / 3;
		object-fit: cover;
	}
.ccmm-svc-tile span {
		display: block;
		padding: .85rem 1rem;
		font-family: var(--wp--preset--font-family--display);
		font-weight: 800;
		font-size: var(--wp--preset--font-size--small);
		line-height: 1.25;
		text-align: center;
	}
.ccmm-svc-tile:hover,
	.ccmm-svc-tile:focus-visible {
		transform: translateY(-3px);
		box-shadow: 0 16px 30px -18px color-mix(in srgb, var(--wp--preset--color--inkdeep) 80%, transparent);
	}
/* Community involvement — the client's own event photography. */
	.pcrs-community-grid {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: var(--wp--preset--spacing--30);
		margin-top: var(--wp--preset--spacing--40);
	}
@media (max-width: 900px) { .pcrs-community-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .pcrs-community-grid { grid-template-columns: 1fr; } }
.pcrs-community-grid figure {
		margin: 0;
	}
.pcrs-community-grid img {
		display: block;
		width: 100%;
		aspect-ratio: 4 / 3;
		object-fit: cover;
		border-radius: 14px;
	}
.pcrs-community-grid figcaption {
		margin-top: calc(var(--wp--preset--spacing--10) * 1.5);
		font-family: var(--wp--preset--font-family--display);
		font-weight: 800;
		font-size: var(--wp--preset--font-size--small);
		color: var(--wp--preset--color--soft);
		text-align: center;
	}
.pcrs-archive-box {
		min-height: 320px;
		display: flex;
		align-items: center;
		justify-content: center;
		text-align: center;
		border-radius: 14px;
		border: 2px dashed color-mix(in srgb, var(--wp--preset--color--paper) 55%, transparent);
		background: rgba(255, 255, 255, .04);
		padding: var(--wp--preset--spacing--40);
	}
.pcrs-archive-box p {
		margin: 0;
		font-family: var(--wp--preset--font-family--display);
		font-weight: 800;
		font-size: var(--wp--preset--font-size--small);
		letter-spacing: .04em;
		text-transform: uppercase;
		color: color-mix(in srgb, var(--wp--preset--color--paper) 75%, transparent);
	}
/* Team roster.
	   The headshots are real studio portraits, so they carry the section — a
	   96px circle threw away almost all of that and left the cards reading as
	   a text list with a bullet. Each photo is now a full-card-width portrait.
	   Circles are deliberately not used: at this size a circular crop cuts the
	   shoulders off a half-length studio shot. */
	.pcrs-team-card {
		text-align: center;
	}
.pcrs-avatar,
	.pcrs-avatar-photo {
		width: 100%;
		aspect-ratio: 4 / 5;
		margin: 0 auto var(--wp--preset--spacing--30);
		border-radius: var(--wp--custom--radius--md, 14px);
		display: block;
	}
.pcrs-avatar {
		display: grid;
		place-items: center;
		background: var(--wp--preset--gradient--accent-btn);
		color: var(--wp--preset--color--onaccent);
		font-family: var(--wp--preset--font-family--display);
		font-weight: 900;
		font-size: clamp(2rem, 6vw, 3.25rem);
	}
.pcrs-avatar-photo {
		object-fit: cover;
		/* The studio shots are framed head-and-torso on white with headroom;
		   pulling the crop above centre keeps the face off the top edge
		   without cropping into the chin. */
		object-position: 50% 22%;
		background: var(--wp--preset--color--paper);
		box-shadow: 0 14px 32px -18px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
	}
.pcrs-team-card h3 {
		margin-bottom: calc(var(--wp--preset--spacing--10) * .5);
	}
.pcrs-team-card p {
		margin: 0;
		font-size: var(--wp--preset--font-size--small);
		color: var(--wp--preset--color--soft);
	}
/* `is-style-rounded` is a WP core block-style class — core CSS isn't
	   loaded in this standalone mockup, so the circular crop it normally
	   supplies is shimmed here for the portrait image only. */
	.ccmm-portrait-wrap img.is-style-rounded {
		border-radius: 50%;
		aspect-ratio: 1 / 1;
		object-fit: cover;
	}
/* labeled placeholder (ported from home) */
.ccmm-placeholder { border: 2px dashed color-mix(in srgb, currentColor 45%, transparent); border-radius: 12px; font-family: var(--wp--preset--font-family--display); font-weight: 800; font-size: var(--wp--preset--font-size--small); text-transform: uppercase; letter-spacing: .03em; text-align: center; }
/* ==========================================================================
   NEW — fixed top bar (formula #0). Always visible, not scroll-triggered —
   it absorbs the job the old scroll-triggered .ccmm-sticky-bar used to do
   (that bar + its JS toggle are removed below in favour of this one).
   ========================================================================== */
.ccmm-topbar {
	position: sticky;
	top: 0;
	z-index: 70;
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
}
.ccmm-topbar-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-block: 0.55rem;
	font-size: var(--wp--preset--font-size--eyebrow);
}
.ccmm-topbar-marks {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--20);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-topbar-mark {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--wp--preset--color--support);
	white-space: nowrap;
}
.ccmm-topbar-mark:not(.ccmm-placeholder)::before {
	content: '\2713';
	margin-right: .4em;
	color: var(--wp--preset--color--accent);
}
.ccmm-topbar-call {
	display: flex;
	align-items: center;
	gap: .5em;
	white-space: nowrap;
	font-weight: 800;
}
.ccmm-topbar-call-label {
	text-transform: uppercase;
	letter-spacing: .04em;
	opacity: .85;
}
.ccmm-topbar-call a {
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--display);
}
.ccmm-topbar-btn {
	flex: 0 0 auto;
	display: inline-block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--eyebrow);
	text-transform: uppercase;
	letter-spacing: .03em;
	border-radius: 999px;
	padding: .5rem 1.1rem;
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--onaccent);
	white-space: nowrap;
}
@media (max-width: 700px) {
	.ccmm-topbar-marks { display: none; }
}
/* ---- footer v2 (global module, formula #15): 4 columns = contact/legal +
   the old site's real footer link columns (_site-chrome.md) + social +
   office-hours placeholder. Overrides the earlier 2-col footer rules. ---- */
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.6fr 1fr 1fr 1.1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 1000px) { .ccmm-footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px)  { .ccmm-footer-grid { grid-template-columns: 1fr; } }
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin: 0 0 var(--wp--preset--spacing--10); }
.ccmm-footer :is(h2,h3) + p, .ccmm-footer ul + :is(h2,h3) { margin-top: var(--wp--preset--spacing--20); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; margin: 0 0 .4rem; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer ul { list-style: none; margin: 0; padding: 0; }
.ccmm-footer li { margin-bottom: .35rem; }
.ccmm-footer li a { opacity: .85; font-size: .9rem; }
.ccmm-footer li a:hover { opacity: 1; }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}

/* ---------- page: carpet-cleaning.html ---------- */

/* ---- mockup-only: site chrome (header/nav/footer) + the two new
   global-module bands (blog roll cards, service menu list) — none of these
   are part of the Lane A CLASS-CONTRACT, so they get their own scoped rules
   here rather than touching the shared foundation files. Copied verbatim
   from mockups/home.html for cross-page consistency. ---- */
.ccmm-header {
	background: var(--wp--preset--color--paper);
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.ccmm-header-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-block: var(--wp--preset--spacing--20);
}
.ccmm-logo img { display: block; height: 52px; width: auto; }
.ccmm-nav ul {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-nav a {
	font-family: var(--wp--preset--font-family--display);
	font-size: .85rem;
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
}
.ccmm-nav a:hover { color: var(--wp--preset--color--accent); }
.ccmm-header-phone { white-space: nowrap; }
.ccmm-svc-menu {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-svc-menu a {
	font-family: var(--wp--preset--font-family--display);
	font-size: .85rem;
	font-weight: 800;
	letter-spacing: .02em;
	color: var(--wp--preset--color--paper);
}
.ccmm-svc-menu a:hover { color: var(--wp--preset--color--support); }
.ccmm-sec.is-svc-menu { padding-block: var(--wp--preset--spacing--40); }
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 700px) {
	.ccmm-footer-grid { grid-template-columns: 1fr; }
}
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin-bottom: var(--wp--preset--spacing--10); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}
/* ---- mockup-only: page-specific components added in the enhanced-formula
   recut (formula-delta pass) — the credential-intro 2-col grid (borrowed
   verbatim from mockups/home.html's own "Story" grid, same "not part of the
   Lane A contract" reasoning as the chrome rules above), plus two components
   that don't exist anywhere else yet: the job-photo gallery row and the
   phone-strip band's text treatment. ---- */
.ccmm-story-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
	align-items: center;
	gap: var(--wp--preset--spacing--60);
}
@media (max-width: 900px) {
	.ccmm-story-grid { grid-template-columns: 1fr; }
}
.ccmm-cred-photo {
	border-radius: 18px;
	overflow: hidden;
	box-shadow: 0 20px 40px -18px color-mix(in srgb, var(--wp--preset--color--inkdeep) 55%, transparent);
}
.ccmm-cred-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ccmm-gallery-row {
	display: flex;
	gap: var(--wp--preset--spacing--20);
	overflow-x: auto;
	padding-bottom: var(--wp--preset--spacing--10);
	scroll-snap-type: x proximity;
}
.ccmm-gallery-tile {
	flex: 0 0 auto;
	width: clamp(180px, 22vw, 260px);
	aspect-ratio: 4 / 3;
	margin: 0;
	border-radius: 14px;
	overflow: hidden;
	scroll-snap-align: start;
	box-shadow: 0 12px 30px -18px color-mix(in srgb, var(--wp--preset--color--dark) 40%, transparent);
}
.ccmm-gallery-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ccmm-gallery-tile.is-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	border: 2px dashed var(--wp--preset--color--line);
	background: var(--wp--preset--color--wash);
	color: var(--wp--preset--color--soft);
	padding: var(--wp--preset--spacing--20);
}
.ccmm-gallery-tile.is-placeholder p {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: .02em;
}
.ccmm-gallery-tile.is-placeholder span {
	display: block;
	margin-top: .4rem;
	font-weight: 400;
	text-transform: none;
	letter-spacing: 0;
	font-size: .8rem;
}
.ccmm-phone-strip-text {
	margin: 0;
	text-align: center;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 900;
	font-size: clamp(1.3rem, 3.2vw, 2rem);
	text-transform: uppercase;
	letter-spacing: .02em;
}
.ccmm-phone-strip-text a {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 2px;
}
/* ==========================================================================
   NEW — fixed top bar (formula #0). Always visible, not scroll-triggered —
   it absorbs the job the old scroll-triggered .ccmm-sticky-bar used to do
   (that bar + its JS toggle are removed below in favour of this one).
   ========================================================================== */
.ccmm-topbar {
	position: sticky;
	top: 0;
	z-index: 70;
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
}
.ccmm-topbar-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-block: 0.55rem;
	font-size: var(--wp--preset--font-size--eyebrow);
}
.ccmm-topbar-marks {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--20);
	margin: 0;
	padding: 0;
	list-style: none;
}
.ccmm-topbar-mark {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--wp--preset--color--support);
	white-space: nowrap;
}
.ccmm-topbar-mark:not(.ccmm-placeholder)::before {
	content: '\2713';
	margin-right: .4em;
	color: var(--wp--preset--color--accent);
}
.ccmm-topbar-call {
	display: flex;
	align-items: center;
	gap: .5em;
	white-space: nowrap;
	font-weight: 800;
}
.ccmm-topbar-call-label {
	text-transform: uppercase;
	letter-spacing: .04em;
	opacity: .85;
}
.ccmm-topbar-call a {
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--display);
}
.ccmm-topbar-btn {
	flex: 0 0 auto;
	display: inline-block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--eyebrow);
	text-transform: uppercase;
	letter-spacing: .03em;
	border-radius: 999px;
	padding: .5rem 1.1rem;
	background: var(--wp--preset--gradient--accent-btn);
	color: var(--wp--preset--color--onaccent);
	white-space: nowrap;
}
@media (max-width: 700px) {
	.ccmm-topbar-marks { display: none; }
}
/* ---- footer v2 (global module, formula #15): 4 columns = contact/legal +
   the old site's real footer link columns (_site-chrome.md) + social +
   office-hours placeholder. Overrides the earlier 2-col footer rules. ---- */
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.6fr 1fr 1fr 1.1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 1000px) { .ccmm-footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px)  { .ccmm-footer-grid { grid-template-columns: 1fr; } }
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin: 0 0 var(--wp--preset--spacing--10); }
.ccmm-footer :is(h2,h3) + p, .ccmm-footer ul + :is(h2,h3) { margin-top: var(--wp--preset--spacing--20); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; margin: 0 0 .4rem; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer ul { list-style: none; margin: 0; padding: 0; }
.ccmm-footer li { margin-bottom: .35rem; }
.ccmm-footer li a { opacity: .85; font-size: .9rem; }
.ccmm-footer li a:hover { opacity: 1; }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}

/* ---------- page: dryer-vent-cleaning.html ---------- */

/*
	 * Tier-2 (secondary) page furniture — header, footer, CTA line, native FAQ.
	 * Deliberately plain: no gradients, no motion, no ccmm-* card treatment.
	 * The pretty stuff is reserved for the pillar tier and for the bottom
	 * global modules below, which reuse patterns.css on purpose (REFERENCE-SPEC
	 * furniture is shared across every page, high or low tier).
	 */
	.tier2-topbar {
		border-bottom: 1px solid var(--wp--preset--color--line);
	}
.tier2-topbar-inner {
		max-width: 1200px;
		margin-inline: auto;
		padding: 0.9rem clamp(1.1rem, 4vw, 2.4rem);
		display: flex;
		align-items: center;
		flex-wrap: wrap;
		gap: 1rem;
		justify-content: space-between;
	}
.tier2-logo {
		display: flex;
		flex-direction: column;
		line-height: 1.1;
		font-family: var(--wp--preset--font-family--display);
		font-weight: 900;
		font-size: 1.3rem;
		color: var(--wp--preset--color--dark);
	}
.tier2-logo span {
		font-family: var(--wp--preset--font-family--body);
		font-weight: 400;
		font-size: 0.6rem;
		text-transform: none;
		letter-spacing: 0.02em;
		color: var(--wp--preset--color--soft);
	}
.tier2-nav {
		display: flex;
		flex-wrap: wrap;
		gap: clamp(0.8rem, 2vw, 1.6rem);
	}
.tier2-nav a {
		color: var(--wp--preset--color--ink);
		font-family: var(--wp--preset--font-family--display);
		font-size: 0.85rem;
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.02em;
	}
.tier2-nav a:hover { color: var(--wp--preset--color--accent); }
.tier2-phone {
		display: inline-block;
		background: var(--wp--preset--color--accent);
		color: var(--wp--preset--color--onaccent) !important;
		border-radius: 999px;
		padding: 0.5rem 1.1rem;
		font-family: var(--wp--preset--font-family--display);
		font-weight: 800;
		font-size: 0.85rem;
		white-space: nowrap;
	}
.tier2-cta-line { margin: 1.6rem 0; }
.tier2-faq { margin: 1.6rem 0 2.2rem; }
.tier2-faq details {
		border: 1px solid var(--wp--preset--color--line);
		border-radius: 6px;
		padding: 0.2rem 1.1rem;
		margin-bottom: 0.8rem;
		background: var(--wp--preset--color--paper);
	}
.tier2-faq summary {
		cursor: pointer;
		padding: 0.85rem 0;
		font-weight: 700;
	}
.tier2-faq details p { margin: 0 0 0.9rem; }
.tier2-faq details p:last-child { margin-bottom: 0.85rem; }
/* Sidebar rules removed 2026-08-13 with the sidebar itself — the tier2
	   layout is single-column now. See assets/pcrs-tokens.css. */

	.tier2-footer {
		background: var(--wp--preset--color--inkdeep);
		color: var(--wp--preset--color--paper);
	}
.tier2-footer-inner {
		max-width: 1200px;
		margin-inline: auto;
		padding: clamp(1.6rem, 4vw, 2.6rem) clamp(1.1rem, 4vw, 2.4rem);
		text-align: center;
	}
.tier2-footer-inner p { margin: 0 0 0.4rem; }
.tier2-footer-inner a { color: var(--wp--preset--color--paper); }
.tier2-footer-name { font-family: var(--wp--preset--font-family--display); font-weight: 800; }
.tier2-footer-tag { color: var(--wp--preset--color--onbadge); font-size: var(--wp--preset--font-size--small); }
.tier2-footer-copy { font-size: var(--wp--preset--font-size--small); opacity: 0.75; margin-top: 0.8rem; }
/* ---- footer v2 (global module, formula #15): 4 columns = contact/legal +
   the old site's real footer link columns (_site-chrome.md) + social +
   office-hours placeholder. Overrides the earlier 2-col footer rules. ---- */
.ccmm-footer {
	background: var(--wp--preset--color--inkdeep);
	color: var(--wp--preset--color--paper);
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--40);
}
.ccmm-footer-grid {
	display: grid;
	grid-template-columns: 1.6fr 1fr 1fr 1.1fr;
	gap: var(--wp--preset--spacing--50);
}
@media (max-width: 1000px) { .ccmm-footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px)  { .ccmm-footer-grid { grid-template-columns: 1fr; } }
.ccmm-footer :is(h2,h3) { font-size: 1rem; margin: 0 0 var(--wp--preset--spacing--10); }
.ccmm-footer :is(h2,h3) + p, .ccmm-footer ul + :is(h2,h3) { margin-top: var(--wp--preset--spacing--20); }
.ccmm-footer p { color: var(--wp--preset--color--paper); opacity: .85; margin: 0 0 .4rem; }
.ccmm-footer a { color: var(--wp--preset--color--paper); }
.ccmm-footer ul { list-style: none; margin: 0; padding: 0; }
.ccmm-footer li { margin-bottom: .35rem; }
.ccmm-footer li a { opacity: .85; font-size: .9rem; }
.ccmm-footer li a:hover { opacity: 1; }
.ccmm-footer-tagline { font-style: italic; opacity: .95 !important; }
.ccmm-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.15);
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--20);
	font-size: .8rem;
	opacity: .7;
}
/* ==========================================================================
 * Mean Green Carpet Clean — header + primary nav
 *
 * Written against the markup PCRS_Nav_Walker emits via [pcrs_nav]:
 *
 *   <nav class="ccmm-nav" aria-label="Primary">
 *     <ul>
 *       <li><a href="…">Home</a></li>
 *       <li class="ccmm-has-sub"><a href="…">Services</a>
 *         <ul class="ccmm-sub"><li><a href="…">…</a></li></ul>
 *       </li>
 *     </ul>
 *   </nav>
 *
 * Everything is scoped to #custom_header / #custom_header_mobile so it cannot
 * leak into footer or in-page navs.
 *
 * COLOURS ARE APPROXIMATE — sampled by eye from the reference screenshot.
 * Open the live site, eyedropper the green bar and the CTA button, and paste
 * the exact values into the two variables below before shipping.
 * ========================================================================== */

:root {
  --mg-green:        #6da72e;  /* nav bar background */
  --mg-green-dark:   #5c8f26;  /* nav hover / active state */
  --mg-cta:          #0d4d40;  /* "Free No Obligation Estimate" button */
  --mg-cta-hover:    #0a3d33;
  --mg-ink:          #1a1a1a;  /* phone number */
  --mg-muted:        #9a9a9a;  /* "CALL US TODAY" label */
  --mg-nav-h:        56px;     /* green bar height */
  --mg-nav-font:     15px;
}

/* --------------------------------------------------------------------------
 * 1. Header shell
 * ----------------------------------------------------------------------- */

#custom_header {
  background: #fff;
  position: relative;
  z-index: 999;
}

/* The reference header sits flush against the hero with no gap. Divi adds
 * section padding by default; this removes it for the header only. */
#custom_header .et_pb_section,
#custom_header .et_pb_row {
  padding-top: 0;
  padding-bottom: 0;
}

/* --------------------------------------------------------------------------
 * 2. Utility row — badges, phone, CTA
 *
 * These target the Divi modules inside the header global. Class names depend
 * on how the global was built, so treat this block as a starting point and
 * adjust selectors to match what you see in DevTools.
 * ----------------------------------------------------------------------- */

#custom_header .mg-call-label {
  color: var(--mg-muted);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0;
}

#custom_header .mg-phone,
#custom_header .mg-phone a {
  color: var(--mg-ink);
  font-size: 22px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

#custom_header .mg-cta,
#custom_header .mg-cta a {
  display: inline-block;
  background: var(--mg-cta);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  padding: 14px 26px;
  border: 0;
  border-radius: 2px;
  transition: background-color 0.2s ease;
}

#custom_header .mg-cta a:hover,
#custom_header .mg-cta a:focus-visible {
  background: var(--mg-cta-hover);
}

/* Trust badges row — keeps the four logos on one line, vertically centred. */
#custom_header .mg-badges {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

#custom_header .mg-badges img {
  height: 58px;
  width: auto;
  display: block;
}

/* --------------------------------------------------------------------------
 * 3. Primary nav — the green bar
 * ----------------------------------------------------------------------- */

#custom_header .ccmm-nav {
  background: var(--mg-green);
  min-height: var(--mg-nav-h);
  display: flex;
  align-items: center;
}

#custom_header .ccmm-nav > ul {
  display: flex;
  align-items: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 0;
}

#custom_header .ccmm-nav > ul > li {
  position: relative;   /* anchor for .ccmm-sub */
  list-style: none;
  padding: 0;
}

#custom_header .ccmm-nav > ul > li > a {
  display: flex;
  align-items: center;
  height: 100%;
  min-height: var(--mg-nav-h);
  padding: 0 22px;
  color: #fff;
  font-size: var(--mg-nav-font);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.18s ease;
}

#custom_header .ccmm-nav > ul > li > a:hover,
#custom_header .ccmm-nav > ul > li > a:focus-visible {
  background: var(--mg-green-dark);
  color: #fff;
}

/* Current page — the walker sets aria-current, so no extra class needed. */
#custom_header .ccmm-nav a[aria-current="page"] {
  background: var(--mg-green-dark);
}

/* Keyboard focus stays visible against the green. */
#custom_header .ccmm-nav a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -4px;
}

/* --------------------------------------------------------------------------
 * 4. Dropdown carets
 *
 * Drawn in CSS rather than shipped as an image, so they inherit link colour
 * and stay crisp at any zoom.
 * ----------------------------------------------------------------------- */

#custom_header .ccmm-nav .ccmm-has-sub > a::after {
  content: "";
  display: inline-block;
  margin-left: 8px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform 0.18s ease;
}

#custom_header .ccmm-nav .ccmm-has-sub:hover > a::after {
  transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
 * 5. Submenus
 * ----------------------------------------------------------------------- */

#custom_header .ccmm-nav .ccmm-sub {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 260px;
  margin: 0;
  padding: 8px 0;
  list-style: none;
  background: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  border-top: 3px solid var(--mg-green);

  /* Hidden by default without display:none, so the submenu can animate and
   * still be reachable by screen readers mid-transition. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
  z-index: 1000;
}

#custom_header .ccmm-nav .ccmm-has-sub:hover > .ccmm-sub,
#custom_header .ccmm-nav .ccmm-has-sub:focus-within > .ccmm-sub {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

#custom_header .ccmm-nav .ccmm-sub li {
  list-style: none;
  margin: 0;
  padding: 0;
}

#custom_header .ccmm-nav .ccmm-sub a {
  display: block;
  padding: 11px 20px;
  color: #333;
  font-size: 14px;
  font-weight: 600;
  text-transform: none;
  text-decoration: none;
  letter-spacing: 0;
  transition: background-color 0.15s ease, color 0.15s ease;
}

#custom_header .ccmm-nav .ccmm-sub a:hover,
#custom_header .ccmm-nav .ccmm-sub a:focus-visible {
  background: var(--mg-green);
  color: #fff;
}

/* Last submenu in the bar flips right-aligned so it can't overflow the
 * viewport. Adjust the :nth-last-child value if your menu order changes. */
#custom_header .ccmm-nav > ul > li:nth-last-child(-n + 2) .ccmm-sub {
  left: auto;
  right: 0;
}

/* --------------------------------------------------------------------------
 * 6. Responsive
 *
 * pcrs-mobile-nav.js takes over below 1025px per the functions.php comment.
 * Its toggle class is unknown here, so this only handles the tablet squeeze —
 * inspect the JS and add its open/closed states if the hamburger misbehaves.
 * ----------------------------------------------------------------------- */

@media (max-width: 1280px) {
  #custom_header {
    --mg-nav-font: 14px;
  }
  #custom_header .ccmm-nav > ul > li > a {
    padding: 0 14px;
  }
}

@media (max-width: 1024px) {
  #custom_header {
    display: none;
  }
  #custom_header_mobile {
    display: block;
  }
}

@media (min-width: 1025px) {
  #custom_header_mobile {
    display: none;
  }
}

/* --------------------------------------------------------------------------
 * 7. Reduced motion
 * ----------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  #custom_header .ccmm-nav .ccmm-sub,
  #custom_header .ccmm-nav .ccmm-has-sub > a::after,
  #custom_header .mg-cta a {
    transition: none;
  }
}
