/*
 * Controlled Elements — supplemental brand CSS
 * Only for rules that can't be expressed in theme.json (loaded on front end
 * and mirrored into the editor via add_editor_style). Most styling lives in
 * theme.json. Enqueued from functions.php, versioned with filemtime().
 */

/* --- Image-topped service cards (icon swaps out trivially: replace the SVG) --- */
.ce-card {
	background: var(--wp--preset--color--white);
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
	border-bottom: 3px solid var(--wp--preset--color--ce-green);
	transition: transform 0.2s ease, box-shadow 0.2s ease;
	height: 100%;
}

.ce-card:hover {
	transform: translateY(-6px);
	box-shadow: 0 14px 30px rgba(0, 0, 0, 0.16);
}

/* Image sits flush to the top edge, corners clipped by the card radius */
.ce-card .wp-block-image,
.ce-card figure {
	margin: 0;
}

.ce-card .wp-block-image img {
	display: block;
	width: 100%;
}

.ce-card__body {
	padding: var(--wp--preset--spacing--40);
}

/* Icon badge — swap the inner <svg> for the final icon set later */
.ce-card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var(--wp--preset--color--ce-lime);
	color: var(--wp--preset--color--black);
	margin-bottom: var(--wp--preset--spacing--20);
}

.ce-card__icon svg {
	width: 30px;
	height: 30px;
}

/* --- Mobile: one consistent 24px text gutter in every full-width section. ---
   On phones the gutters stacked up: the alignfull section carries the root
   padding (24px), its inner constrained group adds its own inline spacing30
   (+24px), and media-text content adds core's 8% (+~23px) — so "Our Story" text
   sat ~71px in while "Our Philosophy" sat 48px. Keep ONE layer (the section's
   root padding) and zero the redundant inner ones, so all text and card
   sections share the same ~24px edge gutter and content runs usefully wide.
   !important beats the inner groups' inline padding. Desktop unchanged. */
@media (max-width: 600px) {
	.wp-block-post-content > .alignfull > .wp-block-group.is-layout-constrained {
		padding-left: 0 !important;
		padding-right: 0 !important;
	}
	.wp-block-media-text.is-stacked-on-mobile .wp-block-media-text__content {
		padding-left: 0;
		padding-right: 0;
	}
}

/* About page, Our Story on mobile (600px matches core's media-text stack
   breakpoint). Desktop is untouched — there the section's padding-bottom:0 is
   deliberate so Jeff's photo sits flush with the section bottom.
   1. When the media-text stacks, "President" sat directly against the gray
      Philosophy band (the section's 0 bottom padding) — add breathing room.
   2. Full-bleed Jeff's photo: negative margins cancel the constrained group's
      spacing30 side padding so the stacked image runs edge to edge (core
      already gives the img width:100%). */
@media (max-width: 600px) {
	#ourstory {
		padding-bottom: var(--wp--preset--spacing--50) !important;
	}
	#ourstory .wp-block-media-text.is-stacked-on-mobile .wp-block-media-text__media {
		/* True edge-to-edge: 100vw + centered breakout beats any depth of
		   nested container padding (the negative-margin version only cancelled
		   one level and left a visible gutter on-device). */
		width: 100vw;
		max-width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: calc(50% - 50vw);
	}
	/* Air between the full-bleed photo and the story text below it. */
	#ourstory .wp-block-media-text.is-stacked-on-mobile .wp-block-media-text__content {
		margin-top: 40px;
	}
}

/* Home, reviews section: the Google/Yelp buttons carry an inline 60px bottom
   margin sized for desktop; tighten to 40px on mobile. */
@media (max-width: 599px) {
	#reviews .wp-block-buttons {
		margin-bottom: 40px !important;
	}
}

/* Services page: the 9 service cards use a grid group with a fixed
   columnCount of 2, which WP keeps 2-up at every width — cramped on phones.
   Collapse to a single column on mobile only; desktop stays 2-up. */
@media (max-width: 599px) {
	.page-id-1798 .wp-block-post-content .wp-block-group.is-layout-grid {
		grid-template-columns: 1fr !important;
	}
}

/* Hero: ensure the inner content can offset left within the band */
.ce-hero .wp-block-cover__inner-container {
	width: 100%;
}

