/* ===================================================================
 * EC COMPONENTS — buttons, cards, forms, badges, eyebrows.
 *
 * Bootstrap 3 + OneUp's button system via .btn / .btn-primary.
 * Override with brand colors; preserve OneUp's transitions where they
 * already work. CTA buttons get the gold accent treatment.
 * ================================================================ */

/* --- Buttons (Bootstrap 3 + OneUp) ---------------------------- */
.btn,
.btn-default,
button[type="submit"],
input[type="submit"] {
	font-family: var(--ec-font-family);
	font-weight: 600;
	letter-spacing: var(--ec-nav-tracking);
	border-radius: var(--ec-radius);
	transition: transform var(--ec-transition),
	            box-shadow var(--ec-transition),
	            background-color var(--ec-transition),
	            color var(--ec-transition);
}

.btn-primary,
.wpb_button.btn-primary,
button[type="submit"],
input[type="submit"] {
	background-color: var(--ec-color-accent);
	border-color: var(--ec-color-accent);
	color: var(--ec-color-primary);
}
.btn-primary:hover,
.btn-primary:focus,
.wpb_button.btn-primary:hover,
button[type="submit"]:hover,
input[type="submit"]:hover {
	background-color: var(--ec-color-accent-dark);
	border-color: var(--ec-color-accent-dark);
	color: var(--ec-color-primary);
	transform: translateY(-2px);
	box-shadow: var(--ec-shadow);
}

/* --- .ec-btn — canonical CTA base (audit 2026-06-01) -------------
 * The single shared button base. Formalizes the gold→gold-dark +
 * translateY + shadow treatment .btn-primary (above) already uses,
 * as a complete, pill, padding-owning, focus-ringed, named class.
 * Global sheet (dep ec-tokens) → uses the --ec-color-* family, NOT
 * the front-page-only --ec-gold/--ec-navy. 999px literal for the
 * pill (--ec-radius is 10px); explicit .2s (var(--ec-transition) is
 * referenced in 02/03 CSS but never emitted → resolves to nothing).
 * Modifiers (--arrow/--sm/--ghost/--icon) land per page as each
 * surface migrates — see
 * docs/superpowers/specs/2026-06-01-home-cta-ec-btn-base-design.md
 * -------------------------------------------------------------- */
.ec-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .5em;
	min-height: 48px;                       /* >=44px tap target for every future variant */
	padding: 15px 30px;
	line-height: 1;
	font-family: var(--ec-font-family);
	font-size: 15px;
	font-weight: 700;
	letter-spacing: .01em;
	text-transform: none;
	border: 1px solid var(--ec-color-accent);
	border-radius: 999px;
	background: var(--ec-color-accent);
	color: var(--ec-color-primary);
	text-decoration: none;
	cursor: pointer;
	transition: transform .2s ease, box-shadow .2s ease,
	            background-color .2s ease, color .2s ease;
}
.ec-btn:hover {
	background: var(--ec-color-accent-dark);
	color: var(--ec-color-primary);         /* explicit — fixes the gold-on-gold-dark hover leak */
	transform: translateY(-2px);
	box-shadow: var(--ec-shadow);
}
.ec-btn:focus-visible {
	outline: 2px solid var(--ec-color-accent);
	outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
	.ec-btn { transition: none; }
	.ec-btn:hover { transform: none; }
}

/* --- Eyebrow / pre-heading label ------------------------------ */
.subtitle-section {
	display: inline-block;
	font-family: var(--ec-font-family);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--ec-color-accent);
	margin-bottom: 12px;
}

/* --- Forms (CF7 + WPBakery) ----------------------------------- */
.wpcf7 input[type="text"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"],
.wpcf7 textarea,
.vc_column input[type="text"],
.vc_column input[type="email"] {
	font-family: var(--ec-font-family);
	border-radius: var(--ec-radius);
	transition: border-color var(--ec-transition),
	            box-shadow var(--ec-transition);
}
.wpcf7 input:focus,
.wpcf7 textarea:focus {
	border-color: var(--ec-color-accent);
	box-shadow: 0 0 0 3px var(--ec-color-accent-tint);
	outline: none;
}


/* --- Testimonial author/company color default ----------------- */
/* OneUp's [testimonials] shortcode (oneup_custom_post_types' style1
 * render) emits author + company in <span class="t-author-style1">
 * — meant for dark-bg sections, so it inherits the demo's white
 * default. EC's "Trusted by leading experts" section sits on white
 * page bg, so author/company render white-on-white and disappear.
 *
 * Set explicit dark color. Same fix would apply to .t-author (the
 * style2 wide variant) if EC ever uses it. */
.t-author-style1,
.t-author-style1 a,
.t-author,
.t-author a {
	color: var(--ec-color-primary) !important;
}

/* --- Feature-tile title color default ------------------------- */
/* Many [bsf-info-box] tiles ship without a title_font_color — the
 * demo authored them only where a non-default was wanted (dark-bg
 * sections like the diff-band photo, the hero-photo band, the
 * Contacts cards). Where it's missing, OneUp's cascade leaves the
 * .aio-icon-title h3 at the demo's white default.
 *
 * Branding.php's `oneup_h3_color` filter doesn't help here because
 * theme-styles.php's emitted rule explicitly excludes h3.aio-icon-
 * title and h3.ult-responsive via :not() — both of which apply to
 * every UVCA info-box title.
 *
 * Default to EC primary so titles are readable on white cards / page
 * bg. Tiles with title_font_color="..." in shortcode emit an inline
 * `style="color:..."` that wins via CSS precedence, so the diff-band
 * (white-on-scrim), hero-photo band (white-on-photo) and contact
 * cards (#111 on white) all keep their authored colors. */
.aio-icon-title:not([style*="color"]) {
	color: var(--ec-color-primary) !important;
}

/* --- Feature-tile icon size ----------------------------------- */
/* Custom-uploaded SVG icons inside [bsf-info-box icon_type="custom"]
 * tiles render at sizes baked into the demo's img_width attribute —
 * 70 px on home, 90 px on /what-we-do/ and /our-work/. The 3–4:1
 * icon-to-label ratio reads icon-led; modern B2B precedent is
 * 1.5–2:1 (icons sized 32–48 px against ~22 px labels). Centralize
 * via --ec-icon-feature so size is config, not per-page string-
 * replace in rebuild-*.php.
 *
 * Scope: .aio-icon-img is the wrapper Ultimate VC Addons emits for
 * the IMG-icon variant only. Font-icon tiles (iconsmind / iconsreso-*)
 * use .aio-icon-default and are unaffected here, so the small list-
 * bullet decorations on /what-we-do/, /our-work/ and /contacts/ keep
 * their authored 15–25 px sizes.
 *
 * !important needed: img_width is emitted as inline `font-size:Npx`
 * on .aio-icon-img and as HTML `width="N" height="N"` on .img-icon.
 * The wrapper's inline style would otherwise outweigh author CSS. */
.aio-icon-img {
	font-size: var(--ec-icon-feature) !important;
}
.aio-icon-img > img.img-icon {
	width: var(--ec-icon-feature) !important;
	height: var(--ec-icon-feature) !important;
}

/* --- Blog post / page tables ---------------------------------- */
/* WordPress Classic Editor tables can have content-based widths that
 * exceed the 375px mobile viewport. OneUp uses .the_content/.postcontent,
 * not .entry-content/.post-content. table-layout:fixed + width:100%
 * forces columns to share the container width regardless of cell content;
 * word-break prevents unbreakable strings from re-opening the overflow. */
.the_content table,
.postcontent table,
.entry-content table,
.post-content table {
	table-layout: fixed !important;
	width: 100% !important;
}
.the_content td,
.the_content th,
.postcontent td,
.postcontent th,
.entry-content td,
.entry-content th {
	word-break: break-word;
	overflow-wrap: break-word;
}

/* --- Section bg-image scrim ----------------------------------- */
/* The "Let's make an Impact together" 4-tile differentiator band on
 * post 6936 (home) sits an [ult_content_box el_class="gradient_box"]
 * over a motion-blur trade-show-floor photo. The photo's bright
 * rim-lit ceiling/wall highlights compete with the white-text labels
 * overlaid on top. Drop a 45 % black scrim between the bg image and
 * the foreground tiles so labels read crisply.
 *
 * Scope: .ult-content-box is the inner element that actually carries
 * the bg image (already position:relative + border-radius:30px from
 * Ultimate VC Addons inline styles), so the ::before attaches there
 * — not on the outer .gradient_box wrapper. The
 * [style*="uploads"] qualifier confines the scrim to instances with
 * a real uploaded bg image: /our-work/ also uses .gradient_box but
 * its bg_image references resolve to background-image:url("") — a
 * 0.45 scrim there would black out the "Trusted by leading experts"
 * testimonial block.
 *
 * border-radius:inherit picks up the 30 px rounded corners from the
 * inline style; without it the scrim is a square that bleeds outside
 * the rounded box. pointer-events:none keeps the "Get a Free Quote"
 * button clickable through the scrim. Direct children get z-index:2
 * so they paint above the ::before within the .ult-content-box
 * stacking context (positioned ::before with z-index:1 would
 * otherwise sit above non-positioned block descendants). */
.gradient_box .ult-content-box[style*="uploads"]::before {
	content: "";
	position: absolute;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.45);
	border-radius: inherit;
	pointer-events: none;
	z-index: 1;
}
.gradient_box .ult-content-box[style*="uploads"] > * {
	position: relative;
	z-index: 2;
}

