/*
Theme Name: JCE Tree Service
Description: Custom WordPress theme for JCE Tree Service (River Falls, WI). Content is managed through WordPress (Pages, Services, Locations, Testimonials, Landing Pages) — this theme provides the templates, custom post types, and schema markup.
Author: Patrick Davison
Version: 2.2.4
Text Domain: jce
*/

/* ===========================================================
   0. FONTS — self-hosted from Google Fonts (SIL Open Font License)
   Archivo is a variable font: one file per subset covers 400–700.
   The Latin files are preloaded in inc/theme-setup.php.
   =========================================================== */
@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 400 700;
	font-stretch: 100%;
	font-display: swap;
	src: url("assets/fonts/archivo-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 400 700;
	font-stretch: 100%;
	font-display: swap;
	src: url("assets/fonts/archivo-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Archivo Black';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/archivo-black-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Archivo Black';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/archivo-black-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===========================================================
   1. RESET
   =========================================================== */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, h4, h5, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

/* Component lists that carry their class on the wrapper rather than on the
   list itself, so the [class] selector above misses them and they keep the
   browser's default markers and indent. Listed explicitly rather than
   widening the reset to every ul/ol: prose lists in .entry-content and on
   landing pages need real bullets and numbers. */
.primary-nav ul,
.site-footer ul { list-style: none; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
img, svg, video { max-width: 100%; display: block; }
/* <picture> wraps the homepage hero and, via EWWW's WebP rewriting, any image.
   display:contents takes the wrapper out of layout so the img still sizes
   against its real container — the many "fill the box" rules below
   (height: 100%; object-fit: cover) would otherwise resolve against the
   picture's auto height and collapse. */
picture { display: contents; }
/* …which also exposes <source> to its parent's layout: in a flex row it
   becomes an empty item and picks up an extra gap. It never renders anything;
   image selection doesn't depend on its display. */
picture > source { display: none; }
input, button, textarea, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
button { background: none; border: 0; cursor: pointer; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ===========================================================
   2. BRAND TOKENS — JCE Style Guide v2, September 2026
   =========================================================== */
:root {
	/* Core brand */
	--truck-green:     #357A2A;  /* trucks, large panels — a hair under the paint chip #367C2B so text clears 4.5:1 on cream */
	--truck-green-600: #2C6423;  /* hover/darken */
	--logo-green:      #3DBA63;  /* trees in the logo, small accents */
	--logo-green-600:  #2E9950;  /* hover/darken */
	--logo-green-050:  #EAF7EF;  /* pale tint for icon badges */
	--tan:             #C8A275;  /* canvas tan — secondary panels, apparel */
	--bark:            #686B5D;  /* captions, metadata, rules */
	--clay:            #C4410F;  /* accent — phone number, primary button */
	--clay-600:        #A3360C;  /* hover/darken */
	--yellow:          #D7F205;  /* crew yellow — safety colour, on-site only */

	/* Neutrals */
	--ink:        #2C2E35;
	--body:       var(--ink);   /* body copy is Ink or white at full opacity — no diluted gray */
	--muted:      var(--bark);
	--line:       #DEDACF;
	--cream:      #F4EFE4;
	--warm:       #F0E2C8;  /* warm ground for the band under the hero */
	--white:      #FFFFFF;

	/* Legacy aliases so components below don't each need touching individually */
	--green:        var(--logo-green);
	--green-600:    var(--truck-green);
	--green-700:    var(--truck-green);
	--green-050:    var(--logo-green-050);
	--forest:       var(--ink);
	--forest-900:   #1E1F25;
	--charcoal:     var(--ink);
	--charcoal-900: #1E1F25;
	--amber:        var(--clay);
	--amber-600:    var(--clay-600);

	/* Type */
	/* Archivo Black for headlines/signage — the guide's single approved
	   display weight; Archivo carries everything else. No third font. */
	--font-display: 'Archivo Black', Arial, Helvetica, sans-serif;
	--font-body: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

	/* Scale */
	--step-0: clamp(1rem, .96rem + .2vw, 1.0625rem);
	--step-1: clamp(1.15rem, 1.08rem + .35vw, 1.35rem);
	--step-2: clamp(1.45rem, 1.3rem + .7vw, 1.85rem);
	--step-3: clamp(1.8rem, 1.5rem + 1.4vw, 2.6rem);
	--step-4: clamp(2.2rem, 1.7rem + 2.4vw, 3.6rem);
	--step-5: clamp(2.6rem, 1.8rem + 3.6vw, 4.6rem);

	/* Layout */
	--wrap: 1200px;
	--wrap-narrow: 780px;
	--gutter: clamp(1.15rem, .7rem + 2vw, 2.5rem);
	--section-y: clamp(3.5rem, 2rem + 6vw, 7rem);
	--radius: 10px;
	--radius-lg: 16px;
	--shadow-sm: 0 1px 2px rgba(44,46,53,.06), 0 2px 8px rgba(44,46,53,.05);
	--shadow-md: 0 4px 12px rgba(44,46,53,.07), 0 12px 32px rgba(44,46,53,.08);
	--shadow-lg: 0 18px 50px rgba(44,46,53,.16);
	/* The header is fixed and overlays the hero, so anything that starts a page
	   pads past this value to clear it. */
	--header-h: 98px;
}

/* ===========================================================
   3. BASE TYPOGRAPHY
   =========================================================== */
body {
	font-family: var(--font-body);
	font-size: var(--step-0);
	line-height: 1.65;
	color: var(--body);
	background: var(--white);
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

h1, h2, h3, h4 {
	font-family: var(--font-display);
	color: var(--ink);
	line-height: 1.14;
	font-weight: 400; /* Archivo Black is its own family, already black at 400 */
	letter-spacing: -.01em;
	text-transform: uppercase;
	text-wrap: balance;
}
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p { text-wrap: pretty; }
p + p { margin-top: 1em; }

a:not([class]) {
	color: var(--green-700);
	text-decoration: underline;
	text-underline-offset: 3px;
}
a:not([class]):hover { color: var(--green-600); }

strong { color: var(--ink); font-weight: 600; }

:focus-visible {
	outline: 3px solid var(--green);
	outline-offset: 3px;
	border-radius: 3px;
}

/* ===========================================================
   4. LAYOUT PRIMITIVES
   =========================================================== */
.wrap {
	width: 100%;
	max-width: var(--wrap);
	margin-inline: auto;
	padding-inline: var(--gutter);
}
.wrap--narrow { max-width: var(--wrap-narrow); }
.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
.section--cream { background: var(--cream); }
.section--dark { background: var(--forest); color: rgba(255,255,255,.82); }
.section--dark h2, .section--dark h3 { color: var(--white); }

.section-head { max-width: 720px; margin-bottom: clamp(2rem, 1.4rem + 2vw, 3.25rem); }
.section-head--center { margin-inline: auto; text-align: center; }

.eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .55rem;
	font-family: var(--font-body);
	font-size: .78rem;
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--green-700);
	margin-bottom: .9rem;
}
.eyebrow::before {
	content: "";
	width: 26px;
	height: 2px;
	background: var(--green);
	flex: none;
}
.section--dark .eyebrow { color: var(--green); }
.section-head--center .eyebrow::before { display: none; }

.lede { font-size: var(--step-1); line-height: 1.55; color: var(--body); }
.section--dark .lede { color: rgba(255,255,255,.78); }

/* ===========================================================
   5. BUTTONS
   =========================================================== */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .55rem;
	padding: .85rem 1.6rem;
	border-radius: 6px;
	font-size: .95rem;
	font-weight: 600;
	letter-spacing: .01em;
	line-height: 1.2;
	text-align: center;
	border: 2px solid transparent;
	transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Truck green, not logo green: white type on the brighter logo green is only
   2.5:1. */
.btn--primary { background: var(--truck-green); color: var(--white); border-color: var(--truck-green); }
.btn--primary:hover { background: var(--truck-green-600); border-color: var(--truck-green-600); }

.btn--ghost { background: rgba(0,0,0,.55); color: var(--white); border-color: rgba(255,255,255,.55); }
.btn--ghost:hover { background: var(--white); color: var(--ink); border-color: var(--white); }

.btn--outline { background: transparent; color: var(--green-700); border-color: var(--green); }
.btn--outline:hover { background: var(--green); color: var(--white); }

.btn--emergency { background: var(--amber); color: var(--white); border-color: var(--amber); }
.btn--emergency:hover { background: var(--amber-600); border-color: var(--amber-600); color: var(--white); }

.btn--lg { padding: 1.05rem 2.1rem; font-size: 1.02rem; }
.btn--block { width: 100%; }
.btn .icon { width: 1.05em; height: 1.05em; flex: none; }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }

/* Text link with arrow */
.link-arrow {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	font-weight: 600;
	font-size: .92rem;
	color: var(--green-700);
}
.link-arrow .icon { width: 1em; height: 1em; transition: transform .18s ease; }
.link-arrow:hover .icon { transform: translateX(3px); }

/* ===========================================================
   6. HEADER — floats over the hero
   =========================================================== */
.skip-link {
	position: absolute;
	left: -9999px;
	z-index: 1000;
}
.skip-link:focus {
	left: 1rem;
	top: 1rem;
	position: fixed;
	background: var(--white);
	color: var(--ink);
	padding: .8rem 1.2rem;
	border-radius: 6px;
	box-shadow: var(--shadow-md);
}

/* Fixed so the phone number and the storm button stay reachable the whole
   way down the page. Transparent at rest — a gradient scrim carries the nav
   instead of a bar, so the hero photograph runs uninterrupted behind it. */
.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
}
.site-header::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 190px;
	pointer-events: none;
	background: linear-gradient(to bottom,
		rgba(30,31,37,.88) 0%,
		rgba(30,31,37,.62) 42%,
		rgba(30,31,37,.24) 74%,
		rgba(30,31,37,0) 100%);
	opacity: 1;
	transition: opacity .3s ease;
}
.site-header__bar {
	position: relative;
	background: transparent;
	border-bottom: 2px solid transparent;
	transition: background-color .3s ease, border-color .3s ease, box-shadow .3s ease, backdrop-filter .3s ease;
}