.ce-hero__content {
	max-width: 620px;
}

/* --- Interior page hero (reusable): half-height banner, left-aligned white
   title, horizontal 40%->0% black gradient. Pages only vary image + title. --- */
/* z-index:0 keeps the gradient above the background image but below the title. */
.ce-page-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0) 100%);
	pointer-events: none;
}
/* Force the title container above the gradient. WP core only sets its z-index
   when the cover has no overlay span; editing the page in the block editor adds
   a .wp-block-cover__background span, which turns that rule off and lets the
   gradient paint over the title. Setting z-index here keeps the white title
   crisp either way. */
.ce-page-hero .wp-block-cover__inner-container {
	width: 100%;
	position: relative;
	z-index: 2;
}

/* --- Header nav: uppercase --- */
.ce-nav .wp-block-navigation-item__label {
	text-transform: uppercase;
	letter-spacing: 0.5px;
	font-weight: 600;
}

/* --- GET STARTED CTA: button in the desktop header, menu item on mobile ---
   The nav collapses to a hamburger at <600px. There, hide the standalone
   header button (it was forcing the mobile header onto two rows) and instead
   surface the "Get Started" nav item inside the overlay menu. On desktop the
   button stays and the duplicate nav item is hidden. */
@media (max-width: 599px) {
	.wp-site-blocks > header .wp-block-buttons {
		display: none;
	}
}
@media (min-width: 600px) {
	.ce-nav .ce-mobile-cta {
		display: none;
	}
}

/* --- Mobile header layout: hamburger far-left, logo centered (one row).
   The nav group (which holds the hamburger) is absolutely pinned left, which
   lets the logo center in the row. Mobile only; desktop header is untouched. --- */
@media (max-width: 599px) {
	.wp-site-blocks > header .is-content-justification-space-between {
		position: relative;
		justify-content: center;
	}
	.wp-site-blocks > header .is-content-justification-space-between > .wp-block-group {
		position: absolute;
		left: 0;
		top: 0;
		bottom: 0;
		margin: 0;
		/* Vertically center the hamburger with flexbox, NOT transform. A
		   transform here would become the containing block for the menu
		   overlay's position:fixed (the overlay is a descendant of this group),
		   collapsing the full-screen menu to a tiny sliver. */
		display: flex;
		align-items: center;
	}
}

/* --- Mobile menu: pull the whole overlay column flush-left. ---
   The element that actually positions the menu column is NOT the <ul>/<li> — it's
   core's overlay wrappers:
     1. .wp-block-navigation__responsive-container-content gets
        `align-items: var(--navigation-layout-justification-setting)`, and our
        nav's `items-justified-right` class sets that variable to flex-end, so the
        whole column is pushed to one side (and centered on mobile).
     2. .has-modal-open .wp-block-navigation__responsive-close gets
        `max-width: wide-size; margin: 0 auto`, centering/constraining the panel.
   So we override those two winners (align the content wrapper to the start, drop
   the panel's max-width/auto-margins), then stretch the rows to full width so the
   text AND the section dividers all share one consistent left edge. The overlay
   container's own padding supplies the left margin. Scoped to the open overlay on
   mobile only. --- */
@media (max-width: 599px) {
	.ce-nav .is-menu-open .wp-block-navigation__responsive-close {
		max-width: none !important;
		margin-left: 0 !important;
		margin-right: 0 !important;
		/* Fill the column so the drawer panel below can be full viewport height. */
		flex-grow: 1;
	}
	.ce-nav .is-menu-open .wp-block-navigation__responsive-container-content,
	.ce-nav .is-menu-open .wp-block-navigation__container,
	.ce-nav .is-menu-open .wp-block-navigation__submenu-container {
		align-items: stretch !important;
		text-align: left !important;
	}
	.ce-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item,
	.ce-nav .is-menu-open .wp-block-navigation__submenu-container > .wp-block-navigation-item {
		width: 100% !important;
		align-items: flex-start !important;
		justify-content: flex-start !important;
		text-align: left !important;
	}
	/* Sub-nav flush to the same left edge as the parents (drop core's 2rem indent). */
	.ce-nav .is-menu-open .wp-block-navigation__submenu-container {
		padding-left: 0 !important;
		margin-left: 0 !important;
	}
}

