/*
	Theme Name: Itchen Glass & Glazing (v2)
	Theme URI:
	Description: Standalone theme for the Itchen Glass & Glazing plain-theme rebuild (no Elementor) -- scaffolded from Underscores. Holds the project's design-system CSS custom properties and component styling, ported unchanged from the Elementor-based dev site's itchenglass-child theme.
	Author: Hospitality Innovations
	Version: 0.1.0
	Requires at least: 6.0
	Requires PHP: 8.1
	Text Domain: itchenglassns
*/

/* ---------- Underscores baseline resets (normally generated by _s) ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { line-height: 1.15; -webkit-text-size-adjust: 100%; }
body { margin: 0; }
img { max-width: 100%; height: auto; border: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { background-color: transparent; }
button, input, select, textarea { font-family: inherit; font-size: 100%; }
.screen-reader-text { border: 0; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; }
.screen-reader-text:focus { background-color: #f1f1f1; clip: auto !important; clip-path: none; color: #21759b; display: block; font-size: 14px; font-weight: 700; height: auto; left: 5px; line-height: normal; padding: 15px 23px 14px; text-decoration: none; top: 5px; width: auto; z-index: 100000; }

:root {
	/* Colour — anchored to the palette already live on the 4 SEO pages
	   (double-glazing-southampton etc.), not reinvented for the rebuild. */
	--color-navy: #1c3461;
	--color-navy-deep: #142645;
	--color-amber: #e8a020;
	--color-amber-deep: #c8881a;
	/* amber-deep is 3:1 on white -- fails WCAG AA (4.5:1) for normal-size
	   text. Use this darker variant for amber TEXT on light backgrounds
	   (eyebrow labels, card links); keep amber/amber-deep for buttons,
	   borders and icons where the contrast is computed differently. */
	--color-amber-text: #8c6210;
	--color-light: #f5f7fa;
	--color-white: #ffffff;
	--color-ink: #2d2d2d;
	/* Glass Teal -- the green-blue tint visible at the edge of float glass.
	   Added so the identity isn't carried by navy+amber alone (see the
	   frontend-design self-critique in handoff_v1.md). */
	--color-glass: #2d5265;

	/* Type — Fraunces (display) + Public Sans (body/label/data), loaded
	   via functions.php. "Trustworthy & established" personality. */
	--font-display: 'Fraunces', Georgia, serif;
	--font-body: 'Public Sans', -apple-system, BlinkMacSystemFont, sans-serif;

	/* Spacing — spacious/premium rhythm (matches the 1140px content width
	   and 60-100px section padding already used on the SEO pages). */
	--content-width: 1140px;
	--section-padding-y: 6rem;
	--section-padding-y-mobile: 2.5rem;

	/* design-v2 tokens (2026-08-27) -- see the "DESIGN V2" section below for
	   what uses these. Declared in THIS :root block, not a second one:
	   confirmed via live CSSOM inspection (sheet.cssRules) that a second
	   top-level `:root { ... }` rule later in the same file gets silently
	   dropped during parsing -- every var() referencing it then resolves to
	   the empty string with no console warning, which is a much harder
	   failure to spot than a normal cascade loss (getComputedStyle showed
	   border-width:0/border-style:none on an element with a perfectly
	   valid, matching, !important rule -- the defining :root rule itself
	   was just gone from sheet.cssRules, not merely losing a specificity
	   fight). One :root block per stylesheet file, always. */
	--ink: #10181f;
	--ink-soft: #33424c;
	--slate: #5b6b74;
	--paper: #faf8f4;
	--panel: #f1ede4;
	--glass-100: #eef4f4;
	--glass-300: #cfe1e2;
	--bronze: #b5793a;
	--bronze-dark: #8f5f2a;
	--line: #dcd6c9;
	--v2-radius: 11px;
	--v2-radius-btn: 11px;
	--v2-max: 1240px;
	--shadow-sm: 0 1px 2px rgba(16, 24, 31, 0.05), 0 1px 1px rgba(16, 24, 31, 0.04);
	--shadow-md: 0 10px 24px -10px rgba(16, 24, 31, 0.20), 0 2px 8px -2px rgba(16, 24, 31, 0.08);
	--shadow-lg: 0 30px 60px -24px rgba(16, 24, 31, 0.32), 0 10px 20px -10px rgba(16, 24, 31, 0.14);
	--shadow-hover: 0 22px 40px -16px rgba(16, 24, 31, 0.26), 0 6px 14px -6px rgba(16, 24, 31, 0.12);
}

body {
	font-family: var(--font-body);
	color: var(--color-ink);
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-display);
	color: var(--color-navy);
}

/* Hello Elementor's base stylesheet (registered under the confusingly-named
   "hello-elementor" handle -- see wordpress-elementor-gotchas.md load-order
   section) resets outline to none on every element with no replacement,
   leaving no visible keyboard focus state anywhere on the site. Restore one,
   scoped to :focus-visible so it only shows for keyboard/assistive-tech
   navigation, not mouse clicks. !important guarantees this wins regardless
   of stylesheet load order, same defensive pattern already used elsewhere
   in this file. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 3px solid var(--color-amber) !important;
	outline-offset: 2px !important;
}

/* ---------- Header ---------- */

.itchen-site-header {
	position: sticky;
	top: 0;
	z-index: 999;
	background: var(--color-white) !important;
	border-bottom: 1px solid #e5e5e5;
}

/* Elementor sets flex via a CSS custom property on a two-class selector
   (.e-con.e-flex) that beats a single-class override regardless of load
   order — see wordpress-elementor-gotchas.md gotcha #2. Matching the
   compound here, plus !important, is the documented fix. */
.itchen-site-header .itchen-header-row.e-con.e-flex {
	align-items: center !important;
	justify-content: space-between !important;
}

.itchen-header-logo-col {
	/* Same flex-basis:auto collapse as the nav column (see the nav-col rule
	   below), but this column must NOT grow -- it should hug its content.
	   Pinning width to max-content sidesteps the broken auto-basis
	   resolution entirely instead of fighting it with flex-grow. */
	flex: 0 0 auto !important;
	width: max-content !important;
}

/* Icon-above-wordmark lockup (2026-08-19, real client artwork). Two
   stacked lines need to be more compact than the old single-line 1.5rem
   text to avoid dominating the sticky header's height. */
/* Matches Elementor's own .e-con.e-flex compound-selector specificity
   (see wordpress-elementor-gotchas.md gotcha #2 -- a single-class
   !important isn't reliably enough against that default). */
.itchen-logo-stack.e-con.e-flex {
	flex-direction: column !important;
	align-items: flex-start !important;
	gap: 0.2rem !important;
	padding-block: 0.5rem !important;
	width: 168px !important;
}

.itchen-logo-stack .elementor-widget-image img {
	width: 100%;
	height: auto;
	display: block;
}

.itchen-header-logo-col .itchen-logo-text,
.itchen-header-logo-col h4 {
	font-size: 0.8rem;
	font-weight: 600;
	margin: 0;
	white-space: nowrap;
	width: 100%;
}

.itchen-header-nav-col {
	/* flex-basis: auto (the default) sizes this item from its own content's
	   intrinsic width before growth is applied -- but its content (the
	   ekit-nav-menu widget) is itself a nested flex row with wrapping
	   children, and that combination resolves to a near-zero intrinsic
	   width in Chromium rather than "grow to fill". Using 0% forces sizing
	   purely from flex-grow distribution, ignoring content-based intrinsic
	   sizing entirely -- the reliable fix for a flex item that "should"
	   grow but doesn't when its content is itself flex/wrap. */
	flex: 1 1 0% !important;
	min-width: 0;
}

.itchen-header-nav-col .elementor-widget-ekit-nav-menu,
.itchen-header-nav-col .elementor-widget-container,
.itchen-header-nav-col .ekit-wid-con,
.itchen-header-nav-col .elementskit-menu-container {
	width: 100% !important;
}

.elementskit-navbar-nav {
	flex-wrap: nowrap !important;
}

.itchen-header-cta-col {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	flex: 0 0 auto !important;
	width: max-content !important;
}

a.itchen-header-phone {
	color: var(--color-navy) !important;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	/* Text-only link was a ~19px-tall tap target on mobile -- pad it toward
	   the ~44px touch-target guideline without changing its visual size. */
	display: inline-flex;
	align-items: center;
	padding-block: 0.8rem;
}

/* ekit-nav-menu top-level links */
.elementskit-navbar-nav > li > a {
	color: var(--color-navy) !important;
	font-family: var(--font-body);
	font-weight: 500;
}

/* ---------- Buttons ---------- */

.itchen-btn-amber .elementor-button,
.itchen-btn-amber a.elementor-button {
	background: var(--color-amber) !important;
	color: var(--color-navy) !important;
	font-weight: 600;
	/* elementor-size-sm's own padding renders at 39px tall -- below the
	   ~44px minimum touch-target guideline. Neither button widget call
	   sets an explicit size, so this fixes it sitewide. */
	padding-block: 0.95rem !important;
	border-radius: 4px;
	white-space: nowrap;
}

.itchen-btn-amber .elementor-button:hover {
	background: var(--color-amber-deep) !important;
}

/* ---------- Footer ---------- */

.itchen-site-footer {
	background: var(--color-navy) !important;
	color: var(--color-white);
	padding-inline-start: 5vw !important;
	padding-inline-end: 5vw !important;
}

.itchen-site-footer h4,
.itchen-site-footer .elementor-heading-title {
	/* !important needed: Elementor's own heading-widget default color rule
	   (.elementor-widget-heading .elementor-heading-title, two classes)
	   otherwise outranks this one-class-plus-element selector and renders
	   navy-on-navy (invisible) using the Kit's primary colour. */
	color: var(--color-white) !important;
	font-size: 1.1rem;
	margin-bottom: 1rem;
}

.itchen-site-footer p,
.itchen-site-footer a {
	color: #d7deea;
}

.itchen-site-footer a:hover {
	color: var(--color-amber);
}

.itchen-footer-links {
	list-style: none;
	margin: 0;
	padding: 0;
}

.itchen-footer-links li {
	margin-bottom: 0.5rem;
}

.itchen-footer-bottom {
	border-top: 1px solid rgba(255, 255, 255, 0.15);
	margin-top: 2rem;
	padding-top: 1.5rem;
	text-align: center;
	font-size: 0.85rem;
}

.itchen-footer-bottom p {
	color: #a9b4c6;
}

/* ---------- Layout ---------- */

.e-con.itchen-site-header,
.e-con.itchen-site-footer {
	max-width: 100% !important;
}