/* Past the hero the scrim is doing nothing useful, so it hardens into a
   frosted bar that still lets the page colour through. */
.site-header.is-scrolled::before { opacity: 0; }
.site-header.is-scrolled .site-header__bar {
	background: rgba(30,31,37,.88);
	-webkit-backdrop-filter: blur(14px) saturate(150%);
	backdrop-filter: blur(14px) saturate(150%);
	border-bottom-color: var(--green);
	box-shadow: 0 8px 28px rgba(30,31,37,.28);
}

.site-header__inner {
	display: flex;
	align-items: center;
	gap: 1.5rem;
	min-height: var(--header-h);
	padding-block: .55rem;
}

.site-branding { flex: none; margin-right: auto; }
.site-logo { display: block; }
.site-logo img {
	height: clamp(56px, 4.8vw, 80px);
	width: auto;
	/* Two shadows: a tight one to separate the white wordmark from bright sky,
	   and a wide soft one to lift the whole mark off busy foliage. */
	filter:
		drop-shadow(0 1px 2px rgba(30,31,37,.85))
		drop-shadow(0 4px 18px rgba(30,31,37,.55));
	transition: height .3s ease, filter .3s ease;
}
.site-header.is-scrolled .site-logo img {
	height: clamp(45px, 3.5vw, 58px);
	filter: drop-shadow(0 1px 2px rgba(30,31,37,.35));
}
.site-branding .site-title {
	font-family: var(--font-display);
	font-size: 1.5rem;
	font-weight: 400;
	color: var(--white);
	letter-spacing: -.01em;
	display: flex;
	align-items: baseline;
	gap: .45rem;
}
.site-branding .site-title small {
	font-family: var(--font-body);
	font-size: .6rem;
	font-weight: 600;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--green);
}

/* Primary nav */
.primary-nav > ul { display: flex; align-items: center; gap: clamp(.9rem, .3rem + 1.1vw, 1.9rem); }
.primary-nav a {
	display: block;
	padding: .5rem 0;
	color: rgba(255,255,255,.92);
	font-size: .85rem;
	font-weight: 600;
	letter-spacing: .07em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	position: relative;
	/* Over a bright sky the scrim alone isn't enough — the shadow buys back
	   contrast without darkening the photograph further. */
	text-shadow: 0 1px 3px rgba(30,31,37,.55);
	transition: text-shadow .3s ease, color .3s ease;
}
.site-header.is-scrolled .primary-nav a,
.site-header.is-scrolled .header-phone { text-shadow: none; }
.primary-nav a::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: 2px;
	background: var(--green);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .2s ease;
}
.primary-nav a:hover, .primary-nav .current-menu-item > a { color: var(--white); }
.primary-nav a:hover::after, .primary-nav .current-menu-item > a::after { transform: scaleX(1); }