/* --- WPBakery custom-heading visibility ----------------------- */
/* OneUp's wpb_chars/wpb_lines reveal: js_composer.min.css sets
 *   .wpb_animate_when_almost_visible { opacity: 0 }
 * on the H2 itself. The only restore rule
 *   .charsAnimInLong-1.animated .char { opacity: 1 }
 * targets char children — never the parent. So when the scroll-trigger
 * JS adds .wpb_start_animation and .animated, the chars become visible
 * but the H2 stays at opacity 0 and the whole heading is invisible.
 * Restore parent opacity once either marker class is present.
 *
 * The companion font-size:0 collapse is handled at the source via
 * `pre_option_oneup_h{2,3}_size{,_tablet,_mobile}` filters in
 * branding.php — no CSS override needed. */
.wpb_animate_when_almost_visible.wpb_start_animation,
.wpb_animate_when_almost_visible.animated {
	opacity: 1;
}


/* --- "What we do" feature-card visual upgrade ----------------- *
 * Section 6938 renders 13 [bsf-info-box] tiles, each wrapped in
 * an Ultimate Addons .ult-content-box (white bg, 60px padding,
 * 10px radius, soft shadow — all set inline by OneUp's WPBakery
 * shortcode renderer). Don't fight those inline styles — they
 * make the card. Layer brand-accents on top:
 *
 *   - Idle:  OneUp's white card untouched. Inside, the icon
 *            sits in a gold tile (--ec-color-accent #F9BE17)
 *            with a black SVG icon. Title navy (set by upstream
 *            .aio-icon-title rule), description gray.
 *   - Hover: a 3px gradient stripe (gold → teal #00C9D6, the
 *            two side-faces of the logo's 3D isometric block)
 *            fades in at the card top; the icon tile flips to
 *            navy with the SVG inverted to white; subtle scale
 *            + tilt on the tile.
 *
 * Earlier draft styled .aio-icon-box.left-icon as a card too,
 * which produced a double-bordered nested-card look. Targeting
 * .ult-content-box (the actual card wrapper) keeps it single.
 *
 * Teal #00C9D6 is now in the palette as --ec-color-teal (see
 * assets.php :root builder + config.php EC_COLOR_TEAL).
 *
 * Scope (.section_page-6938) keeps Contacts-card and /what-we-do/
 * page bsf-info-box uses on the existing OneUp styling unchanged. */

.section_page-6938 .ult-content-box-container .ult-content-box {
	position: relative;
	overflow: hidden;
}

.section_page-6938 .ult-content-box-container .ult-content-box::before {
	content: '';
	position: absolute;
	top: 0; left: 0; right: 0;
	height: 3px;
	background: linear-gradient(90deg, var(--ec-color-accent) 0%, var(--ec-color-teal) 100%);
	opacity: 0;
	transition: opacity 280ms ease;
	z-index: 1;
}

.section_page-6938 .ult-content-box-container.hover-effect:hover .ult-content-box::before,
.section_page-6938 .ult-content-box-container .ult-content-box:hover::before {
	opacity: 1;
}

.section_page-6938 .aio-icon-img {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 76px !important;
	height: 76px !important;
	background: var(--ec-color-accent);
	border-radius: 12px;
	transition: background 280ms ease, transform 280ms ease;
}

.section_page-6938 .ult-content-box-container.hover-effect:hover .aio-icon-img,
.section_page-6938 .ult-content-box-container .ult-content-box:hover .aio-icon-img {
	background: var(--ec-color-primary);
	transform: scale(1.04) rotate(-3deg);
}

.section_page-6938 .aio-icon-img > img.img-icon {
	width: 44px !important;
	height: 44px !important;
	filter: brightness(0);
	transition: filter 280ms ease;
}

.section_page-6938 .ult-content-box-container.hover-effect:hover .aio-icon-img > img.img-icon,
.section_page-6938 .ult-content-box-container .ult-content-box:hover .aio-icon-img > img.img-icon {
	filter: brightness(0) invert(1);
}

/* --- Vertical-tabs nav legibility (section 6938) -------------- *
 * OneUp's [verticaltabs] shortcode emits 4 .label tile-buttons in
 * the left rail (rendered as <div class='label 1|2|3|4'> with a
 * <a class='special_tabs_linkage'> title inside). The demo CSS
 * styles inactive tab titles in a near-black color (≈#111111),
 * which renders dark-on-dark against the section's dark cards —
 * tabs 2/3/4 are invisible until interacted with.
 *
 * Force all 4 titles to white for legibility. Active tab gets an
 * EC-gold accent so the active state remains visually distinct
 * (the arrow indicator on .services-7-arrow already differentiates
 * the active card; this color shift reinforces it).
 *
 * Tab body text (.label .title > p) is already legible in OneUp's
 * default; left untouched. Tabbed content panels (.tab-container)
 * are also untouched. */
.section_page-6938 .special_tabs .label .title a.special_tabs_linkage {
	color: #ffffff !important;
}

.section_page-6938 .special_tabs .label.current .title a.special_tabs_linkage,
.section_page-6938 .special_tabs .label:hover .title a.special_tabs_linkage {
	color: var(--ec-color-accent) !important;
}

/* --- Vertical-tabs right-column image grid (section 6938) ---- *
 * Each tab's right column shows 2–4 [vc_single_image] boxes that
 * carry the source image's intrinsic aspect ratio through. Tabs
 * 1/2/4 are 2-up with mixed landscapes/portraits; Tab 3 was a
 * 2×2 grid of 4 client photos.
 *
 * Lock to a uniform 16:10 landscape per slot, 2-up, regardless
 * of tab. Tab 3's 3rd and 4th images are hidden via :nth-of-type
 * so the visual stays consistent on every tab click — no more
 * grid-shape whiplash.
 *
 * `.tab-container` is OneUp's container for the active panel's
 * content (the left .tab-selector is unaffected, so tab buttons
 * keep their own sizing). */

.section_page-6938 .special_tabs .tab-container .wpb_single_image,
.section_page-6938 .special_tabs .tab-container .vc_single_image-wrapper {
	aspect-ratio: 16 / 10;
	overflow: hidden;
	border-radius: 8px;
}

.section_page-6938 .special_tabs .tab-container .vc_single_image-wrapper img,
.section_page-6938 .special_tabs .tab-container .wpb_single_image img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover;
	object-position: center;
}

/* Tab 3 (Living Optics) flatten 2×2 → 2-up: hide 3rd + 4th image. */
.section_page-6938 .special_tabs .tab-container .wpb_single_image:nth-of-type(n+3) {
	display: none;
}

/* --- "Who we are" client showcase cards (section 6936) -------- *
 * The OneUp demo's [ult_team] team-member component was repurposed
 * by the rebuild as a 4-card client showcase (Adaptive Shield,
 * Living Optics, Kornit Digital, Sweet Security booth photos).
 * Three issues with the demo carryover:
 *
 *   1. Image aspect ratios bleed through — Living Optics is portrait
 *      while the others are landscape. Lock to a uniform 4:5 portrait
 *      card with object-fit cover.
 *   2. Empty social-icon links (href="#" Dribbble/Facebook/Twitter)
 *      render as 3 white squares on the dark photo. Hide outright —
 *      EC isn't selling team-member follow buttons.
 *   3. The empty `.ult-team-member-bio-wrap > h2` is blank but takes
 *      vertical space. Hide.
 *
 * The description overlay (h5 client name + p industry tag) is moved
 * to an always-visible bottom gradient — readable on scroll, not
 * hidden behind a hover-only state. EC gold underlines the client
 * name; the industry tag is small uppercase white at 78% opacity.
 *
 * Demo names ("Lucas Manuel" / "Art director" etc.) are replaced
 * via $REPLACEMENTS in rebuild-homepage.php with the actual client
 * names + their industry verticals (Identity Security, Optical
 * Sensing, Digital Print, Cloud Security). */