/* ==========================================================================
   Homepage sections
   All row containers below use an explicit pixel flex-basis (never bare
   "auto") on their children, plus flex-wrap: wrap -- see gotcha #14 in
   wordpress-elementor-gotchas.md: flex-basis:auto on a programmatically
   built nested container can collapse to near-zero instead of sizing to
   content, and Elementor containers don't wrap by default without an
   explicit flex-wrap.
   ========================================================================== */

.itchen-section {
	max-width: var(--content-width);
	margin-inline: auto !important;
	padding-block: var(--section-padding-y) !important;
	padding-inline: 5vw !important;
}

.itchen-section-title {
	text-align: center;
	font-size: 2rem;
	margin-bottom: 2.5rem !important;
}

.itchen-final-cta-title {
	text-align: center;
	font-size: 2rem;
	margin-bottom: 0.5rem !important;
}

/* `color` set here does nothing on its own -- Elementor's own heading-widget
   default color rule targets .elementor-heading-title (the actual inner
   element) directly, which beats a rule that only reaches the outer
   .itchen-*-title wrapper div, same root cause as the footer h4 fix above.
   Every itchen_heading() color override needs this descendant form. */
.itchen-final-cta-title .elementor-heading-title {
	color: var(--color-white) !important;
}

/* ---------- Hero ---------- */

.itchen-hero {
	min-height: 560px;
	display: flex !important;
	align-items: center;
	padding-inline: 5vw !important;
}

.itchen-hero-inner {
	max-width: 720px;
	width: 100%;
}

.itchen-hero-title {
	font-size: 3rem;
	line-height: 1.15;
	margin-bottom: 1.25rem !important;
}

/* See the .itchen-final-cta-title comment above -- color must reach the
   actual .elementor-heading-title element, not just the outer wrapper. */
.itchen-hero-title .elementor-heading-title {
	color: var(--color-white) !important;
	/* Belt-and-suspenders on top of the overlay -- real installation photos
	   vary a lot in brightness, and a fixed overlay opacity can't guarantee
	   contrast against every one of them. */
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9), 0 4px 18px rgba(0, 0, 0, 0.55);
}

.itchen-hero-sub p,
.itchen-hero-sub {
	color: var(--color-white);
	font-size: 1.15rem;
	max-width: 560px;
	margin-bottom: 2rem !important;
	text-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}

.itchen-hero-ctas {
	flex-wrap: wrap !important;
	gap: 1rem;
	margin-bottom: 0.75rem !important;
}

.itchen-hero-ctas > .e-con {
	flex: 0 0 auto !important;
	width: max-content !important;
}

.itchen-btn-outline .elementor-button,
.itchen-btn-outline a.elementor-button {
	background: transparent !important;
	color: var(--color-white) !important;
	padding-block: 0.95rem !important;
	border: 2px solid var(--color-white);
	font-weight: 600;
	border-radius: 4px;
}

.itchen-btn-outline .elementor-button:hover {
	background: rgba(255, 255, 255, 0.15) !important;
}

.itchen-hero-proof {
	color: var(--color-white);
	opacity: 0.9;
	font-size: 0.95rem;
}

/* ---------- Page hero (style sub-pages) ----------
   Rebuilt 2026-08-19 from a flat text-on-dimmed-photo single container to
   a layered card composition (reference: orion-windows.co.uk's product
   pages) -- contrast now comes from the opaque card, not a dark overlay
   wash, so the real photo behind it stays fully bright. See
   design-review-discuss-first memory for why this took several passes. */

.itchen-page-hero {
	position: relative;
	min-height: 560px;
	display: flex !important;
	/* This is a COLUMN-direction flex container (Elementor sets that per
	   element, not here) -- align-items therefore controls the HORIZONTAL
	   cross-axis, not vertical as the original comment assumed.
	   align-items:center was centering the card in the middle of the hero,
	   hiding most of the photo either side. flex-start + justify-content
	   (the real vertical control in column mode) is what "left-aligned,
	   vertically centered" actually needs. Confirmed 2026-08-20 via
	   computed styles: card was landing at x=482px in a 1425px-wide hero,
	   not near the 72px left padding as intended. */
	align-items: flex-start;
	justify-content: center;
	padding-inline: 5vw !important;
	padding-block: 4rem !important;
}

.itchen-page-hero-inner {
	max-width: 460px;
	width: 100%;
}

/* The card itself -- the signature move. An elliptical top border-radius
   (wide flat ellipse, not a corner radius) cuts the fanlight-arch curve
   already used as the section-divider motif into the card's top edge, so
   this reads as part of the Itchen system rather than a borrowed device. */
.itchen-hero-card {
	background: rgba(245, 247, 250, 0.97);
	/* Tightened 2026-08-20 (was 3.25rem 2.25rem 2.25rem) -- card was
	   overflowing the viewport (698px tall at 1440x900) before the NAV
	   rework that would let it fit properly; this and the margin cuts
	   below recover ~120-150px without the NAV change. */
	padding: 2.25rem 1.75rem 1.75rem;
	border-radius: 50% 50% 8px 8px / 42px 42px 8px 8px;
	box-shadow: 0 20px 50px rgba(20, 38, 69, 0.35);
}

.itchen-page-hero .itchen-hero-card .itchen-breadcrumb-back {
	color: var(--color-navy);
	opacity: 0.65;
}

.itchen-page-hero .itchen-hero-card .itchen-breadcrumb-back:hover {
	opacity: 1;
	color: var(--color-amber-deep);
}

.itchen-page-hero .itchen-hero-card .itchen-eyebrow {
	color: var(--color-amber-text);
	opacity: 1;
	text-align: left;
	position: relative;
	padding-bottom: 0.9rem;
}

.itchen-page-hero .itchen-hero-card .itchen-eyebrow::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: 0;
	width: 42px;
	height: 3px;
	background: var(--color-amber);
}

.itchen-page-hero-title {
	font-size: 2.2rem;
	line-height: 1.15;
	margin-bottom: 0.5rem !important;
}

.itchen-page-hero-title .elementor-heading-title {
	color: var(--color-navy) !important;
	text-shadow: none;
}

.itchen-page-hero-sub p,
.itchen-page-hero-sub {
	color: var(--color-ink);
	font-size: 1rem;
	margin-bottom: 0.85rem !important;
	text-shadow: none;
}

.itchen-hero-bullets {
	list-style: none;
	margin: 0 0 1rem !important;
	padding: 0;
}

.itchen-hero-bullets li {
	position: relative;
	padding-left: 1.6rem;
	line-height: 1.4;
	color: var(--color-ink);
	font-weight: 600;
	font-size: 0.95rem;
	margin-bottom: 0.4rem;
}

.itchen-hero-bullets li::before {
	content: '\2713';
	position: absolute;
	left: 0;
	color: var(--color-amber-text);
	font-weight: 700;
}

/* Second plane -- a floating credibility badge, the honest equivalent of
   Orion's sale badge (we don't have a sale to advertise; Itchen's real
   equivalent is 30+ years of local trust). Gives the composition the same
   layered depth without inventing a promotion. */
.itchen-hero-badge {
	position: absolute;
	top: 2.5rem;
	right: 5vw;
	max-width: 190px;
	background: var(--color-navy);
	padding: 1rem 1.25rem;
	border-radius: 6px;
	box-shadow: 0 12px 30px rgba(20, 38, 69, 0.4);
	font-size: 0.82rem;
	font-weight: 600;
	line-height: 1.4;
	text-align: center;
}

/* Elementor's text-editor widget carries its own default text color with
   enough specificity to beat a plain `.itchen-hero-badge { color: ... }`
   rule on the outer wrapper -- same root cause as the heading-color fix
   elsewhere in this file (see the comment above .itchen-final-cta-title).
   Reach the actual text node directly, not just the wrapper. */
.itchen-hero-badge,
.itchen-hero-badge .elementor-widget-text-editor,
.itchen-hero-badge .elementor-widget-container {
	color: var(--color-white) !important;
}

@media (max-width: 900px) {
	.itchen-hero-badge {
		display: none;
	}
}

@media (max-width: 600px) {
	.itchen-hero-card {
		border-radius: 40% 40% 6px 6px / 28px 28px 6px 6px;
		padding: 2.5rem 1.5rem 1.75rem;
	}
}

/* ---------- Trust strip ---------- */

.itchen-trust-strip {
	background: var(--color-light);
	max-width: 100%;
	padding-block: 3rem !important;
}

.itchen-trust-row {
	flex-wrap: wrap !important;
	gap: 2rem;
	max-width: var(--content-width);
	margin-inline: auto !important;
}

.itchen-trust-item {
	flex: 1 1 220px !important;
	min-width: 0;
	text-align: center;
}

.itchen-trust-title {
	color: var(--color-amber-deep);
	font-size: 1.4rem;
	margin-bottom: 0.4rem !important;
}

.itchen-trust-item p {
	font-size: 0.95rem;
	color: var(--color-ink);
}

/* ---------- Category cards ---------- */

.itchen-category-row,
.itchen-project-row,
.itchen-benefit-row,
.itchen-step-row {
	flex-wrap: wrap !important;
	gap: 1.75rem;
}

.itchen-card {
	flex: 1 1 220px !important;
	min-width: 0;
	background: var(--color-white);
	border-radius: 6px;
	overflow: hidden;
	box-shadow: 0 2px 12px rgba(28, 52, 97, 0.08);
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.itchen-card:hover {
	transform: translateY(-3px);
	box-shadow: 0 8px 24px rgba(28, 52, 97, 0.14);
}

.itchen-card .elementor-widget-image img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}

.itchen-card-title {
	font-size: 1.2rem;
	padding-inline: 1.25rem;
	margin-top: 1rem !important;
	margin-bottom: 0.4rem !important;
}

.itchen-card-desc {
	padding-inline: 1.25rem;
}

.itchen-card-desc p {
	font-size: 0.92rem;
	color: var(--color-ink);
}

.itchen-card-link {
	display: block;
	padding: 0.5rem 1.25rem 1.25rem;
	color: var(--color-amber-text) !important;
	font-weight: 600;
	text-decoration: none;
}

.itchen-card-link:hover {
	color: var(--color-navy) !important;
}

/* ---------- Homeowner benefits ---------- */

.itchen-benefit-item {
	flex: 1 1 220px !important;
	min-width: 0;
	text-align: center;
	padding-inline: 1rem;
}

.itchen-benefit-title {
	font-size: 1.2rem;
	margin-bottom: 0.5rem !important;
}

/* ---------- Featured projects ---------- */

.itchen-project-card {
	flex: 1 1 280px !important;
	min-width: 0;
	border-radius: 6px;
	overflow: hidden;
}

.itchen-project-card .elementor-widget-image img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}