/* Dropdowns */
.primary-nav li { position: relative; }
.primary-nav .sub-menu {
	position: absolute;
	top: 100%;
	left: -1rem;
	min-width: 230px;
	background: var(--white);
	border-radius: var(--radius);
	box-shadow: var(--shadow-md);
	padding: .5rem;
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.primary-nav li:hover > .sub-menu,
.primary-nav li:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.primary-nav .sub-menu a {
	color: var(--body);
	text-transform: none;
	letter-spacing: 0;
	font-size: 1rem;
	font-weight: 500;
	text-shadow: none;
	padding: .6rem .85rem;
	border-radius: 6px;
}
.primary-nav .sub-menu a:hover { background: var(--green-050); color: var(--green-700); }
.primary-nav .sub-menu a::after { display: none; }
.primary-nav .sub-menu li + li { border-top: 1px solid rgba(44,46,53,.12); }

.header-actions { display: flex; align-items: center; gap: .75rem; flex: none; }
.header-phone {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	color: var(--white);
	font-weight: 700;
	font-size: 1rem;
	line-height: 1;
	white-space: nowrap;
	text-shadow: 0 1px 3px rgba(30,31,37,.55);
}
.header-phone .icon { width: 1.1rem; height: 1.1rem; color: var(--green); flex: none; }
.header-phone:hover { color: var(--green); }

/* Emergency nav button — pulses gently to draw the storm caller's eye */
.btn--emergency-nav { padding: .7rem 1.25rem; font-size: .84rem; letter-spacing: .05em; text-transform: uppercase; }

/* Mobile nav toggle */
.nav-toggle {
	display: none;
	width: 44px;
	height: 44px;
	align-items: center;
	justify-content: center;
	border-radius: 6px;
	color: var(--white);
	flex: none;
}
.nav-toggle:hover { background: rgba(255,255,255,.1); }
.nav-toggle__box { display: block; width: 22px; height: 15px; position: relative; }
.nav-toggle__box span {
	position: absolute;
	left: 0;
	width: 100%;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	transition: transform .22s ease, opacity .22s ease, top .22s ease;
}
.nav-toggle__box span:nth-child(1) { top: 0; }
.nav-toggle__box span:nth-child(2) { top: 6.5px; }
.nav-toggle__box span:nth-child(3) { top: 13px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(1) { top: 6.5px; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__box span:nth-child(3) { top: 6.5px; transform: rotate(-45deg); }

/* Mobile submenu "+" toggle — desktop dropdowns open on hover/focus instead */
.submenu-toggle { display: none; }
.submenu-toggle__icon { display: block; width: 14px; height: 14px; position: relative; transition: transform .2s ease; }
.submenu-toggle__icon::before,
.submenu-toggle__icon::after {
	content: "";
	position: absolute;
	background: currentColor;
	border-radius: 2px;
}
.submenu-toggle__icon::before { left: 0; right: 0; top: 6px; height: 2px; }
.submenu-toggle__icon::after { top: 0; bottom: 0; left: 6px; width: 2px; }
.submenu-toggle[aria-expanded="true"] .submenu-toggle__icon { transform: rotate(45deg); }

@media (max-width: 1023px) {
	.nav-toggle { display: flex; }
	/* Visually hidden, not display:none — the number is the link's only text,
	   so screen readers still need it. */
	.header-phone span {
		position: absolute;
		width: 1px; height: 1px;
		margin: -1px;
		overflow: hidden;
		clip: rect(0,0,0,0);
		white-space: nowrap;
	}
	/* The bar itself is transparent, so the open menu supplies its own
	   solid ground rather than letting the hero show through the links. */
	.primary-nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		background: rgba(30,31,37,.97);
		-webkit-backdrop-filter: blur(14px);
		backdrop-filter: blur(14px);
		border-top: 1px solid rgba(255,255,255,.12);
		box-shadow: 0 12px 30px rgba(30,31,37,.32);
		max-height: 0;
		overflow: hidden;
		transition: max-height .3s ease;
	}
	.primary-nav a { text-shadow: none; }
	.primary-nav.is-open { max-height: 75vh; overflow-y: auto; }
	.primary-nav > ul { flex-direction: column; align-items: stretch; gap: 0; padding: .5rem var(--gutter) 1.5rem; }
	.primary-nav > ul > li { border-bottom: 1px solid rgba(255,255,255,.08); }
	.primary-nav a { padding: .95rem 0; font-size: .92rem; }
	.primary-nav a::after { display: none; }
	.primary-nav .sub-menu {
		position: static;
		opacity: 1;
		visibility: visible;
		transform: none;
		background: transparent;
		box-shadow: none;
		padding: 0 0 .5rem .9rem;
	}
	.primary-nav .sub-menu a { color: rgba(255,255,255,.7); }
	.primary-nav .sub-menu a:hover { background: transparent; color: var(--green); }
	/* Parents with a submenu: the link and its "+" share a row, and the list
	   stays collapsed below them until the button opens it. */
	.primary-nav > ul > .menu-item-has-children {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: center;
		column-gap: .75rem;
	}
	.primary-nav > ul > .menu-item-has-children > .sub-menu { grid-column: 1 / -1; display: none; }
	.primary-nav > ul > .menu-item-has-children.is-expanded > .sub-menu { display: block; }
	.submenu-toggle {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		border: 1px solid rgba(255,255,255,.22);
		border-radius: 6px;
		color: var(--white);
		transition: border-color .2s ease, background-color .2s ease, color .2s ease;
	}
	.submenu-toggle:hover { border-color: rgba(255,255,255,.45); }
	.submenu-toggle[aria-expanded="true"] {
		border-color: var(--green);
		background: rgba(61,186,99,.12);
		color: var(--green);
	}
}
@media (max-width: 620px) {
	.btn--emergency-nav { padding: .6rem .85rem; font-size: .75rem; }
	/* Icon-only on phones; the label stays readable to screen readers. */
	.btn--emergency-nav span {
		position: absolute;
		width: 1px; height: 1px;
		margin: -1px;
		overflow: hidden;
		clip: rect(0,0,0,0);
		white-space: nowrap;
	}
	.btn--emergency-nav .icon { width: 1.15rem; height: 1.15rem; }
}

/* ===========================================================
   7. HERO
   =========================================================== */
.hero {
	position: relative;
	display: flex;
	align-items: center;
	/* Top padding adds the fixed header's height on top of the same gap used
	   below the CTA row, so the visible whitespace roughly matches on both
	   sides; scaled down 20% since the header itself already reads as space.
	   The photo itself still runs to the very top of the viewport. */
	padding-top: calc((var(--header-h) + clamp(4rem, 2rem + 8vw, 8rem)) * 0.8 + var(--top-alert-h, 0px));
	min-height: clamp(560px, 82vh, 820px);
	padding-bottom: clamp(4rem, 2rem + 8vw, 8rem);
	isolation: isolate;
	color: var(--white);
	overflow: hidden;
}
.hero__media {
	position: absolute;
	inset: 0;
	z-index: -2;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* Weighted to the left: dark enough behind the type to hold white text, then
   clearing fast so the crew, the equipment and the property stay readable.
   The second layer is a short fade that seats the wood band underneath. */
.hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(to top, rgba(30,31,37,.42) 0%, rgba(30,31,37,0) 20%),
		linear-gradient(96deg,
			rgba(30,31,37,.90) 0%,
			rgba(30,31,37,.76) 24%,
			rgba(30,31,37,.40) 48%,
			rgba(30,31,37,.14) 70%,
			rgba(30,31,37,.04) 100%);
}
/* Narrow column keeps the headline off the subject of the photo. */
.hero__inner { position: relative; max-width: 620px; }
.hero h1 {
	color: var(--white);
	font-size: clamp(2.3rem, 1.45rem + 3.1vw, 3.8rem);
	margin-bottom: 1.15rem;
	text-shadow: 0 2px 20px rgba(30,31,37,.5);
}
.hero__accent {
	display: block;
	color: var(--green);
	margin-top: .1em;
}
.hero__subhead {
	font-size: var(--step-1);
	color: rgba(255,255,255,.9);
	max-width: 34rem;
	margin-bottom: 2rem;
	text-shadow: 0 1px 10px rgba(30,31,37,.55);
}
.hero__actions { margin-bottom: 0; }

/* -----------------------------------------------------------
   Wood-grain trust band — the border along the bottom of the hero.
   Full-bleed dark walnut photo with a translucent ink scrim, four
   credentials in a single row. Matches the approved 1A layout.
----------------------------------------------------------- */
.trust-band {
	position: relative;
	z-index: 6;
	overflow: hidden;
	background-color: var(--ink);
	background-image: url("assets/images/trust-band-wood.webp");
	background-size: cover;
	background-position: center;
	border-top: 3px solid var(--green);
}
.trust-band::before {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(44,46,53,.72);
}
.trust-band__inner {
	position: relative;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	align-items: center;
	padding-block: 1.5rem;
	/* Wider than the standard 1200px wrap. Four credentials genuinely need the
	   room, and the band is full-bleed already, so the only thing the narrower
	   measure bought was a horizontal scrollbar. */
	max-width: 1440px;
}
.trust-item {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	padding: 0 clamp(.7rem, .2rem + 1.6vw, 1.9rem);
	border-left: 1px solid rgba(244,239,228,.28);
	text-align: center;
	color: var(--white);
}
.trust-item:first-child { border-left: 0; }
.trust-item--stat { flex-direction: column; gap: 8px; }
.trust-item__lead-row { display: flex; align-items: center; gap: 10px; }
.trust-item__lead {
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem);
	line-height: 1;
	color: var(--white);
}
.trust-item__stars {
	position: relative;
	display: inline-block;
	line-height: 1;
	letter-spacing: .04em;
	font-size: clamp(.85rem, .8vw + .55rem, 1.3rem);
	white-space: nowrap;
}
/* Two identical star strings stacked: a dim track for the full five, and a
   gold copy clipped to the rating's percentage of five stars. Because both
   layers render the same glyphs at the same size, the clip always lands
   inside the star it's partially filling instead of just showing fewer
   whole stars. */
.trust-item__stars-track { color: rgba(255,255,255,.25); }
.trust-item__stars-fill {
	position: absolute;
	top: 0;
	left: 0;
	overflow: hidden;
	width: var(--rating-fill, 100%);
	color: #FBBC04;
}
.trust-item__label {
	font-family: var(--font-display);
	font-size: clamp(.66rem, .5vw + .5rem, .82rem);
	letter-spacing: .12em;
	text-transform: uppercase;
	line-height: 1.4;
	/* Wrapping is the backstop: whatever the credential wording ends up
	   being, it reflows instead of forcing the band to scroll. */
	white-space: normal;
}
.trust-item__label--left { text-align: left; }
.trust-item__label-break { display: inline; }
.trust-item__badge { height: clamp(56px, 5.5vw, 84px); width: auto; flex: none; display: block; }

/* 2 x 2. The rule sits between the columns only, so it never lands at the
   start of a row. */
@media (min-width: 601px) and (max-width: 1199px) {
	.trust-band__inner { grid-template-columns: repeat(2, 1fr); row-gap: 1.4rem; }
	.trust-item:nth-child(3) { border-left: 0; }
}

/* Stacked one per row on phones. The rule that separates columns on wider
   screens becomes a horizontal rule between rows here instead of vanishing. */
@media (max-width: 600px) {
	.trust-band__inner { grid-template-columns: 1fr; row-gap: 1.1rem; }
	.trust-item { border-left: 0; border-top: 1px solid rgba(244,239,228,.28); padding-block: .8rem; }
	.trust-item:first-child { border-top: 0; padding-top: 0; }

	/* Only the arborist-count line is long enough to need a deliberate break;
	   everything else stays on one line at this width. */
	.trust-item__label-break { display: block; }

	/* Left-alignment reads fine next to the badge on wider layouts, but
	   stacked full-width on a phone it just looks off-center. */
	.trust-item--arborist .trust-item__label--left { text-align: center; }
}

/* -----------------------------------------------------------
   Storm / high-volume alert banner — a single amber strip directly under
   the trust band, toggled from Business Info > Storm / High-Volume Alert.
   Amber, not green, for the same reason as .callout--warn: it's the accent
   the brand brief reserves for storm/urgency content.
----------------------------------------------------------- */
.alert-band {
	position: relative;
	z-index: 5;
	background: var(--amber);
	border-top: 1px solid rgba(0,0,0,.08);
}
.alert-band__inner {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .65rem;
	padding-block: .8rem;
	text-align: center;
}
.alert-band__inner p { margin: 0; color: var(--white); font-size: .95rem; font-weight: 600; }
.alert-band__inner .alert-band__icon { flex: none; width: 1.2rem; height: 1.2rem; color: var(--white); }
@media (max-width: 600px) {
	.alert-band__inner { gap: .5rem; padding-block: .7rem; }
	.alert-band__inner p { font-size: .85rem; }
}

/* Site-wide placement: first child of the fixed header, so it stays pinned
   above the nav. Slimmer than the Contact-page strip since it's always on
   screen. main.js publishes its height as --top-alert-h, which the heroes
   add to their top padding so the nav doesn't cover their content. */
.alert-band--top { z-index: 1; border-top: 0; }
.site-header::before { top: var(--top-alert-h, 0px); }
/* First-paint estimate (one line desktop, two on phones) until main.js
   replaces it with the measured height inline. */
:root:has(.alert-band--top) { --top-alert-h: 2.3rem; }
@media (max-width: 600px) {
	:root:has(.alert-band--top) { --top-alert-h: 3rem; }
}
.alert-band--top .alert-band__inner { padding-block: .5rem; }
.alert-band--top .alert-band__inner p { font-size: .85rem; }
@media (max-width: 600px) {
	.alert-band--top .alert-band__inner { padding-block: .45rem; }
	.alert-band--top .alert-band__inner p { font-size: .78rem; line-height: 1.35; }
}

/* -----------------------------------------------------------
   Proof statement — the approved "anyone with a chainsaw" line between
   the trust band and Services. A bare paragraph on white read as an
   empty gap, so it gets a highlighted payoff line instead of any new
   copy.
----------------------------------------------------------- */
.proof-statement { text-align: center; }
.proof-statement .wrap--narrow { max-width: 1040px; }
.proof-statement__punch { color: var(--green-700); font-weight: 700; }

/* Compact hero for interior pages */
.page-hero {
	position: relative;
	isolation: isolate;
	background: var(--forest);
	color: var(--white);
	padding-top: calc(var(--header-h) + var(--top-alert-h, 0px) + clamp(2.5rem, 1.8rem + 3vw, 4rem));
	padding-bottom: clamp(3rem, 2rem + 4vw, 5.5rem);
	overflow: hidden;
}
.page-hero__media { position: absolute; inset: 0; z-index: -2; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(95deg, rgba(30,31,37,.94) 0%, rgba(30,31,37,.72) 100%);
}
/* On phones, center the text block on the photo: the same gap above and
   below it. The header is transparent at the top of the page, so the gap
   above is measured from the bottom of the logo (56px tall at this width,
   centered in --header-h), not from the bottom of the header box. */
@media (max-width: 600px) {
	.page-hero {
		--page-hero-gap: clamp(2.5rem, 1.8rem + 3vw, 4rem);
		padding-top: calc((var(--header-h) + 56px) / 2 + var(--top-alert-h, 0px) + var(--page-hero-gap));
		padding-bottom: var(--page-hero-gap);
	}
	/* As inline-flex the eyebrow sits in a line box with ~7px of invisible
	   strut above it, which throws the balance off. Block-level, its top
	   edge is the top of the text block. */
	.page-hero .eyebrow { display: flex; }
}
.page-hero h1 { color: var(--white); max-width: 20ch; }
.page-hero__sub { color: rgba(255,255,255,.82); max-width: 60ch; margin-top: 1rem; font-size: var(--step-1); }


/* ===========================================================
   9. STATS BAND
   Used by the About page for "What 25 Years Actually Buys You" — the
   approved copy's own headed recap, distinct from the compact trust-band
   strip under every page's hero.
   =========================================================== */
.stats { background: var(--charcoal); color: var(--white); padding-top: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
.stats__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 2rem 1.5rem;
	padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem);
}
.stat { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding-inline: 1rem; }
.stat__icon { display: inline-block; width: 1.6rem; height: 1.6rem; margin-bottom: .6rem; color: var(--green); }
/* Badge stats get real credential artwork instead of a line icon — sized up
   a bit so it reads as a seal, not a shrunken icon, but centered alongside
   the plain stats so neither group looks like an afterthought. */