.section_page-6936 .ult-team-member-image {
	position: relative;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	border-radius: 8px;
	background-color: #111111 !important;
}

.section_page-6936 .ult-team-member-image > img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover;
	object-position: center;
	transition: transform 380ms ease;
}

.section_page-6936 .ult-team-member-image:hover > img {
	transform: scale(1.06);
}

/* Description: absolute bottom overlay, gold-accented client name. */
.section_page-6936 .ult-team-member-description {
	position: absolute !important;
	bottom: 0 !important;
	left: 0 !important;
	right: 0 !important;
	margin: 0 !important;
	padding: 70px 20px 20px !important;
	background: linear-gradient(180deg, transparent 0%, rgba(4,23,26,0.88) 70%) !important;
	color: #ffffff !important;
	pointer-events: none;
}

.section_page-6936 .ult-team-member-description > p {
	margin: 0 !important;
}

.section_page-6936 .ult-team-member-description .team-item-detail-title {
	color: #ffffff !important;
	font-size: 18px !important;
	font-weight: 600 !important;
	margin: 0 0 6px !important;
	border-bottom: 2px solid var(--ec-color-accent);
	padding-bottom: 4px;
	display: inline-block;
}

.section_page-6936 .ult-team-member-description p:not(.team-item-detail-title) {
	color: rgba(255,255,255,0.78) !important;
	font-size: 12px !important;
	letter-spacing: 0.8px !important;
	text-transform: uppercase !important;
	margin: 4px 0 0 !important;
}

.section_page-6936 .ult-social-buttons,
.section_page-6936 .ult-team-member-bio-wrap {
	display: none !important;
}

/* Phase 4b (section 6936) — right-column showcase overflow.
 * Spec: docs/spec-home-6936-visual-design-v2.md §3 Phase 4 + §5 Q-4b + §1h.
 *
 * mcp playwright probed slot-3 (post-Phase-3: Innoviz-01.jpeg) at 1440 viewport
 * and measured imgRight=1373, parent .vc_row right=1358 — a +15px overflow.
 *
 * Initial fix attempted `max-width: 100%` on the img + wrapper, but a re-probe
 * showed the overflow persists because it lives at the COLUMN level, not the
 * img level: the img is 249px (fits comfortably inside its 675px col), but
 * its parent inner row `.vc_row.vc_inner.without-padding` carries WPBakery's
 * `margin: 0 -15px` grid pattern. That negative right-margin extends the
 * inner row 15px past the section's content area (the .container at right=1343
 * + 15px gutter = 1358). Slots 1 + 2 are left/center-aligned inside their
 * cols and don't reach the right edge; slot 3 is right-aligned, so its img
 * lands at the inner-row's overflowing right edge (1373).
 *
 * Targeted fix: zero out the right margin on the photo-collage inner row.
 * Selector is tightly scoped (`.call-action-2-images > .vc_column-inner >
 * .wpb_wrapper > .vc_row.vc_inner.without-padding`) so it cannot leak to the
 * credibility-row inner row (which lives in the LEFT column, outside
 * `.call-action-2-images`). Slots 1 + 2 maintain their visual position
 * because their imgs are left/center-anchored — only slot 3's right edge
 * shifts (from 1373 -> 1358, exactly the +15px we wanted to remove).
 *
 * The `max-width: 100%` on wrapper/img stays as a defensive lock so a future
 * intrinsic-size change can't blow the column width either. No !important
 * needed — there's no upstream cascade fighting max-width or margin here.
 */
.section_page-6936 .call-action-2-images > .vc_column-inner > .wpb_wrapper > .vc_row.vc_inner.without-padding {
	margin-right: 0;
}

.section_page-6936 .vc_single_image-wrapper,
.section_page-6936 .vc_single_image-wrapper img {
	max-width: 100%;
	height: auto;
}

/* ============================================================
 * Home 6936 — "Where craft meets impact" right column simplified
 * to a SINGLE focal image (client request 2026-06-02).
 *
 * The demo collage stacks 3 parallax images (.call-action-2-image-1
 * top / -2 middle / -3 bottom) plus a decorative .absolute-element-
 * top-right badge. Per request we keep ONLY the middle image (-2, the
 * wide booth-floor shot), drop the top + bottom, and center the
 * survivor in the column as the focal point. CSS-only: the collage
 * rows live in the demo post_content (DB), not in rebuild-homepage.php,
 * so hiding here is the surgical, reversible move.
 * ============================================================ */

/* hide top + bottom images and the empty rotating badge */
.section_page-6936 .call-action-2-image-1,
.section_page-6936 .call-action-2-image-3,
.section_page-6936 .absolute-element-top-right {
	display: none !important;
}

/* collapse the now-empty parallax rows (top + bottom) so they leave no gap */
.section_page-6936 .call-action-2-images .vc_row.vc_inner:has(.call-action-2-image-1),
.section_page-6936 .call-action-2-images .vc_row.vc_inner:has(.call-action-2-image-3) {
	display: none !important;
}

/* vertical-center the surviving middle image against the text column */
.section_page-6936 .call-action-2-images > .vc_column-inner {
	display: flex;
	flex-direction: column;
	justify-content: center;
	height: 100%;
}

/* the focal image: kill parallax drift, fill the column, rounded + soft shadow */
.section_page-6936 .call-action-2-image-2 {
	transform: none !important;   /* freeze the rellax translate so it stays centered */
}
.section_page-6936 .call-action-2-image-2 .vc_single_image-wrapper {
	display: block;
	width: 100% !important;
	max-width: 100% !important;
	margin: 0 auto;
	border-radius: 18px;
	overflow: hidden;
	box-shadow: 0 26px 60px -22px rgba(4, 23, 26, 0.38);
}
.section_page-6936 .call-action-2-image-2 img {
	width: 100%;
	height: auto;
	display: block;
}

/* ============================================================
 * Homepage — unify EVERY CTA button onto the header pill
 * (.ec-header__cta): gold pill, navy text, 1px gold border, hover
 * flips to transparent bg + gold text. (client request 2026-06-02)
 *
 * Collapses the two button systems colliding on this page into one:
 *   - legacy Ultimate VC [ult_buttons] -> <button.ubtn> in every size +
 *     icon mode (ubtn-large stacked, ubtn-sep-icon-at-left/right)
 *   - the Contact Form 7 submit (#6942 "Send Message")
 * and aligns the already-migrated hero .ec-btn hover to the same flip,
 * so the whole page reads as one button family.
 *
 * All three .ubtn variants share one DOM order [icon, hover, text], so
 * a single row-reverse gives every button a uniform TRAILING icon.
 * Dimensions mirror the canonical .ec-btn base (15/700, pad 15x30,
 * 999px, min-height 48). Scoped to body.home so interior pages keep
 * the global .ec-btn base and any other [ult_buttons] untouched.
 *
 * Ultimate VC writes inline bg/color styles + a .ubtn-hover overlay
 * span, so every property needs !important and the overlay is killed
 * to let the hover read transparent like the header. Tracks the SAME
 * tokens the header uses (--ec-color-accent / --ec-h-bg).
 * ============================================================ */