.itchen-project-caption {
	font-size: 0.9rem;
	color: var(--color-ink);
	margin-top: 0.6rem;
	text-align: center;
}

.itchen-projects-cta {
	text-align: center;
	margin-top: 2rem !important;
}

.itchen-projects-cta .itchen-card-link {
	display: inline;
	padding: 0;
}

/* ---------- How it works ---------- */

.itchen-how-it-works {
	background: var(--color-light);
	max-width: 100%;
	padding-block: var(--section-padding-y) !important;
}

.itchen-how-it-works .itchen-section-title {
	max-width: var(--content-width);
	margin-inline: auto !important;
}

.itchen-step-row {
	max-width: var(--content-width);
	margin-inline: auto !important;
	position: relative;
}

.itchen-step-item {
	flex: 1 1 220px !important;
	min-width: 0;
	text-align: center;
	position: relative;
}

/* The river-line motif from the logo: a thin connecting line threading
   through the process steps, echoing the brand mark instead of using bare
   numbered circles as unrelated decoration. */
.itchen-step-row::before {
	content: '';
	position: absolute;
	top: 20px;
	left: 5%;
	right: 5%;
	height: 2px;
	background: var(--color-amber);
	opacity: 0.4;
	z-index: 0;
}

.itchen-step-num {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--color-amber);
	color: var(--color-navy);
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.1rem;
	margin-bottom: 1rem;
}

.itchen-step-title {
	font-size: 1.1rem;
	margin-bottom: 0.4rem !important;
}

/* ---------- Repairs callout ---------- */

.itchen-repairs-callout {
	background: var(--color-navy);
	max-width: 100%;
	padding-block: var(--section-padding-y) !important;
}

.itchen-repairs-callout-row {
	max-width: var(--content-width);
	margin-inline: auto !important;
}

.itchen-repairs-callout-text {
	flex: 1 1 100% !important;
	text-align: center;
}

.itchen-repairs-callout .itchen-section-title {
	color: var(--color-white);
}

.itchen-repairs-callout-text p {
	color: #d7deea;
	max-width: 640px;
	margin-inline: auto !important;
	margin-bottom: 1.5rem !important;
}

/* ---------- Service area ---------- */

.itchen-service-area {
	text-align: center;
}

.itchen-service-area p {
	max-width: 640px;
	margin-inline: auto !important;
	color: var(--color-ink);
}

/* ---------- Final CTA ---------- */

.itchen-final-cta {
	background: var(--color-navy);
	max-width: 100%;
	text-align: center;
}

.itchen-final-cta p {
	color: #d7deea;
	margin-bottom: 1.5rem !important;
}

.itchen-final-cta-row {
	justify-content: center !important;
	align-items: center;
	flex-wrap: wrap !important;
	gap: 1.5rem;
}

.itchen-final-cta-row > .e-con {
	flex: 0 0 auto !important;
	width: max-content !important;
}

.itchen-final-cta-phone {
	color: var(--color-white);
	font-weight: 600;
	text-decoration: none;
}

.itchen-final-cta-phone:hover {
	color: var(--color-amber);
}

/* ==========================================================================
   Signature: the fanlight motif
   The logo is a semi-circular fanlight window with radiating glazing bars,
   framing the river-and-hills illustration. Carried onto the site as a
   recurring arch shape at major section transitions -- one motif, applied
   consistently, rather than several competing decorative devices.
   ========================================================================== */

.itchen-arch-divider {
	position: relative;
	height: 48px;
	margin-top: -48px;
	/* Elementor applies its own default 20px bottom margin to every
	   top-level widget/element, this divider included -- confirmed
	   2026-08-20 via computed styles (margin-bottom measured as 20px on
	   the live page despite this rule, and a real 20px gap between the
	   divider and the next section, not a sub-pixel rounding issue as
	   first assumed). It's invisible when the gap happens to sit on a
	   white background already (e.g. the bottom arch against the white
	   FAQ section above it) and glaring everywhere else (e.g. the top arch
	   against the hero photo) -- same bug, coincidentally hidden in one
	   spot. !important is required to actually beat Elementor's rule; a
	   plain override doesn't win. */
	margin-bottom: -2px !important;
	pointer-events: none;
	z-index: 2;
}

.itchen-arch-divider svg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

/* Left-aligned sitewide as of 2026-08-20 (was centred) -- client direction:
   every section eyebrow reads as a left-aligned label, matching the hero
   card's own treatment, not a centred caption floating above centred copy. */
.itchen-eyebrow {
	display: block;
	font-family: var(--font-body);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-amber-text);
	text-align: left;
	margin-bottom: 0.75rem;
}

.itchen-hero .itchen-eyebrow {
	color: var(--color-white);
	opacity: 0.85;
	text-align: left;
}

/* On a dark (navy) section, amber-text is too dark to read -- match the
   hero's white-eyebrow treatment (see .itchen-hero .itchen-eyebrow above). */
.itchen-benefits-dark .itchen-eyebrow {
	color: var(--color-white);
	opacity: 0.85;
}

/* Restrained, single page-load reveal -- respects reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
	.itchen-hero-inner > .e-con {
		opacity: 0;
		transform: translateY(14px);
		animation: itchen-fade-up 0.7s ease-out forwards;
	}
	.itchen-hero-inner > .e-con:nth-child(1) { animation-delay: 0.05s; }
	.itchen-hero-inner > .e-con:nth-child(2) { animation-delay: 0.15s; }
	.itchen-hero-inner > .e-con:nth-child(3) { animation-delay: 0.28s; }
	.itchen-hero-inner > .e-con:nth-child(4) { animation-delay: 0.4s; }
}

@keyframes itchen-fade-up {
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@media (max-width: 767px) {
	.itchen-hero-title {
		font-size: 2rem;
	}
	.itchen-section-title {
		font-size: 1.5rem;
	}
}

/* ==========================================================================
   Contact page -- Fluent Forms embed reskinned to match the site's tokens
   ========================================================================== */

.itchen-contact-row {
	gap: 3rem;
	align-items: flex-start;
	flex-wrap: wrap;
}

.itchen-contact-form-col {
	flex: 1 1 55%;
	min-width: 320px;
}

.itchen-contact-info-col {
	flex: 1 1 30%;
	min-width: 260px;
	background: var(--color-light);
	border-left: 4px solid var(--color-amber);
	padding: 2rem;
}

.itchen-contact-info-title {
	color: var(--color-navy);
	margin-bottom: 1rem !important;
}

.itchen-contact-info-body p {
	margin-bottom: 1rem !important;
	line-height: 1.6;
}

.itchen-contact-info-body strong {
	color: var(--color-navy);
	display: block;
	font-family: var(--font-body);
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	margin-bottom: 0.2rem;
}

.itchen-contact-info-body a {
	color: var(--color-ink);
	text-decoration: none;
}

.itchen-contact-info-body a:hover {
	color: var(--color-amber-deep);
}

.fluentform-widget-wrapper .ff-el-input--label label,
.fluentform-widget-wrapper label {
	color: var(--color-navy);
	font-family: var(--font-body);
	font-weight: 600;
}

.fluentform-widget-wrapper input:not([type="submit"]),
.fluentform-widget-wrapper select,
.fluentform-widget-wrapper textarea {
	border: 1px solid #d5dae2 !important;
	border-radius: 4px !important;
	font-family: var(--font-body);
}

.fluentform-widget-wrapper input:not([type="submit"]):focus,
.fluentform-widget-wrapper select:focus,
.fluentform-widget-wrapper textarea:focus {
	border-color: var(--color-amber) !important;
	box-shadow: 0 0 0 3px rgba(232, 160, 32, 0.18) !important;
}

/* Elementor auto-generates a per-page, per-widget rule for this button
   (".elementor-{page} .elementor-element.elementor-element-{id} ...
   .ff-btn-submit { background-color: ... !important }") that is 6
   class-selectors deep -- it varies by page/widget ID so it can't be
   targeted directly. The repeated class below is a deliberate,
   ID-independent specificity bump past it (7 class-selectors), not a
   typo -- see wordpress-elementor-gotchas.md before "simplifying" it. */
.fluentform-widget-wrapper .fluentform .frm-fluent-form .ff-el-group .ff-btn-submit.ff-btn-submit.ff-btn-submit {
	background-color: var(--color-amber) !important;
	border-color: var(--color-amber) !important;
	color: var(--color-navy-deep) !important;
	font-weight: 700 !important;
	border-radius: 4px !important;
}

.fluentform-widget-wrapper .fluentform .frm-fluent-form .ff-el-group .ff-btn-submit.ff-btn-submit.ff-btn-submit:hover {
	background-color: var(--color-amber-deep) !important;
	border-color: var(--color-amber-deep) !important;
}

@media (max-width: 767px) {
	.itchen-contact-row {
		flex-direction: column;
	}
}

/* ==========================================================================
   About page -- stats strip and story section
   ========================================================================== */

.itchen-stats-strip {
	background: var(--color-light);
	padding-block: 3rem !important;
}

.itchen-stats-row {
	flex-wrap: wrap;
	justify-content: space-around;
	gap: 2rem;
	text-align: center;
}

.itchen-stat-item {
	flex: 1 1 160px;
}

.itchen-stat-number {
	font-family: var(--font-display);
	font-size: 2.5rem;
	margin-bottom: 0.25rem !important;
}

/* color must reach .elementor-heading-title directly -- see the
   .itchen-final-cta-title comment further up for why the bare class alone
   doesn't work. */
.itchen-stat-number .elementor-heading-title {
	/* amber-deep is 2.8:1 on --color-light -- just under the 3:1 AA floor
	   even for this large (2.5rem) text. amber-text has enough margin. */
	color: var(--color-amber-text) !important;
}

.itchen-stat-label p {
	color: var(--color-ink);
	font-weight: 600;
	margin: 0 !important;
}

.itchen-story-row {
	gap: 3rem;
	align-items: center;
	flex-wrap: wrap;
}

.itchen-story-image-col,
.itchen-story-text-col {
	flex: 1 1 45%;
	min-width: 300px;
}

.itchen-story-image-col img {
	border-radius: 6px;
	width: 100%;
	height: auto;
	display: block;
}

.itchen-story-text-col p {
	line-height: 1.7;
	margin-bottom: 1rem !important;
}

.itchen-benefits-dark {
	background: var(--color-navy);
}

.itchen-benefits-dark .itchen-section-title .elementor-heading-title,
.itchen-benefits-dark .itchen-benefit-title .elementor-heading-title {
	color: var(--color-white) !important;
}

.itchen-benefits-dark .itchen-benefit-item p {
	color: #d7deea;
}