.stat__icon--badge { width: auto; height: 3.4rem; margin-bottom: .8rem; }
.stat__icon--badge img { display: block; height: 100%; width: auto; }
.stat__num {
	font-family: var(--font-display);
	font-size: clamp(2.4rem, 1.8rem + 2.4vw, 3.4rem);
	font-weight: 400;
	line-height: 1;
	color: var(--green);
	display: block;
}
.stat__label {
	margin-top: .6rem;
	font-size: .88rem;
	color: rgba(255,255,255,.72);
	letter-spacing: .04em;
}
/* Dividers only once the grid has settled into a single row — on a wrapped
   mobile stack a left border reads as a stray line, not a divider. */
@media (min-width: 761px) {
	.stat + .stat { border-left: 1px solid rgba(255,255,255,.14); }
}

/* ===========================================================
   10. SPLIT (image + copy)
   =========================================================== */
.split {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: clamp(2rem, 1rem + 4vw, 4.5rem);
	align-items: center;
}
.split--reverse .split__media { order: 2; }
/* Contact page: the copy column is shorter than the form beside it, and the
   default vertical centering left "Reach Us" floating well below the form's
   top edge. This keeps both columns flush at the top instead. */
.split--top { align-items: start; }
.split__media { position: relative; }
.split__media img, .split__media .media-ph { border-radius: var(--radius-lg); }

/* A full-width photo otherwise fills a full 1fr track and renders far taller
   than the copy beside it. Capping the track width keeps it human-scaled;
   height stays auto (not forced/cropped) so the whole photo stays visible. */
.split__media img { width: 100%; height: auto; }
@media (min-width: 761px) {
	.split--photo { grid-template-columns: minmax(280px, 420px) 1fr; }
}

/* Floating badge on split images */
.split__badge {
	position: absolute;
	right: -1rem;
	bottom: -1rem;
	background: var(--green);
	color: var(--white);
	padding: 1.15rem 1.5rem;
	border-radius: var(--radius);
	box-shadow: var(--shadow-md);
	text-align: center;
	max-width: 200px;
}
.split__badge strong { display: block; color: var(--white); font-family: var(--font-display); font-weight: 400; font-size: 1.9rem; line-height: 1; }
.split__badge span { font-size: .8rem; opacity: .9; display: block; margin-top: .3rem; line-height: 1.3; }

/* Photo caption, pulled from the attachment's Caption field (Media Library).
   Shared by every photo spot on the site — split photos, proof shots, etc. */
.jce-caption { margin-top: .6rem; font-size: .85rem; font-style: italic; color: var(--muted); }

/* Service body split into several photo/paragraph rows (single-service.php)
   — one .split per row, stacked in one wrap rather than one section each. */
.split-rows > .split + .split { margin-top: clamp(3rem, 2rem + 3vw, 5rem); }

@media (max-width: 760px) {
	.split--reverse .split__media { order: 0; }
	.split__badge { right: 1rem; bottom: -1rem; }
}

/* ===========================================================
   11. SERVICES GRID
   =========================================================== */
/* auto-FIT, not auto-fill: at the full 1200px wrap there is room for four
   tracks, so a three-card row (the Service Area pages' most-requested
   services) would otherwise reserve an empty fourth track and sit at
   three-quarters width while the list below it ran full-bleed. auto-fit
   collapses the empty track so any card count fills the wrap. With enough
   cards to occupy every track the two behave identically, so the eight-card
   services grid is unaffected. */
.services-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
	gap: 1.25rem;
}
.service-card {
	display: flex;
	flex-direction: column;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	overflow: hidden;
	transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.service-card:hover {
	border-color: transparent;
	box-shadow: var(--shadow-md);
	transform: translateY(-4px);
}
.service-card__media { aspect-ratio: 16 / 10; overflow: hidden; background: var(--cream); }
.service-card__media img, .service-card__media .media-ph { width: 100%; height: 100%; object-fit: cover; }
.service-card__body { padding: 1.5rem; display: flex; flex-direction: column; flex: 1; gap: .6rem; }
.service-card h3 { font-size: var(--step-1); color: var(--ink); }
.service-card p { font-size: .93rem; flex: 1; }
.service-card .link-arrow { margin-top: .4rem; }

/* Whole-card click target: the "Learn more" link stretches to cover the
   card via ::after so the entire card is one accessible link, without
   nesting a second anchor around the title. The anchor itself must stay
   unpositioned (no position/z-index) — giving it one makes it the
   containing block for its own ::after, shrinking the click target down
   to just the "Learn more" text instead of the whole card. */
.service-card { position: relative; }
.service-card .stretched-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.service-card:has(.stretched-link) { cursor: pointer; }

/* Card eyebrows drop the rule that precedes a section eyebrow — inside a
   narrow card it steals a line and pushes the label into an awkward wrap. */
.service-card .eyebrow { margin-bottom: 0; font-size: .72rem; letter-spacing: .11em; }
.service-card .eyebrow::before { display: none; }

/* Priority service gets visual weight (removal-first, per the brief) */
.service-card--featured { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }

/* Compact thumbnail cards — "What Else We Handle" at the foot of a service
   page. A lighter version of .service-card: no description or icon, just a
   near-square photo and a label, sized to sit several across a row. */
.thumb-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1.25rem;
}
@media (min-width: 561px) {
	.thumb-grid { grid-template-columns: repeat(4, 1fr); }
}
.thumb-card {
	display: flex;
	flex-direction: column;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	overflow: hidden;
	text-decoration: none;
	color: var(--ink);
	transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.thumb-card:hover { border-color: transparent; box-shadow: var(--shadow-md); transform: translateY(-4px); }
.thumb-card__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--cream); }
.thumb-card__media img, .thumb-card__media .media-ph { width: 100%; height: 100%; object-fit: cover; }
.thumb-card__label { padding: .9rem 1rem; font-weight: 600; font-size: .93rem; text-align: center; }

/* Location page "Keep Looking" row: five cards, so the base four-column
   .thumb-grid would always strand one alone. Steps 1 -> 2 -> 3 -> 5 instead
   of the base's 2 -> 4, landing on five-across only once the 1200px wrap has
   room for it. */