/* pill shell — all homepage ubtn + the CF7 submit */
body.home .ubtn,
body.home input.wpcf7-submit {
	display: inline-flex !important;
	flex-direction: row-reverse;          /* DOM [icon,text] -> text left, icon right */
	align-items: center;
	justify-content: center;
	gap: .5em;
	width: auto !important;
	min-height: 48px;
	padding: 15px 30px !important;
	border-radius: 999px !important;      /* full pill, like the header CTA */
	background: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	border: 1px solid var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	box-shadow: none !important;
	color: var(--ec-h-bg, #04171A) !important;     /* CF7 submit: text is the element itself */
	font-weight: 700 !important;
	font-size: 15px !important;
	letter-spacing: .3px !important;
	text-transform: none !important;
	transition: background .15s, color .15s, border-color .15s !important;
}

/* ubtn inner spans → navy on gold. The sep-icon modes pin .ubtn-icon
 * position:absolute (left/right) and reserve text padding for it; force
 * it back into the flex flow + zero the reserved padding so row-reverse
 * trails EVERY icon uniformly (matching the ubtn-large arrow). */
body.home .ubtn .ubtn-text {
	color: var(--ec-h-bg, #04171A) !important;
	font-weight: 700 !important;
	font-size: 15px !important;
	letter-spacing: .3px !important;
	text-transform: none !important;
	padding: 0 !important;
}
body.home .ubtn .ubtn-icon {
	position: static !important;          /* was absolute in sep-icon mode */
	margin: 0 !important;
	padding: 0 !important;
	display: inline-flex !important;
	background: transparent !important;
	border: 0 !important;
}
body.home .ubtn .ubtn-icon i {
	color: var(--ec-h-bg, #04171A) !important;
	font-size: 17px !important;
}

/* Both "Get a Free Quote" CTAs should be icon-free (client request
 * 2026-06-02) — the header CTA has no icon. The two instances carry DIFFERENT
 * demo glyphs: #6936 a person-check, #6938 an arrow. Drop #6936 by glyph (so
 * the other arrow buttons keep theirs) and #6938 by section (its only .ubtn).
 * Hiding the whole .ubtn-icon (not just the <i>) keeps the flex gap clean. */
body.home .ubtn .ubtn-icon:has(i.iconsreso-user-check),
body.home .section_page-6938 .ubtn .ubtn-icon {
	display: none !important;
}

/* kill the fade-overlay so the hover can read transparent */
body.home .ubtn .ubtn-hover {
	display: none !important;
}

/* hover: transparent bg + gold text/icon + gold border (header behavior).
 * Applied to ubtn, the CF7 submit, AND the hero .ec-btn (overriding its
 * gold-dark+lift hover) so the whole homepage hovers identically. */
body.home .ubtn:hover,
body.home .ubtn-link:hover .ubtn,
body.home input.wpcf7-submit:hover,
body.home .ec-btn:hover {
	background: transparent !important;
	color: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	border-color: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	transform: none !important;
	box-shadow: none !important;
}
body.home .ubtn:hover .ubtn-text,
body.home .ubtn:hover .ubtn-icon i,
body.home .ubtn-link:hover .ubtn .ubtn-text,
body.home .ubtn-link:hover .ubtn .ubtn-icon i {
	color: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
}

/* The EC editorial CTA (.ec-cta-btn — "See All Projects" in the projects
 * preview) is the 4th button family here. It is already a gold pill but
 * uppercase + wide-tracked, border-less, with a transform-only hover and
 * a ::after "→". Normalize it to the same header pill on the homepage
 * (keeping the arrow). Selector body.home .ec-our-projects a.ec-cta-btn
 * (0,0,3,3) beats our-projects.css's tightest rule
 * .ec-our-projects .ec-closing .ec-cta-btn (0,0,3,0) on font-size +
 * letter-spacing. Scoped to body.home so /our-projects/ + interior pages
 * keep the editorial uppercase style. */
body.home .ec-our-projects a.ec-cta-btn {
	padding: 15px 30px !important;
	border: 1px solid var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	border-radius: 999px !important;
	background: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	color: var(--ec-h-bg, #04171A) !important;
	font-size: 15px !important;
	font-weight: 700 !important;
	letter-spacing: .3px !important;
	text-transform: none !important;
	transition: background .15s, color .15s, border-color .15s !important;
}
body.home .ec-our-projects a.ec-cta-btn:hover {
	background: transparent !important;
	color: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	border-color: var(--ec-color-accent, var(--ec-h-gold, #F9BE17)) !important;
	transform: none !important;
}

/* Section 6938 ("What we do") — stop the Cato image from clipping the
 * "Get a Free Quote" pill (client report 2026-06-02). The image is the
 * immediate next sibling of the CTA's container and its wrapper carries an
 * editorial margin-top:-20px (vc_custom_1741364808866) that tucks it up over
 * the button's bottom ~20px; as a parallax-mousemove element it owns a
 * stacking context and paints OVER the pill, cutting its rounded bottom.
 * (Only at desktop widths where the image shows — it's disable-mobile hidden
 * below ~1025px.) Replace the negative tuck with a small positive gap so the
 * pill is never overlapped. 6938 has exactly one .wpb_single_image, so this
 * is precise; (0,0,3,1) outranks the vc_custom_* !important rule (0,0,1,0). */
body.home .section_page-6938 .wpb_single_image {
	margin-top: 18px !important;
}

/* Home cube portfolio (#cbpw-grid198) — uniform tile heights.
 *
 * Root cause: layout 198 ships as cbp-l-grid-masonry. Cube portfolio's JS
 * init reads each image's natural aspect ratio (via imagesLoaded.js) and
 * sets a per-item height ≈ column_width × (naturalH / naturalW). The 6 EC
 * tiles span mixed ratios — Cato-01 1:1 (1080×1080), Adaptive-Shield 4:3
 * (1600×1200), Sweet/Innoviz/LO-cropped ~3:4 portrait, Tama-booth ~4:3 —
 * so masonry produces 293–568px-tall cells at a 420px column (measured
 * live on staging at 1440 viewport).
 *
 * Cube portfolio JS rewrites the DOM on init: the original
 * <div id="cbpw-grid198" class="cbp-l-grid-masonry cbp"> becomes
 * id="cbpw-grid198" class="cbp-wrapper-outer" with .cbp-l-grid-masonry
 * pushed onto an inner element. So scope the override on the id chain
 * `#cbpw-wrap198 .cbp-l-grid-masonry` (descendant), NOT on the id alone.
 *
 * Switching layout 198's type from masonry to mosaic in the DB would also
 * work, but cube portfolio's JS still computes absolute positions either
 * way and we'd be coupled to its grid math. Instead, bypass the JS layout
 * entirely with CSS Grid scoped to this one grid. !important defeats the
 * inline `style="height: 980px"` on the masonry wrapper and the inline
 * `style="width: 420px; left: 0; top: 0"` on each .cbp-item.
 *
 * Filter UI is not used on this layout (no [cubeportfolio_filter]
 * shortcode), so disabling masonry's animated reflow has no UX cost.
 * Hover overlay (.cbp-caption-activeWrap) keeps working — it's positioned
 * relative to .cbp-caption (the <a>), which we leave at its computed
 * default.
 */
#cbpw-wrap198 .cbp-l-grid-masonry,
#cbpw-wrap198 #cbpw-grid198 {
	height: auto !important;
	position: static !important;
}

#cbpw-wrap198 #cbpw-grid198 > .cbp-wrapper {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
	height: auto !important;
	position: static !important;
}

#cbpw-wrap198 #cbpw-grid198 > .cbp-wrapper > .cbp-item {
	position: static !important;
	top: auto !important;
	left: auto !important;
	width: auto !important;
	height: auto !important;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	padding: 0 !important;
}

#cbpw-wrap198 .cbp-item .cbp-caption,
#cbpw-wrap198 .cbp-item .cbp-caption-defaultWrap {
	display: block;
	width: 100%;
	height: 100%;
}

#cbpw-wrap198 .cbp-item img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover !important;
	object-position: center !important;
	position: relative !important;
	top: auto !important;
	left: auto !important;
}

@media (max-width: 768px) {
	#cbpw-wrap198 #cbpw-grid198 > .cbp-wrapper { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 480px) {
	#cbpw-wrap198 #cbpw-grid198 > .cbp-wrapper { grid-template-columns: 1fr; }
}

/* iconsreso webfont — restore missing @font-face for the OneUp icon font.
 *
 * Root cause (verified 2026-05-08): the OneUp theme's style.css references
 * font-family: 'iconsreso' on .iconsreso-* selectors and defines per-glyph
 * codepoints (e.g., .iconsreso-arrow-right:before { content: "\e906" }),
 * but the bundle ships NO @font-face declaration and NO font file inside
 * /wp-content/themes/oneup/. Confirmed by listing icon-fonts/ on staging —
 * fontawesome / WooCommerce / star fonts present, no iconsreso.*.
 * document.fonts had 115 families on first audit, none 'iconsreso'.
 *
 * Result without this rule: 22 .iconsreso-* glyphs across the home page
 * render as empty <i> tags — where a parent .aio-icon has a styled disc
 * (bg-color + border-radius:50%), the disc shows but no glyph. Most
 * visible failure was the "Open the map" toggle in section 6942 contacts
 * (black circle with no pin) and the 7 "Why Choose Us" check-disc cards.
 *
 * The actual font file ships in the OneUp distribution but in a separate
 * Resources/iconsreso-v1.0.zip — a deploy step the install never executed.
 * Codepoints in the package's style.css match those in OneUp's style.css
 * 1:1 (verified arrow-right=\e906, location=\e969, check=\e91a, etc.) so
 * loading the font here makes every existing rule in oneup/style.css
 * resolve correctly without further per-class overrides.
 *
 * Files committed to prod/mu-plugins/ec/assets/fonts/iconsreso/. Hosting
 * the font with the mu-plugin co-locates it with the CSS that uses it
 * and survives any future theme update.
 */
@font-face {
	font-family: 'iconsreso';
	src: url('../fonts/iconsreso/iconsreso.eot');
	src: url('../fonts/iconsreso/iconsreso.eot?#iefix') format('embedded-opentype'),
		url('../fonts/iconsreso/iconsreso.woff') format('woff'),
		url('../fonts/iconsreso/iconsreso.ttf') format('truetype');
	font-weight: normal;
	font-style: normal;
	font-display: block;
}

[class^="iconsreso-"]::before,
[class*=" iconsreso-"]::before {
	font-family: 'iconsreso' !important;
	speak: never;
	font-style: normal;
	font-weight: normal;
	font-variant: normal;
	text-transform: none;
	line-height: 1;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* iconsreso glyph codepoints — ported from
 * Resources/iconsreso-v1.0/style.css (OneUp distribution). The package's
 * rules use `.icon-X:before { content: "\eXXX" }` (their own prefix);
 * OneUp's templates emit `.iconsreso-X` (theme-prefixed). Same codepoints,
 * different class names, so the package's rules don't match OneUp's HTML.
 * Below is the package's rule set with the prefix renamed `icon-` →
 * `iconsreso-`. 189 glyphs, covers every iconsreso-* class the OneUp
 * theme can emit; future iconsreso uses also resolve without needing
 * extra rules.
 *
 * The font-family / antialiasing setup is in the [class^="iconsreso-"]
 * block above; per-class rules below ONLY supply content codepoints.
 */
.iconsreso-x-twitter:before {
  content: "\e931";
}
.iconsreso-quotation-mark:before {
  content: "\e934";
}
.iconsreso-star-rate:before {
  content: "\e935";
}
.iconsreso-star-rate-a:before {
  content: "\e936";
}
.iconsreso-globe1:before {
  content: "\e937";
}
.iconsreso-info:before {
  content: "\e938";
}
.iconsreso-arrow-left2:before {
  content: "\e939";
}
.iconsreso-arrow-right2:before {
  content: "\e93b";
}
.iconsreso-arrow-down1:before {
  content: "\e93c";
}
.iconsreso-arrow-up1:before {
  content: "\e93d";
}
.iconsreso-arrow-down11:before {
  content: "\e93e";
}
.iconsreso-arrow-up11:before {
  content: "\e93f";
}
.iconsreso-arrow-left1:before {
  content: "\e940";
}
.iconsreso-arrow-right1:before {
  content: "\e941";
}
.iconsreso-play:before {
  content: "\e942";
}
.iconsreso-arrow-right3:before {
  content: "\e943";
}
.iconsreso-location1:before {
  content: "\e92f";
}
.iconsreso-contacts:before {
  content: "\e930";
}
.iconsreso-svg-path17:before {
  content: "\e92c";
}
.iconsreso-svg-path-37:before {
  content: "\e916";
}
.iconsreso-svg-path-36:before {
  content: "\e917";
}
.iconsreso-svg-path-35:before {
  content: "\e918";
}
.iconsreso-svg-path-34:before {
  content: "\e919";
}
.iconsreso-svg-path-33:before {
  content: "\e91b";
}
.iconsreso-svg-path-32:before {
  content: "\e91c";
}
.iconsreso-svg-path-31:before {
  content: "\e91d";
}
.iconsreso-svg-path-30:before {
  content: "\e91e";
}
.iconsreso-svg-path-29:before {
  content: "\e91f";
}
.iconsreso-svg-path-28:before {
  content: "\e920";
}
.iconsreso-svg-path-27:before {
  content: "\e921";
}
.iconsreso-svg-path-26:before {
  content: "\e922";
}
.iconsreso-svg-path-25:before {
  content: "\e923";
}
.iconsreso-svg-path-24:before {
  content: "\e924";
}
.iconsreso-svg-path-23:before {
  content: "\e925";
}
.iconsreso-svg-path-22:before {
  content: "\e926";
}
.iconsreso-svg-path-21:before {
  content: "\e927";
}
.iconsreso-svg-path-20:before {
  content: "\e928";
}
.iconsreso-svg-path-19:before {
  content: "\e92a";
}
.iconsreso-svg-path-18:before {
  content: "\e92b";
}
.iconsreso-svg-path-16:before {
  content: "\e92d";
}
.iconsreso-svg-path-15:before {
  content: "\e92e";
}
.iconsreso-svg-path-14:before {
  content: "\e90b";
}
.iconsreso-svg-path-12:before {
  content: "\e90c";
}
.iconsreso-svg-path-13:before {
  content: "\e90d";
}
.iconsreso-svg-path-11:before {
  content: "\e90e";
}
.iconsreso-svg-path-10:before {
  content: "\e90f";
}
.iconsreso-svg-path-9:before {
  content: "\e910";
}
.iconsreso-svg-path-8:before {
  content: "\e911";
}
.iconsreso-svg-path-7:before {
  content: "\e912";
}
.iconsreso-svg-path-6:before {
  content: "\e913";
}
.iconsreso-svg-path-5:before {
  content: "\e914";
}
.iconsreso-svg-path-4:before {
  content: "\e915";
}
.iconsreso-svg-path-1:before {
  content: "\e900";
}
.iconsreso-svg-path-2:before {
  content: "\e901";
}
.iconsreso-svg-path-3:before {
  content: "\e90a";
}
.iconsreso-arrow-down:before {
  content: "\e902";
}
.iconsreso-arrow-left:before {
  content: "\e903";
}
.iconsreso-arrow-left-down:before {
  content: "\e904";
}
.iconsreso-arrow-left-up:before {
  content: "\e905";
}
.iconsreso-arrow-right:before {
  content: "\e906";
}
.iconsreso-arrow-right-down:before {
  content: "\e907";
}
.iconsreso-arrow-right-up:before {
  content: "\e908";
}
.iconsreso-arrow-up:before {
  content: "\e909";
}
.iconsreso-check:before {
  content: "\e91a";
}
.iconsreso-circle-check:before {
  content: "\e929";
}
.iconsreso-computer:before {
  content: "\e93a";
}
.iconsreso-email:before {
  content: "\e94b";
}
.iconsreso-favorite:before {
  content: "\e952";
}
.iconsreso-heart1:before {
  content: "\e95e";
}
.iconsreso-laptop1:before {
  content: "\e963";
}
.iconsreso-link-alt:before {
  content: "\e967";
}
.iconsreso-location:before {
  content: "\e969";
}
.iconsreso-message:before {
  content: "\e970";
}
.iconsreso-message-alt:before {
  content: "\e971";
}
.iconsreso-mobile1:before {
  content: "\e973";
}
.iconsreso-search1:before {
  content: "\e988";
}
.iconsreso-user:before {
  content: "\e9a7";
}
.iconsreso-user-check:before {
  content: "\e9a9";
}
.iconsreso-users:before {
  content: "\e9ab";
}
.iconsreso-window:before {
  content: "\e9b1";
}
.iconsreso-mobile:before {
  content: "\e000";
}
.iconsreso-laptop:before {
  content: "\e001";
}
.iconsreso-desktop:before {
  content: "\e002";
}
.iconsreso-tablet:before {
  content: "\e003";
}
.iconsreso-phone:before {
  content: "\e004";
}
.iconsreso-document:before {
  content: "\e005";
}
.iconsreso-documents:before {
  content: "\e006";
}
.iconsreso-search:before {
  content: "\e007";
}
.iconsreso-clipboard:before {
  content: "\e008";
}
.iconsreso-newspaper:before {
  content: "\e009";
}
.iconsreso-notebook:before {
  content: "\e00a";
}
.iconsreso-book-open:before {
  content: "\e00b";
}
.iconsreso-browser:before {
  content: "\e00c";
}
.iconsreso-calendar:before {
  content: "\e00d";
}
.iconsreso-presentation:before {
  content: "\e00e";
}
.iconsreso-picture:before {
  content: "\e00f";
}
.iconsreso-pictures:before {
  content: "\e010";
}
.iconsreso-video:before {
  content: "\e011";
}
.iconsreso-camera:before {
  content: "\e012";
}
.iconsreso-printer:before {
  content: "\e013";
}
.iconsreso-toolbox:before {
  content: "\e014";
}
.iconsreso-briefcase:before {
  content: "\e015";
}
.iconsreso-wallet:before {
  content: "\e016";
}
.iconsreso-gift:before {
  content: "\e017";
}
.iconsreso-bargraph:before {
  content: "\e018";
}
.iconsreso-grid:before {
  content: "\e019";
}
.iconsreso-expand:before {
  content: "\e01a";
}
.iconsreso-focus:before {
  content: "\e01b";
}
.iconsreso-edit:before {
  content: "\e01c";
}
.iconsreso-adjustments:before {
  content: "\e01d";
}
.iconsreso-ribbon:before {
  content: "\e01e";
}
.iconsreso-hourglass:before {
  content: "\e01f";
}
.iconsreso-lock:before {
  content: "\e020";
}
.iconsreso-megaphone:before {
  content: "\e021";
}
.iconsreso-shield:before {
  content: "\e022";
}
.iconsreso-trophy:before {
  content: "\e023";
}
.iconsreso-flag:before {
  content: "\e024";
}
.iconsreso-map:before {
  content: "\e025";
}
.iconsreso-puzzle:before {
  content: "\e026";
}
.iconsreso-basket:before {
  content: "\e027";
}
.iconsreso-envelope:before {
  content: "\e028";
}
.iconsreso-streetsign:before {
  content: "\e029";
}
.iconsreso-telescope:before {
  content: "\e02a";
}
.iconsreso-gears:before {
  content: "\e02b";
}
.iconsreso-key:before {
  content: "\e02c";
}
.iconsreso-paperclip:before {
  content: "\e02d";
}
.iconsreso-attachment:before {
  content: "\e02e";
}
.iconsreso-pricetags:before {
  content: "\e02f";
}
.iconsreso-lightbulb:before {
  content: "\e030";
}
.iconsreso-layers:before {
  content: "\e031";
}
.iconsreso-pencil:before {
  content: "\e032";
}
.iconsreso-tools:before {
  content: "\e033";
}
.iconsreso-tools-2:before {
  content: "\e034";
}
.iconsreso-scissors:before {
  content: "\e035";
}
.iconsreso-paintbrush:before {
  content: "\e036";
}
.iconsreso-magnifying-glass:before {
  content: "\e037";
}
.iconsreso-circle-compass:before {
  content: "\e038";
}
.iconsreso-linegraph:before {
  content: "\e039";
}
.iconsreso-mic:before {
  content: "\e03a";
}
.iconsreso-strategy:before {
  content: "\e03b";
}
.iconsreso-beaker:before {
  content: "\e03c";
}
.iconsreso-caution:before {
  content: "\e03d";
}
.iconsreso-recycle:before {
  content: "\e03e";
}
.iconsreso-anchor:before {
  content: "\e03f";
}
.iconsreso-profile-male:before {
  content: "\e040";
}
.iconsreso-profile-female:before {
  content: "\e041";
}
.iconsreso-bike:before {
  content: "\e042";
}
.iconsreso-wine:before {
  content: "\e043";
}
.iconsreso-hotairballoon:before {
  content: "\e044";
}
.iconsreso-globe:before {
  content: "\e045";
}
.iconsreso-genius:before {
  content: "\e046";
}
.iconsreso-map-pin:before {
  content: "\e047";
}
.iconsreso-dial:before {
  content: "\e048";
}
.iconsreso-chat:before {
  content: "\e049";
}
.iconsreso-heart:before {
  content: "\e04a";
}
.iconsreso-cloud:before {
  content: "\e04b";
}
.iconsreso-upload:before {
  content: "\e04c";
}
.iconsreso-download:before {
  content: "\e04d";
}
.iconsreso-target:before {
  content: "\e04e";
}
.iconsreso-hazardous:before {
  content: "\e04f";
}
.iconsreso-piechart:before {
  content: "\e050";
}
.iconsreso-speedometer:before {
  content: "\e051";
}
.iconsreso-global:before {
  content: "\e052";
}
.iconsreso-compass:before {
  content: "\e053";
}
.iconsreso-lifesaver:before {
  content: "\e054";
}
.iconsreso-clock:before {
  content: "\e055";
}
.iconsreso-aperture:before {
  content: "\e056";
}
.iconsreso-quote:before {
  content: "\e057";
}
.iconsreso-scope:before {
  content: "\e058";
}
.iconsreso-alarmclock:before {
  content: "\e059";
}
.iconsreso-refresh:before {
  content: "\e05a";
}
.iconsreso-happy:before {
  content: "\e05b";
}
.iconsreso-sad:before {
  content: "\e05c";
}
.iconsreso-facebook:before {
  content: "\e05d";
}
.iconsreso-twitter:before {
  content: "\e05e";
}
.iconsreso-googleplus:before {
  content: "\e05f";
}
.iconsreso-rss:before {
  content: "\e060";
}
.iconsreso-tumblr:before {
  content: "\e061";
}
.iconsreso-linkedin:before {
  content: "\e062";
}
.iconsreso-dribbble:before {
  content: "\e063";
}
.iconsreso-display:before {
  content: "\e956";
}
.iconsreso-mobile2:before {
  content: "\e958";
}
.iconsreso-mobile21:before {
  content: "\e959";
}
.iconsreso-equalizer2:before {
  content: "\e993";
}
.iconsreso-gift1:before {
  content: "\e99f";
}
.iconsreso-cloud-check:before {
  content: "\e9c4";
}
.iconsreso-star-empty:before {
  content: "\e9d7";
}
.iconsreso-star-half:before {
  content: "\e9d8";
}
.iconsreso-star-full:before {
  content: "\e9d9";
}

/* =========================================================================
 * Home 6936 — McLean Humvee booth hero (industrial-editorial)
 *
 * Spec: docs/superpowers/specs/2026-05-11-home-6936-industrial-editorial-polish.md
 *
 * Hard-edge 38vw dark panel on the left + editorial typesetting + teal
 * hairline under headline + editorial <ol> numbered trust list. Replaces
 * the OneUp "creative-agency soft gradient overlay" treatment with
 * something that reflects EC's actual brand (we build walls, not gradients).
 * ========================================================================= */
.ec-hero-mclean { position: relative; }

/* `.upb_row_bg` is the Ultimate-Addons photo layer — and the FULL-BLEED one
 * (bg_override="ex-full" → the plugin sets it position:absolute, width:100vw).
 * Force it to z-index 0 so it sits below the column content (z-index 2). The dark
 * scrim is painted as `.upb_row_bg::after` (below) so it shares this layer's
 * full-bleed geometry and covers the photo edge to edge; it renders above the
 * photo (a pseudo on the bg element) and below the content (z0 stacking context
 * vs the z2 column). Originally the scrim lived on the contained row's ::before,
 * which left the photo's margins exposed at desktop widths.
 *
 * Photo swap (Build Spec, 2026-06-27): override the McLean attachment with a
 * clean own-project booth — Innoviz CES 2024, a premium dark automotive build
 * that recedes dark on the right under the scrim and carries no competing
 * baked-in headline (McLean's "SURVIVABILITY DONE DIFFERENTLY" screen fought
 * the hero copy). Root-relative URL keeps it portable across staging/prod,
 * mirroring the foretellix Impact-band override further below; the McLean
 * attachment stays as the WPBakery fallback in post_content. */
.ec-hero-mclean .upb_row_bg {
	z-index: 0 !important;
	background-image: url('/wp-content/uploads/innoviz-hero-booth.jpg') !important;
	background-position: center 42% !important;
	background-size: cover !important;
}

/* Right-anchored "wall" scrim — painted on the PHOTO LAYER (.upb_row_bg), not the
 * contained row. The row content is constrained to the site container (~992px),
 * but the photo breaks out to the full viewport (WPBakery bg_override="ex-full":
 * the plugin sets .upb_row_bg to position:absolute; width:100vw; left:-<gutter>).
 * A scrim anchored to the row (::before) therefore left ~72px+ of raw photo
 * exposed in each margin — and the Innoviz shot's right edge is colorful
 * background booths ("Togo"), so it read as an image bleeding off the right side.
 * Putting the scrim on .upb_row_bg::after makes it inherit the plugin's full-bleed
 * geometry at every width (no 100vw scrollbar risk), so it covers the photo edge
 * to edge. Renders above the photo (pseudo on the bg layer) and below the content
 * (the column is z-index:2; .upb_row_bg is its own z-index:0 stacking context).
 *
 * The hero's content column sits in the RIGHT half (OneUp "One page 5" layout),
 * so the dark sits right — behind headline / spec list / CTA — and feathers open
 * left so the booth photo carries the left of the frame. The right ~44% stays
 * near-opaque (small text fully legible); the feather is short so it reads as a
 * wall edge, not a creative-agency wash. */
.ec-hero-mclean .upb_row_bg::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to left,
		rgba(4, 23, 26, 0.95) 0%,
		rgba(4, 23, 26, 0.94) 44%,
		rgba(4, 23, 26, 0.62) 60%,
		rgba(4, 23, 26, 0.16) 82%,
		rgba(4, 23, 26, 0.06) 100%);
	pointer-events: none;
}