@media (max-width: 767px) {
	.itchen-story-row {
		flex-direction: column;
	}
}

/* ==========================================================================
   Projects / portfolio grid
   ========================================================================== */

.itchen-portfolio-row {
	flex-wrap: wrap;
	gap: 2rem;
	margin-bottom: 2rem;
}

.itchen-portfolio-card {
	flex: 1 1 calc(33.333% - 1.4rem);
	min-width: 280px;
}

.itchen-portfolio-card img {
	border-radius: 6px;
	width: 100%;
	height: 220px;
	object-fit: cover;
	display: block;
	margin-bottom: 1rem;
}

@media (max-width: 900px) {
	.itchen-portfolio-card {
		flex: 1 1 calc(50% - 1rem);
	}
}

@media (max-width: 600px) {
	.itchen-portfolio-card {
		flex: 1 1 100%;
	}
}

/* ==========================================================================
   Style sub-pages (Casement Windows, Composite Doors, etc.)
   ========================================================================== */

.itchen-breadcrumb-back {
	display: inline-block;
	color: var(--color-white);
	opacity: 0.8;
	font-size: 0.85rem;
	font-weight: 600;
	text-decoration: none;
	margin-bottom: 1rem;
}

.itchen-breadcrumb-back:hover {
	opacity: 1;
	color: var(--color-amber);
}

.itchen-style-intro {
	max-width: 760px;
}

.itchen-style-intro p {
	line-height: 1.8;
	font-size: 1.05rem;
	margin-bottom: 1.25rem !important;
}

/* Rebuilt 2026-08-19 as a full-width navy band -- was a plain light card
   with dot bullets, sitting flat between two other light/white sections
   with no visual rhythm. Echoes orion-windows.co.uk's navy icon-benefit
   strip, translated through Itchen's own navy/amber rather than copied. */
.itchen-supplier-section {
	max-width: 100%;
	background: var(--color-navy-deep);
	padding-block: 4.5rem !important;
}

.itchen-supplier-panel {
	max-width: var(--content-width);
	margin-inline: auto;
	padding-inline: 5vw;
	text-align: left;
}

/* Kept centred per client direction 2026-08-20 -- the rest of the panel
   (intro paragraph, facts list) stays left-aligned, only the
   eyebrow+heading pair here is the exception to the sitewide left-align
   pass. */
.itchen-supplier-section .itchen-eyebrow {
	color: var(--color-white);
	opacity: 0.85;
	text-align: center;
}

.itchen-supplier-title {
	margin-bottom: 0.75rem !important;
}

/* Same wrapper-vs-widget pattern as every other coloured heading on this
   site -- the class lands on the outer div, Elementor's own default wins
   on .elementor-heading-title unless reached directly. */
.itchen-supplier-title .elementor-heading-title {
	color: var(--color-white) !important;
}

.itchen-supplier-intro p {
	color: var(--color-white);
	opacity: 0.85;
	line-height: 1.7;
	margin: 0 auto 1.75rem !important;
	max-width: 640px;
}

.itchen-supplier-facts {
	list-style: none;
	margin: 0 auto;
	padding: 0;
	max-width: 760px;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1rem 2.5rem;
	text-align: left;
}

.itchen-supplier-facts li {
	position: relative;
	padding-left: 1.75rem;
	line-height: 1.5;
	color: var(--color-white);
}

.itchen-supplier-facts li::before {
	content: '\2713';
	position: absolute;
	left: 0;
	top: 0;
	color: var(--color-amber);
	font-weight: 700;
}

@media (max-width: 700px) {
	.itchen-supplier-facts {
		grid-template-columns: 1fr;
	}
}

/* ---------- Style-page image/content split sections ----------
   Pairs a real installation photo with a text column -- the piece the
   original generic template was missing entirely (no image widgets were
   ever placed in any of the 21 style sub-pages' bodies). Reusable across
   any style page, in either column order. */

.itchen-split-section {
	max-width: 100%;
}

.itchen-split-tint {
	background: var(--color-light);
}

.itchen-split-row {
	max-width: var(--content-width);
	margin-inline: auto !important;
	padding-inline: 5vw !important;
	align-items: center;
	gap: 3rem;
	flex-wrap: wrap !important;
}

.itchen-split-col {
	flex: 1 1 320px !important;
	min-width: 0;
}

.itchen-split-col .elementor-widget-image img {
	width: 100%;
	border-radius: 6px;
	box-shadow: 0 8px 30px rgba(28, 52, 97, 0.15);
	display: block;
}

.itchen-split-title {
	margin-bottom: 0.75rem !important;
}

.itchen-split-col p {
	color: var(--color-ink);
	line-height: 1.7;
}

.itchen-feature-list,
.itchen-finish-list {
	list-style: none;
	margin: 0.5rem 0 0;
	padding: 0;
}

.itchen-feature-list li {
	position: relative;
	padding-left: 1.5rem;
	line-height: 1.6;
	color: var(--color-ink);
	margin-bottom: 0.85rem;
}

.itchen-feature-list li::before {
	content: '';
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 8px;
	height: 8px;
	background: var(--color-glass);
	border-radius: 50%;
}

.itchen-finish-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.6rem 1.5rem;
}

.itchen-finish-list li {
	position: relative;
	padding-left: 1.5rem;
	line-height: 1.5;
	color: var(--color-ink);
}

.itchen-finish-list li::before {
	content: '\2713';
	position: absolute;
	left: 0;
	color: var(--color-amber-text);
	font-weight: 700;
}

.itchen-finish-note {
	margin-top: 1.1rem !important;
	font-size: 0.85rem !important;
	color: var(--color-ink);
	opacity: 0.75;
}

.itchen-finish-note a {
	color: var(--color-amber-text);
}

.itchen-specs-section {
	background: var(--color-light);
}

/* Alternating-band modifier (2026-08-20) -- used on the second of two
   adjacent itchen_specs_section() calls (e.g. Configs directly after
   Specs) so they don't render as two identical grey bands in a row. */
.itchen-specs-alt {
	background: transparent;
}

.itchen-specs-inner {
	max-width: 900px;
	margin: 0 auto;
	text-align: left;
}

/* Section titles left-aligned to match the now-left eyebrow above them
   (2026-08-20) -- scoped to these specific containers rather than the
   shared .itchen-section-title class itself, which is also used by
   homepage sections (How It Works, Repairs Callout) not part of this
   change. Supplier/System-Partner heading deliberately excluded -- client
   wants that one kept centred, the rest of the panel stays left. */
.itchen-specs-inner .itchen-section-title,
.itchen-faq-inner .itchen-section-title {
	text-align: left;
}

.itchen-supplier-title {
	text-align: center;
}

.itchen-spec-list {
	list-style: none;
	margin: 0.75rem 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.6rem 2.5rem;
}

.itchen-spec-list li {
	position: relative;
	padding-left: 1.5rem;
	line-height: 1.6;
	color: var(--color-ink);
}

.itchen-spec-list li::before {
	content: '\2713';
	position: absolute;
	left: 0;
	color: var(--color-amber-text);
	font-weight: 700;
}

@media (max-width: 700px) {
	.itchen-spec-list {
		grid-template-columns: 1fr;
	}
}

/* ---------- FAQ accordion (native <details>/<summary>, no JS) ---------- */

/* Alternating-band modifier (2026-08-20, same pattern as
   .itchen-specs-alt) -- used when FAQ needs to land on grey instead of its
   default transparent, so it doesn't repeat whatever band came right
   before it. Which one applies is computed per-page in the build loop,
   not fixed here. */
.itchen-faq-tint {
	background: var(--color-light);
}

.itchen-faq-inner {
	max-width: 900px;
	margin: 0 auto;
	text-align: left;
}

.itchen-faq-item {
	border-bottom: 1px solid rgba(20, 38, 69, 0.12);
	padding: 1rem 0;
}

.itchen-faq-item summary {
	cursor: pointer;
	list-style: none;
	font-family: var(--font-display);
	font-weight: 600;
	color: var(--color-navy);
	padding-right: 2rem;
	position: relative;
}

.itchen-faq-item summary::-webkit-details-marker {
	display: none;
}

.itchen-faq-item summary::after {
	content: '+';
	position: absolute;
	right: 0;
	top: 0;
	color: var(--color-amber-text);
	font-weight: 700;
	font-size: 1.2rem;
}

.itchen-faq-item[open] summary::after {
	content: '\2212';
}

.itchen-faq-item p {
	margin: 0.75rem 0 0;
	color: var(--color-ink);
	line-height: 1.6;
}