.thumb-grid--5up { grid-template-columns: 1fr; }
@media (min-width: 601px) {
	.thumb-grid--5up { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 861px) {
	.thumb-grid--5up { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1024px) {
	.thumb-grid--5up { grid-template-columns: repeat(5, 1fr); }
}

/* ===========================================================
   12. PROCESS STEPS
   =========================================================== */
#personal-estimate .section-head { max-width: none; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 2rem 1.75rem; counter-reset: step; }
.step { position: relative; counter-increment: step; padding-top: 3.6rem; }
.step::before {
	content: counter(step);
	position: absolute;
	top: 0;
	left: 0;
	font-family: var(--font-display);
	font-size: 2.6rem;
	font-weight: 400;
	line-height: 1;
	color: var(--green);
	opacity: .32;
}
.step h3 { margin-bottom: .6rem; font-size: var(--step-1); }
.step p { font-size: .95rem; }
.section--dark .step p { color: rgba(255,255,255,.75); }

/* ===========================================================
   13. CREDENTIALS ("which means…")
   =========================================================== */
.credentials { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; }
.credential {
	background: rgba(255,255,255,.05);
	border: 1px solid rgba(255,255,255,.1);
	border-radius: var(--radius-lg);
	padding: 1.9rem 1.7rem;
}
.credential h3 { font-size: var(--step-1); margin-bottom: .6rem; }
.credential p { font-size: .94rem; color: rgba(255,255,255,.75); }

/* Photo cap. The image runs flush to the card's top edge, so the card's
   padding moves off the article and onto the body below it — the outer
   shape is unchanged, the photo just fills the part of it above the text.
   The gradient is a short fade rather than a hard edge: the card's ground is
   only 5% white over the band, too close to the photo to read as a seam. */
.credential--photo { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.credential__media {
	position: relative;
	flex: none;
	aspect-ratio: 16 / 10;  /* matches the jce-card size, 720×450 */
	margin: 0;
	overflow: hidden;
	background: var(--forest-900);
}
.credential__media img, .credential__media .media-ph { width: 100%; height: 100%; object-fit: cover; }
.credential__media::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 42%;
	background: linear-gradient(to bottom, rgba(44,46,53,0), rgba(44,46,53,.9));
}
.credential__body { padding: 1.5rem 1.7rem 1.9rem; }

/* ===========================================================
   14. REVIEWS
   =========================================================== */
.reviews-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; }
.reviews-grid--single { max-width: 640px; margin: 0 auto; }
/* More than 3 reviews: one scrollable row instead of wrapping to a second
   line. Native scroll-snap needs no JS — swipe on touch, drag/wheel on a
   trackpad, or click-drag with a mouse. */
.reviews-grid--scroll {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scroll-padding-inline: 1px;
	padding-bottom: .75rem;
	margin-bottom: -.75rem;
	-webkit-overflow-scrolling: touch;
}
.reviews-grid--scroll .review {
	flex: 0 0 min(340px, 85vw);
	scroll-snap-align: start;
}
@media (max-width: 600px) {
	/* One card at a time on mobile, snapping cleanly into place — a peek of
	   the next card is a useful hint on a wide desktop row, but on a phone
	   it just reads as a cut-off review. Applies to every review row, not
	   just the >3-review scroll variant: a 2- or 3-up grid would otherwise
	   just wrap to a second/third row instead of scrolling. */
	/* The arrows + dots below replace the native scrollbar as the "there's
	   more" cue — a bare scrollbar under one card reads as a layout bug. */
	.reviews-grid {
		display: flex;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: 1px;
		padding-bottom: 0;
		margin-bottom: 0;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}
	.reviews-grid::-webkit-scrollbar { display: none; }
	.reviews-grid .review { flex: 0 0 100%; scroll-snap-align: start; }
}
.review {
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	padding: 2rem 1.8rem;
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
}
.review__stars { display: flex; gap: .15rem; color: var(--green-700); }
.review__stars .icon { width: 1.05rem; height: 1.05rem; }
.review__body { font-size: 1.02rem; color: var(--ink); flex: 1; quotes: "\201C" "\201D"; }
.review__body p + p { margin-top: .75em; }
.review__body > p:first-child::before { content: open-quote; }
.review__body > p:last-child::after { content: close-quote; }
.review__meta { border-top: 1px solid var(--line); padding-top: 1.1rem; font-size: .88rem; }
.review__name { display: block; font-weight: 700; color: var(--ink); font-size: .95rem; }
.review__detail { color: var(--muted); }
.review__job {
	display: inline-block;
	margin-top: .55rem;
	background: var(--green-050);
	color: var(--green-700);
	font-size: .78rem;
	font-weight: 600;
	padding: .25rem .6rem;
	border-radius: 99px;
}

/* Prev/next arrows for a reviews-grid--scroll row — the row already
   scrolls natively (swipe/drag/wheel need no JS), these are just a click
   target for anyone who'd rather not drag. Rendered whenever there's more
   than one review; hidden on desktop unless the row actually scrolls. */
.reviews-scroller__nav { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1.25rem; }
.reviews-scroller__arrow {
	display: grid;
	place-items: center;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--white);
	border: 1px solid var(--line);
	color: var(--green-700);
	box-shadow: var(--shadow-sm);
	transition: background-color .18s ease, transform .18s ease, opacity .18s ease;
}
.reviews-scroller__arrow .icon { width: 16px; height: 16px; }
.reviews-scroller__arrow--prev .icon { transform: rotate(180deg); }
.reviews-scroller__arrow:hover { background: var(--cream); transform: translateY(-1px); }
.reviews-scroller__arrow:disabled { opacity: .35; cursor: default; transform: none; }
.reviews-scroller__dots { display: flex; align-items: center; }
/* 24px tap target, 8px visible dot. */
.reviews-scroller__dot {
	display: grid;
	place-items: center;
	width: 24px;
	height: 24px;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
}
.reviews-scroller__dot::before {
	content: "";
	width: 8px;
	height: 8px;
	border-radius: 99px;
	background: var(--line);
	transition: width .2s ease, background-color .2s ease;
}
.reviews-scroller__dot[aria-current="true"]::before { width: 20px; background: var(--green-700); }
@media (min-width: 601px) {
	/* On desktop, 2–3 reviews sit in a static grid, so there's nothing to
	   page through; and with >3, several cards are visible at once, so
	   one-dot-per-card would misreport position. */
	.reviews-scroller__nav--mobile,
	.reviews-scroller__dots { display: none; }
}

/* ===========================================================
   15. SERVICE AREA
   =========================================================== */
.area-primary { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.25rem; margin-bottom: 2rem; }
.area-card {
	display: flex;
	flex-direction: column;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	overflow: hidden;
	transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.area-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); border-color: transparent; }
.area-card__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--cream); }
.area-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.area-card:hover .area-card__media img { transform: scale(1.04); }
.area-card__body { display: block; padding: 1.4rem 1.5rem; border-left: 4px solid var(--green); flex: 1; }
.area-card h3 { font-size: var(--step-1); margin-bottom: .3rem; }
.area-card p { font-size: .9rem; }
.area-card .link-arrow { margin-top: .75rem; }
.area-secondary { font-size: .95rem; color: var(--body); }
.area-secondary strong { color: var(--ink); }

/* ===========================================================
   16. CTA BAND
   =========================================================== */
.cta-band { background: var(--truck-green); color: var(--white); }
.cta-band__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 2rem;
	padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem);
	flex-wrap: wrap;
}
.cta-band h2 { color: var(--white); font-size: var(--step-3); max-width: 22ch; }
.cta-band p { color: rgba(255,255,255,.9); margin-top: .6rem; max-width: 48ch; }
.cta-band .btn--primary { background: var(--white); color: var(--truck-green); border-color: var(--white); }
.cta-band .btn--primary:hover { background: var(--charcoal); color: var(--white); border-color: var(--charcoal); }
.cta-band .link-arrow { color: var(--white); }

/* Emergency variant */
.cta-band--emergency { background: var(--charcoal); }
.cta-band--emergency .btn--primary { background: var(--amber); color: var(--white); border-color: var(--amber); }
.cta-band--emergency .btn--primary:hover { background: var(--white); color: var(--ink); border-color: var(--white); }

/* ===========================================================
   17. MEDIA PLACEHOLDER (until real photos land)
   =========================================================== */