.ec-hero-mclean > .vc_column-inner,
.ec-hero-mclean .wpb_column,
.ec-hero-mclean .wpb_wrapper { position: relative; z-index: 2; }

/* Eyebrow — the single typographic signature. IBM Plex Mono names the service
 * like a drawing title-block ("spec stamp"); the short gold tick is the only
 * decorative mark, replacing the old full-width green underline that ran under
 * the headline and encoded nothing. Bright --ec-green (not --ec-green-text,
 * which resolves to the dark #13805F ink outside the hero whitelist) stays
 * AA-legible on the navy scrim. */
.ec-hero-mclean .ec-hero-eyebrow-wrap { margin: 0 0 14px; }
.ec-hero-mclean .ec-hero-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	font-family: var(--ec-font-mono);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ec-green);
}
.ec-hero-mclean .ec-hero-eyebrow::after {
	content: '';
	width: 28px;
	height: 2px;
	background: var(--ec-gold);
}

.ec-hero-mclean .ec-headline {
	margin: 0 0 18px;
	max-width: 560px;
	font-weight: 800 !important;
	line-height: 1.05;
	letter-spacing: -0.01em;
	color: #FFFFFF !important;
}

/* Subhead — dimmed below the headline to build hierarchy. The vc_custom_heading
 * sets color:#fff inline on the h5, so the dim needs !important. */
