/* =============================================================================
 * D&E Proelectric — Elementor widget styling.
 * -----------------------------------------------------------------------------
 * After the container refactor this file no longer builds any layout. Section
 * structure, grids, gaps, padding, and backgrounds are all owned by Elementor
 * Flexbox / Grid Containers and editable from the Elementor UI.
 *
 * What lives here:
 *   1. Typography utility classes applied to native Heading / Text widgets.
 *   2. Button skins applied to native Button widgets.
 *   3. The capability-list skin applied to the native Icon List widget.
 *   4. A handful of component variant hooks (chip colours, wide tile).
 *   5. Dark-band inheritance for widgets inside dark containers.
 *
 * Component internals live in the D&E Elementor Components plugin;
 * colour/type tokens live in design-system.css.
 * ========================================================================== */

/* =============================================================================
 * 1 · Typography on native widgets
 *
 * Elementor puts a widget's CSS Classes on the outer `.elementor-widget`
 * wrapper, so each rule reaches through to the real text node.
 * ========================================================================== */

/* Display heading — hero H1 */
.de-display .elementor-heading-title,
.elementor-widget-heading.de-display .elementor-heading-title {
	font-family: var(--de-font-display);
	font-weight: 700;
	font-size: clamp(2.5rem, 5vw + 1rem, 4.5rem);
	line-height: 1.05;
	letter-spacing: -0.04em;
	text-transform: uppercase;
	color: var(--de-ink);
	margin: 0;
}
.de-display .accent {
	background: linear-gradient(90deg, var(--de-blue) 0%, var(--de-blue-active) 60%, var(--de-yellow) 100%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* Section headline — H2 across every band */
.de-headline .elementor-heading-title,
.elementor-widget-heading.de-headline .elementor-heading-title {
	font-family: var(--de-font-display);
	font-weight: 600;
	font-size: clamp(1.75rem, 2.5vw + 1rem, 3rem);
	line-height: 1.15;
	letter-spacing: -0.03em;
	text-transform: uppercase;
	color: var(--de-ink);
	margin: 0;
}
/* Panel-scale headline (service cards) */
.de-headline--panel .elementor-heading-title { font-size: 1.75rem; }
/* Small headline (estimate card) */
.de-headline--sm .elementor-heading-title    { font-size: 1.25rem; letter-spacing: -0.02em; }

/* Lede paragraph */
.de-lede,
.de-lede p {
	font-family: var(--de-font-body);
	font-size: 1.125rem;
	line-height: 1.6;
	letter-spacing: -0.01em;
	color: var(--de-text-muted);
}
.de-lede p:last-child { margin-bottom: 0; }

/* Mono eyebrow above headings */
.de-eyebrow,
.de-eyebrow p {
	font-family: var(--de-font-mono);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--de-text-muted);
	margin: 0;
}

/* Default body copy inside text-editor widgets */
.elementor-widget-text-editor p { margin: 0 0 0.75rem; }
.elementor-widget-text-editor p:last-child { margin-bottom: 0; }

/* Reading measure for lede paragraphs — sits on the heading/text element
 * itself, never on a wrapper, so the cap is in the element's own font size. */
.de-measure p { max-width: 42rem; }

/* =============================================================================
 * 2 · Button skins on the native Button widget
 * ========================================================================== */
.elementor-widget-button.de-btn .elementor-button,
.elementor-widget-button.de-btn .elementor-button:visited {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	background: var(--de-ink);
	color: #FFFFFF;
	fill: #FFFFFF;
	padding: 12px 20px;
	font-family: var(--de-font-display);
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	border: 0;
	border-left: 2px solid var(--de-blue);
	border-radius: 0;
	box-shadow: none;
	transition: background 100ms linear, border-color 100ms linear;
}
.elementor-widget-button.de-btn .elementor-button:hover {
	background: var(--de-blue);
	color: #FFFFFF;
	border-left-color: var(--de-yellow);
}

.elementor-widget-button.de-btn-ghost .elementor-button,
.elementor-widget-button.de-btn-ghost .elementor-button:visited {
	background: transparent;
	color: var(--de-ink);
	border: 1px solid var(--de-ink);
	border-radius: 0;
	padding: 11px 18px;
	font-family: var(--de-font-mono);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	box-shadow: none;
	transition: background 100ms linear;
}
.elementor-widget-button.de-btn-ghost .elementor-button:hover {
	background: var(--de-substrate);
	color: var(--de-ink);
}

.elementor-widget-button.de-btn-volt .elementor-button,
.elementor-widget-button.de-btn-volt .elementor-button:visited {
	background: var(--de-yellow);
	color: var(--de-ink);
	border: 0;
	border-radius: 0;
	padding: 12px 20px;
	font-family: var(--de-font-display);
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	box-shadow: none;
	transition: background 100ms linear;
}
.elementor-widget-button.de-btn-volt .elementor-button:hover { background: var(--de-yellow-active); }

/* Buttons sit flush-left in their container rather than stretching */
.elementor-widget-button.de-btn,
.elementor-widget-button.de-btn-ghost,
.elementor-widget-button.de-btn-volt { width: auto; }

/* =============================================================================
 * 3 · Capability list — native Icon List widget as the square-bullet grid
 * ========================================================================== */
.de-check-list .elementor-icon-list-items {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.5rem 1rem;
	padding: 0;
	margin: 0;
}
@media (max-width: 640px) {
	.de-check-list .elementor-icon-list-items { grid-template-columns: 1fr; }
}
.de-check-list .elementor-icon-list-item {
	position: relative;
	padding-left: 1rem;
	margin: 0;
	font-family: var(--de-font-body);
	font-size: 0.9rem;
	line-height: 1.5;
	color: var(--de-text);
}
.de-check-list .elementor-icon-list-item::before {
	content: '';
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 6px;
	height: 6px;
	background: var(--de-blue);
}
/* Hide the icon slot — the ::before square is the marker */
.de-check-list .elementor-icon-list-icon { display: none; }
.de-check-list .elementor-icon-list-text { padding-left: 0; }

/* =============================================================================
 * 4 · Component variant hooks
 * ========================================================================== */
/* Service-panel badges */
.de-chip--blue   .de-c-chip { color: var(--de-blue); }
.de-chip--yellow .de-c-chip { color: var(--de-yellow-active); }

/* The first project tile spans two grid columns on desktop */
.de-tile-grid > .de-tile--wide { grid-column: span 2; }
@media (max-width: 1024px) {
	.de-tile-grid > .de-tile--wide { grid-column: auto; }
}

/* Commitment rules — yellow leading edge on the stacked meta rows */
.de-rule-item .de-c-meta {
	padding: 0.75rem 1rem;
	border-left: 2px solid var(--de-yellow);
	background: rgba(255, 184, 0, 0.06);
}
.de-rule-item .de-c-meta__label { color: var(--de-yellow-active); }

/* Estimate card — volt leading edge */
.de-estimate-card { border-left-color: var(--de-yellow) !important; }
.de-phone-row .de-c-meta__text {
	font-family: var(--de-font-display);
	font-size: 1.125rem;
	font-weight: 700;
	color: var(--de-ink);
}

/* Service panel card hover */
.de-panel-card { transition: border-color 150ms linear; }
.de-panel-card:hover { border-color: var(--de-ink) !important; }

/* =============================================================================
 * 5 · Dark-band inheritance
 *
 * Elementor's global kit emits `.elementor-kit-N h2 { color: … }` at a higher
 * specificity than a bare class, so dark overrides are forced.
 * ========================================================================== */
.de-dark .de-display .elementor-heading-title,
.de-dark .de-headline .elementor-heading-title,
.de-dark .elementor-widget-heading .elementor-heading-title { color: #F8FAFC !important; }
.de-dark .de-lede,
.de-dark .de-lede p,
.de-dark .elementor-widget-text-editor,
.de-dark .elementor-widget-text-editor p { color: #CBD5E1 !important; }
.de-dark .de-eyebrow,
.de-dark .de-eyebrow p { color: #94A3B8 !important; }
.de-dark .de-check-list .elementor-icon-list-item { color: #E2E8F0; }
.de-dark .elementor-widget-button.de-btn-ghost .elementor-button {
	color: #F8FAFC;
	border-color: #F8FAFC;
}
.de-dark .elementor-widget-button.de-btn-ghost .elementor-button:hover {
	background: var(--de-ink-4);
	color: #FFFFFF;
}

/* =============================================================================
 * 6 · Estimate popup shell (Theme Builder popup content styles the inside)
 * ========================================================================== */
.de-form input[type="text"],
.de-form input[type="email"],
.de-form input[type="tel"],
.de-form select,
.de-form textarea {
	border-radius: 0 !important;
	border: 1px solid var(--de-hairline-strong);
	background: var(--de-canvas);
	padding: 0.85rem 1rem;
	font-family: var(--de-font-body);
	font-size: 0.9375rem;
	color: var(--de-ink);
	box-shadow: none;
	width: 100%;
}
.de-form input:focus,
.de-form select:focus,
.de-form textarea:focus {
	outline: 1px solid var(--de-blue);
	border-color: var(--de-blue);
}
.de-form label {
	font-family: var(--de-font-mono);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--de-text-muted);
	display: block;
	margin-bottom: 0.4rem;
}

/* Shared inline-SVG icons (masks, so they inherit currentColor). */
:root {
	--de-icon-phone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M6.6 10.8c1.4 2.8 3.8 5.2 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.4.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .7-.2 1l-2.3 2.2z'/%3E%3C/svg%3E");
}

/* =============================================================================
 * 7 · Theme Builder — Global Header
 *
 * Structure (containers, sticky, borders, background) is configured in the
 * "D&E — Global Header" template. These rules only skin the widgets inside it.
 * ========================================================================== */
/* Sticky via CSS, not the Sticky module — that module clones the element,
 * which would duplicate the off-canvas widget inside it.
 *
 * The sticky must sit on the Theme Builder's `elementor-location-header`
 * wrapper, not on .de-header-bar: a sticky element only travels within its
 * parent's box, and .de-header-bar's parent is exactly header-height, so it
 * had no room to stick. The wrapper's parent is the page, which does. */
header.elementor-location-header {
	position: sticky;
	top: 0;
	z-index: 100;
}
.de-header-bar { backdrop-filter: blur(10px); }

/* Nav-menu widget → the mono uppercase pill nav.
 *
 * Sized up from 0.7rem/600/muted at the client's request: at the original size
 * the tabs read as secondary metadata next to the phone number and CTA, not as
 * the site's primary navigation. Ink instead of muted grey is what actually
 * makes them "noticeable" — the weight bump alone barely registers on mono. */
.de-hd-nav .elementor-nav-menu > li > a.elementor-item {
	font-family: var(--de-font-mono);
	font-size: 1.02rem;
	font-weight: 800;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--de-ink-2);
	padding: 0.75rem 0.85rem;
	transition: color 100ms linear, background 100ms linear;
}
.de-hd-nav .elementor-nav-menu > li > a.elementor-item:hover,
.de-hd-nav .elementor-nav-menu > li > a.elementor-item.elementor-item-active,
.de-hd-nav .elementor-nav-menu > li > a.elementor-item.highlighted {
	color: var(--de-blue);
	background: var(--de-substrate);
}
/* Kill Elementor's default underline pointer so the pill is the only state */
.de-hd-nav .e--pointer-underline .elementor-item:after,
.de-hd-nav .e--pointer-underline .elementor-item:before { display: none; }
/* The bordered pill container around the nav */
.de-hd-nav .elementor-nav-menu--main > .elementor-nav-menu {
	background: var(--de-canvas);
	border: 1px solid var(--de-hairline);
	padding: 4px;
}
/* Mobile dropdown panel */
.de-hd-nav .elementor-nav-menu--dropdown a.elementor-item {
	font-family: var(--de-font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--de-ink);
}
.de-hd-nav .elementor-menu-toggle {
	border: 1px solid var(--de-hairline);
	border-radius: 0;
	color: var(--de-ink);
}

/* Phone lockup — the number is prefixed with a handset mark.
 *
 * Drawn as an inline-SVG mask rather than an icon font: the ekiticons
 * stylesheet was dequeued for performance, and pulling Font Awesome back in
 * for a single glyph would undo that. A mask (rather than a background image)
 * lets the icon inherit `currentColor`, so it turns electric blue with the
 * number on hover without needing a second asset. */
.de-hd-phone .elementor-heading-title a::before {
	content: '';
	display: inline-block;
	width: 15px;
	height: 15px;
	margin-right: 7px;
	vertical-align: -2px;
	background-color: currentColor;
	-webkit-mask-image: var(--de-icon-phone);
	mask-image: var(--de-icon-phone);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-position: center;
	mask-position: center;
}

/* Phone lockup */
.de-hd-phone .elementor-heading-title,
.de-hd-phone .elementor-heading-title a {
	font-family: var(--de-font-display);
	font-size: 0.9375rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--de-ink);
	text-decoration: none;
	text-transform: none;
}
.de-hd-phone .elementor-heading-title a:hover { color: var(--de-blue); }
.de-hd-chip .de-c-chip {
	background: transparent;
	border: 0;
	padding: 0;
	font-size: 0.625rem;
	color: var(--de-text-muted);
}

/* Header CTA sits tighter than the page-level primary button */
.de-hd-cta .elementor-button { padding: 10px 14px; font-size: 11px; letter-spacing: 0.08em; }



/* =============================================================================
 * 8 · Theme Builder — Global Footer
 * ========================================================================== */
.de-ft-title .elementor-heading-title {
	font-family: var(--de-font-mono);
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #94A3B8 !important;
	margin: 0;
}
.de-ft-links .elementor-icon-list-item > a,
.de-ft-links .elementor-icon-list-text {
	font-family: var(--de-font-body);
	font-size: 0.9375rem;
	color: #E2E8F0;
	transition: color 100ms linear;
}
.de-ft-links .elementor-icon-list-item > a:hover .elementor-icon-list-text { color: var(--de-blue-soft); }
.de-ft-links .elementor-icon-list-icon { display: none; }
.de-ft-blurb p { color: #94A3B8 !important; font-size: 0.9375rem; max-width: 26rem; }
.de-ft-contact .de-c-meta__label { color: #94A3B8; font-size: 11px; letter-spacing: 0.12em; }
.de-ft-contact .de-c-meta__text {
	color: #FFFFFF !important;
	font-family: var(--de-font-display);
	font-size: 1rem;
	font-weight: 600;
}
.de-ft-contact .de-c-meta__item { flex-direction: column; align-items: flex-start; gap: 2px; }
.de-ft-legal p {
	font-family: var(--de-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #64748B !important;
	margin: 0;
}

/* =============================================================================
 * 9 · Theme Builder — Request Estimate Popup
 * ========================================================================== */
.de-popup-body { border-left-color: var(--de-blue) !important; }
.de-estimate-form .elementor-field-group > label {
	font-family: var(--de-font-mono);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--de-text-muted);
	margin-bottom: 0.4rem;
}
.de-estimate-form .elementor-field-textual {
	border-radius: 0;
	border: 1px solid var(--de-hairline-strong);
	background: var(--de-canvas);
	padding: 0.85rem 1rem;
	font-family: var(--de-font-body);
	font-size: 0.9375rem;
	color: var(--de-ink);
	box-shadow: none;
}
.de-estimate-form .elementor-field-textual:focus {
	outline: 1px solid var(--de-blue);
	border-color: var(--de-blue);
	box-shadow: none;
}
.elementor-widget-form.de-estimate-form .elementor-button[type="submit"] {
	background: var(--de-ink);
	color: #FFFFFF;
	border: 0;
	border-left: 2px solid var(--de-blue);
	border-radius: 0;
	padding: 0.95rem 1.75rem;
	font-family: var(--de-font-display);
	font-size: 0.875rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	transition: background 100ms linear;
}
.elementor-widget-form.de-estimate-form .elementor-button[type="submit"]:hover {
	background: var(--de-blue);
	border-left-color: var(--de-yellow);
}

/* Header stays a single compact row at every width: the phone lockup drops out
 * below 1024, and the CTA shrinks rather than stretching. */
@media (max-width: 1024px) {
	.de-hd-cta .elementor-button { padding: 0.6rem 0.9rem; font-size: 0.7rem; letter-spacing: 0.08em; }
}
@media (max-width: 480px) {
	.de-hd-cta .elementor-button { padding: 0.55rem 0.7rem; font-size: 0.625rem; }

}
.de-header-bar .elementor-widget-button { width: auto; }

/* =============================================================================
 * 10 · Header navigation — desktop pill vs ElementsKit off-canvas
 * -----------------------------------------------------------------------------
 * Desktop (>1024px): the Elements Stack nav-menu renders as the bordered pill.
 * Tablet / mobile:   that nav is hidden and ElementsKit's off-canvas panel
 *                    (slide-in from the right) takes over.
 * ========================================================================== */

/* The logo and the nav pill are fixed-size items in a nowrap row, so both opt
 * out of shrinking — otherwise flex squeezes the logo down to a thumbnail.
 * The actions cluster is the only element allowed to give up space. */
.de-header-bar .de-hd-logo,
.de-header-bar .de-hd-nav { flex-shrink: 0; }
.de-header-bar .de-hd-logo img { width: 100%; height: auto; display: block; }

/* ---- Logo scale-up (client request) -------------------------------------
 * Template 40 sets the logo widget to 180/156/124px. Overriding here rather
 * than in the template keeps the header's two size decisions — logo box and
 * bar height — next to each other, since one can't change without the other:
 * the logo art is ~3:1, so 232px wide needs 77px of height and the original
 * 80px bar left it no breathing room.
 *
 * Both selectors clear Elementor's `.elementor-element-<id>` (0,1,0) on
 * specificity, so this wins regardless of stylesheet order. */
.elementor-location-header .de-header-bar { min-height: 96px; }
.de-header-bar .de-hd-logo {
	width: 236px;
	--container-widget-width: 236px;
}
@media (max-width: 1024px) {
	.elementor-location-header .de-header-bar { min-height: 82px; }
	.de-header-bar .de-hd-logo {
		width: 190px;
		--container-widget-width: 190px;
	}
}
@media (max-width: 767px) {
	.elementor-location-header .de-header-bar { min-height: 68px; }
	.de-header-bar .de-hd-logo {
		width: 150px;
		--container-widget-width: 150px;
	}
}

/* =============================================================================
 * 10c · Header utility band
 * -----------------------------------------------------------------------------
 * The phone lockup and the social links live on a dark strip above the main
 * bar. Splitting the header in two is what makes the client's other two asks
 * possible at once: the main bar only has to carry logo + nav + CTA, so both
 * the logo and the tabs can grow without the row running out of width.
 * ========================================================================== */
:root { --de-utility-h: 38px; }

.de-hd-utility {
	color: #fff;
	font-family: var(--de-font-mono);
}
/* The phone lockup was skinned for the white bar, so its colour is set on the
 * inner .elementor-heading-title, not on the widget wrapper. Overriding the
 * wrapper alone left the number painted --de-ink on an --de-ink band: present
 * in the DOM, invisible on screen. The icon is a currentColor mask, so it
 * follows the text automatically. */
.de-hd-utility .de-hd-phone .elementor-heading-title,
.de-hd-utility .de-hd-phone .elementor-heading-title a {
	font-size: 0.9rem;
	color: #FFFFFF;
}
.de-hd-utility .de-hd-phone .elementor-heading-title a:hover { color: var(--de-yellow); }
.de-hd-utility .de-hd-chip .de-c-chip { color: #94A3B8; }

/* Social row — Elementor renders these as inline SVG (e_font_icon_svg is on),
 * so no icon font is pulled in for three glyphs. */
.de-hd-social .elementor-social-icon {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: 0;
	color: #fff;
	transition: background 120ms linear, border-color 120ms linear, color 120ms linear;
}
.de-hd-social .elementor-social-icon:hover {
	background: var(--de-blue);
	border-color: var(--de-blue);
	color: #fff;
}
.de-hd-social .elementor-social-icon svg { fill: currentColor; }

/* Only the main bar should stay on screen. Pulling the sticky origin up by the
 * utility height lets that strip scroll away while .de-header-bar pins — doing
 * it here rather than with a second sticky element keeps the off-canvas widget
 * from being cloned, which is why the main bar was never sticky on its own. */
header.elementor-location-header { top: calc(-1 * var(--de-utility-h)); }

@media (max-width: 767px) {
	:root { --de-utility-h: 34px; }
	.de-hd-utility { min-height: 34px; }
	.de-hd-utility .de-hd-phone { font-size: 0.82rem; }
}

/* ---- Early nav collapse --------------------------------------------------
 * The tabs are now 15px/800, so the six of them plus a 276px logo and the CTA
 * need about 1240px of window before the row starts squeezing the button.
 * Elementor's own visibility controls only swap the nav for the off-canvas at
 * its tablet breakpoint (1024px), which left 1025-1240px overflowing, so the
 * swap is pulled forward here. Both rules out-specify Elementor's
 * .elementor-hidden-* classes, which is why they take effect at all. */
@media (min-width: 1025px) and (max-width: 1240px) {
	.elementor-location-header .de-header-bar .de-hd-nav { display: none; }
	.elementor-location-header .de-header-bar .de-hd-offcanvas.elementor-hidden-desktop { display: block; }
}
.de-hd-nav .elementor-nav-menu {
	flex-wrap: nowrap;
	white-space: nowrap;
}
.de-hd-nav .elementor-nav-menu > li { flex: 0 0 auto; }

/* The actions cluster gives up space first. */
.de-header-bar .de-hd-actions { flex-shrink: 1; min-width: 0; }

/* ---- Breakpoint swap ----------------------------------------------------
 * Handled by Elementor's own responsive-visibility controls on the widgets
 * (nav = hidden-tablet/hidden-mobile, off-canvas = hidden-desktop), because a
 * plain class rule loses to Elementor's per-element display CSS. Keeping it
 * on the widgets also leaves it editable under Advanced → Responsive.
 */

/* ---- Off-canvas trigger (hamburger) ------------------------------------- */
.de-hd-offcanvas .ekit_menu_responsive_hamburger,
.de-hd-offcanvas .ekit-menu-hamburger,
.de-hd-offcanvas .ekit_navsidebar-panel--toggle {
	border: 1px solid var(--de-hairline);
	border-radius: 0;
	padding: 0.5rem 0.65rem;
	color: var(--de-ink);
	background: transparent;
	line-height: 1;
	cursor: pointer;
}
.de-hd-offcanvas .ekit_menu_responsive_hamburger:hover { background: var(--de-substrate); }

/* ---- Off-canvas panel --------------------------------------------------- */
/* ElementsKit's own text-widget wrapper adds a 60px top pad on top of its 40px
 * close-button row, and the panel then centres its content vertically — which
 * together pushed the menu ~190px down the screen. Reset all three so the nav
 * starts just under the close button. */
.ekit_sidebar-textwidget { padding-top: 16px !important; }
.de-oc-panel {
	min-height: auto;
	padding-top: 8px !important;
	justify-content: flex-start !important;
}

/* Close button: ElementsKit ships it at #333, invisible on the obsidian panel. */
.ekit_close-side-widget,
.ekit_close-side-widget i,
.de-hd-offcanvas .ekit_close-side-widget {
	color: #F8FAFC !important;
	font-size: 22px !important;
	line-height: 1;
	opacity: 1;
}
.ekit_widget-heading {
	padding: 16px 20px !important;
	display: flex;
	justify-content: flex-end;
}

/* ElementsKit's inner wrappers render taller than the fixed panel and then
 * centre themselves, which pushed the whole menu down the screen. Pin the
 * chain to the top and let the panel itself do any scrolling. */
.ekit-sidebar-widget .ekit_sidebar-widget-container {
	height: auto !important;
	min-height: 100%;
	display: flex;
	flex-direction: column;
	justify-content: flex-start !important;
	align-items: stretch;
}
.ekit-sidebar-widget .ekit_sidebar-textwidget,
.ekit-sidebar-widget .widgetarea_warper,
.ekit-sidebar-widget .ekit-widget-area-container,
.ekit-sidebar-widget .elementor {
	height: auto !important;
	min-height: 0 !important;
	display: block;
}
.ekit_close-side-widget:hover { color: var(--de-yellow) !important; }
.de-oc-nav .elementor-nav-menu--main > .elementor-nav-menu { background: transparent; border: 0; padding: 0; }
.de-oc-nav .elementor-nav-menu a.elementor-item {
	font-family: var(--de-font-mono);
	/* 14px, not 0.8125rem — the host root is not 16px, which rendered these
	 * at ~11.8px and made the mobile menu hard to read. */
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: #E2E8F0;
	padding: 14px 0;
	border-bottom: 1px solid var(--de-ink-4);
}
.de-oc-nav .elementor-nav-menu a.elementor-item:hover,
.de-oc-nav .elementor-nav-menu a.elementor-item.elementor-item-active {
	color: var(--de-blue-soft);
	background: transparent;
}
.de-oc-phone .elementor-heading-title a::before {
	content: '';
	display: inline-block;
	width: 18px;
	height: 18px;
	margin-right: 9px;
	vertical-align: -3px;
	background-color: currentColor;
	-webkit-mask-image: var(--de-icon-phone);
	mask-image: var(--de-icon-phone);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	mask-size: contain;
}
.de-oc-phone .elementor-heading-title,
.de-oc-phone .elementor-heading-title a {
	font-family: var(--de-font-display);
	font-size: 1.375rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	color: #FFFFFF !important;
	text-decoration: none;
	text-transform: none;
}
.de-oc-cta .elementor-button { width: 100%; justify-content: center; }

/* Header CTA keeps to one line at every width. */
.de-hd-cta .elementor-button { white-space: nowrap; }
.de-hd-cta .elementor-button-text { white-space: nowrap; }

/* ---- Off-canvas panel surface -------------------------------------------
 * The panel content container carries `de-dark`, which forces light text.
 * ElementsKit's own background control paints an inner wrapper we do not
 * control reliably, so the dark ground is set here on both the panel shell
 * and our content container — otherwise it is white text on a white panel.
 */
.ekit-sidebar-widget,
.ekit_navsidebar-panel,
.ekit-sidebar-group .ekit-sidebar-widget,
.de-hd-offcanvas .ekit-sidebar-widget {
	background: var(--de-ink) !important;
	/* The panel is position:fixed but ElementsKit leaves it at the height of
	 * the header it was rendered inside, so it collapses to an ~80px sliver.
	 * Pin it to the full viewport and let long menus scroll inside. */
	height: 100vh !important;
	max-height: 100vh;
	top: 0 !important;
	bottom: 0;
	right: 0 !important;
	width: min(340px, 82vw) !important;
	overflow-y: auto;
	overscroll-behavior: contain;
}
.de-oc-panel {
	background: var(--de-ink);
	min-height: 100vh;
}
/* Close button sits on the dark ground */
.ekit-sidebar-group .ekit_close-btn,
.ekit_navsidebar-panel--close,
.de-hd-offcanvas .ekit_close-btn {
	color: #F8FAFC;
	border: 1px solid var(--de-ink-4);
	border-radius: 0;
	opacity: 1;
}
.ekit-sidebar-group .ekit_close-btn:hover { background: var(--de-ink-4); color: #FFFFFF; }
/* Dim the page behind the panel */
.ekit-sidebar-group .ekit-overlay,
.ekit-sidebar-group.ekit-sidebar-active .ekit-overlay {
	background: rgba(11, 15, 23, 0.7);
}

/* ---- Off-canvas panel refinements --------------------------------------- */
/* Kill the nav widget's default thick "underline pointer"; the design uses a
 * hairline divider per row plus a colour shift on the active item. */
.de-oc-nav .e--pointer-underline .elementor-item:after,
.de-oc-nav .e--pointer-underline .elementor-item:before,
.de-oc-nav .elementor-item:after,
.de-oc-nav .elementor-item:before { display: none !important; }
.de-oc-nav .elementor-nav-menu a.elementor-item-active { color: var(--de-blue-soft) !important; }

/* CTA fills the panel width and never wraps mid-label. */
.de-oc-cta .elementor-button { white-space: nowrap; padding: 0.9rem 1rem; }

/* Dim the page behind the open panel. */
.ekit-sidebar-group .ekit-overlay,
.ekit-sidebar-group.ekit_isActive .ekit-overlay,
.ekit_isActive + .ekit-overlay { background: rgba(11, 15, 23, 0.72) !important; }

/* =============================================================================
 * 11 · Responsive typography — mobile & tablet
 * -----------------------------------------------------------------------------
 * The Precision Spec Grid leans on 0.6875rem monospaced labels. Astra's base
 * font-size resolves those to ~10.2px, which is below the readable floor on a
 * phone. Bump the mono layer (and tighten the display layer) at small widths
 * without changing the desktop design.
 * ========================================================================== */
@media (max-width: 767px) {

	/* --- Monospaced label layer: 10.2px -> 12px --- */
	/* Component-internal responsive sizing lives in the plugin stylesheet
	 * (components.css), which Elementor enqueues AFTER this file — a rule here
	 * would lose at equal specificity. Only widget-level type is set below. */
	.de-eyebrow,
	.de-eyebrow p { font-size: 12px; letter-spacing: 0.09em; }

	/* --- Display layer: keep the impact, lose the overflow --- */
	.de-display .elementor-heading-title { font-size: clamp(2rem, 9vw, 2.75rem); line-height: 1.08; }
	.de-headline .elementor-heading-title { font-size: clamp(1.5rem, 6.5vw, 2rem); }
	.de-headline--panel .elementor-heading-title { font-size: 1.375rem; }
	.de-lede, .de-lede p { font-size: 1rem; line-height: 1.55; }

	/* Body copy floor */
	.de-check-list .elementor-icon-list-item { font-size: 15px; line-height: 1.55; }
	.de-lede, .de-lede p { font-size: 16px; }
	.elementor-widget-text-editor p { font-size: 15px; }


	/* Buttons hug their label rather than stretching edge-to-edge — a
	 * full-bleed CTA reads as a banner, not a button. Tap height stays 44px. */
	.elementor-widget-button.de-btn,
	.elementor-widget-button.de-btn-ghost,
	.elementor-widget-button.de-btn-volt { width: auto; }
	.elementor-widget-button.de-btn .elementor-button,
	.elementor-widget-button.de-btn-ghost .elementor-button,
	.elementor-widget-button.de-btn-volt .elementor-button {
		width: auto;
		display: inline-flex;
		justify-content: center;
		min-height: 44px;
		padding: 11px 16px;
		font-size: 12px;
	}
	/* The header CTA stays compact — it shares the bar with the hamburger. */
	.de-header-bar .elementor-widget-button.de-hd-cta { width: auto; }
	.de-hd-cta .elementor-button {
		width: auto;
		min-height: 40px;
		font-size: 0.5625rem;
		letter-spacing: 0.06em;
		padding: 0.5rem 0.6rem;
		border-left-width: 2px;
	}
	/* Drop the arrow glyph on the header CTA — the label alone fits. */
	.de-hd-cta .elementor-button-icon { display: none; }

}

/* --- Tablet: 768–1024 --- */
@media (min-width: 768px) and (max-width: 1024px) {
	.de-display .elementor-heading-title  { font-size: clamp(2.5rem, 6vw, 3.5rem); }
	.de-headline .elementor-heading-title { font-size: clamp(1.75rem, 4vw, 2.5rem); }
	/* Touch targets stay finger-sized on tablets. */
	.elementor-widget-button.de-btn .elementor-button,
	.elementor-widget-button.de-btn-ghost .elementor-button,
	.elementor-widget-button.de-btn-volt .elementor-button { min-height: 44px; }
	.de-hd-cta .elementor-button { min-height: 42px; }
	/* Two-up capability lists have room at tablet; keep them two-up. */
	.de-check-list .elementor-icon-list-items { grid-template-columns: 1fr 1fr; }
}

/* =============================================================================
 * 12 · Hero imagery — approved overlap composition
 * -----------------------------------------------------------------------------
 * Stitch spec: a 460px main visual at col-span-10 (83%) carrying a bottom-left
 * badge, with a col-span-6 (50%) conduit frame absolutely positioned at
 * bottom:-24px / right:-8px so it hangs off the main image's bottom-right
 * corner. Elementor containers expose `position` but no offset controls, so the
 * offsets live here.
 * ========================================================================== */
.de-hero-visual { position: relative; }

@media (min-width: 1025px) {
	.de-hero-main    { width: 83%; }
	.de-hero-overlap {
		/* Elementor emits a per-element `position: relative` at higher
		 * specificity than a bare class, so the override is forced. */
		position: absolute !important;
		right: -8px;
		bottom: -24px;
		width: 50%;
		z-index: 2;
		margin: 0 !important;
	}
}

/* Tablet: the hero has stacked, so the visual column is full width. Pull the
 * main frame in and let the conduit frame hang off its right edge rather than
 * covering it — same corner relationship as desktop, scaled down. */
@media (min-width: 768px) and (max-width: 1024px) {
	.de-hero-main    { width: 72%; }
	.de-hero-overlap {
		position: absolute !important;
		right: 0;
		bottom: -20px;
		width: 42%;
		z-index: 2;
		margin: 0 !important;
	}
}

/* Mobile: no room to overlap — stack the two frames cleanly. */
@media (max-width: 767px) {
	.de-hero-main,
	.de-hero-overlap { position: static !important; width: 100%; margin: 0 !important; }
	.de-hero-overlap { margin-top: 12px !important; }
}

/* =============================================================================
 * 13 · CSS-drawn off-canvas icons
 * -----------------------------------------------------------------------------
 * The ElementsKit icon font (ekiticons, ~81KB + font file) is dequeued because
 * the site renders exactly two of its glyphs. Both are drawn here instead.
 * ========================================================================== */
.de-hd-offcanvas .icon-burger-menu,
.ekit_close-side-widget .icon-close {
	font-family: inherit !important;
	font-style: normal;
	display: inline-block;
	position: relative;
	width: 22px;
	height: 16px;
	vertical-align: middle;
}
.de-hd-offcanvas .icon-burger-menu::before,
.de-hd-offcanvas .icon-burger-menu::after,
.de-hd-offcanvas .icon-burger-menu > span {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	height: 2px;
	background: currentColor;
	border-radius: 0;
}
/* Three bars: top, middle (box-shadow), bottom */
.de-hd-offcanvas .icon-burger-menu::before {
	top: 1px;
	box-shadow: 0 6px 0 currentColor;
}
.de-hd-offcanvas .icon-burger-menu::after { bottom: 1px; }

/* Close: two crossed bars */
.ekit_close-side-widget .icon-close { width: 20px; height: 20px; }
.ekit_close-side-widget .icon-close::before,
.ekit_close-side-widget .icon-close::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	right: 0;
	height: 2px;
	background: currentColor;
}
.ekit_close-side-widget .icon-close::before { transform: rotate(45deg); }
.ekit_close-side-widget .icon-close::after  { transform: rotate(-45deg); }

/* =============================================================================
 * 14 · Floating WhatsApp button
 * -----------------------------------------------------------------------------
 * Rendered by inc/whatsapp.php and configured under Settings → WhatsApp Button.
 * Position, shape, and breakpoint visibility all come from that screen via the
 * --de-wa-* custom properties and the de-wa--* modifier classes.
 * ========================================================================== */
.de-wa {
	position: fixed;
	bottom: var(--de-wa-bottom, 24px);
	z-index: 9990;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 12px 16px;
	background: #25D366;
	color: #FFFFFF;
	text-decoration: none;
	font-family: var(--de-font-display);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1;
	border-radius: 0;
	/* The design system rejects blurred elevation, so the button reads as a
	 * solid plate with a hairline edge rather than a floating pill. */
	border-left: 3px solid #0B0F17;
	transition: background 140ms linear, transform 200ms cubic-bezier(.22,.61,.36,1);
}
.de-wa--right { right: var(--de-wa-side, 24px); }
.de-wa--left  { left:  var(--de-wa-side, 24px); border-left: 0; border-right: 3px solid #0B0F17; }

.de-wa:hover,
.de-wa:focus-visible { background: #1DA851; color: #FFFFFF; transform: translateY(-2px); }
.de-wa:focus-visible { outline: 2px solid #0B0F17; outline-offset: 2px; }

.de-wa__icon { display: inline-flex; flex: 0 0 auto; }
.de-wa__icon svg { display: block; }
.de-wa__label { white-space: nowrap; }

/* Round variant — the familiar WhatsApp circle, label dropped. */
.de-wa--round {
	border-radius: 999px;
	padding: 14px;
	border-left: 0;
	border-right: 0;
}
.de-wa--round .de-wa__label { display: none; }

/* Icon-only (label switched off in settings) */
.de-wa--icon-only { padding: 13px; }
.de-wa--icon-only .de-wa__label { display: none; }

/* Breakpoint visibility from the settings screen */
@media (min-width: 1025px) { .de-wa--no-desktop { display: none; } }
@media (max-width: 1024px) { .de-wa--no-mobile  { display: none; } }

/* On phones the label costs too much width — icon only, and a slightly
 * larger tap target. */
@media (max-width: 767px) {
	.de-wa { padding: 13px; gap: 0; }
	.de-wa__label { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.de-wa { transition: background 140ms linear; }
	.de-wa:hover { transform: none; }
}

/* =============================================================================
 * 15 · Form field height fix
 * -----------------------------------------------------------------------------
 * Elementor's form widget sets a fixed `height: 40px` on every field. Our
 * padding (13.6px top and bottom) then leaves a 12.8px content box for a
 * 24.8px line — so the text was clipped, most visibly in the <select>s where
 * "Commercial" and "Panel Upgrade" were sliced in half.
 *
 * Letting the field size itself from padding + line-height fixes all three
 * control types at once, and the min-height keeps the 48px touch target.
 * ========================================================================== */
.de-form .elementor-field-textual,
.de-estimate-form .elementor-field-textual,
.de-form input.elementor-field,
.de-form select.elementor-field,
.de-form textarea.elementor-field {
	height: auto;
	min-height: 48px;
	line-height: 1.4;
}

/* Textareas size from their rows attribute, not the min-height. */
.de-form textarea.elementor-field,
.de-estimate-form textarea.elementor-field {
	min-height: 120px;
	padding-top: 12px;
	padding-bottom: 12px;
}

/* The select loses its native arrow to `appearance: none`, so draw the
 * caret as a background chevron and reserve room for it. */
.de-form select.elementor-field,
.de-estimate-form select.elementor-field {
	padding-right: 40px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%230B0F17' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 11px 8px;
	cursor: pointer;
}

/* Keep the submit button on the same scale as the fields. */
.de-form .elementor-button[type="submit"],
.elementor-widget-form.de-estimate-form .elementor-button[type="submit"] { min-height: 48px; }

/* =============================================================================
 * 14 · Field galleries — Commercial / Residential
 * -----------------------------------------------------------------------------
 * Elementor's Basic Gallery renders WordPress's [gallery] shortcode, so the
 * markup is .gallery > .gallery-item > .gallery-icon > a > img, and WordPress
 * prints per-column width rules of its own. Laying the wrapper out as a grid
 * and clearing those widths is what turns it into the spec-grid tile field.
 *
 * The source photos are 36 landscape to 49 portrait. Left alone that produces
 * a ragged grid of different-height cells, so every cell is pinned to a 4:3
 * frame and the photo is cropped to fill it.
 * ========================================================================== */
.de-gallery .gallery {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 8px;
	margin: 0;
}
/* WordPress prints `#gallery-N .gallery-item { width: 25% }` from
 * gallery_shortcode(). That is an id selector, so no stack of classes can
 * out-specify it and !important is the only lever short of a PHP filter —
 * without it each cell collapses to a quarter of its own grid track. */
.de-gallery .gallery-item {
	width: auto !important;
	max-width: none !important;
	margin: 0 !important;
	/* WordPress's gallery style also puts 10px of padding on every item, which
	 * added 20px to each visual gutter on top of the grid gap — the tiles read
	 * as floating rather than as a field. The grid gap is the only spacing. */
	padding: 0 !important;
	float: none;
	display: block;
}
.de-gallery .gallery-icon {
	margin: 0;
	border: 1px solid var(--de-hairline);
	background: var(--de-substrate);
	overflow: hidden;
	position: relative;
	transition: border-color 140ms linear;
}
.de-gallery .gallery-icon a {
	display: block;
	line-height: 0;
}
.de-gallery .gallery-icon img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
	height: auto;
	transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
.de-gallery .gallery-icon:hover { border-color: var(--de-blue); }
.de-gallery .gallery-icon:hover img { transform: scale(1.045); }

/* Keyboard parity with the hover state — the lightbox is reachable by tab. */
.de-gallery .gallery-icon a:focus-visible {
	outline: 2px solid var(--de-blue);
	outline-offset: 2px;
}


@media (max-width: 1024px) {
	.de-gallery .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
}
@media (max-width: 767px) {
	.de-gallery .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
	.de-gallery .gallery-icon img { transition: none; }
	.de-gallery .gallery-icon:hover img { transform: none; }
}

/* =============================================================================
 * 15 · About hero — client photograph as the band background
 * -----------------------------------------------------------------------------
 * The scrim is a left-weighted gradient rather than a flat overlay. The
 * headline sits in the left column and the photograph's subject stands there
 * too, so a flat wash dark enough to carry white text would have flattened the
 * whole sunset. Weighting it left keeps contrast where the words are and lets
 * the sky stay legible on the right.
 *
 * Painted with ::before rather than Elementor's background-overlay control so
 * the gradient stops live here next to the colour tokens.
 * ========================================================================== */
.de-about-hero {
	position: relative;
	isolation: isolate;
	background-attachment: scroll;
}
.de-about-hero::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(
		100deg,
		rgba(11, 15, 23, 0.92) 0%,
		rgba(11, 15, 23, 0.82) 34%,
		rgba(11, 15, 23, 0.44) 66%,
		rgba(11, 15, 23, 0.30) 100%
	);
}
/* The band's own children need to sit above the scrim. */
.de-about-hero > .e-con-inner,
.de-about-hero > .elementor-element { position: relative; z-index: 1; }

/* The chip is drawn for light backgrounds; on the photograph it needs its own
 * plate or the pulse marker disappears into the sky. */
.de-about-hero .de-c-chip {
	background: rgba(255, 255, 255, 0.1);
	border: 1px solid rgba(255, 255, 255, 0.22);
	color: #F8FAFC;
	padding: 6px 10px;
}
.de-about-hero .de-c-meta,
.de-about-hero .de-c-meta__label { color: #CBD5E1; }
.de-about-hero .elementor-widget-button.de-btn-ghost .elementor-button {
	color: #F8FAFC;
	border-color: rgba(255, 255, 255, 0.45);
}
.de-about-hero .elementor-widget-button.de-btn-ghost .elementor-button:hover {
	background: rgba(255, 255, 255, 0.12);
	color: #FFFFFF;
}

@media (max-width: 767px) {
	/* Portrait viewports crop the dune out entirely; pulling the focal point
	 * right keeps the horizon and the sun in frame. */
	.de-about-hero { background-position: 68% center; }
	.de-about-hero::before {
		background: linear-gradient(
			180deg,
			rgba(11, 15, 23, 0.86) 0%,
			rgba(11, 15, 23, 0.72) 60%,
			rgba(11, 15, 23, 0.58) 100%
		);
	}
}

/* =============================================================================
 * 16 · Footer social row
 * ========================================================================== */
.de-ft-social .elementor-social-icon {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, 0.2);
	border-radius: 0;
	color: #F8FAFC;
	transition: background 120ms linear, border-color 120ms linear;
}
.de-ft-social .elementor-social-icon:hover {
	background: var(--de-blue);
	border-color: var(--de-blue);
}
.de-ft-social .elementor-social-icon svg { fill: currentColor; }
.de-ft-social { margin-top: 4px; }

/* =============================================================================
 * 17 · Homepage gallery teaser
 * -----------------------------------------------------------------------------
 * Same tile treatment as the Projects galleries, but a single six-across strip
 * that reads as a sample rather than an archive. The shared .de-gallery rules
 * do the framing; only the column count and the crop change here.
 * ========================================================================== */
.de-gallery--teaser .gallery { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.de-gallery--teaser .gallery-icon img { aspect-ratio: 1 / 1; }

@media (max-width: 1024px) {
	.de-gallery--teaser .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
	.de-gallery--teaser .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =============================================================================
 * 18 · Client reviews
 * -----------------------------------------------------------------------------
 * Cards are hairline panels on the substrate, matching the estimate card and
 * the value items rather than introducing a third card treatment.
 *
 * The placeholder meta line is deliberately loud: these cards ship without real
 * review text, and a quiet grey caption would let fake-looking testimonials go
 * live unnoticed. Delete the .de-review-meta line once the real names are in.
 * ========================================================================== */
.de-review-card {
	border: 1px solid var(--de-hairline);
	border-top: 2px solid var(--de-blue);
}
.de-review-stars .elementor-star-rating {
	font-size: 15px;
	color: var(--de-yellow);
}
.de-review-stars .elementor-star-rating i:before { color: var(--de-yellow); }
.de-review-quote p {
	font-family: var(--de-font-body);
	font-size: 1rem;
	line-height: 1.6;
	color: var(--de-ink-2);
	margin: 0;
}
.de-review-name .elementor-heading-title {
	font-family: var(--de-font-display);
	font-size: 0.95rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--de-ink);
	margin: 0;
}
.de-review-meta p {
	font-family: var(--de-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--de-text-muted);
	margin: 0;
}

/* Footer social row sits flush with the logo and blurb above it, not centred —
 * Elementor's social-icons widget centres itself by default. */
.de-ft-social .elementor-social-icons-wrapper {
	justify-content: flex-start;
	text-align: left;
}
.de-ft-social .elementor-widget-container { text-align: left; }

/* =============================================================================
 * 19 · Timeline body colour
 * -----------------------------------------------------------------------------
 * The Timeline Item component hardcodes #CBD5E1 on its body copy: it was drawn
 * for the dark Family Business band on the homepage and never re-checked on a
 * light one. On the About page's Origin band that put pale grey text on white.
 *
 * Default it to the muted ink used everywhere else on the canvas and restore
 * the light value only inside a dark band, so both placements read correctly.
 * The extra .de-c-tl in the selector is what clears the plugin stylesheet,
 * which is enqueued after the theme's. */
.de-c-tl .de-c-tl__body { color: var(--de-text-muted); }
.de-dark .de-c-tl .de-c-tl__body { color: #CBD5E1; }

/* ==========================================================================
 * .de-frame-fill — image column takes its height from the copy column
 * --------------------------------------------------------------------------
 * These frames sit in a two-column row (`flex_align_items: stretch`) opposite
 * a block of copy. The widget's `image_height` control writes a fixed px
 * height onto the <img>, so the photo kept its own height no matter how tall
 * the text beside it ran.
 *
 * Stretching the frame alone did NOT fix it: with `height: 100%` on an <img>
 * whose parent has no definite height, the percentage cannot resolve and the
 * image falls back to its intrinsic height — a 4000px photo scaled to column
 * width is enormous, so the IMAGE set the row height and the copy column was
 * left with dead space beneath it. Taking the figure out of flow is what
 * actually reverses the dependency: an absolutely positioned frame
 * contributes nothing to the row, so the copy column alone decides how tall
 * the row is, and the photo then fills exactly that box.
 * ========================================================================== */
.de-frame-fill { align-self: stretch; display: flex; min-height: 0; }
.de-frame-fill > .elementor-widget-container {
	position: relative;
	flex: 1 1 auto;
	min-height: 0;
}
.de-frame-fill .de-c-frame {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
}
.de-frame-fill .de-c-frame__media { flex: 1 1 auto; min-height: 0; }
.de-frame-fill .de-c-frame__media img {
	height: 100% !important;
	width: 100%;
	object-fit: cover;
}

/* Once the row stacks there is no copy column left to match and an absolute
 * frame would collapse to nothing, so hand the height back to the image. */
@media (max-width: 1024px) {
	.de-frame-fill > .elementor-widget-container { position: static; }
	.de-frame-fill .de-c-frame { position: static; }
	.de-frame-fill .de-c-frame__media img { height: 360px !important; }
}
@media (max-width: 767px) {
	.de-frame-fill .de-c-frame__media img { height: 280px !important; }
}