.media-ph {
	position: relative;
	display: grid;
	place-items: center;
	width: 100%;
	aspect-ratio: 4 / 3;
	background:
		radial-gradient(120% 90% at 20% 10%, rgba(61,186,99,.24) 0%, transparent 60%),
		linear-gradient(155deg, var(--truck-green) 0%, var(--ink) 55%, #1E1F25 100%);
	color: rgba(255,255,255,.35);
	overflow: hidden;
	border-radius: var(--radius-lg);
}
.media-ph > svg { position: relative; z-index: 2; width: 34%; max-width: 110px; height: auto; opacity: .5; }
.media-ph--wide { aspect-ratio: 16 / 9; }
.media-ph--fill { aspect-ratio: auto; height: 100%; }

/* Treeline silhouette so an image-less section still reads as designed
   rather than broken while photography is pending. */
.media-ph::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: 38%;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='70' viewBox='0 0 300 70' preserveAspectRatio='none'%3E%3Cg fill='%230A1A10'%3E%3Cpolygon points='20,18 34,70 6,70'/%3E%3Cpolygon points='52,30 64,70 40,70'/%3E%3Cpolygon points='88,10 104,70 72,70'/%3E%3Cpolygon points='126,26 140,70 112,70'/%3E%3Cpolygon points='160,16 176,70 144,70'/%3E%3Cpolygon points='198,32 210,70 186,70'/%3E%3Cpolygon points='232,14 248,70 216,70'/%3E%3Cpolygon points='270,28 284,70 256,70'/%3E%3C/g%3E%3C/svg%3E");
	background-repeat: repeat-x;
	background-size: auto 100%;
	background-position: bottom center;
	opacity: .5;
	pointer-events: none;
	z-index: 1;
}

.media-ph__label {
	position: absolute;
	z-index: 3;
	bottom: .8rem;
	left: 0; right: 0;
	text-align: center;
	font-size: .7rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: rgba(255,255,255,.5);
}

/* ===========================================================
   18. FORMS
   =========================================================== */
.form-field { margin-bottom: 1.15rem; }
.form-field label { display: block; font-size: .88rem; font-weight: 600; color: var(--ink); margin-bottom: .4rem; }
.form-field .req { color: var(--green-700); }
.form-field input, .form-field select, .form-field textarea {
	width: 100%;
	padding: .8rem 1rem;
	border: 1px solid var(--line);
	border-radius: 6px;
	background: var(--white);
	font-size: .97rem;
	transition: border-color .18s ease, box-shadow .18s ease;
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
	outline: none;
	border-color: var(--green);
	box-shadow: 0 0 0 3px rgba(61,186,99,.16);
}
.form-field textarea { min-height: 140px; resize: vertical; }
/* The CF7 form nests each control inside its <label>, and CF7 turns the
   editor's line breaks into <p>/<br>. Neutralize those and space the control
   off the label text explicitly, so the live form matches the fallback's
   label → .4rem → field rhythm regardless of how the editor text is typed. */
.wpcf7-form .form-field p { margin: 0; }
.wpcf7-form .form-field br { display: none; }
.wpcf7-form .form-field label { margin-bottom: 0; }
.wpcf7-form .form-field .wpcf7-form-control-wrap { display: block; margin-top: .4rem; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 1.15rem; }

.form-panel {
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
	box-shadow: var(--shadow-sm);
}

/* Contact detail list */
.contact-list { display: grid; gap: 1.5rem; }
.contact-item { display: flex; gap: 1rem; }
.contact-item__icon {
	width: 42px; height: 42px; flex: none;
	display: grid; place-items: center;
	border-radius: 8px;
	background: var(--green-050);
	color: var(--green-700);
}
.contact-item__icon .icon { width: 20px; height: 20px; }
.contact-item h3 { font-size: 1.05rem; margin-bottom: .2rem; }
.contact-item a { font-weight: 600; color: var(--green-700); }
.contact-item a:hover { text-decoration: underline; }

/* ===========================================================
   19. EMERGENCY PAGE
   =========================================================== */
.emergency-hero {
	background: var(--charcoal);
	color: var(--white);
	padding-top: calc(var(--header-h) + var(--top-alert-h, 0px) + clamp(2.5rem, 1.8rem + 3vw, 4rem));
	padding-bottom: clamp(3rem, 2rem + 4vw, 5rem);
}
.emergency-hero--has-image { position: relative; isolation: isolate; overflow: hidden; }
.emergency-hero__media { position: absolute; inset: 0; z-index: -2; }
.emergency-hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* Heavier scrim than the marketing heroes — the phone number has to stay
   legible for someone reading this on a phone in bad weather. */
.emergency-hero--has-image::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(95deg, rgba(30,31,37,.95) 0%, rgba(30,31,37,.86) 55%, rgba(30,31,37,.62) 100%);
}
.emergency-hero h1 { color: var(--white); }
.emergency-hero__sub { color: rgba(255,255,255,.8); font-size: var(--step-1); margin-top: 1rem; max-width: 60ch; }
.emergency-call {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: .3rem;
	background: var(--amber);
	color: var(--white);
	border-radius: var(--radius-lg);
	padding: 1.35rem 2rem;
	margin-top: 2rem;
	transition: transform .18s ease, background-color .18s ease;
}
.emergency-call:hover { transform: translateY(-3px); background: var(--clay-600); }
.emergency-call__label { font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; opacity: .8; }
.emergency-call__num { font-family: var(--font-display); font-size: clamp(1.9rem, 1.4rem + 2vw, 2.8rem); font-weight: 400; line-height: 1; }

.checklist { display: grid; gap: .9rem; }
.checklist li { display: flex; gap: .75rem; align-items: flex-start; }
.checklist .icon { width: 1.35rem; height: 1.35rem; color: var(--green); flex: none; margin-top: .15rem; }
.checklist--warn .icon { color: var(--amber); }

/* ===========================================================
   20. BLOG
   =========================================================== */
.post-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 2rem 1.75rem; }
.post-card { display: flex; flex-direction: column; gap: .9rem; }
.post-card__media { aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden; }
.post-card__media img, .post-card__media .media-ph { width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius); }
.post-card h2, .post-card h3 { font-size: var(--step-1); }
.post-card h2 a, .post-card h3 a { color: inherit; }
.post-card h2 a:hover, .post-card h3 a:hover { color: var(--ink); }
.post-meta { font-size: .82rem; color: var(--muted); letter-spacing: .04em; text-transform: uppercase; }

.entry-content { font-size: 1.05rem; }
.entry-content > * + * { margin-top: 1.15em; }
.entry-content h2 { font-size: var(--step-3); margin-top: 2.2em; }
.entry-content h3 { font-size: var(--step-2); margin-top: 1.8em; }
.entry-content ul, .entry-content ol { padding-left: 1.35rem; }
.entry-content ul { list-style: disc; }
.entry-content ol { list-style: decimal; }
.entry-content li + li { margin-top: .45em; }
.entry-content img { border-radius: var(--radius); }
.entry-content blockquote {
	border-left: 4px solid var(--green);
	padding: .4rem 0 .4rem 1.4rem;
	font-size: var(--step-1);
	color: var(--ink);
	font-style: italic;
}
.entry-content a { color: var(--green-700); text-decoration: underline; text-underline-offset: 3px; }

/* -----------------------------------------------------------
   Service-page body — "Open Measure", plus one pull statement.

   The body is where a service page makes its actual argument, so it is set
   as running prose rather than left at default size: a longer line-height
   and more air between paragraphs, with every paragraph at the same size —
   no standfirst step-up on the opening line. Nothing is added to the markup
   for any of it, so the copy is written in WordPress exactly as before.
----------------------------------------------------------- */
.entry-content--service { font-size: 1.06rem; line-height: 1.78; }
.entry-content--service > * + * { margin-top: 1.4em; }

/* Running text gets a comfortable measure. */
.entry-content--service > p,
.entry-content--service > ul,
.entry-content--service > ol { max-width: 68ch; }

/* The lead row (see single-service.php) no longer sizes its paragraphs any
   differently from the rest of the body — every paragraph across the page
   reads at the same size. Only the green accent rule above the opening
   paragraph marks it as the start of the body copy. */
.entry-content--service-lead > p:first-child::before {
	content: "";
	display: block;
	width: 54px;
	height: 3px;
	background: var(--green);
	margin-bottom: 1.5rem;
}

/* The pull statement — one sentence per page, chosen in the editor via
   Paragraph > Styles > "Pull Statement". Two class hooks: the one the block
   editor generates, and a plain .pull for hand-written HTML. */
.entry-content--service .is-style-jce-pull,
.entry-content--service .pull {
	font-family: var(--font-display);
	font-size: var(--step-2);
	line-height: 1.4;
	/* Archivo Black is its own family with a single weight — any other
	   value here would be synthesised by the browser rather than loaded. */
	font-weight: 400;
	letter-spacing: -.015em;
	color: var(--forest);
	border-left: 3px solid var(--green);
	padding-left: clamp(1rem, .6rem + 1.2vw, 1.75rem);
	margin-top: 1.75em;
	margin-bottom: 1.75em;
	max-width: 42ch;
}
/* Never let the standfirst rule and the pull treatment stack on the same
   paragraph — an editor can apply the style to the first block. */
.entry-content--service-lead > p:first-child.is-style-jce-pull::before,
.entry-content--service-lead > p:first-child.pull::before { display: none; }

/* Photos dropped into the body via the block editor's own Image block, to
   break up a long run of paragraphs. Unlike running text these are exempt
   from the 68ch measure — a photo held to reading width looks cramped next
   to the copy either side of it. */