/* --- Mobile menu: breathing room from the screen edges + reachable close.
   Core's overlay relies on root-padding variables that don't resolve here, so
   the menu sat flush against the left edge and the X was jammed into the very
   top-right corner. Give the column horizontal padding and pull the close button
   inward with a larger tap target so it clears the top/right edges. --- */
@media (max-width: 599px) {
	.ce-nav .is-menu-open .wp-block-navigation__responsive-container-content {
		padding-left: 1.5rem !important;
		padding-right: 1.5rem !important;
		/* Breathing room below the last item (core leaves padding-bottom at 0,
		   so "Get Started" sat flush against the end of the scroll area). */
		padding-bottom: 3rem !important;
	}
	.ce-nav .is-menu-open .wp-block-navigation__responsive-container-close {
		top: 1.25rem !important;
		right: 1.25rem !important;
		padding: 10px !important;
	}
}

/* --- Mobile menu: dim scrim + floating drawer. ---
   Turn the full-screen overlay into a drawer over a dimmed site. The overlay
   CONTAINER becomes a 50% black scrim (the page stays faintly visible and
   recessed); the menu sits on a solid-black DRAWER panel (the dialog) that,
   being a child of the container, paints above the scrim automatically — no
   z-index needed (the overlay already lives in the sticky header's z:100
   stacking context, which is above all page content). The scrim must beat the
   has-black-background-color preset (#000 !important), hence the !important +
   extra class. Tapping the scrim outside the drawer closes the menu
   (mobile-menu.js); body scroll is locked by core (html.has-modal-open{
   overflow:hidden}). --- */
@media (max-width: 599px) {
	.ce-nav .wp-block-navigation__responsive-container.is-menu-open {
		background-color: rgba(0, 0, 0, 0.5) !important;
	}
	.ce-nav .is-menu-open .wp-block-navigation__responsive-dialog {
		background-color: #000;
		width: min(84vw, 340px);
		min-height: 100%;
		box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
	}
}

/* --- Mobile menu: sub-nav hierarchy. Top-level items stay bold ALL-CAPS white
   (from the base .ce-nav label rule); demote the children to Title Case, muted
   gray, lighter weight so the hierarchy reads at a glance. Mobile overlay only;
   the desktop dropdowns (>=783px) are styled separately below. --- */
@media (max-width: 599px) {
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__label {
		text-transform: none; /* labels are stored Title Case in the markup */
		font-weight: 400;
	}
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		color: #b0b0b0;
	}
}

/* --- Mobile menu: page-break dividers between the top-level section groups.
   A thin low-opacity rule before every top-level item from the 3rd on — i.e.
   before SERVICES, OUR WORK, REVIEWS, GET STARTED — so each parent reads as a
   group with its children. (Home + About share the first group; no rule before
   either.)
   Spacing is symmetric by reusing the menu's own block-gap (24px) everywhere:
   the ul's row-gap already puts the divider 24px below the previous content
   (no extra margin-top — that was adding 0.85rem and unbalancing it), and
   padding-top matches the same gap so the parent link sits 24px below the
   divider — equal to the 24px between the parent and its first sub-item / the
   next divider. Every parent is centered between its divider and what follows. --- */
@media (max-width: 599px) {
	.ce-nav .wp-block-navigation__container > .wp-block-navigation-item:nth-child(n + 3) {
		border-top: 1px solid rgba(255, 255, 255, 0.15);
		margin-top: 0;
		padding-top: var(--wp--style--block-gap, 1.5rem);
	}
}

/* --- Mobile menu: "Get Started" as a lime CTA button. Mirrors the hero's lime
   Call button (ce-lime bg, black text) so the menu ends on the same call to
   action treatment used across the site. Shrink-wraps to its label. --- */
@media (max-width: 599px) {
	.ce-nav .is-menu-open .ce-mobile-cta .wp-block-navigation-item__content {
		background-color: var(--wp--preset--color--ce-lime);
		color: #000;
		padding: 0.55em 1.3em;
		border-radius: 4px;
	}
}