.ec-hero-mclean .ec-hero-subhead {
	margin: 0 0 6px !important;
	max-width: 460px;
	font-weight: 500;
	line-height: 1.5;
	color: rgba(255, 255, 255, 0.78) !important;
}

/* Trust list rebuilt as a 2-column "spec table" — a mono key ┄ value pair per
 * hairline-ruled row, reading like the data block on a build drawing. Keys
 * (BUILD / LEAD / FOOTPRINT) encode category, NOT sequence, so there are no
 * 01/02/03 numerals (they implied an order the content lacks and collided with
 * the real 01–04 numerals on the "OUR EDGE" cards below). Both columns are
 * filled, which also kills the old trailing-hairline emptiness. The FOOTPRINT
 * value sits in mono as a drawing-style dimension annotation. */
.ec-hero-mclean .ec-trust-list-wrap { margin: 0; }

.ec-hero-mclean .ec-trust-list {
	list-style: none;
	margin: 0 0 28px;
	padding: 0;
	max-width: 460px;
	/* Pin the brand body font: OneUp's global `li {font-family:'',...}` reset
	 * (empty family → Arial) would otherwise win on these list items. */
	font-family: var(--ec-font-body);
	color: #FFFFFF;
}
.ec-hero-mclean .ec-trust-list li {
	display: grid;
	grid-template-columns: 118px 1fr;
	align-items: baseline;
	gap: 20px;
	padding: 13px 0;
	border-top: 1px solid rgba(255, 255, 255, 0.16);
}
.ec-hero-mclean .ec-trust-list li:last-child {
	border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}