.entry-content--service > .wp-block-image {
	max-width: 100%;
	margin-top: 2.2em;
	margin-bottom: 2.2em;
}
.entry-content--service > .wp-block-image img { border-radius: var(--radius-lg); width: 100%; height: auto; }
.entry-content--service > .wp-block-image figcaption {
	margin-top: .6rem;
	font-size: .85rem;
	color: var(--muted);
	text-align: center;
}

.pagination { display: flex; gap: .5rem; justify-content: center; margin-top: 3rem; flex-wrap: wrap; }
.pagination .page-numbers {
	display: grid; place-items: center;
	min-width: 42px; height: 42px;
	padding-inline: .6rem;
	border: 1px solid var(--line);
	border-radius: 6px;
	font-size: .92rem;
	font-weight: 600;
}
.pagination .page-numbers:hover { border-color: var(--green); color: var(--green-700); }
.pagination .page-numbers.current { background: var(--green); border-color: var(--green); color: var(--white); }

/* ===========================================================
   21. FOOTER
   =========================================================== */
.site-footer { background: var(--forest-900); color: rgba(255,255,255,.68); font-size: .93rem; }
.site-footer a:hover { color: var(--green); }
.site-footer__main {
	padding-block: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-start;
	gap: 2rem;
}
.site-footer h3 {
	font-family: var(--font-body);
	font-size: .82rem;
	font-weight: 700;
	letter-spacing: .13em;
	text-transform: uppercase;
	color: var(--white);
	margin-bottom: 1.15rem;
}
.site-footer ul { display: grid; gap: .7rem; }
.footer-brand img { max-height: 44px; width: auto; margin-bottom: .6rem; }
.footer-brand p { max-width: 34ch; }
.footer-socials { display: flex; gap: .6rem; margin-top: .85rem; }
.footer-socials a {
	width: 32px; height: 32px;
	display: grid; place-items: center;
	border: 1px solid rgba(255,255,255,.18);
	border-radius: 8px;
	transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.footer-socials a:hover { background: var(--green); border-color: var(--green); color: var(--white); }
.footer-socials .icon { width: .95rem; height: .95rem; }

/* ISA credential list. The tile's padding is the logo's required free space
   (about the width of its "ISA" mark), and ISA sets a 1/2" minimum height —
   don't shrink the badge below 48px or trim the padding. */
.footer-isa { display: flex; align-items: center; gap: 1.25rem; }
.footer-isa__badge {
	flex: none;
	background: var(--white);
	padding: 24px;
	border-radius: 8px;
	line-height: 0;
}
.footer-isa__badge img { width: 58px; height: 96px; }
.site-footer .footer-isa__title {
	font-size: .95rem;
	letter-spacing: 0;
	text-transform: none;
	margin-bottom: .6rem;
}
.footer-isa__title sup { font-size: .6em; }
.site-footer .footer-isa__list { gap: .3rem; }
.footer-isa__id { font-variant-numeric: tabular-nums; color: rgba(255,255,255,.5); }

.site-footer__bottom {
	border-top: 1px solid rgba(255,255,255,.1);
	padding-block: 1rem;
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	font-size: .85rem;
	color: rgba(255,255,255,.5);
}
.site-footer__bottom ul { display: flex; gap: 1.25rem; }
/* Menu links carry no class, so the global link rule would make them truck
   green — too dark to read on the footer ground. */
.site-footer__bottom a { color: var(--logo-green); }
.site-footer__bottom a:hover { color: var(--white); }


/* Sticky mobile call bar — high-intent storm/emergency traffic */
.mobile-callbar {
	position: fixed;
	bottom: 0; left: 0; right: 0;
	z-index: 90;
	display: none;
	background: var(--charcoal);
	border-top: 2px solid var(--green);
	padding: .6rem;
	gap: .5rem;
}
.mobile-callbar .btn { flex: 1; padding: .8rem .5rem; font-size: .85rem; }
@media (max-width: 767px) {
	.mobile-callbar { display: flex; }
	body { padding-bottom: 68px; }
}

/* ===========================================================
   22. UTILITIES
   =========================================================== */
.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0,0,0,0);
	white-space: nowrap;
	border: 0;
}
.text-center { text-align: center; }
.mt-0 { margin-top: 0 !important; }
/* Default box so an icon is never clipped if a context forgets to size it. */
.icon { display: inline-block; width: 1em; height: 1em; flex: none; overflow: visible; vertical-align: middle; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.icon--filled { fill: currentColor; stroke: none; }

/* ===========================================================
   23. PAGE SECTIONS — services, service area, about
   Components used by single-service.php, single-location.php, and the
   Services / About / Service Area page templates.
   Every one of them is driven by an editable field, so each has
   to survive both two items and ten.
   =========================================================== */

/* -----------------------------------------------------------
   Feature list — labelled points
   ----------------------------------------------------------- */
.feature-list { display: grid; gap: 1.5rem; }
.feature-list__item strong {
	display: block;
	font-family: var(--font-display);
	font-size: var(--step-1);
	font-weight: 400;
	line-height: 1.25;
	letter-spacing: -.01em;
	color: var(--ink);
	margin-bottom: .3rem;
}
.feature-list__copy { display: block; font-size: .95rem; color: var(--body); }

.section--dark .feature-list__item strong { color: var(--white); }
.section--dark .feature-list__copy { color: rgba(255,255,255,.75); }

/* -----------------------------------------------------------
   FAQ — native <details>, so it works with JS disabled
   ----------------------------------------------------------- */
.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1.5rem;
	padding: 1.35rem 0;
	cursor: pointer;
	list-style: none;
	font-family: var(--font-display);
	font-size: var(--step-1);
	font-weight: 400;
	line-height: 1.3;
	color: var(--ink);
	transition: color .18s ease;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--ink); }
.faq__chevron {
	width: 1.35rem; height: 1.35rem;
	flex: none;
	margin-top: .2rem;
	color: var(--green-700);
	transition: transform .22s ease;
}
.faq__item[open] .faq__chevron { transform: rotate(180deg); }
.faq__a { padding: 0 0 1.5rem; max-width: 68ch; }
.faq__a p { color: var(--body); }

.section--dark .faq { border-color: rgba(255,255,255,.14); }
.section--dark .faq__item { border-color: rgba(255,255,255,.14); }
.section--dark .faq__q { color: var(--white); }
.section--dark .faq__a p { color: rgba(255,255,255,.75); }

/* -----------------------------------------------------------
   Highlight cards — values / coverage promises
   ----------------------------------------------------------- */
.highlight-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
	gap: 1.5rem;
}
.highlight-card {
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	padding: 2rem 1.75rem;
	transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.highlight-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: transparent; }
.highlight-card__icon {
	width: 48px; height: 48px;
	display: grid; place-items: center;
	border-radius: 10px;
	background: var(--green-050);
	color: var(--green-700);
	margin-bottom: 1.15rem;
}
.highlight-card__icon .icon { width: 24px; height: 24px; }
.highlight-card h3 { font-size: var(--step-1); margin-bottom: .55rem; }
.highlight-card p { font-size: .94rem; }

/* -----------------------------------------------------------
   Chip links (related services, secondary towns)
   ----------------------------------------------------------- */