@media (max-width: 700px) {
	.itchen-split-row {
		gap: 1.75rem;
	}
	.itchen-finish-list {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   DESIGN V2 -- 2026-08-27
   Ported from design-explorations/homepage-concept.html and
   casement-windows-concept.html (itchen-ns), approved by the client as a
   static localhost concept before this port. Ground rules that keep this
   additive rather than a breaking rewrite of the system above:

   - New tokens use fresh custom-property names (--ink, --bronze, --radius,
     --shadow-*, etc.) -- never reusing --color-*/--font-*/--content-width,
     so pages still on the v1 system (everything not yet migrated) are
     completely unaffected.
   - New component classes reuse the concept files' own names verbatim
     (.hero, .svc-card, .megamenu, ...) -- none of them collide with the
     "itchen-" prefixed v1 classes above, checked directly against this
     file before writing a line of this block.
   - The only v1 selectors edited in place are the header/footer ones
     (.itchen-site-header, .itchen-header-*, .itchen-site-footer,
     .itchen-footer-*) -- those are global chrome shared by every page,
     v1 or v2, so the client's "same look everywhere" request for
     nav/footer/WhatsApp tab means editing them in place rather than
     forking a parallel set. Every *body* section below is new/additive.
   - Headings and body text inside v2 markup are hand-authored raw HTML
     (via text-editor widgets, not the heading widget) -- see
     wordpress-elementor-gotchas.md gotcha #13 (wpautop) for why, and
     functions.php for the matching remove_filter. That also means the
     usual ".foo .elementor-heading-title" wrapper-vs-widget dance isn't
     needed for v2 headings -- plain "h1,h2,h3" tag selectors reach them
     directly, same as the static concept files.
   ========================================================================== */

.ic-page {
	font-family: 'IBM Plex Sans', system-ui, sans-serif;
	font-size: 16px;
	line-height: 1.55;
	color: var(--ink);
	background: var(--paper);
	max-width: 100% !important;
}

.ic-page img { max-width: 100%; display: block; }
/* :not(.btn) -- otherwise this beats .btn-primary/.btn-ghost/.btn-ghost-dark's
   own explicit color on specificity (class+element beats a single class),
   so every button silently inherited whatever dark text color cascaded down
   instead of its own intended color -- confirmed via document.styleSheets
   rule matching, not guessed: on a bronze or --ink background this made
   button text unreadable. Plain inline links still want the old inherit
   behaviour, so only buttons are excluded. */
.ic-page a:not(.btn) { color: inherit; }
/* Same class of bug as the rule above, caught 2026-08-31 building the hub
   hero forms: a plugin's reset.css ships `[type="button"], [type="submit"],
   button { color: #cc3366; background: transparent; }` and theme.css ships
   `.page-content a { text-decoration: underline; }`, both loaded AFTER this
   stylesheet with specificity equal to (button) or higher than (link) a
   bare `.btn-primary`/`.btn-ghost-dark` single-class rule -- so any real
   <button> (e.g. .qf-submit) silently rendered pink/transparent instead of
   bronze, and any ghost link inside .page-content silently gained an
   underline. Confirmed via document.styleSheets rule matching against the
   live homepage's own pre-existing quote-card form, not just the new hub
   heroes -- this bug already existed sitewide, just never checked on a
   real <button> element before. Fixed by scoping to `.ic-page` (two
   classes beats both offending rules), following the same pattern as the
   rule above. */
.ic-page .btn { text-decoration: none; }
.ic-page .btn-primary { background: var(--bronze-dark); color: #fff; border-color: transparent; }
.ic-page .btn-primary:hover { background: #6f4a20; color: #fff; }
.ic-page .btn-ghost { border-color: var(--ink); color: var(--ink); background: transparent; }
.ic-page .btn-ghost:hover { background: var(--ink); color: #fff; }
.ic-page .btn-ghost-dark { border-color: #5a6870; color: #fff; background: transparent; }
.ic-page .btn-ghost-dark:hover { background: #fff; color: var(--ink); }
/* Every v2 section is one Elementor container holding a single text-editor
   widget whose "editor" setting is hand-authored raw HTML (see note above).
   Elementor's own frontend CSS sets position:relative on that widget's
   wrapper div, which silently becomes the containing block for any
   position:absolute full-bleed element inside the raw HTML (e.g. .hero-bg)
   -- sizing it to the widget wrapper's own content footprint instead of the
   outer .ic-page section it's meant to fill edge-to-edge. The static concept
   files have no such wrapper at all, so this only shows up once ported.
   Neutralize it so absolutely-positioned children size against .ic-page's
   own positioned ancestor (.hero, .anatomy, etc.) as intended. */
.ic-page > .elementor-widget-text-editor { position: static; }
.ic-page h1, .ic-page h2, .ic-page h3 {
	font-family: 'Space Grotesk', system-ui, sans-serif;
	margin: 0;
	letter-spacing: -0.01em;
	/* Explicit -- on the Elementor dev site this fell back to Hello
	   Elementor's own reset.css (`h1..h6 { color: inherit }`, loaded after
	   this stylesheet), silently overriding the legacy v1 `color:
	   var(--color-navy)` rule above with no dependency on it ever written
	   down anywhere in this project's own CSS. Standalone (no Elementor)
	   has no such reset, so v2 headings rendered navy until this was
	   found and set explicitly. Never rely on a plugin's own reset.css to
	   supply a color a design actually depends on -- own it here instead. */
	color: var(--ink);
}
.mono { font-family: 'IBM Plex Mono', monospace; }
.ic-wrap { max-width: var(--v2-max); margin: 0 auto; padding: 0 32px; }
.ic-wrap-wide { max-width: 1400px; }
.ic-section { padding: 88px 0; }
.ic-section.tight { padding: 56px 0; }
.ic-band-line { border-top: 1px solid var(--line); }
.paper-bg { background: var(--paper); }
.panel-bg { background: var(--panel); }

.section-tag {
	font-family: 'IBM Plex Mono', monospace;
	font-size: 12.5px;
	letter-spacing: 0.02em;
	color: var(--bronze-dark);
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 14px;
}
.section-tag::after { content: ""; flex: 0 0 40px; height: 1px; background: var(--line); }
.section-tag.on-dark { color: #d9b98a; }
.section-tag.on-dark::after { background: #3a4750; }
.section-h { font-size: clamp(26px, 2.6vw, 34px); margin-bottom: 14px; max-width: 26ch; }
.section-sub { color: var(--slate); max-width: 60ch; font-size: 16px; margin-bottom: 44px; }

.btn {
	font-family: 'IBM Plex Sans'; font-weight: 600; font-size: 14.5px;
	padding: 11px 20px; border-radius: var(--v2-radius-btn); text-decoration: none;
	display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
	border: 1px solid transparent; cursor: pointer;
	transition: background .18s ease, box-shadow .18s ease, transform .18s ease;
}
.btn-primary { background: var(--bronze-dark); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: #6f4a20; box-shadow: var(--shadow-md); transform: translateY(-1px); color: #fff; }
.btn-ghost { border-color: var(--ink); color: var(--ink); background: transparent; }
.btn-ghost:hover { background: var(--ink); color: #fff; transform: translateY(-1px); }
.btn-ghost-dark { border-color: #5a6870; color: #fff; background: transparent; }
.btn-ghost-dark:hover { background: #fff; color: var(--ink); transform: translateY(-1px); }

:focus-visible { outline: 2px solid var(--bronze); outline-offset: 3px; }

/* ---------- header (edited in place -- shared chrome, every page) ---------- */

.itchen-site-header {
	position: sticky; top: 0; z-index: 999;
	background: rgba(250, 248, 244, 0.92) !important;
	backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
	border-bottom: 1px solid var(--line);
	font-family: 'IBM Plex Sans', system-ui, sans-serif;
	max-width: 100% !important;
}
.itchen-site-header .itchen-header-row.e-con.e-flex { display: block !important; padding: 0 !important; }

.nav-row {
	display: flex; align-items: center; justify-content: space-between; flex-wrap: nowrap; gap: 16px;
	padding: 14px 28px; max-width: var(--v2-max); margin: 0 auto;
}
.brand { display: flex; align-items: center; gap: 8px; font-family: 'Space Grotesk'; font-weight: 700; font-size: 17px; text-decoration: none; color: var(--ink); white-space: nowrap; flex: 0 0 auto; }
.brand img { width: 36px; height: 36px; object-fit: contain; flex: 0 0 auto; }
nav.primary { display: flex; gap: 0; align-items: center; flex-wrap: nowrap; }
nav.primary > a { font-size: 13.5px; font-weight: 500; text-decoration: none; color: var(--ink-soft); padding: 8px 9px; border-bottom: 1px solid transparent; white-space: nowrap; }
nav.primary > a:hover { color: var(--ink); border-color: var(--bronze); }

.nav-item { position: relative; flex: 0 0 auto; }
/* Hello Elementor's base stylesheet applies a default pink (#cc3366)
   background to bare <button> elements on hover/focus (confirmed via
   getComputedStyle -- not something this theme sets anywhere). !important
   on every interactive state is required since load order alone isn't
   reliable against a UA/parent-theme default here. */
.nav-link, .nav-link:hover, .nav-link:focus, .nav-item:hover .nav-link, .nav-item:focus-within .nav-link, .nav-item:focus .nav-link {
	background: none !important;
}
.nav-link { display: flex; align-items: center; gap: 4px; white-space: nowrap; font-size: 13.5px; font-weight: 500; color: var(--ink-soft); padding: 8px 9px; border: none; cursor: pointer; font-family: 'IBM Plex Sans'; }
.nav-link .caret { width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); margin-top: -3px; transition: transform .15s ease; }
.nav-item:hover .nav-link, .nav-item:focus-within .nav-link { color: var(--ink); }
.nav-item:hover .caret, .nav-item:focus-within .caret { transform: rotate(-135deg); margin-top: 2px; }

.megamenu {
	position: absolute; top: 100%; left: 50%; transform: translate(-50%, 8px);
	width: 640px; max-width: 90vw;
	background: #fff; border-radius: var(--v2-radius); box-shadow: var(--shadow-lg);
	padding: 24px;
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity .16s ease, transform .16s ease, visibility .16s;
	z-index: 60;
}
.nav-item:hover .megamenu, .nav-item:focus-within .megamenu { opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 0); }
.mega-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: 28px; }
.mega-featured { display: flex; flex-direction: column; gap: 12px; }
.mega-tile { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ink); padding: 6px; border-radius: var(--v2-radius-btn); transition: background .15s ease; }
.mega-tile:hover { background: var(--panel); }
.mega-tile img { width: 64px; height: 48px; object-fit: cover; border-radius: 8px; flex: 0 0 auto; }
.mega-tile span { font-size: 13.5px; font-weight: 600; }
.mega-tile.mega-tile--all { color: var(--bronze-dark); font-family: 'IBM Plex Mono'; font-size: 12.5px; padding-left: 6px; }
.mega-col h4 { font-family: 'IBM Plex Mono'; font-size: 11.5px; color: var(--slate); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 12px; font-weight: 500; }
.mega-col { display: flex; flex-direction: column; }
.mega-col a { font-size: 13.5px; color: var(--ink-soft); text-decoration: none; padding: 5px 0; }
.mega-col a:hover { color: var(--bronze-dark); }
.mega-foot { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.mega-foot p { margin: 0; font-size: 13px; color: var(--slate); }

.header-right { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; }
.phone { font-family: 'IBM Plex Mono'; font-size: 14px; text-decoration: none; color: var(--ink); white-space: nowrap; }
/* Hello Elementor's reset (the "hello-elementor" stylesheet handle -- see
   wordpress-elementor-gotchas.md load-order section) strips border and
   background off form controls with !important, confirmed via
   getComputedStyle showing border-width:0 and the spans' background
   resolving to transparent despite the rules below. Every property it
   resets needs matching !important here to actually win. */
.nav-toggle, .nav-toggle:hover, .nav-toggle:focus {
	background: transparent !important;
	border: 1px solid var(--line) !important;
}
.nav-toggle { display: none; flex-direction: column; justify-content: center; gap: 5px; width: 38px; height: 38px; border-radius: var(--v2-radius-btn); cursor: pointer; padding: 0; }
.nav-toggle span { display: block; width: 16px; height: 1.5px; background: var(--ink) !important; margin: 0 auto; transition: transform .2s ease, opacity .2s ease; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
.mobile-nav { display: none; flex-direction: column; border-top: 1px solid var(--line); background: var(--paper); }
.mobile-nav.open { display: flex; }
.mobile-nav a { padding: 16px 32px; font-size: 15px; font-weight: 500; text-decoration: none; color: var(--ink); border-bottom: 1px solid var(--line); }
.mobile-nav .mobile-phone { font-family: 'IBM Plex Mono'; color: var(--bronze-dark); }

.whatsapp-float {
	position: fixed; right: 0; top: 50%; transform: translateY(-50%) translateX(4px);
	width: 56px; height: 64px; border-radius: 14px 0 0 14px;
	background: #25D366; box-shadow: var(--shadow-md);
	display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
	text-decoration: none; z-index: 70;
	opacity: 0; pointer-events: none;
	transition: opacity .25s ease, transform .25s ease;
}
.whatsapp-float.show { opacity: 1; pointer-events: auto; transform: translateY(-50%) translateX(0); }
.whatsapp-float:hover, .whatsapp-float.show:hover { transform: translateY(-50%) translateX(-3px); box-shadow: var(--shadow-hover); }
.whatsapp-float svg { width: 24px; height: 24px; flex: 0 0 auto; }
.whatsapp-float span { font-family: 'IBM Plex Mono'; font-size: 9px; color: #fff; letter-spacing: 0.02em; }

@media (max-width: 980px) {
	nav.primary { display: none; }
	.nav-toggle { display: flex; }
}
@media (max-width: 640px) {
	.ic-wrap { padding: 0 20px; }
	.nav-row { padding: 10px 16px; gap: 8px; }
	.header-right .phone { display: none; }
	.header-right .btn-primary { display: none; }
	.header-right { gap: 10px; }
	.brand { font-size: 16px; gap: 8px; }
	.brand img { width: 30px; height: 30px; }
	.nav-toggle { width: 44px; height: 44px; flex: 0 0 auto; }
	.mobile-nav a { padding: 14px 16px; }
	.whatsapp-float { width: 46px; height: 56px; border-radius: 12px 0 0 12px; }
	.whatsapp-float svg { width: 21px; height: 21px; }
	.whatsapp-float span { display: none; }
}
@media (prefers-reduced-motion: reduce) {
	.whatsapp-float { transition: opacity .01ms; }
	.anatomy-row { opacity: 1; }
	html { scroll-behavior: auto; }
}

/* ---------- footer (edited in place -- shared chrome, every page) ---------- */

/* Selector is footer#colophon, not .itchen-site-footer: the v2 footer
   rebuild (post 391) is a single bare text-editor widget with no outer
   Elementor container to hang a css_classes setting on, so
   .itchen-site-footer never matched any element in the live DOM -- this
   whole block (including the top padding) was dead code, confirmed via
   document.querySelector('.itchen-site-footer') returning null on the
   live page. #colophon is Hello Elementor's own stable footer landmark
   ID, always present. */
footer#colophon {
	background: var(--paper) !important; color: var(--ink);
	border-top: 1px solid var(--line);
	padding: 64px 5vw 32px !important;
	font-family: 'IBM Plex Sans', system-ui, sans-serif;
	max-width: 100% !important;
}
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 48px; max-width: var(--v2-max); margin-inline: auto; }
.foot-grid h4 { font-family: 'Space Grotesk'; font-size: 14px; margin-bottom: 16px; color: var(--ink); }
.foot-grid ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.foot-grid a { text-decoration: none; color: var(--slate); font-size: 14px; }
.foot-grid a:hover { color: var(--bronze-dark); }
.foot-bottom { border-top: 1px solid var(--line); padding-top: 24px; display: flex; justify-content: space-between; font-size: 13px; color: var(--slate); flex-wrap: wrap; gap: 8px; max-width: var(--v2-max); margin-inline: auto; }
@media (max-width: 980px) { .foot-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .foot-grid { grid-template-columns: 1fr; } }

/* ---------- hero ---------- */

.hero { position: relative; overflow: hidden; padding: 80px 0 72px; min-height: 680px; display: flex; align-items: center; color: #fff; }
.hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.hero::after { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(100deg, rgba(8, 11, 14, 0.94) 0%, rgba(8, 11, 14, 0.90) 48%, rgba(8, 11, 14, 0.55) 64%, rgba(8, 11, 14, 0.15) 86%); }
.hero .ic-wrap { position: relative; z-index: 2; width: 100%; }
.hero-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 64px; align-items: center; }
.chip { display: inline-flex; align-items: center; gap: 8px; font-family: 'IBM Plex Mono'; font-size: 12.5px; color: #f0ede6; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.28); backdrop-filter: blur(6px); padding: 6px 12px; border-radius: 99px; margin-bottom: 22px; }
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: #6bcf8f; flex: 0 0 auto; }
.hero h1 { font-size: clamp(36px, 4.6vw, 58px); font-weight: 700; line-height: 1.04; letter-spacing: -0.02em; color: #fff; margin-bottom: 22px; text-shadow: 0 2px 20px rgba(0, 0, 0, 0.4); }
.hero-copy { font-size: 17px; color: #e6e2d9; max-width: 46ch; margin-bottom: 32px; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35); }
.hero-ctas { display: flex; gap: 14px; margin-bottom: 44px; flex-wrap: wrap; }
.hero-ctas .btn { padding: 14px 24px; font-size: 15px; }
.hero-ctas .btn-ghost { border-color: rgba(255, 255, 255, 0.65); color: #fff; }
.hero-ctas .btn-ghost:hover { background: #fff; color: var(--ink); }
.spec-strip { display: flex; gap: 0; border-top: 1px solid rgba(255, 255, 255, 0.25); padding-top: 26px; flex-wrap: wrap; }
.spec-item { flex: 1; min-width: 110px; padding-right: 18px; }
.spec-item + .spec-item { border-left: 1px solid rgba(255, 255, 255, 0.25); padding-left: 18px; }
.spec-num { font-family: 'Space Grotesk'; font-weight: 700; font-size: 32px; letter-spacing: -0.02em; color: #fff; display: block; text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35); }
.spec-label { font-size: 12.5px; color: #d8d3c8; margin-top: 4px; }
.hero-visual { position: relative; }
.quote-card { background: #fff; border-radius: var(--v2-radius); box-shadow: var(--shadow-lg); padding: 32px 30px; display: flex; flex-direction: column; gap: 14px; color: var(--ink); }
.quote-card h2 { font-size: 21px; color: var(--ink); }
.quote-card-sub { margin: -8px 0 6px; font-size: 13.5px; color: var(--slate); }
.qf-field { display: flex; flex-direction: column; gap: 6px; }
.qf-field span { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.qf-field input, .qf-field select { font-family: 'IBM Plex Sans'; font-size: 15px; color: var(--ink); padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--v2-radius-btn); background: var(--paper); transition: border-color .15s ease, box-shadow .15s ease; width: 100%; box-sizing: border-box; }
.qf-field input:focus, .qf-field select:focus { outline: none; border-color: var(--bronze); box-shadow: 0 0 0 3px rgba(181, 121, 58, 0.16); }
.qf-submit { justify-content: center; margin-top: 6px; font-size: 15px; padding: 13px 20px; width: 100%; }

@media (max-width: 980px) {
	.hero { min-height: 0; padding: 56px 0 48px; }
	.hero::after { background: linear-gradient(180deg, rgba(8, 11, 14, 0.86) 0%, rgba(8, 11, 14, 0.88) 55%, rgba(8, 11, 14, 0.94) 100%); }
	.hero-grid { grid-template-columns: 1fr; gap: 32px; }
	.quote-card { padding: 26px 22px; }
}
@media (max-width: 640px) {
	.spec-strip { gap: 16px; }
	.spec-item { min-width: 44%; border-left: none !important; padding-left: 0 !important; }
}

/* ---------- services grid ---------- */

.services-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px; }
.svc-card { border-radius: var(--v2-radius); background: #fff; overflow: hidden; display: flex; flex-direction: column; text-decoration: none; color: var(--ink); box-shadow: var(--shadow-sm); transition: box-shadow .28s ease, transform .28s ease; position: relative; }
.svc-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-5px); }
.svc-card .thumb { position: relative; aspect-ratio: 16/10; overflow: hidden; background: var(--panel); }
.svc-card .thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.svc-card:hover .thumb img { transform: scale(1.05); }
.svc-card.repairs .thumb { display: flex; align-items: center; justify-content: center; background: var(--ink); }
.svc-body { padding: 22px 24px 26px; }
.svc-num { font-family: 'IBM Plex Mono'; font-size: 12px; color: var(--bronze-dark); display: block; margin-bottom: 8px; }
.svc-card h3 { font-size: 19px; margin-bottom: 8px; color: var(--ink); }
.svc-card p { font-size: 14.5px; color: var(--slate); margin: 0 0 12px; }
.svc-link { font-family: 'IBM Plex Mono'; font-size: 12.5px; color: var(--bronze-dark); }
.svc-card.featured { grid-column: span 3; grid-row: span 2; }
.svc-card.featured .thumb { position: relative; flex: 1; aspect-ratio: unset; }
.svc-card.featured .svc-overlay { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; padding: 30px 28px 28px; background: linear-gradient(180deg, transparent, rgba(16, 24, 31, 0.1) 40%, rgba(11, 16, 20, 0.88) 100%); color: #fff; }
.svc-card.featured .svc-num { color: #e7c493; }
.svc-card.featured .svc-overlay h3 { color: #fff; font-size: 26px; margin-bottom: 10px; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35); }
.svc-card.featured .svc-overlay p { color: #d9dee1; max-width: 38ch; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.3); }
.svc-card.featured .svc-overlay .svc-link { color: #e7c493; }

@media (max-width: 980px) {
	.services-grid { grid-template-columns: repeat(2, 1fr); }
	.svc-card.featured { grid-column: span 2; }
}
@media (max-width: 640px) {
	.services-grid { grid-template-columns: 1fr; }
	.svc-card.featured { grid-column: span 1; }
	.svc-card.featured .thumb { flex: none; aspect-ratio: 16/11; }
}

/* ---------- anatomy / behind-the-glass (signature scroll element) ---------- */

.anatomy { background: var(--ink); color: #fff; padding: 112px 0; overflow-x: hidden; }
.anatomy .section-sub { color: #a9b6bd; }
.anatomy h2 { color: #fff; }
.anatomy-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.explode-stage { position: relative; width: 100%; max-width: 300px; aspect-ratio: 1/1.15; margin: 0 auto; }
.ex-part-wrap { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) translate(var(--ex-x, 0px), var(--ex-y, 0px)) rotate(var(--ex-r, 0deg)) scale(var(--ex-s, 1)); }
.ex-part-wrap[data-part="frame"] { width: 64%; z-index: 1; }
.ex-part-wrap[data-part="sash"] { width: 52%; z-index: 2; }
.ex-part-wrap[data-part="glazing"] { width: 38%; z-index: 3; }
.ex-part-wrap[data-part="hardware"] { width: 20%; z-index: 4; }
.ex-part { width: 100%; display: block; filter: drop-shadow(0 24px 34px rgba(0, 0, 0, 0.5)); }
.ex-tag { position: absolute; top: 4%; left: 4%; width: 22px; height: 22px; border-radius: 50%; background: var(--bronze-dark); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 500; border: 1.5px solid rgba(255, 255, 255, 0.55); box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); }
.anatomy-list { display: flex; flex-direction: column; gap: 0; }
.anatomy-row { display: flex; gap: 16px; padding: 18px 0; border-top: 1px solid #263038; align-items: baseline; opacity: 0.8; transition: opacity .4s ease; }
.anatomy-row.in { opacity: 1; }
.anatomy-row:last-child { border-bottom: 1px solid #263038; }
.anatomy-row .tag { font-family: 'IBM Plex Mono'; font-size: 12px; color: var(--bronze); width: 26px; flex: 0 0 auto; }
.anatomy-row h4 { font-family: 'Space Grotesk'; font-size: 16px; font-weight: 600; margin: 0 0 4px; color: #fff; }
.anatomy-row p { margin: 0; font-size: 14px; color: #a9b6bd; }
@media (max-width: 980px) { .anatomy-grid { grid-template-columns: 1fr; gap: 36px; } }

/* ---------- process rail ---------- */

.process-rail { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; position: relative; }
.process-rail::before { content: ""; position: absolute; top: 15px; left: 0; right: 0; height: 1px; background: var(--line); }
.process-step { padding-right: 24px; position: relative; }
.step-num { font-family: 'IBM Plex Mono'; font-size: 13px; color: #fff; background: var(--ink); width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; z-index: 1; margin-bottom: 20px; }
.process-step h3 { font-size: 17px; margin-bottom: 8px; color: var(--ink); }
.process-step p { font-size: 14px; color: var(--slate); margin: 0; }
@media (max-width: 980px) { .process-rail { grid-template-columns: 1fr 1fr; row-gap: 32px; } .process-rail::before { display: none; } }

/* ---------- recent work ---------- */

.work-head { margin-bottom: 40px; }
.work-head .section-h { max-width: none; margin-bottom: 0; }
.work-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.work-item { position: relative; border-radius: var(--v2-radius); overflow: hidden; box-shadow: var(--shadow-sm); transition: box-shadow .28s ease, transform .28s ease; }
.work-item:hover { box-shadow: var(--shadow-hover); transform: translateY(-5px); }
.work-item img { width: 100%; height: 300px; object-fit: cover; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.work-item:hover img { transform: scale(1.05); }
.work-cap { position: absolute; left: 0; right: 0; bottom: 0; background: linear-gradient(180deg, transparent, rgba(16, 24, 31, 0.82) 70%); color: #fff; padding: 16px; font-size: 13.5px; font-family: 'IBM Plex Mono'; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.35); }
@media (max-width: 980px) { .work-grid { grid-template-columns: 1fr; } .work-item img { height: 220px; } }

/* ---------- repair CTA band ---------- */

.repair-band { background: var(--panel); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
/* Homepage-only override so this one repair-band instance can sit on
   paper instead of panel to keep the section-background alternation
   going -- other pages' repair-band (e.g. the Windows hub) keep the
   default panel background. Two classes beats one, so this wins over
   .repair-band regardless of source order. */
.repair-band.repair-band-paper { background: var(--paper); }
.repair-grid { display: grid; grid-template-columns: auto 1fr auto; gap: 36px; align-items: center; }
.repair-icon { width: 64px; height: 64px; flex: 0 0 auto; }
.repair-grid h3 { font-size: 22px; margin-bottom: 8px; color: var(--ink); }
.repair-grid p { margin: 0; color: var(--ink-soft); font-size: 15px; max-width: 58ch; }
@media (max-width: 980px) { .repair-grid { grid-template-columns: 1fr; text-align: left; } }

/* ---------- where we work ---------- */

.areas { display: flex; flex-wrap: wrap; gap: 10px; }
.area-pill { font-family: 'IBM Plex Mono'; font-size: 13px; border: 1px solid var(--line); padding: 8px 14px; border-radius: 99px; color: var(--ink-soft); display: inline-block; }

/* ---------- final CTA ---------- */

.final-cta { background: var(--ink); color: #fff; text-align: left; }
.final-cta .ic-wrap { display: flex; justify-content: space-between; align-items: center; gap: 40px; flex-wrap: wrap; }
.final-cta h2 { color: #fff; font-size: clamp(24px, 3vw, 32px); margin-bottom: 10px; }
.final-cta p { color: #a9b6bd; margin: 0; font-size: 15px; }
.final-actions { display: flex; gap: 14px; flex-wrap: wrap; }
@media (max-width: 640px) { .final-cta .ic-wrap { flex-direction: column; align-items: flex-start; } }

/* ---------- breadcrumb (product/hub sub-pages) ---------- */

.v2-breadcrumb { border-bottom: 1px solid var(--line); background: var(--panel); padding: 14px 0; }
.v2-breadcrumb a { font-family: 'IBM Plex Mono'; font-size: 12.5px; color: var(--ink-soft); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
.v2-breadcrumb a:hover { color: var(--bronze-dark); }
.v2-breadcrumb a::before { content: "←"; }

/* ---------- product page hero ---------- */

.p-hero { padding: 64px 0 88px; }
.p-hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 64px; align-items: center; }
.p-hero h1 { font-size: clamp(34px, 4.2vw, 50px); line-height: 1.05; margin-bottom: 18px; color: var(--ink); }
.p-hero-sub { font-size: 17.5px; color: var(--ink-soft); max-width: 50ch; margin-bottom: 28px; }
.p-feature-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 32px; list-style: none; padding: 0; }
.p-feature-list li { display: flex; align-items: center; gap: 12px; font-size: 15px; color: var(--ink-soft); }
.p-feature-list .tick { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; background: var(--glass-100); color: var(--bronze-dark); display: flex; align-items: center; justify-content: center; font-size: 12px; }
.p-hero-photo { position: relative; border-radius: var(--v2-radius); overflow: hidden; box-shadow: var(--shadow-lg); }
.p-hero-photo img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/5; }
.p-hero-photo .cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 20px; background: linear-gradient(180deg, transparent, rgba(16, 24, 31, 0.78) 85%); color: #fff; font-family: 'IBM Plex Mono'; font-size: 12px; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.35); }
@media (max-width: 980px) { .p-hero-grid { grid-template-columns: 1fr; gap: 32px; } .p-hero-photo img { aspect-ratio: 16/10; } }

/* ---------- hub hero (new, 2026-08-31) ----------
   Full-bleed photo hero for the 4 category hub pages, replacing .p-hero
   as their opening section -- same visual language as the homepage's
   .hero (full-bleed image, dark gradient, two-column grid) but under
   its own class so it doesn't inherit .hero's `overflow: hidden`, which
   would clip the .style-cta dropdown below. Reuses .hero-visual /
   .quote-card / .qf-field / .qf-submit as-is (already generic, not
   scoped to .hero). Per-page background crop (object-position) is set
   inline on each page's <img class="hub-hero-bg">, same convention the
   homepage hero already uses for its own inline positioning styles. */

.hub-hero { position: relative; padding: 80px 0 72px; min-height: 660px; display: flex; align-items: center; color: #fff; }
.hub-hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.hub-hero::after { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(100deg, rgba(8, 11, 14, 0.94) 0%, rgba(8, 11, 14, 0.90) 48%, rgba(8, 11, 14, 0.55) 64%, rgba(8, 11, 14, 0.15) 86%); }
.hub-hero .ic-wrap { position: relative; z-index: 2; width: 100%; }
.hub-hero-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 64px; align-items: center; }
.hub-hero-eyebrow { font-family: 'IBM Plex Mono'; font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase; color: #d9b98a; display: block; margin-bottom: 14px; }
.hub-hero h1 { font-size: clamp(32px, 4.4vw, 50px); font-weight: 700; line-height: 1.05; letter-spacing: -0.02em; color: #fff; margin-bottom: 16px; max-width: 16ch; text-shadow: 0 2px 20px rgba(0, 0, 0, 0.4); }
.hub-hero-sub { font-size: 16.5px; color: #e6e2d9; max-width: 50ch; margin-bottom: 22px; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35); }
.hub-hero-ticks { display: flex; flex-direction: column; gap: 10px; list-style: none; padding: 0; margin: 0 0 30px; }
.hub-hero-ticks li { display: flex; align-items: center; gap: 12px; font-size: 14.5px; color: #e6e2d9; text-shadow: 0 1px 10px rgba(0, 0, 0, 0.3); }
.hub-hero-ticks .tick { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%; background: rgba(255, 255, 255, 0.14); color: #d9b98a; display: flex; align-items: center; justify-content: center; font-size: 11px; }
.hub-hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.hub-hero-ctas .btn { padding: 14px 22px; font-size: 15px; }

/* ---------- style dropdown CTA (new, 2026-08-31) ----------
   A single-button dropdown of style links, reusing the megamenu's
   hover/focus-within reveal pattern but scoped to one trigger instead
   of the nav bar. Deliberately NOT nested inside anything with
   `overflow: hidden` (see .hub-hero comment above). */

.style-cta { position: relative; }
.style-cta-trigger .caret { width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); margin-top: -2px; transition: transform .15s ease; }
.style-cta:hover .style-cta-trigger .caret, .style-cta:focus-within .style-cta-trigger .caret { transform: rotate(-135deg); margin-top: 2px; }
.style-cta-panel { position: absolute; top: calc(100% + 10px); left: 0; width: 300px; max-width: 86vw; max-height: 70vh; overflow-y: auto; background: #fff; border-radius: var(--v2-radius); box-shadow: var(--shadow-lg); padding: 10px; opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(6px); transition: opacity .16s ease, transform .16s ease, visibility .16s; z-index: 20; }
.style-cta:hover .style-cta-panel, .style-cta:focus-within .style-cta-panel { opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0); }
.style-cta-panel a { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; border-radius: 8px; text-decoration: none; color: var(--ink); font-size: 14.5px; font-weight: 500; }
.style-cta-panel a:hover { background: var(--panel); color: var(--bronze-dark); }
.style-cta-panel a .arrow { color: var(--slate); font-size: 13px; }
.style-cta-panel a:hover .arrow { color: var(--bronze-dark); }
.style-cta-panel a.style-cta-all { margin-top: 4px; padding-top: 14px; border-top: 1px solid var(--line); color: var(--bronze-dark); font-family: 'IBM Plex Mono'; font-size: 12.5px; font-weight: 500; border-radius: 0; justify-content: flex-start; gap: 8px; }

@media (max-width: 980px) {
	.hub-hero-grid { grid-template-columns: 1fr; gap: 32px; }
}
@media (max-width: 640px) {
	.hub-hero { min-height: 0; padding: 56px 0 48px; }
	.hub-hero::after { background: linear-gradient(180deg, rgba(8, 11, 14, 0.86) 0%, rgba(8, 11, 14, 0.88) 55%, rgba(8, 11, 14, 0.94) 100%); }
}

/* ---------- intro / trust split ---------- */

.intro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
.intro-copy p { color: var(--ink-soft); font-size: 15.5px; margin: 0 0 16px; }
.intro-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.intro-photos img { border-radius: var(--v2-radius); box-shadow: var(--shadow-sm); aspect-ratio: 3/4; object-fit: cover; }
.intro-photos figure { margin: 0; }
.intro-photos figcaption { font-family: 'IBM Plex Mono'; font-size: 11px; color: var(--slate); margin-top: 8px; }
@media (max-width: 980px) { .intro-grid { grid-template-columns: 1fr; gap: 32px; } }
@media (max-width: 640px) { .intro-photos { grid-template-columns: 1fr; } }

/* ---------- benefits grid (product pages) ---------- */

.benefits-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.benefit-card { background: #fff; border-radius: var(--v2-radius); box-shadow: var(--shadow-sm); padding: 26px 24px; transition: box-shadow .28s ease, transform .28s ease; }
.benefit-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-5px); }
.benefit-num { font-family: 'IBM Plex Mono'; font-size: 12px; color: var(--bronze-dark); display: block; margin-bottom: 14px; }
.benefit-icon { width: 36px; height: 36px; margin-bottom: 14px; color: var(--bronze-dark); }
.benefit-card h3 { font-size: 17px; margin-bottom: 8px; color: var(--ink); }
.benefit-card p { font-size: 14px; color: var(--slate); margin: 0; }
@media (max-width: 980px) { .benefits-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .benefits-grid { grid-template-columns: 1fr; } }

/* ---------- system-partner panel ---------- */

.partner-panel { background: var(--ink); color: #fff; border-radius: var(--v2-radius); padding: 48px; display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.partner-panel h3 { color: #fff; font-size: 24px; margin-bottom: 12px; }
.partner-panel > div:first-child p { color: #a9b6bd; font-size: 15px; margin: 0; }
.partner-points { display: flex; flex-direction: column; gap: 0; list-style: none; margin: 0; padding: 0; }
.partner-points li { display: flex; gap: 14px; padding: 14px 0; border-top: 1px solid #263038; font-size: 14px; color: #d3d9dc; align-items: baseline; }
.partner-points li:last-child { border-bottom: 1px solid #263038; }
.partner-points .tag { font-family: 'IBM Plex Mono'; font-size: 12px; color: var(--bronze); flex: 0 0 auto; width: 20px; }
@media (max-width: 980px) { .partner-panel { grid-template-columns: 1fr; padding: 32px; gap: 24px; } }

/* ---------- product spec list ---------- */

.spec-list { display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px; margin: 0; }
.spec-row { display: flex; justify-content: space-between; gap: 20px; padding: 16px 0; border-top: 1px solid var(--line); }
.spec-row dt { font-family: 'IBM Plex Mono'; font-size: 13px; color: var(--slate); flex: 0 0 auto; }
.spec-row dd { margin: 0; font-size: 14.5px; color: var(--ink); text-align: right; max-width: 30ch; }
.spec-source { margin-top: 24px; font-size: 12.5px; color: var(--slate); }
.spec-source a { color: var(--bronze-dark); }
@media (max-width: 980px) { .spec-list { grid-template-columns: 1fr; } }

/* ---------- material toggle (uPVC / Aluminium dual-material pages) ---------- */
/* CSS-only tabs, same no-JS-dependency approach as the FAQ <details> accordions. */

.material-tabs { display: flex; gap: 10px; margin-bottom: 40px; }
.material-tabs input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.material-tab { font-family: 'IBM Plex Mono'; font-size: 13.5px; font-weight: 500; padding: 11px 26px; border-radius: 99px; border: 1px solid var(--line); background: #fff; color: var(--ink-soft); cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.material-tabs input[type="radio"]:checked + .material-tab { background: var(--bronze-dark); color: #fff; border-color: var(--bronze-dark); }
.material-tabs input[type="radio"]:focus-visible + .material-tab { outline: 2px solid var(--bronze-dark); outline-offset: 2px; }
.material-panel { display: none; }
.material-toggle-wrap:has(#mat-upvc:checked) .material-panel-upvc { display: block; }
.material-toggle-wrap:has(#mat-alu:checked) .material-panel-alu { display: block; }

/* Text (heading, tabs, copy) left / photo right. The photo column holds one
   <figure class="material-panel material-panel-upvc|alu"> per material -- the
   :has() toggle rules above already match them wherever they're nested, so
   showing/hiding the right-hand photo in sync with the left-hand copy needs
   no extra rule, just the same classes. */
.material-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
.material-photo { position: relative; }
.material-photo .material-panel { margin: 0; }
.material-photo img { width: 100%; border-radius: var(--v2-radius); box-shadow: var(--shadow-sm); }
@media (max-width: 980px) { .material-grid { grid-template-columns: 1fr; gap: 32px; } }

/* ---------- gallery (masonry grid + CSS-only lightbox) ---------- */
/* Same no-JS-dependency approach as the FAQ <details> accordions and the
   material toggle: each thumbnail links to #gN, the matching overlay is
   shown via :target, prev/next are just links to the neighbouring #gN
   (wrapping at both ends), and close links to "#" which clears :target. */
.gallery-masonry { column-count: 3; column-gap: 20px; margin-top: 32px; }
.gallery-item { display: block; margin-bottom: 20px; break-inside: avoid; border-radius: var(--v2-radius); overflow: hidden; box-shadow: var(--shadow-sm); }
.gallery-item img { width: 100%; display: block; transition: transform .25s ease; }
.gallery-item:hover img { transform: scale(1.04); }
@media (max-width: 900px) { .gallery-masonry { column-count: 2; } }
@media (max-width: 560px) { .gallery-masonry { column-count: 1; } }

.lightbox { display: none; position: fixed; inset: 0; background: rgba(20,24,28,.94); z-index: 9999; align-items: center; justify-content: center; padding: 40px; }
.lightbox:target { display: flex; }
.lightbox img { max-width: 90vw; max-height: 85vh; object-fit: contain; border-radius: 4px; box-shadow: 0 20px 60px rgba(0,0,0,.5); }
.lightbox-close { position: absolute; top: 24px; right: 32px; font-size: 42px; line-height: 1; text-decoration: none; font-family: Arial, sans-serif; opacity: .85; }
.lightbox-close:hover { opacity: 1; }
.lightbox-prev, .lightbox-next { position: absolute; top: 50%; transform: translateY(-50%); text-decoration: none; font-size: 28px; padding: 16px 20px; opacity: .8; }
/* .ic-page a:not(.btn) { color: inherit } is two classes + the "a" element
   (0,2,1) -- beats a single-class .lightbox-close rule outright. Match its
   specificity exactly (same 0,2,1) and win on source order instead. */
.ic-page a.lightbox-close, .ic-page a.lightbox-prev, .ic-page a.lightbox-next { color: #fff; text-decoration: none; }
.lightbox-prev:hover, .lightbox-next:hover { opacity: 1; }
.lightbox-prev { left: 8px; }
.lightbox-next { right: 8px; }
@media (max-width: 640px) {
  .lightbox-close { top: 12px; right: 16px; font-size: 34px; }
  .lightbox-prev, .lightbox-next { font-size: 22px; padding: 12px; }
}

/* ---------- configurations pills ---------- */

.config-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.config-pill { font-family: 'IBM Plex Mono'; font-size: 13px; border: 1px solid var(--line); padding: 9px 15px; border-radius: 99px; color: var(--ink-soft); background: #fff; display: inline-block; }

/* ---------- colours & finishes ---------- */

.colours-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.swatch-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }
.swatch { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.swatch-chip { width: 100%; aspect-ratio: 1/1; border-radius: var(--v2-radius-btn); box-shadow: var(--shadow-sm); border: 1px solid rgba(16, 24, 31, 0.08); display: block; }
.swatch span { font-size: 12px; color: var(--ink-soft); }
.colours-photo { border-radius: var(--v2-radius); overflow: hidden; box-shadow: var(--shadow-md); }
.colours-photo img { aspect-ratio: 4/3; object-fit: cover; width: 100%; }
.colours-note { margin-top: 18px; font-size: 13px; color: var(--slate); }
.colours-note a { color: var(--bronze-dark); }
@media (max-width: 980px) { .colours-grid { grid-template-columns: 1fr; gap: 28px; } .swatch-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 640px) { .swatch-grid { grid-template-columns: repeat(3, 1fr); } }

/* ---------- FAQ accordion (product pages, native details/summary) ---------- */

.faq-list { display: flex; flex-direction: column; gap: 14px; max-width: 840px; }
.faq-item { background: #fff; border-radius: var(--v2-radius); box-shadow: var(--shadow-sm); padding: 4px 24px; }
.faq-item summary { padding: 20px 0; font-family: 'Space Grotesk'; font-weight: 600; font-size: 16px; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 16px; color: var(--ink); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary .plus { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; background: var(--panel); display: flex; align-items: center; justify-content: center; color: var(--bronze-dark); font-size: 15px; transition: transform .2s ease; }
.faq-item[open] summary .plus { transform: rotate(45deg); }
.faq-item p { margin: 0 0 20px; font-size: 14.5px; color: var(--ink-soft); max-width: 70ch; }

/* ---------- hub page product grid ---------- */

.hub-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.hub-card { border-radius: var(--v2-radius); background: #fff; overflow: hidden; text-decoration: none; color: var(--ink); box-shadow: var(--shadow-sm); transition: box-shadow .28s ease, transform .28s ease; display: block; }
.hub-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-5px); }
.hub-card .thumb { aspect-ratio: 4/3; overflow: hidden; background: var(--panel); }
.hub-card .thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.hub-card:hover .thumb img { transform: scale(1.05); }
.hub-card .hub-body { padding: 20px 22px 24px; }
.hub-card h3 { font-size: 18px; margin-bottom: 6px; color: var(--ink); }
.hub-card p { font-size: 14px; color: var(--slate); margin: 0 0 10px; }
.hub-card .svc-link { font-family: 'IBM Plex Mono'; font-size: 12.5px; color: var(--bronze-dark); }
@media (max-width: 980px) { .hub-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .hub-grid { grid-template-columns: 1fr; } }