/* --- Desktop sub-nav dropdowns: white panel flush under the black header --- */
@media (min-width: 783px) {
	/* Extra classes (.wp-block-navigation + .has-child) beat WP core's
	   0,3,0 submenu rules that force inherit background + 1px border. */
	.ce-nav.wp-block-navigation .has-child .wp-block-navigation__submenu-container {
		top: 100%;
		left: 0;
		/* Transparent top border bridges the gap from the nav item down to the
		   header's bottom edge, so the white panel starts flush below the black
		   bar and hovering across the gap keeps the menu open. */
		border: 0;
		border-top: 37px solid transparent;
		/* !important overrides the has-black-background-color preset class WP
		   auto-adds to submenu containers (preset color classes use !important). */
		background-color: var(--wp--preset--color--white) !important;
		background-clip: padding-box;
		width: max-content;
		min-width: 220px;
		box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
	}
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item {
		color: #000;
	}
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		color: #000;
		white-space: nowrap; /* keep link labels on one line */
	}
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
	.ce-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus {
		color: var(--wp--preset--color--ce-green);
	}
}

/* --- Flush top-level bands: kill the default gap above main + footer --- */
.wp-site-blocks > main,
.wp-site-blocks > footer {
	margin-block-start: 0;
}

/* Full-bleed colored sections should stack flush — the post-content's
   constrained layout otherwise inserts a block-gap margin between siblings,
   showing the white page background between bands. Each section owns its
   internal padding, so the inter-section margin is just an unwanted gap. */
.wp-block-post-content > .alignfull {
	margin-block-start: 0;
	margin-block-end: 0;
}
/* Anchored full-width sections (e.g. #ourstory) clear the sticky header when
   jumped to from the sub-nav. */
.wp-block-post-content > .alignfull[id] {
	scroll-margin-top: 90px;
}

/* --- Sticky header --- */
.wp-site-blocks > header {
	position: sticky;
	top: 0;
	z-index: 100;
	box-shadow: 0 1px 12px rgba(0, 0, 0, 0.08);
}

/* Offset for the WordPress admin bar so the header doesn't jump on first
   scroll while logged in (admin bar is 32px desktop / 46px mobile). */
.admin-bar .wp-site-blocks > header {
	top: 32px;
}
@media screen and (max-width: 782px) {
	.admin-bar .wp-site-blocks > header {
		top: 46px;
	}
}

/* --- Subtle texture for otherwise-flat brand bands (SubtlePatterns-style) --- */
.ce-pattern {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M0 24 24 0M-6 6 6 -6M18 30 30 18' stroke='%23000000' stroke-opacity='0.04' stroke-width='1'/%3E%3C/svg%3E");
	background-repeat: repeat;
}

/* Subtle white texture for solid colored bands (e.g. the green stats band) */
.ce-pattern-soft {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M0 28 28 0M-7 7 7 -7M21 35 35 21' stroke='%23ffffff' stroke-opacity='0.08' stroke-width='1.5'/%3E%3C/svg%3E");
	background-repeat: repeat;
}

/* --- Pre-footer contact form: compact + brand submit (scoped to footer) --- */
.wp-site-blocks > footer .quform-spacer { padding-bottom: 8px; }
.wp-site-blocks > footer .quform-label { font-size: 15px; margin-bottom: 3px; }
.wp-site-blocks > footer .quform-field {
	font-size: 16px;
	padding: 8px 11px;
	line-height: 1.35;
	font-family: inherit; /* unify all fields on the site font (inputs default to Arial, textareas to monospace) */
}
.wp-site-blocks > footer .quform-field-textarea { min-height: 64px; }

/* Radio options (Quote / Service / Contact): keep Quform's "hollow button"
   style (selection shows as a dark fill) but round the corners to 5px and
   drop the wide letter-spacing so labels stay on one line.
   Beat Quform's (0,4,0) .quform .quform-input .quform-button-style-hollow rule. */