.chip-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
	gap: .8rem;
	list-style: none;
	padding: 0;
}
.chip-grid--compact { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

.chip-link {
	display: flex;
	align-items: center;
	gap: .75rem;
	padding: .85rem 1rem;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	font-weight: 600;
	font-size: .93rem;
	color: var(--ink);
	white-space: nowrap;
	transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.chip-grid--compact .chip-link { padding: 1.15rem 1.35rem; font-size: 1.02rem; }
.chip-link:hover { border-color: var(--green); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.chip-link__icon {
	width: 32px; height: 32px; flex: none;
	display: grid; place-items: center;
	border-radius: 7px;
	background: var(--green-050);
	color: var(--green-700);
}
.chip-grid--compact .chip-link__icon { width: 38px; height: 38px; }
.chip-grid--compact .chip-link__icon .icon { width: 19px; height: 19px; }
.chip-link__icon .icon { width: 17px; height: 17px; }
.chip-link__label { flex: 1; line-height: 1.25; }
.chip-link__arrow { width: 1rem; height: 1rem; color: var(--green-700); opacity: 0; transition: opacity .18s ease, transform .18s ease; }
.chip-link:hover .chip-link__arrow { opacity: 1; transform: translateX(2px); }

.town-list { margin-top: 2.5rem; }

/* ===========================================================
   24. SERVICE PAGE — hero actions, proof blocks, sub-services
   =========================================================== */

/* Hero buttons + the "Proudly serving…" line under them */
.page-hero__actions { margin-top: 2rem; }
.page-hero__area {
	display: flex;
	align-items: flex-start;
	gap: .55rem;
	margin-top: 1.5rem;
	/* Matches the rendered width of the two hero buttons above (~582px)
	   with enough headroom that "Hastings, Roberts, Hammond, Baldwin,
	   Beldenville, and Houlton." reliably holds as one second line instead
	   of dropping "Houlton" to a third. */
	max-width: 610px;
	font-size: 1.05rem;
	line-height: 1.6;
	color: rgba(255,255,255,.7);
}
.page-hero__area .icon { width: 1.05rem; height: 1.05rem; color: var(--green); flex: none; margin-top: .25rem; }
.page-hero__area-link { color: rgba(255,255,255,.92); text-decoration: underline; text-decoration-color: rgba(255,255,255,.35); text-underline-offset: 3px; transition: color .15s ease, text-decoration-color .15s ease; }
.page-hero__area-link:hover,
.page-hero__area-link:focus-visible { color: var(--white); text-decoration-color: var(--green); }
/* On phones the town list wraps to four or five lines and stretches the
   hero into a tall, narrow box that crops the cover photo down to a sliver,
   so it's dropped there. */
@media (max-width: 600px) {
	.page-hero__area { display: none; }
}

/* A long keyword headline steps down a size and gets a wider measure —
   at --step-5 across 20ch it runs to five lines and swamps the hero. */
.page-hero--long h1 { font-size: var(--step-4); max-width: 26ch; }

/* The trust band sits under a hero photo on the homepage, where the wood
   texture reads as a border on the image. Away from a hero it needs its own
   top edge instead. */
.trust-band--flat { border-top: 0; }
.trust-band--flat .trust-band__inner { padding-block: 1.35rem; }

/* Five-step process: 3 + 2 rather than a lopsided 4 + 1 */
@media (min-width: 901px) {
	.steps--3up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 601px) and (max-width: 900px) {
	.steps--3up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* -----------------------------------------------------------
   Photo reel — browsable job photos right after the body copy.
   One slide wide so a photo is looked at, not shrunk to fit beside text.
   ----------------------------------------------------------- */
.photo-reel__head { margin-bottom: clamp(1.5rem, 1.1rem + 1.5vw, 2.25rem); }
.photo-reel__head h2 { font-size: var(--step-3); }

/* A landscape shot and a phone-held portrait shot land in the same stage,
   so the stage keeps a fixed wide shape and letterboxes rather than
   cropping — the dark ground is the same gradient .media-ph uses, so an
   uncropped portrait photo reads as framed on purpose, not badly fitted. */
.photo-reel__stage {
	position: relative;
	aspect-ratio: 16 / 9;
	border-radius: var(--radius-lg);
	overflow: hidden;
	box-shadow: var(--shadow-md);
	background:
		radial-gradient(120% 90% at 20% 10%, rgba(61,186,99,.24) 0%, transparent 60%),
		linear-gradient(155deg, var(--truck-green) 0%, var(--ink) 55%, #1E1F25 100%);
}
.photo-reel__slide {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	opacity: 0;
	visibility: hidden;
	transition: opacity .5s ease;
}
.photo-reel__slide.is-active { opacity: 1; visibility: visible; }
.photo-reel__slide img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	border-radius: 0;
}
.photo-reel__slide .media-ph {
	width: 100%;
	height: 100%;
	border-radius: 0;
	background: none;
}
.photo-reel__cap {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 2.75rem 1.35rem 1.1rem;
	background: linear-gradient(to top, rgba(44,46,53,.82), transparent);
	color: var(--white);
	font-size: .95rem;
	font-weight: 500;
}

.photo-reel__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	margin-top: 1.1rem;
}
.photo-reel__arrow {
	display: grid;
	place-items: center;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--white);
	border: 1px solid var(--line);
	color: var(--green-700);
	box-shadow: var(--shadow-sm);
	transition: background-color .18s ease, transform .18s ease;
}
.photo-reel__arrow .icon { width: 16px; height: 16px; }
.photo-reel__arrow--prev .icon { transform: rotate(180deg); }
.photo-reel__arrow:hover { background: var(--cream); transform: translateY(-1px); }
.photo-reel__dots { display: flex; align-items: center; gap: .5rem; }
.photo-reel__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border-radius: 50%;
	background: var(--line);
	transition: background-color .18s ease, transform .18s ease;
}
.photo-reel__dot:hover { background: var(--green-600); }
.photo-reel__dot.is-active { background: var(--green); transform: scale(1.3); }

/* -----------------------------------------------------------
   Proof blocks — claim, quote, photograph
   ----------------------------------------------------------- */
.proof-blocks { display: grid; gap: clamp(3rem, 2rem + 4vw, 5rem); }
.proof-block {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: clamp(1.75rem, 1rem + 3vw, 3.5rem);
	align-items: center;
}
@media (min-width: 861px) {
	.proof-block--reverse .proof-block__media { order: 2; }
}
.proof-block__media { display: grid; gap: .75rem; }
.proof-block__media--pair { grid-template-columns: 1fr 1fr; }
.proof-shot { margin: 0; }
.proof-shot .media-ph { border-radius: var(--radius-lg); }
.proof-shot img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-lg); }

.proof-block__body h3 { font-size: var(--step-3); margin-bottom: .9rem; }
.proof-block__body > p { font-size: 1.02rem; }

/* The quote is evidence for the claim above it, so it hangs off the same
   green rule the entry-content blockquote uses rather than becoming a card. */
.proof-quote {
	margin-top: 1.75rem;
	padding-left: 1.4rem;
	border-left: 4px solid var(--green);
}
.proof-quote__stars { display: flex; gap: .15rem; color: var(--green); margin-bottom: .6rem; }
.proof-quote__stars .icon { width: 1rem; height: 1rem; }
.proof-quote p { font-size: var(--step-1); line-height: 1.5; color: var(--ink); font-style: italic; }
.proof-quote__cite {
	display: block;
	margin-top: .7rem;
	font-style: normal;
	font-weight: 700;
	font-size: .9rem;
	color: var(--body);
}

/* -----------------------------------------------------------
   Sub-services + the "Good to Know" panel
   ----------------------------------------------------------- */
.good-to-know {
	background: var(--green-050);
	border: 1px solid rgba(61,186,99,.28);
	border-radius: var(--radius-lg);
	padding: clamp(1.4rem, 1.1rem + 1.2vw, 2rem);
	margin-top: clamp(2rem, 1.5rem + 2vw, 3rem);
}
.good-to-know__head { display: flex; align-items: center; gap: .8rem; margin-bottom: .9rem; }
.good-to-know h3 { font-size: var(--step-1); }
.good-to-know__intro { font-size: .97rem; margin-bottom: 1.1rem; }
.good-to-know__list { display: grid; gap: .8rem; list-style: none; padding: 0; }
.good-to-know__list li { display: flex; gap: .7rem; align-items: flex-start; font-size: .95rem; }
.good-to-know__list .icon { width: 1.25rem; height: 1.25rem; color: var(--green-700); flex: none; margin-top: .15rem; }

.sub-service-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
	gap: 1.5rem;
}
.sub-service {
	display: flex;
	flex-direction: column;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	overflow: hidden;
	transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.sub-service:hover { box-shadow: var(--shadow-md); transform: translateY(-4px); border-color: transparent; }
.sub-service__media { aspect-ratio: 16 / 10; background: var(--cream); }
.sub-service__media img, .sub-service__media .media-ph { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.sub-service__body { padding: 1.5rem; display: flex; flex-direction: column; gap: .55rem; flex: 1; }
.sub-service h3 { font-size: var(--step-1); }
.sub-service p { font-size: .93rem; }

/* ===========================================================
   25. CALLOUT — a paragraph that must not read as body prose
   Used inside entry-content for safety instructions, where
   burying "call 911 first" in a run of paragraphs would be a
   real-world failure rather than a design one.
   =========================================================== */
.callout {
	display: flex;
	gap: .9rem;
	padding: 1.15rem 1.35rem;
	border-radius: var(--radius);
	background: var(--green-050);
	border-left: 4px solid var(--green);
}
.callout p { margin: 0; color: var(--ink); font-size: 1rem; }
.callout::before {
	content: "";
	flex: none;
	width: 1.4rem;
	height: 1.4rem;
	margin-top: .1rem;
	background: currentColor;
	color: var(--green-700);
	/* Info glyph, masked so it inherits the callout's colour. */
	-webkit-mask: var(--callout-glyph) center / contain no-repeat;
	mask: var(--callout-glyph) center / contain no-repeat;
	--callout-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E");
}

/* Amber, not green — this is the emergency accent the brand brief reserves
   for storm/safety content so it cuts through the green everywhere else. */
.callout--warn {
	background: #FBE7DE;
	border-left-color: var(--amber);
}
.callout--warn::before {
	color: var(--amber-600);
	--callout-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
}
.entry-content .callout p + p { margin-top: .6em; }

/* reCAPTCHA v3 badge — hidden per Google's own guidance (visibility, not
   display:none, is the sanctioned way), with the required attribution
   text shown near the form instead. See .recaptcha-disclosure below. */
.grecaptcha-badge {
	visibility: hidden;
}
.recaptcha-disclosure {
	margin-top: 1rem;
	font-size: .8rem;
	color: var(--muted);
}
.recaptcha-disclosure a {
	color: inherit;
	text-decoration: underline;
}