.ec-hero-mclean .ec-trust-key {
	font-family: var(--ec-font-mono);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ec-green);
}
.ec-hero-mclean .ec-trust-label {
	font-size: 15px;
	font-weight: 500;
	line-height: 1.3;
	color: rgba(255, 255, 255, 0.82);
}
.ec-hero-mclean .ec-trust-foot {
	font-family: var(--ec-font-mono);
	letter-spacing: 0.02em;
	color: #FFFFFF;
}
/* Legacy decorative spans (if a stale DB still carries them) stay hidden. */
.ec-hero-mclean .ec-trust-list .ec-num,
.ec-hero-mclean .ec-trust-list .ec-trust-em { display: none; }

/* Rhythm: WPBakery emits three [vc_empty_space] dividers in this column at
 * 20/20/40px (inline height), leaving a ~80px dead zone above the CTA. Normalize
 * them to one even gap so the eyebrow → headline → subhead → spec-table → CTA
 * cadence is governed by element margins, not stray spacers. !important is
 * required to beat the inline height. */
.ec-hero-mclean .vc_empty_space { height: 18px !important; }

@media (max-width: 980px) {
	/* Content stacks full-width here, so the right-anchored gradient gives way to
	 * a strong flat scrim (0.86) under the whole column. Same selector as the base
	 * scrim rule (.ec-hero-mclean .upb_row_bg::after) so source order decides. */
	.ec-hero-mclean .upb_row_bg::after {
		background: rgba(4, 23, 26, 0.86);
	}
	/* Keep the spec table as a key|value pair even when narrow — a tighter key
	 * column + smaller gap fits the row at 375px without wrapping. */
	.ec-hero-mclean .ec-trust-list { max-width: none; }
	.ec-hero-mclean .ec-trust-list li { grid-template-columns: 92px 1fr; gap: 14px; }
	.ec-hero-mclean .ec-hero-subhead { max-width: none; }
	/* ROOT-CAUSE FIX: the eyebrow's one-line width (text + gap + gold tick) is
	 * ~325px — wider than the ~295px mobile content column. `display:inline-flex`
	 * forces all of it onto one flex line, which is unsolvable at this width: with
	 * `white-space:nowrap` it bled past the viewport edge ("overflow to the sides"),
	 * and without nowrap a squeezed flex text-item broke MID-WORD (CUST/OM). Escape
	 * inline-flex → `display:block` makes it normal block text: bounded by the
	 * column (can't overflow) and wrapping at SPACES (can't break mid-word). The
	 * tick trails the text inline (gap no longer applies under display:block). */
	.ec-hero-mclean .ec-hero-eyebrow {
		display: block;
		font-size: 11px;
		letter-spacing: 0.05em;
	}
	.ec-hero-mclean .ec-hero-eyebrow::after {
		display: inline-block;
		vertical-align: middle;
		margin-left: 10px;
	}
}

@media (max-width: 380px) {
	/* On the narrowest phones the eyebrow wraps to two lines; drop the trailing
	 * gold tick so it doesn't strand alone on the second line. */
	.ec-hero-mclean .ec-hero-eyebrow::after { display: none; }
}

/* =========================================================================
 * Home 6936 — "Let's make an Impact" 4-card row (industrial-editorial)
 *
 * Oversized green numerals 01–04 and per-card hairlines — rendered as CSS
 * pseudo-elements + a CSS counter on the
 * `.aio-icon-component` cards. (The 4 cards are NOT DOM siblings — each
 * sits in its own deep `.ult-animation` wrapper — so `:nth-of-type` on the
 * column won't work; a counter increments per-card regardless of tree
 * structure.) The only post_content change is `el_class="ec-why-cards"`
 * on the wrapping vc_row.
 * ========================================================================= */
.ec-why-cards { position: relative; counter-reset: ec-card-counter; }

/* Section scrim — the band's bg photo (booth on staging; a softer image on
 * local) sits on the `.gradient_box .ult-content-box` wrapper INSIDE this row and
 * already carries a base 45% black scrim (see "Section bg-image scrim" earlier in
 * this file). That 0.45 is too weak here — the busy booth photo bled through and
 * made the four translucent panels look muddy and mismatched. Deepen it to a
 * brand-navy band, scoped to .ec-why-cards ONLY (so the testimonials gradient_box,
 * which shares the [style*="uploads"] selector, keeps its lighter 0.45). The booth
 * recedes to atmosphere; the frosted spec-cards read clean. This overrides ONLY
 * the background of the existing ::before — its inset / border-radius / z-index:1 /
 * pointer-events still come from the base rule, and content stays above it via the
 * base rule's `[style*="uploads"] > * { z-index:2 }`. */