.wp-site-blocks > footer .quform .quform-input .quform-button-style-hollow .quform-option-label {
	border-radius: 5px;
	letter-spacing: 0;
	padding: 3px 10px;
	white-space: nowrap;
	text-align: center;
}
.wp-site-blocks > footer .quform-submit {
	background-color: #009933;
	color: #fff;
	border: 0;
	border-radius: 4px;
	padding: 9px 26px;
	font-weight: 700;
	cursor: pointer;
	transition: background-color 0.2s ease;
}
.wp-site-blocks > footer .quform-submit:hover { background-color: #85db02; color: #000; }

/* --- Pre-footer band: grayscale ductwork bg + green overlay, floating form card --- */
.ce-prefooter {
	position: relative;
	isolation: isolate;
	overflow: visible;
	scroll-margin-top: 90px; /* offset the sticky header when jumping to #getstarted */
}
.ce-prefooter::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -2;
	background: url("/wp-content/uploads/2026/06/Spiral-Ductwork-03.jpg") center top / cover no-repeat;
	filter: grayscale(1);
}
.ce-prefooter::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: rgba(0, 153, 51, 0.7);
}
/* Form card floats over the image; its thick green top border rises above it.
   Scoped selector beats WP's .is-layout-flex > * { margin:0 } reset. */
.ce-prefooter .ce-prefooter__card {
	margin-top: -150px;
	position: relative;
	z-index: 1;
}
/* Columns stack below 782px: drop the negative lift so the card no longer
   overlaps the logo/address/hours/license block above it. */
@media (max-width: 781px) {
	.ce-prefooter .ce-prefooter__card {
		margin-top: var(--wp--preset--spacing--40);
	}
	/* Balanced band spacing when stacked: the desktop 100px inline padding-top
	   left a dead zone above the logo, but matching the card gap exactly (24px)
	   read too tight on-device. 3rem (48px) splits the difference — clearly
	   less than 100px, comfortably more than the 24px license->card gap below.
	   !important beats the inline padding-top:100px. */
	.ce-prefooter {
		padding-top: 3rem !important;
	}
}

/* --- Galleries: hover zoom + clickable cue --- */
.wp-block-gallery .wp-block-image {
	overflow: hidden;
	border-radius: 6px;
}
.wp-block-gallery .wp-block-image img {
	transition: transform 0.4s ease;
	cursor: zoom-in;
}
.wp-block-gallery .wp-block-image:hover img {
	transform: scale(1.08);
}

/* --- Lightbox (custom, gallery-aware) --- */
.ce-lightbox {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: none;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.9);
}
.ce-lightbox.is-open { display: flex; }
.ce-lightbox__img {
	max-width: 90vw;
	max-height: 85vh;
	object-fit: contain;
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
.ce-lightbox__btn {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
	font-size: 30px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.2s ease;
}
.ce-lightbox__btn:hover { background: rgba(255, 255, 255, 0.28); }
.ce-lightbox__prev { left: 3vw; }
.ce-lightbox__next { right: 3vw; }
.ce-lightbox__close {
	top: 4vh;
	right: 4vw;
	transform: none;
	width: 44px;
	height: 44px;
	font-size: 26px;
}
.ce-lightbox__count {
	position: absolute;
	bottom: 4vh;
	left: 0;
	right: 0;
	text-align: center;
	color: #fff;
	font-size: 14px;
	letter-spacing: 1px;
}
@media (max-width: 600px) {
	.ce-lightbox__prev { left: 1vw; }
	.ce-lightbox__next { right: 1vw; }
}

/* --- Floating back-to-top button (injected by back-to-top.js) --- */
.ce-to-top {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 90; /* above content, below sticky header (100) and lightbox (99999) */
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--wp--preset--color--ce-green);
	color: #fff;
	cursor: pointer;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s, background-color 0.2s ease;
}
.ce-to-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}
.ce-to-top:hover {
	background: var(--wp--preset--color--ce-lime);
	color: #000;
}
.ce-to-top svg {
	width: 24px;
	height: 24px;
}

/* --- Phone-width refinements (<=600px) --- */
@media (max-width: 600px) {
	/* Our Work jump-links: stack into full-width, easily tappable buttons
	   instead of cramped centered pills of varying width. */
	.ce-jumpnav.wp-block-buttons {
		flex-direction: column;
		align-items: stretch;
	}
	.ce-jumpnav.wp-block-buttons > .wp-block-button {
		width: 100%;
	}
	.ce-jumpnav .wp-block-button__link {
		display: block;
		text-align: center;
	}

	/* Home hero: drop the extra 40px content indent on phones so the headline
	   uses the available width (the cover already has spacing40 side padding).
	   Inline style needs !important to beat it. */
	.ce-hero .ce-hero__content {
		padding-left: 0 !important;
	}
}