.ec-why-cards .gradient_box .ult-content-box[style*="uploads"]::before {
	background-color: transparent;
	/* Light scrim — the booth photo MUST stay clearly visible (the frosted,
	 * near-opaque cards carry their own legibility now, so the section scrim only
	 * has to take the edge off the photo's brightness behind the left-hand heading
	 * + CTA). A left-biased horizontal gradient keeps that text crisp while letting
	 * the booth read through the center/right and in the gaps between cards. */
	background-image: linear-gradient(100deg,
		rgba(4, 23, 26, 0.62) 0%,
		rgba(4, 23, 26, 0.40) 40%,
		rgba(3, 16, 18, 0.26) 100%);
}

.ec-why-cards .aio-icon-component {
	counter-increment: ec-card-counter;
	position: relative;
	padding: 30px 30px 30px 138px;
	min-height: 168px;
	/* Frosted "spec-panel" — the fix for the muddy-squares bug. The old flat
	 * rgba(…,0.55) fill let the busy booth photo bleed through unevenly, so the
	 * four cards washed out over bright booth areas and read solid over dark ones
	 * (mismatched, accidental). Now: a near-opaque dark-glass gradient (the photo
	 * can't bleed through) + backdrop-filter blur (frosts whatever IS behind for
	 * depth; degrades to the gradient where unsupported) so all four read
	 * identically. Green left "index rail" (inset shadow) ties each card to its
	 * oversized numeral; sharp 3px corners + thin green frame keep the blueprint/
	 * spec language ("we build walls, not gradients"). */
	background: linear-gradient(158deg, rgba(9, 32, 36, 0.72) 0%, rgba(3, 16, 18, 0.86) 100%);
	-webkit-backdrop-filter: blur(12px) saturate(115%);
	backdrop-filter: blur(12px) saturate(115%);
	border: 1px solid rgba(57, 219, 176, 0.16);
	border-radius: 3px;
	box-shadow:
		inset 3px 0 0 0 var(--ec-color-green),
		inset 0 1px 0 rgba(255, 255, 255, 0.05),
		0 24px 50px -30px rgba(0, 0, 0, 0.80);
	transition: background 220ms ease, border-color 220ms ease, transform 220ms ease, box-shadow 220ms ease;
}

.ec-why-cards .aio-icon-component::before {
	content: counter(ec-card-counter, decimal-leading-zero);
	position: absolute;
	left: 24px;
	top: 20px;
	font-size: 88px;
	font-weight: 300;
	line-height: 1;
	color: var(--ec-color-green);
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum';
}

/* Numeral underscore — sits directly beneath the oversized numeral. The old
 * left:110px/top:96px landed it across the title, reading as a strike-through. */
.ec-why-cards .aio-icon-component::after {
	content: '';
	display: block;
	width: 72px;
	height: 2px;
	background: var(--ec-color-green);
	position: absolute;
	left: 24px;
	top: 112px;
}

/* Default text colors — guarantee legibility on the translucent panel in the
 * default (non-hover) state; clears the prior img-over-text contrast risk. */
.ec-why-cards .aio-icon-title,
.ec-why-cards .aio-icon-component h3 { color: #FFFFFF !important; }
.ec-why-cards .aio-icon-description,
.ec-why-cards .aio-icon-component p { color: rgba(255, 255, 255, 0.82) !important; }

/* Hide the small line-icon — the oversized numeral is the single signature mark;
 * the icon previously collided with it in the top-left corner. */
.ec-why-cards .aio-icon-img { display: none !important; }

/* Hover = subtle lift + accent edge, not a full invert. Every card already has a
 * panel, so hover refines rather than being the only legible state. */
.ec-why-cards .aio-icon-component:hover {
	background: linear-gradient(158deg, rgba(13, 42, 47, 0.80) 0%, rgba(5, 23, 26, 0.92) 100%);
	border-color: rgba(249, 190, 23, 0.50);
	transform: translateY(-3px);
	box-shadow:
		inset 3px 0 0 0 var(--ec-color-accent),
		inset 0 1px 0 rgba(255, 255, 255, 0.07),
		0 30px 60px -28px rgba(0, 0, 0, 0.85);
}
.ec-why-cards .aio-icon-component:hover::before { color: var(--ec-color-accent); }
.ec-why-cards .aio-icon-component:hover::after  { background: var(--ec-color-accent); }
.ec-why-cards .aio-icon-component:hover .aio-icon-description,
.ec-why-cards .aio-icon-component:hover p { color: #FFFFFF !important; }

@media (prefers-reduced-motion: reduce) {
	.ec-why-cards .aio-icon-component { transition: none; }
	.ec-why-cards .aio-icon-component:hover { transform: none; }
}

@media (max-width: 980px) {
	.ec-why-cards .aio-icon-component { padding: 22px 22px 22px 92px; min-height: 0; }
	.ec-why-cards .aio-icon-component::before { font-size: 56px; left: 18px; top: 18px; }
	.ec-why-cards .aio-icon-component::after { top: 78px; left: 18px; width: 56px; }
}

/* =========================================================================
 * OUR EDGE — vertical stack (client "Final Remarks" #2)
 *
 * "Have all boxes aligned one under the other. 1,2,3,4."
 *
 * The cards do NOT stagger via any EC rule — the diagonal comes from the OneUp
 * demo's inner-row column structure inside post 6936: the cards live in
 * `.vc_col-sm-4` (⅓-width) inner columns with `.wide-2col add-padding`
 * modifiers, so they land side-by-side at different x-offsets over the bg photo.
 * We can't edit that DB markup, so override the column layout: turn the inner
 * row into a single full-width vertical stack and force every inner ⅓ column to
 * 100% width, killing the horizontal add-padding offset. Result: card 1 over
 * card 2 over card 3 (…4), a clean numbered column. Scoped to `.ec-why-cards`
 * so no other WPBakery row is affected.
 * ========================================================================= */
.ec-why-cards .vc_row.vc_inner {
	display: flex;
	flex-direction: column;
	gap: 18px;
	max-width: 640px;   /* keep the stacked column a readable width, left-aligned */
}
.ec-why-cards .vc_row.vc_inner > .wpb_column[class*="vc_col-sm-"] {
	width: 100% !important;
	max-width: 100% !important;
	float: none !important;
	margin: 0 !important;
	padding-left: 0 !important;   /* neutralize `.add-padding` horizontal offset */
	padding-right: 0 !important;
}
/* The demo tucks a spacer column ("wide-single-col") before the cards to create
   the top offset — collapse it so the stack starts clean. */
.ec-why-cards .vc_row.vc_inner > .wide-single-col:empty { display: none; }
/* Kill the demo's per-card ult-spacer gaps (we own the flex `gap` now). */
.ec-why-cards .vc_row.vc_inner .ult-spacer { display: none !important; }

/* =========================================================================
 * Home 6936 — "Let's make an Impact together" gradient_box bg sharpness
 *
 * Ultimate Addons' ult_content_box hardcodes WP's 'large' (1024px) size for its
 * bg_image (Ultimate_VC_Addons/modules/ultimate_content_box.php:93), so this
 * near-full-width panel upscales the photo ~2x on Retina — reads soft and
 * apparently "zoomed". Force the full-resolution file and beat the plugin's
 * inline background-image with !important. Root-relative URL keeps it portable
 * across staging/prod. Pairs with bg_image="8101" (foretellix-booth-front.jpg)
 * set in rebuild-homepage.php — swap BOTH together if the Impact photo changes.
 * ========================================================================= */
body.home .ult-content-box-container.gradient_box .ult-content-box {
	background-image: url('/wp-content/uploads/foretellix-booth-front.jpg') !important;
	background-position: center center !important;
}

/* =========================================================================
 * "Why EC" checklist disc recolor (client feedback 2026-06-30)
 *
 * The OneUp demo baked a crimson #ae1f38 check disc INLINE on the four
 * homepage "Why EC" items (Passionate Experts / Results-Driven / Forward-
 * Thinking / WE Care). Recolor to the brand mint green with a navy check so
 * it matches the palette and stays legible (white-on-mint was too low
 * contrast). Scoped by the inline color via [style*="ae1f38"] so other
 * .aio-icon.advanced discs (e.g. gold) are untouched — and it survives a
 * demo re-import since it's CSS, not a one-off DB edit.
 * ========================================================================= */
.aio-icon.advanced[style*="ae1f38"],
.aio-icon.advanced[style*="AE1F38"] {
	background: var(--ec-color-green) !important;
	border-color: var(--ec-color-green) !important;
	color: var(--ec-color-primary) !important; /* navy check glyph on mint disc */
}
