/*
Theme Name: INDO 2026
Theme URI: https://indolighting.com
Description: Custom child theme of Hello Elementor for INDO. Mobile-first, accessible, design-led case-study and project layouts; transparent over-hero header that swaps on scroll. Brand: cyan #00a6db.
Author: INDO
Author URI: https://indolighting.com
Template: hello-elementor
Version: 2.3.48
License: GNU General Public License v3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
Text Domain: indo-2026
*/

/* ----------------------------------------------------------------------
 *  INDO 2026 — global styles
 *  All design tokens are defined in theme.json. We re-export them as CSS
 *  custom properties here for use in legacy/non-block contexts.
 * ---------------------------------------------------------------------- */

:root {
    --indo-cyan: #00a6db;
    --indo-cyan-light: #00acea;
    /* --indo-cyan-link removed 20260501-1500 (Tom directive): brand cyan #00a6db is authoritative on body links too. AA contrast for body text-on-white must be remediated by size/weight or dark-bg context, NEVER by darkening the cyan. */
    --indo-blue: #1863dc;
    --indo-charcoal: #212121;
    --indo-navy: #121c22;
    --indo-gray: #abafb5;
    --indo-light: #f4f4f4;

    --indo-font-display: "Lexend Deca", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
    --indo-font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

    --indo-header-h-desktop: 80px;
    --indo-header-h-sticky:  80px; /* unified at 80px — no scroll-shrink. Consistent header height across all pages and all scroll states; dropdown positions don't jump. */
    /* 2026-05-02: bumped 64 → 80. The high-specificity `body .site-header
     * { height: var(--indo-header-h-desktop) }` rule at line 87 wins over
     * the @media (max-width: 991px) `.site-header { height: var(--indo-header-h-mobile) }`
     * rule at line 242 — meaning the rendered header is 80px on mobile too.
     * Keeping the var at 64 lied about reality, which broke (a) the inner-page
     * body padding (was 64px, content overlapped header by 16px on Support
     * child pages and similar non-pillar pages), and (b) the mobile drawer
     * top inset (drawer started 16px above header bottom). Var now matches
     * actual rendered height; both downstream uses self-correct. */
    --indo-header-h-mobile:  80px;

    --indo-section-pad:        clamp(60px, 10vw, 120px);
    --indo-section-pad-narrow: clamp(40px, 6vw, 80px);

    /* -------------------------------------------------------------------
     * SITE-WIDE SPACING DESIGN TOKENS  (added 2026-05-03, theme 2.3.0)
     * Tom brief: every primary page uses ONE inter-section vertical gap
     * token (uniform across all top-level sections) and ONE intra-section
     * element gap token (used between widgets within a single section).
     * Inter > intra at every breakpoint to maintain hierarchy.
     *
     * Inter-section padding is applied symmetrically — section padding-top
     * + padding-bottom both use the same token. Visible gap between two
     * adjacent sections = 2× the token at that breakpoint:
     *   mobile  56 → 112px gap
     *   tablet  72 → 144px gap
     *   desktop 88 → 176px gap
     * 8px-grid aligned, smooth +16px progression per breakpoint.
     *
     * Intra-section gap is roughly half the inter-section value at every
     * breakpoint (24/32/40 = 8px-grid). This is the rhythm rule for
     * heading→CTA, badge→row, body→cite spacing within a section.
     * ----------------------------------------------------------------- */
    --indo-section-pad-y-mobile:  56px;
    --indo-section-pad-y-tablet:  72px;
    --indo-section-pad-y-desktop: 88px;

    --indo-element-gap-mobile:  24px;
    --indo-element-gap-tablet:  32px;
    --indo-element-gap-desktop: 40px;

    --indo-radius: 4px;
    --indo-easing: cubic-bezier(.4,0,.2,1);
}

/* ----------------------------------------------------------------------
 *  Reset / base
 * ---------------------------------------------------------------------- */

html, body { overflow-x: hidden; }   /* prevent horizontal scroll from rogue children */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
    font-family: var(--indo-font-body);
    color: var(--indo-charcoal);
    line-height: 1.6;
    background: #fff;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--indo-cyan); text-decoration: none; transition: color .15s var(--indo-easing); } /* revert 20260501-1500: was var(--indo-cyan-link); brand cyan is authoritative on body links per Tom directive. */
a:hover, a:focus { color: var(--indo-cyan-light); }
*:focus-visible { outline: 2px solid var(--indo-cyan); outline-offset: 2px; }

/* Display headings — Lexend Deca, light weight */
h1, h2, h3, h4 {
    font-family: var(--indo-font-display);
    font-weight: 200;
    line-height: 1.1;
    color: var(--indo-charcoal);
    margin: 0 0 .5em;
}
h1 { font-size: clamp(36px, 6vw, 60px); }
h2 { font-size: clamp(28px, 4.5vw, 48px); }
h3 { font-size: clamp(22px, 3vw, 32px); }
h4 { font-size: clamp(18px, 2.4vw, 22px); font-weight: 400; }

/* Lowercase section headings */
.section-title {
    letter-spacing: -0.01em;
    font-weight: 200;
}

/* ----------------------------------------------------------------------
 *  Header — transparent over-hero, swaps to white-bg on scroll/inner pages
 * ---------------------------------------------------------------------- */

/* High-specificity override for Hello Elementor's .site-header constraints */
.site-header,
body .site-header,
body.home .site-header {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    height: var(--indo-header-h-desktop);
    z-index: 99;
    display: flex;
    align-items: center;
    padding: 0 clamp(16px, 3vw, 40px);
    background: transparent;
    transition: background .2s var(--indo-easing), height .2s var(--indo-easing), box-shadow .2s var(--indo-easing);
}
.site-header__inner {
    width: 100%;
    max-width: 1440px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: clamp(16px, 3vw, 40px);
    /* Span the full header height so flex children with `align-self: stretch`
     * (the language dropdown) get a positioning context whose bottom edge lines
     * up with the header bottom — same vertical anchor used by the primary nav
     * sub-menus. Sibling children keep `align-self: auto` and stay centred. */
    height: 100%;
}

/* Logo: outlined white PNG masked via CSS so we can recolor on light bg.
   The same source asset works on dark hero (mask-fill = white) and on
   white background (mask-fill = brand cyan). */
.site-header__logo {
    display: block;
    flex: 0 0 auto;
    width: 110px;
    height: 36px;
    background-color: #fff;
    -webkit-mask: url('assets/img/indo-logo-white.png') no-repeat center / contain;
            mask: url('assets/img/indo-logo-white.png') no-repeat center / contain;
}
.header--on-light .site-header__logo {
    background-color: var(--indo-cyan);
}

/* Primary nav (desktop) */
.site-header__nav {
    flex: 1 1 auto;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: clamp(8px, 1.6vw, 24px);
}
.site-header__nav ul { list-style: none; margin: 0; padding: 0; display: flex; gap: clamp(4px, 1vw, 18px); }
.site-header__nav a {
    color: #fff;
    font: 400 15px/1 var(--indo-font-body);
    text-decoration: none;
    padding: 10px 12px;
    border-radius: var(--indo-radius);
    transition: color .15s var(--indo-easing), background .15s var(--indo-easing);
    white-space: nowrap;          /* never wrap nav labels onto two lines */
}
@media (max-width: 1199px) {
    .site-header__nav a { font-size: 14px; padding: 10px 8px; }
}
.site-header__nav a:hover,
.site-header__nav a:focus,
.site-header__nav .current-menu-item > a {
    color: var(--indo-cyan);
}
.header--on-light .site-header__nav a {
    color: var(--indo-charcoal);
}
.header--on-light .site-header__nav a:hover,
.header--on-light .site-header__nav a:focus,
.header--on-light .site-header__nav .current-menu-item > a {
    color: var(--indo-cyan);
}

/* Search trigger */
.site-header__search {
    appearance: none;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    padding: 10px;
    line-height: 0;
    transition: color .15s var(--indo-easing);
}
.site-header__search svg { width: 22px; height: 22px; fill: currentColor; }
.site-header:not(.header--on-light) .site-header__search { color: #fff; }
.header--on-light .site-header__search { color: var(--indo-charcoal); }
.site-header__search:hover, .site-header__search:focus { color: var(--indo-cyan); }

/* Scrolled / on-light state — fully opaque so charcoal text is readable
 * over any underlying section colour. */
.header--on-light,
body .header--on-light,
body.home .header--on-light {
    background: #ffffff !important;
    height: var(--indo-header-h-sticky);
    box-shadow: 0 1px 0 rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.04);
}

/* Mega menu (sub-menu) — desktop */
.site-header__nav .menu-item-has-children { position: relative; }
.site-header__nav .sub-menu {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 240px;
    background: #fff;
    box-shadow: 0 12px 32px rgba(0,0,0,0.08);
    border-radius: 0; /* sharp corners — INDO house style */
    padding: 8px 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .15s var(--indo-easing), transform .15s var(--indo-easing), visibility 0s linear .15s;
    z-index: 100000;
    display: block;
    flex-direction: column;
    list-style: none;
}
.site-header__nav .menu-item-has-children:hover > .sub-menu,
.site-header__nav .menu-item-has-children:focus-within > .sub-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition-delay: 0s;
}
.site-header__nav .sub-menu li { display: block; margin: 0; }
.site-header__nav .sub-menu a {
    color: var(--indo-charcoal);
    padding: 12px 20px;
    line-height: 1.4;
    display: block;
    font-size: 15px;
}

/* Mobile / hamburger */
.site-header__toggle {
    display: none;
    appearance: none;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    padding: 10px;
    line-height: 0;
}
.site-header__toggle svg { width: 26px; height: 26px; fill: currentColor; }
.site-header:not(.header--on-light) .site-header__toggle { color: #fff; }
.header--on-light .site-header__toggle { color: var(--indo-charcoal); }

@media (max-width: 991px) {
    .site-header { padding: 0 16px; height: var(--indo-header-h-mobile); }
    .site-header__nav {
        position: fixed;
        inset: var(--indo-header-h-mobile) 0 0 0;
        background: #fff;
        flex-direction: column;
        padding: 32px 20px;
        align-items: stretch;
        justify-content: flex-start;
        gap: 0;
        transform: translateX(100%);
        transition: transform .24s var(--indo-easing);
        overflow-y: auto;
    }
    .site-header.is-open .site-header__nav { transform: translateX(0); }
    .site-header__nav ul { flex-direction: column; gap: 0; width: 100%; }
    .site-header__nav a { color: var(--indo-charcoal) !important; padding: 16px 8px; min-height: 44px; display: flex; align-items: center; }
    .site-header__nav .sub-menu {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        box-shadow: none;
        background: var(--indo-light);
        padding-left: 16px;
    }
    .site-header__toggle { display: inline-block; }
    /* 2026-05-02: right-align the search + hamburger cluster on mobile so
       the icons mirror the INDO logo's left-edge offset. The desktop nav
       is `position: fixed` (off-canvas drawer) at this breakpoint, so the
       inner flex row is logo + search + toggle. Without this rule those
       three pack flush-left and the right side of the header sits empty.
       margin-left: auto on the search button absorbs all available space,
       pushing search + toggle to the right edge of the inner container,
       which is itself ~10px from the viewport edge — same as the logo's
       left offset. Result: visual symmetry. */
    .site-header__inner > .site-header__search {
        margin-left: auto;
    }
    /* Tighter gap between search and toggle so they read as a single
       cluster rather than two unrelated icons. The inner flex `gap` is
       16px at this breakpoint; pull the toggle 8px closer with a negative
       margin → 8px effective gap. The :first-of-type guard keeps this
       margin off the search button when, for some reason, search ever
       gets removed and toggle becomes the only icon. */
    .site-header__search + .site-header__toggle {
        margin-left: -8px;
    }
}

/* Body padding — pages with full-bleed hero don't need top space; others do */
body:not(.has-fullbleed-hero) main {
    padding-top: var(--indo-header-h-desktop);
}
@media (max-width: 991px) {
    body:not(.has-fullbleed-hero) main {
        padding-top: var(--indo-header-h-mobile);
    }
}

/* ----------------------------------------------------------------------
 *  Elementor compat: make every top-level Elementor section span the full
 *  viewport width by default. The legacy industrium pages were authored at
 *  a "boxed" 1200px width which now reads as cramped on a modern 1440-1920+
 *  viewport. We expand sections to 100vw and only constrain inner columns.
 *
 *  The `data-settings` of any section that explicitly opted INTO boxed via
 *  Elementor's UI will still work because the inner row keeps its max-width.
 * ---------------------------------------------------------------------- */

.elementor-section.elementor-section-boxed > .elementor-container,
.elementor-section.elementor-section-content-middle > .elementor-container {
    max-width: 100% !important;          /* let columns breathe to viewport */
    padding-left: clamp(16px, 4vw, 64px);
    padding-right: clamp(16px, 4vw, 64px);
}
.elementor-section-stretched,
.elementor-section.elementor-section-full_width {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    max-width: 100vw;
    width: 100vw;
}

/* The home-page hero: the first Elementor section under <main> on the
 * front page is always treated as a full-bleed hero. */
body.home main > .elementor,
body.home main > .elementor > div,
body.home main > div > .elementor-section:first-child {
    width: 100%;
    max-width: 100%;
}
body.home main .elementor-section:first-of-type {
    margin-left: 0;
    margin-right: 0;
}
body.home main .elementor-section:first-of-type > .elementor-container {
    max-width: 100% !important;
    padding-left: 0;
    padding-right: 0;
}

/* ----------------------------------------------------------------------
 * Industrium-theme legacy CSS overrides
 * The re-enqueued industrium theme.css restores Elementor widget styles
 * but also brings back its menu chevrons (fontello ::before glyphs) and
 * decorative subheading backdrops that don't belong in the new design.
 * ---------------------------------------------------------------------- */

/* Kill the fontello chevron glyphs the Industrium theme renders next to
 * every <li> (it's a global ::before icon). Scope: anywhere in our new
 * theme's namespaces (.site-header, .indo-*, .site-footer). Industrium's
 * own widgets keep their styling because we don't suppress it inside
 * .industrium-* containers. */
.site-header__nav li::before,
.site-header__nav li::after,
.site-header__nav a::before,
.site-header__nav a::after,
.indo-filter li::before,
.indo-filter li::after,
.indo-card-grid li::before,
.indo-card-grid li::after,
.indo-pagination li::before,
.indo-pagination li::after,
/* WC pagination: suppress Industrium fontello glyph injected via ul > li::before */
.woocommerce-pagination li::before,
.woocommerce-pagination li::after,
.site-footer li::before,
.site-footer li::after,
.entry-content > ul > li::before,
.entry-content > ul > li::after,
/* Language dropdown lives outside .site-header__nav so the global
 * chevron-glyph rule from Industrium leaks into each <li>. Suppress it
 * here so the language items render with flag + label only. */
.indo-lang-dropdown__panel li::before,
.indo-lang-dropdown__panel li::after,
.indo-lang-dropdown__item::before,
.indo-lang-dropdown__item::after {
    content: none !important;
    display: none !important;
    background: none !important;
}

/* The faint "Projects" / "Subheading" backdrop label that sits behind the
 * "Successfully completed projects" headline — drop it, it's busy. */
.industrium-subheading,
.subheading,
.industrium-special-text-decoration,
.industrium-counter-decoration,
.elementor-widget .industrium-special-text .special-text-decoration,
.industrium-counter-bg-text {
    display: none !important;
}

/* The "Completed projects" counter widget renders its label rotated 90deg
 * and a giant decorative number behind it. Both are too busy for the new
 * design — strip them both. */
[class*="industrium-counter"],
[class*="industrium-counter"] * {
    writing-mode: horizontal-tb !important;
    text-orientation: mixed !important;
    transform: none !important;
    -webkit-transform: none !important;
}
.industrium-counter-bg-text,
.industrium-counter-text-rotated,
.counter-bg-number,
.industrium-counter-decoration {
    display: none !important;
}

/* Decorative coloured squares the industrium-plugin renders around contact
 * and product/range tiles. Hide the entire decoration widget. */
.industrium-decoration,
.decoration-container,
.decoration-widget,
.elementor-widget-industrium-decoration {
    display: none !important;
}

/* The Elementor native Counter widget on the home renders its label vertically
 * and shows a giant pale "215+" number behind it. Both are too busy. */
.elementor-counter-title {
    writing-mode: horizontal-tb !important;
    text-orientation: mixed !important;
    transform: none !important;
    -webkit-transform: none !important;
    text-align: center !important;
    margin-top: 12px !important;
}
.elementor-widget-counter .elementor-counter {
    text-align: center;
}

/* Make sure the header's max-width comfortably fits all 7 nav items + logo
 * + search at desktop widths from 1280 up. */
.site-header__inner { max-width: min(1600px, 100%); }
@media (min-width: 1280px) {
    .site-header__nav a { font-size: 15px; padding: 10px 14px; }
}
@media (max-width: 1279px) {
    .site-header__nav a { font-size: 14px; padding: 10px 8px; }
}
@media (max-width: 1099px) and (min-width: 992px) {
    .site-header__nav a { font-size: 13px; padding: 10px 6px; }
}

/* ----------------------------------------------------------------------
 *  Hero (full-bleed, used on home + project category landings)
 * ---------------------------------------------------------------------- */

.indo-hero {
    position: relative;
    width: 100%;
    min-height: 80vh;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    background: var(--indo-navy);
}
@media (max-width: 767px) { .indo-hero { min-height: 60vh; } }
.indo-hero__media,
.indo-hero__media picture,
.indo-hero__media video,
.indo-hero__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}
/* Hero img needs to win against two things:
 *   1. The `.entry-content img { height: auto }` defensive rule lower in
 *      this file (same specificity, later source order — would otherwise
 *      override `height: 100%`).
 *   2. The implicit `aspect-ratio: auto W/H` browsers derive from the
 *      <img width="…" height="…"> attributes WordPress emits. The hero
 *      container's height comes from `.indo-hero { min-height: … }` — the
 *      parent has no *definite* height, so a child `height: 100%` resolves
 *      to `auto` for replaced elements, and the browser then sizes the img
 *      from the implicit aspect-ratio. The result is a letterboxed image
 *      with the navy `.indo-hero` background showing through below.
 * `!important` plus `aspect-ratio: auto` neutralises both. */
.indo-hero .indo-hero__media img {
    height: 100% !important;
    aspect-ratio: auto !important;
}
.indo-hero__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0.20) 0%, rgba(0,0,0,0.45) 100%);
    pointer-events: none;
}
.indo-hero__inner {
    position: relative;
    z-index: 1;
    max-width: 960px;
    padding: 0 24px;
    text-align: center;
}
.indo-hero h1 { color: #fff; font-weight: 200; }
.indo-hero p { font-size: clamp(16px, 1.6vw, 20px); opacity: .9; margin-top: 16px; }

/* ----------------------------------------------------------------------
 *  Section utilities
 * ---------------------------------------------------------------------- */

.indo-section {
    padding: var(--indo-section-pad) clamp(16px, 4vw, 40px);
}
/* fix-cluster-articles-002 20260501-1209: add horizontal padding to .indo-container so content does not bleed to viewport edge below 1440px [closes 6 entries: articles-002, category-blog-002, category-clippings-002, category-news-002, projects--category-exterior-lighting-005, projects--category-horticultural-003] */
.indo-container {
    max-width: 1280px;
    margin: 0 auto;
    padding-inline: clamp(16px, 4vw, 32px);
    box-sizing: border-box;
}
.indo-section--narrow .indo-container { max-width: 960px; }

/* ----------------------------------------------------------------------
 *  Project / News / Events card grid
 * ---------------------------------------------------------------------- */

.indo-card-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(24px, 3vw, 48px);
    list-style: none;
    margin: 0;
    padding: 0;
}
.indo-card-grid > li { list-style: none; margin: 0; padding: 0; }
@media (max-width: 767px) {
    .indo-card-grid { grid-template-columns: 1fr; gap: 24px; }
}

.indo-card {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: transform .25s var(--indo-easing);
}
.indo-card:hover, .indo-card:focus-visible { transform: translateY(-4px); }
.indo-card__media {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--indo-light);
    border-radius: var(--indo-radius);
    margin-bottom: 16px;
    position: relative;
}
.indo-card__media img {
    width: 100% !important;
    height: 100% !important;
    max-width: none;
    object-fit: cover;
    transition: transform .4s var(--indo-easing);
    position: absolute;
    inset: 0;
}
.indo-card:hover .indo-card__media img { transform: scale(1.04); }
.indo-card__title {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(20px, 2.4vw, 28px);
    color: var(--indo-charcoal);
    line-height: 1.2;
    margin: 0 0 4px;
}
.indo-card:hover .indo-card__title,
.indo-card:focus-visible .indo-card__title {
    color: var(--indo-cyan);
}
/* fix-cluster-product-category-highway-lighting-003 20260501-1220: change .indo-card__sub color from --indo-gray (#abafb5, 2.5:1 on white) to #595959 (4.74:1) to pass WCAG AA 1.4.3 [closes 5 entries: product-category-highway-lighting-003, product-category-lighting-for-rail-003, product-category-major-minor-road-lighting-004, product-category-top-light-003, product-category-vertical-farming-003] */
.indo-card__sub {
    font-size: 14px;
    color: #595959;
    margin: 0;
}
.indo-card__date {
    font-size: 13px;
    color: var(--indo-gray);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: 8px;
}

/* Filter chips for /projects/ */
.indo-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 48px;
    padding: 0;
    list-style: none;
}
.indo-filter a {
    display: inline-block;
    padding: 8px 18px;
    border: 1px solid var(--indo-gray);
    border-radius: 999px;
    color: var(--indo-charcoal);
    font-size: 14px;
    text-decoration: none;
    transition: all .15s var(--indo-easing);
}
.indo-filter a:hover,
.indo-filter a:focus,
.indo-filter .is-active a {
    background: var(--indo-cyan);
    border-color: var(--indo-cyan);
    color: #fff;
}

/* Pagination */
.indo-pagination {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 48px;
}
.indo-pagination a, .indo-pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 12px;
    border-radius: var(--indo-radius);
    color: var(--indo-charcoal);
    text-decoration: none;
}
.indo-pagination .current { background: var(--indo-cyan); color: #fff; }
.indo-pagination a:hover { background: var(--indo-light); }

/* ----------------------------------------------------------------------
 *  Single project layout (Phase 2.3)
 * ---------------------------------------------------------------------- */

.indo-single-project__hero {
    width: 100%;
    aspect-ratio: 16/9;
    overflow: hidden;
    background: var(--indo-navy);
    position: relative;
}
.indo-single-project__hero img,
.indo-single-project__hero video,
.indo-single-project__hero-video {
    width: 100%; height: 100%; object-fit: cover;
    display: block; /* kills the baseline gap that <video> inherits as an
                       inline replaced element — without this the navy
                       hero background shows through as a thin line at
                       the bottom of the video. */
}
/* Dark overlay so the transparent header's white text stays legible
 * against bright photographic content. */
.indo-single-project__hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.10) 30%, rgba(0,0,0,0.25) 100%);
    pointer-events: none;
}
.indo-single-project__head {
    padding: 48px 0 24px;
    text-align: center;
}
.indo-single-project__body {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: clamp(24px, 4vw, 64px);
    padding: 0 0 var(--indo-section-pad);
}
@media (max-width: 991px) {
    .indo-single-project__body { grid-template-columns: 1fr; }
}
.indo-single-project__meta { font-size: 14px; color: var(--indo-gray); }
.indo-single-project__meta dt { font-weight: 600; color: var(--indo-charcoal); margin-top: 16px; text-transform: uppercase; letter-spacing: .05em; font-size: 12px; }
.indo-single-project__meta dd { margin: 4px 0 0; color: var(--indo-charcoal); }

/* ----------------------------------------------------------------------
 *  Search overlay (search icon trigger)
 * ---------------------------------------------------------------------- */

.indo-search-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255,255,255,0.97);
    z-index: 100001;
    display: none;
    align-items: center;
    justify-content: center;
}
.indo-search-overlay.is-open { display: flex; }
.indo-search-overlay form {
    width: min(640px, 90vw);
    display: flex;
    gap: 12px;
}
.indo-search-overlay input[type=search] {
    flex: 1 1 auto;
    font-size: 24px;
    padding: 12px 16px;
    border: 0;
    border-bottom: 2px solid var(--indo-charcoal);
    background: transparent;
    color: var(--indo-charcoal);
    font-family: var(--indo-font-display);
    font-weight: 200;
}
.indo-search-overlay input[type=search]:focus { outline: 0; border-bottom-color: var(--indo-cyan); }
.indo-search-overlay__close {
    appearance: none;
    background: none;
    border: 0;
    cursor: pointer;
    font-size: 32px;
    color: var(--indo-charcoal);
    line-height: 1;
}

/* ----------------------------------------------------------------------
 *  Floating "Get a quote" CTA
 * ---------------------------------------------------------------------- */

.indo-floater {
    position: fixed;
    right: clamp(12px, 2vw, 24px);
    bottom: clamp(12px, 2vw, 24px);
    z-index: 90;
    background: var(--indo-cyan); /* revert 20260501-1430: brand cyan #00a6db is authoritative on the global GET A QUOTE floater — Tom directive. AA contrast remediated separately (label-size or navy-text-on-cyan, NEVER darken brand cyan on global CTAs). */
    color: #fff;
    width: clamp(72px, 8vw, 96px);
    height: clamp(72px, 8vw, 96px);
    border-radius: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    text-decoration: none;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    line-height: 1.2;
    box-shadow: 0 8px 24px rgba(0,0,0,0.15);
    transition: transform .2s var(--indo-easing), box-shadow .2s var(--indo-easing);
}
.indo-floater:hover, .indo-floater:focus {
    transform: translateY(-2px);
    box-shadow: 0 12px 32px rgba(0,0,0,0.20);
    color: #fff;
}

/* ===== HOME PAGE FIXES (sub-agent) =====
 * Audit 2026-04-28: legacy industrium-plugin widgets on the front page
 * (post 393) are still injecting Helvetica + Helvetica-bold for headings
 * and big chunky margins between sections. Until the page is rebuilt, we
 * coerce them into the new visual language here. All rules scoped to
 * body.home so they don't bleed onto inner Elementor pages.
 * --------------------------------------------------------------------- */

/* 1. FONT FAMILY — force every heading inside the home Elementor wrapper
 *    to use Lexend Deca light, overriding industrium's Helvetica-bold. */
body.home .elementor h1,
body.home .elementor h2,
body.home .elementor h3,
body.home .elementor h4,
body.home .elementor h5,
body.home .elementor h6,
body.home .elementor .elementor-heading-title,
body.home .elementor .industrium-heading,
body.home .elementor .industrium-heading * {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    letter-spacing: -0.01em;
    line-height: 1.15;
}
/* Restore brand colour for headings on dark sections (navy bg) */
body.home .elementor [style*="background-color:#121c22"] h1,
body.home .elementor [style*="background-color:#121c22"] h2,
body.home .elementor [style*="background-color:#121c22"] h3,
body.home .elementor [style*="background-color: rgb(18"] h1,
body.home .elementor [style*="background-color: rgb(18"] h2,
body.home .elementor [style*="background-color: rgb(18"] h3 {
    color: #fff !important;
}

/* Body / paragraph text inside Elementor on the home: use Inter, not Helvetica */
body.home .elementor p,
body.home .elementor .elementor-text-editor,
body.home .elementor .elementor-text-editor p,
body.home .elementor .industrium-services-listing,
body.home .elementor .industrium-services-listing * {
    font-family: var(--indo-font-body) !important;
}

/* 2. INTRO BAND — the pale grey "UK manufacturer of exterior street lighting"
 *    section currently uses 200 weight at 48px which reads too light/bare.
 *    Bump weight slightly and add breathing room. */
/* Section padding + margin-top:0 migrated to _elementor_data (post 393, section
   89ad7fd) on 2026-05-05 so Tom can edit them in Elementor's UI. The legacy
   clamp values resolve to 110px/60px desktop and 60px/20px mobile. */
body.home .elementor-element-89ad7fd .elementor-container {
    max-width: 1280px !important;
    margin: 0 auto !important;
}
body.home .elementor-element-89ad7fd h1,
body.home .elementor-element-89ad7fd h2 {
    font-weight: 300 !important;
    font-size: clamp(28px, 4vw, 44px) !important;
    color: var(--indo-charcoal) !important;
    max-width: 22ch;
}

/* "What makes us unique" CTA button — outlined cyan style, fix invisibility. */
body.home .elementor-element-89ad7fd .industrium-button,
body.home .elementor-element-89ad7fd .industrium-button a,
body.home .elementor .industrium-button a {
    display: inline-flex !important;
    align-items: center;
    gap: 10px;
    padding: 14px 26px !important;
    border: 1px solid var(--indo-cyan) !important;
    color: var(--indo-cyan) !important;
    background: transparent !important;
    font-family: var(--indo-font-body) !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    text-transform: uppercase;
    letter-spacing: .06em;
    border-radius: var(--indo-radius);
    transition: all .15s var(--indo-easing);
    text-decoration: none !important;
}
body.home .elementor .industrium-button a:hover,
body.home .elementor .industrium-button a:focus {
    background: var(--indo-cyan) !important;
    color: #fff !important;
}

/* 3. "DELIVERING VALUE SINCE 2007" — two column intro section. Tighten copy
 *    weight + spacing so it reads modern. Section padding migrated to
 *    _elementor_data on 2026-05-05 (88/60/88/60 desktop, 64/20/64/20 mobile). */
body.home .elementor-element-9e24185 .elementor-container {
    max-width: 1280px !important;
    margin: 0 auto !important;
}
body.home .elementor-element-9e24185 h2 {
    font-size: clamp(28px, 4vw, 44px) !important;
}
body.home .elementor-element-9e24185 .elementor-text-editor {
    font-size: 16px;
    line-height: 1.7;
    color: var(--indo-charcoal);
}

/* 4. TRUSTED BY logo carousel — kill ugly heavy heading + tighten band */
body.home .elementor-section:has(.elementor-widget-image-carousel) {
    padding: clamp(40px, 6vw, 80px) clamp(20px, 5vw, 60px) !important;
}
body.home .elementor-section:has(.elementor-widget-image-carousel) h2,
body.home .elementor-section:has(.elementor-widget-image-carousel) h3 {
    text-align: center;
    color: var(--indo-charcoal) !important;
    /* Bumped 2026-04-30 from 14-16px to match live homepage's ~40px heading
     * presence; user-requested size increase ("use live as reference").
     * Bumped again 2026-05-03 from clamp(28px, 3.4vw, 40px) to
     * clamp(32px, 4.5vw, 48px) per Tom — "Trusted By" was reading as visually
     * weaker than its weight-200 siblings (44-48px) because at these sizes
     * size beats weight. Now matches the surrounding section H2 ceiling
     * while keeping its bold-700 differentiation. No colour, no accent. */
    font-size: clamp(32px, 4.5vw, 48px) !important;
    font-weight: 700 !important;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif) !important;
    /* Tight letter-spacing — the previous .15em was tuned for the old 14px
     * micro-label rendering and looks gappy at 40px+. */
    letter-spacing: -0.005em;
    margin-bottom: 48px !important;
}
body.home .elementor-widget-image-carousel .swiper-slide img {
    filter: grayscale(1);
    opacity: .85;
    transition: filter .2s var(--indo-easing), opacity .2s var(--indo-easing);
    /* Bumped 2026-04-30 from 64px to 140px — matches live's 150px logos
     * (slight reduction for visual balance with the 40px heading above). */
    max-height: 140px;
    width: auto;
    object-fit: contain;
    margin: 0 auto;
}
body.home .elementor-widget-image-carousel .swiper-slide:hover img {
    filter: grayscale(0);
    opacity: 1;
}
/* 4b. Trusted By — uniform white card for every logo regardless of
 *     whether the underlying image has a transparent or white background.
 *     SVGs (SSE, TfL, Edmundson, National Highways, University of Birmingham,
 *     Cardiff University, Bridge Greenhouses) and RGBA PNGs (Westminster,
 *     Rothamsted, Unigro, Duke Electrical) previously showed the page's
 *     #f8f9fa off-white through them, making them appear to float without
 *     a card while the -colour.jpg logos had their own white boxes baked in.
 *     Fix: apply white bg + uniform padding to every figure.swiper-slide-inner
 *     inside this section. Version 2.3.41 — 2026-05-11. */
body.home .elementor-element-bc68b9f figure.swiper-slide-inner {
    background: #fff;
    border-radius: 6px;
    padding: 12px 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 80px;
    box-sizing: border-box;
}

/* 5. "SUCCESSFULLY COMPLETED PROJECTS" navy band — strip the 150px top margin
 *    + 140px top padding that creates a giant white gap above the section.
 *    Padding bumped 2026-05-01 from 60-110px to 96-160px so the heading +
 *    counter cluster has more breathing room above the slider. */
/* Section padding + margin:0 migrated to _elementor_data on 2026-05-05
   (104/60/112/60 desktop, 72/20/80/20 mobile). The bg/color stay in CSS
   because the navy bg is already in Elementor data and the white text
   colour propagates through every child via this selector. */
body.home .elementor-element-9e0df2f {
    background: var(--indo-navy) !important;
    color: #fff !important;
}
body.home .elementor-element-9e0df2f .elementor-container {
    max-width: 1280px !important;
    margin: 0 auto !important;
    align-items: center;
}
body.home .elementor-element-9e0df2f h1,
body.home .elementor-element-9e0df2f h2,
body.home .elementor-element-9e0df2f h3 {
    color: #fff !important;
    font-weight: 200 !important;
    font-size: clamp(28px, 4vw, 44px) !important;
    max-width: 22ch;
}
body.home .elementor-element-9e0df2f .elementor-counter-number-wrapper,
body.home .elementor-element-9e0df2f .elementor-counter-number {
    color: var(--indo-cyan) !important;
    /* Manrope 700 — matches the legacy live homepage counter look per
     * user request 2026-04-30 ("can you use the previous font from the
     * live homepage?"). Loaded via wp_enqueue_style in functions.php.
     *
     * Size capped at 110px (was 150px). At 1280px viewport "4,700+" at
     * 150px is ~430px wide; the right column is only ~470px wide so
     * even right-aligned the digits still cross into the heading
     * column. 110px keeps the number prominent but ~310px wide, which
     * fits comfortably with a guaranteed clearance from the heading. */
    font-family: "Manrope", "Lexend Deca", sans-serif !important;
    font-weight: 700 !important;
    font-size: clamp(64px, 8.5vw, 110px) !important;
    letter-spacing: -0.03em !important;
    line-height: 1;
}
body.home .elementor-element-9e0df2f .elementor-counter-title {
    color: var(--indo-gray) !important;
    font-family: var(--indo-font-body) !important;
    font-size: 13px !important;
    text-transform: uppercase !important;
    letter-spacing: .1em !important;
    margin-top: 12px !important;
    text-align: left !important;
}
/* "View Case Studies" link button on the navy band */
body.home .elementor-element-9e0df2f .industrium-button a {
    border-color: #fff !important;
    color: #fff !important;
}
body.home .elementor-element-9e0df2f .industrium-button a:hover {
    background: #fff !important;
    color: var(--indo-navy) !important;
}
/* Ensure the counter widget sits above the heading + projects-listing widget
 * which together render a 1280x144 invisible h2 that overlays the counter. */
body.home .elementor-element-9e0df2f .elementor-widget-counter {
    position: relative !important;
    z-index: 5 !important;
}
body.home .elementor-element-9e0df2f .industrium-heading,
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget {
    position: relative;
    z-index: 1;
}
/* The "successfully completed projects for our clients" heading needs to
 * stay confined to the left ~60% of the section so the counter widget on the
 * right is visible. */
body.home .elementor-element-9e0df2f .industrium-heading {
    max-width: 60% !important;
}
/* Force-show the counter widget that has elementor-hidden-mobile classes
 * applied on it (was hiding at our 1424 viewport for unknown reason). */
body.home .elementor-element-9e0df2f .elementor-widget-counter.elementor-hidden-mobile,
body.home .elementor-element-9e0df2f .elementor-widget-counter.elementor-hidden-mobile_extra {
    display: block !important;
}
/* Counter title (the "Completed projects" stacked label) — small caps
 * label sitting under the cyan number. */
body.home .elementor-element-9e0df2f .elementor-counter-title {
    color: var(--indo-gray) !important;
    font-family: var(--indo-font-body) !important;
    font-size: 12px !important;
    text-transform: uppercase !important;
    letter-spacing: .12em !important;
    margin-top: 8px !important;
    text-align: left !important;
    line-height: 1.4 !important;
    writing-mode: horizontal-tb !important;
}
/* Make the elementor-counter flex layout stack title-below-number cleanly */
body.home .elementor-element-9e0df2f .elementor-counter {
    display: flex !important;
    flex-direction: column-reverse !important;
    align-items: flex-start !important;
}
body.home .elementor-element-9e0df2f .elementor-counter-number-suffix,
body.home .elementor-element-9e0df2f .elementor-counter-number-prefix {
    color: var(--indo-cyan) !important;
    font-family: "Manrope", "Lexend Deca", sans-serif !important;
    font-size: clamp(64px, 8.5vw, 110px) !important;
    line-height: 1;
    font-weight: 700 !important;
    letter-spacing: -0.03em !important;
}
/* CRITICAL: Elementor's default counter widget has `background-clip: text`
 * on the number wrapper, which (when combined with our transparent bg)
 * makes the digits invisible. Reset background-clip to border-box so the
 * cyan text colour actually paints. */
body.home .elementor-element-9e0df2f .elementor-counter-number-wrapper,
body.home .elementor-element-9e0df2f .elementor-counter-number,
body.home .elementor-element-9e0df2f .elementor-counter-number-prefix,
body.home .elementor-element-9e0df2f .elementor-counter-number-suffix {
    background-clip: border-box !important;
    -webkit-background-clip: border-box !important;
    -webkit-text-fill-color: var(--indo-cyan) !important;
    background-image: none !important;
    background: transparent !important;
}

/* 6. CONTACT / "GET IN TOUCH" section — was overriding the contact band's
   default padding. Padding/margin migrated to _elementor_data on 2026-05-05:
   section 4e3d2f3 (the :nth-last-child(2)) now carries 100/60/120/60 desktop
   and 60/20/96/20 mobile. The map (:last-child, 7752216) keeps its
   padding:0 opt-out at line ~9650, so removal is safe. */
body.home .elementor.elementor-393 > .elementor-section:last-child h1,
body.home .elementor.elementor-393 > .elementor-section:last-child h2,
body.home .elementor.elementor-393 > .elementor-section:last-child h3 {
}
/* "Get in Touch" form heading — make sure it uses display font + readable size */
body.home .elementor.elementor-393 .elementor-element form h2,
body.home .elementor.elementor-393 .elementor-element form h3,
body.home .elementor.elementor-393 .elementor-element h2:has(+ form),
body.home .elementor.elementor-393 .elementor-element h3:has(+ form) {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    font-size: clamp(28px, 4vw, 40px) !important;
    color: var(--indo-navy) !important;
}

/* 7. Hide the empty 1px decoration-only sections that create no visible
 *    content but add to overall page height. */
body.home .elementor-element-5e56e6d {
    display: none !important;
}

/* 8. Header transparent state — push the on-light trigger threshold so it
 *    only swaps when the user scrolls PAST the hero (currently fires too early).
 *    JS reads window.innerHeight * 0.7; we can also nudge via CSS by ensuring
 *    the hero is at least 100vh tall on the home page. */
body.home main > .elementor > .elementor-section:first-child,
body.home main .elementor-393 > .elementor-section:first-child {
    min-height: calc(100vh - 0px);
}
body.home main .elementor-393 > .elementor-section:first-child img {
    width: 100% !important;
    height: 100% !important;
    min-height: 100vh !important;
    object-fit: cover !important;
    object-position: center;
}

/* 9. Industrium services listing widget — used in "UK manufacturer" intro. The
 *    legacy widget renders as ugly bullet text; hide it for now since the
 *    section has no other illustrative content. */
body.home .elementor-element-89ad7fd .elementor-widget-industrium-services-listing {
    display: none !important;
}

/* 10. Forms inside the home contact section — float labels, cyan focus.
 *     Override industrium's heavy default field styling. */
body.home .elementor.elementor-393 input[type=text],
body.home .elementor.elementor-393 input[type=email],
body.home .elementor.elementor-393 input[type=tel],
body.home .elementor.elementor-393 textarea,
body.home .elementor.elementor-393 select {
    font-family: var(--indo-font-body) !important;
    font-size: 15px !important;
    padding: 14px 0 !important;
    border: 0 !important;
    border-bottom: 1px solid #e1e6e9 !important;
    background: transparent !important;
    color: var(--indo-charcoal) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}
body.home .elementor.elementor-393 input:focus,
body.home .elementor.elementor-393 textarea:focus,
body.home .elementor.elementor-393 select:focus {
    border-bottom-color: var(--indo-cyan) !important;
    outline: 0 !important;
}
body.home .elementor.elementor-393 button[type=submit],
body.home .elementor.elementor-393 input[type=submit] {
    background: var(--indo-cyan) !important;
    color: #fff !important;
    border: 0 !important;
    padding: 14px 28px !important;
    font-family: var(--indo-font-body) !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    text-transform: uppercase;
    letter-spacing: .06em;
    border-radius: var(--indo-radius);
    transition: background .15s var(--indo-easing);
    cursor: pointer;
}
body.home .elementor.elementor-393 button[type=submit]:hover,
body.home .elementor.elementor-393 input[type=submit]:hover {
    background: var(--indo-cyan-light) !important;
}

/* 11. Hero (first elementor section on home) — guarantee no max-width, full
 *     viewport bleed, no white sliver on either side regardless of scrollbar. */
body.home main .elementor-393 > .elementor-section:first-child,
body.home main .elementor-393 > .elementor-section:first-child > .elementor-container {
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
/* Image inside the hero must fill the section corner-to-corner */
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image .elementor-widget-container,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image .elementor-image,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image a {
    width: 100% !important;
    height: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    line-height: 0 !important;
}
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image img {
    width: 100% !important;
    height: 100vh !important;
    max-width: none !important;
    object-fit: cover !important;
    display: block !important;
}

/* 11b. Section margins migrated to _elementor_data on 2026-05-05. The five
        named sections (9e24185, bc68b9f, 9e0df2f, 5e56e6d, 4e3d2f3) and
        89ad7fd already carry margin: 0 in their settings, so the per-section
        and universal margin-zero overrides here are redundant and have been
        removed. Section 5e56e6d remains display:none via the rule at line
        ~1080. */

/* 11c. "Trusted By" band — give it a soft top divider so it doesn't smash
 *      directly into the navy stats band beneath it. Padding migrated to
 *      _elementor_data on 2026-05-05 (80/60/80/60 desktop, 40/20/40/20 mobile);
 *      background colour stays in CSS because the original Elementor data has
 *      no background colour set. */
body.home .elementor-element-bc68b9f {
    background: #f8f9fa !important;
}

/* 12. Mobile — make sure the contact section's two columns stack and the
 *     navy stats band keeps padding sane. */
@media (max-width: 767px) {
    body.home .elementor-element-9e0df2f .elementor-counter-number {
        font-size: 56px !important;
    }
    body.home .elementor-element-89ad7fd h2,
    body.home .elementor-element-9e24185 h2,
    body.home .elementor-element-9e0df2f h2 {
        font-size: 28px !important;
    }
}

/* =========================================================================
   ===== ABOUT PAGE FIXES (sub-agent) =====
   Page ID: 395. Body class hook: body.page-id-395
   Issues addressed (audit 2026-04-28):
   1. Section 1 left col displays Favicon.jpg blown up to 500x500 (the
      "giant cyan ring" graphic) — hide it.
   2. Section 0 ("since 2007") has 212px section but only a tiny subtitle —
      tighten padding.
   3. Section 1 heading "If you want a committed..." renders in Helvetica,
      not the Lexend display font — force display family + lowercase.
   4. Navy section (630a8fa) "British Designed" — image is a 625x187 thin
      slab; widen and add object-fit. Also kill empty 70px column padding.
   5. Section 38d041d "Values" infographic — center cleanly, kill huge
      empty void below.
   6. Meet the Team section (e0f172e) — team widget renders empty (broken
      industrium widget). Hide entire section since it would just be a
      heading floating in 600px of whitespace.
   7. Inner section 7b87f0c (40px slim empty bar under team heading) — hide.
   8. Testimonial section (59113ac) — carousel JS is dead, items render as
      a tall vertical stack of testimonials (1169px). Style them as a
      clean grid of cards instead.
   9. Partners section (5127dca) — image carousel JS is dead, 1537px tall
      vertical stack of partner logos. Convert to a grayscale grid.
   10. Hide industrium_decoration empty placeholder elements.
   ========================================================================= */

/* --- 1. Kill the giant Favicon "ring" graphic in section 1 left column --- */
body.page-id-395 .elementor-element-61ddadd > .elementor-container > .elementor-column:first-child .elementor-widget-image {
    display: none !important;
}
/* The empty icon widget above it too */
body.page-id-395 .elementor-element-61ddadd > .elementor-container > .elementor-column:first-child .elementor-widget-icon {
    display: none !important;
}
/* Now collapse the empty left column and let the content column span full width */
body.page-id-395 .elementor-element-61ddadd > .elementor-container {
    max-width: 1100px !important;
    margin: 0 auto !important;
    padding: 0 clamp(20px, 4vw, 40px) !important;
}
body.page-id-395 .elementor-element-61ddadd > .elementor-container > .elementor-column:first-child {
    display: none !important;
}
body.page-id-395 .elementor-element-61ddadd > .elementor-container > .elementor-column:last-child {
    width: 100% !important;
    max-width: 100% !important;
    flex: 1 0 100% !important;
}

/* --- 2. Section 0 "since 2007" subtitle — typography only.
       (2026-05-05) Padding/margin/text-align rule for 0d5381e removed:
       that section ID does not exist in the page's _elementor_data, so
       the rule was a no-op. Typography rules below remain (they target
       child .industrium-special-text classes; equally dead but harmless). --- */
body.page-id-395 .elementor-element-0d5381e .industrium-special-text,
body.page-id-395 .elementor-element-0d5381e [class*="special-text"] {
    text-align: center !important;
    color: var(--indo-gray, #abafb5) !important;
    font-family: var(--indo-font-body, "Inter"), sans-serif !important;
    font-size: 13px !important;
    text-transform: uppercase !important;
    letter-spacing: .18em !important;
    font-weight: 500 !important;
}

/* --- 3. Section 1 heading + body styling --- */
/* (2026-05-05) Section padding/margin migrated into _elementor_data so the
   editor's per-section Padding control is authoritative. Typography rules
   below remain because they target child elements, not the section itself. */
body.page-id-395 .elementor-element-61ddadd .industrium-heading,
body.page-id-395 .elementor-element-61ddadd .industrium-heading-content,
body.page-id-395 .elementor-element-61ddadd h1,
body.page-id-395 .elementor-element-61ddadd h2,
body.page-id-395 .elementor-element-61ddadd h2 span,
body.page-id-395 .elementor-element-61ddadd h3 {
    font-family: var(--indo-font-display, "Lexend Deca"), sans-serif !important;
    font-weight: 200 !important;
    font-size: clamp(28px, 4vw, 46px) !important;
    line-height: 1.18 !important;
    color: var(--indo-charcoal, #212121) !important;
    letter-spacing: -0.01em !important;
    margin: 0 0 32px 0 !important;
    max-width: 22ch !important;
    text-align: left !important;
    background: transparent !important;
}
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor,
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor p,
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor span,
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor div,
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor li,
body.page-id-395 .elementor-element-61ddadd .gdlr-item,
body.page-id-395 .elementor-element-61ddadd .gdlr-color-wrapper {
    font-family: var(--indo-font-body, "Inter"), sans-serif !important;
    font-weight: 400 !important;
    font-size: 16px !important;
    line-height: 1.75 !important;
    color: var(--indo-charcoal, #212121) !important;
    letter-spacing: 0 !important;
}
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor p {
    max-width: 64ch !important;
    margin: 0 0 16px 0 !important;
}
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor strong,
body.page-id-395 .elementor-element-61ddadd .elementor-widget-text-editor b {
    font-weight: 600 !important;
}
/* Reset legacy industrium .gdlr-* container widths so text isn't constrained */
body.page-id-395 .elementor-element-61ddadd .gdlr-color-wrapper,
body.page-id-395 .elementor-element-61ddadd .gdlr-color-wrapper .container,
body.page-id-395 .elementor-element-61ddadd .gdlr-color-wrapper .four.columns,
body.page-id-395 .elementor-element-61ddadd .gdlr-color-wrapper [class*="columns"] {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    float: none !important;
    background: transparent !important;
}

/* --- 4. Navy "British Designed" section (630a8fa) --- */
/* (2026-05-05) padding + margin migrated into _elementor_data. Background
   colour stays because Elementor's section background_color setting is empty
   for this section and we want the navy treatment to remain CSS-driven. */
body.page-id-395 .elementor-element-630a8fa {
    background: var(--indo-navy, #121c22) !important;
    color: #fff !important;
}
/* (2026-05-05) ef1f02f inner-section padding/margin migrated to _elementor_data. */
body.page-id-395 .elementor-element-630a8fa .elementor-element-ef1f02f > .elementor-container {
    max-width: 1180px !important;
    margin: 0 auto !important;
    gap: 48px !important;
    align-items: flex-start !important;
}
/* (2026-05-05) column padding migrated into _elementor_data on the three child columns
   (ed68f9e, a1d6b89, 16dfcd1). */
body.page-id-395 .elementor-element-630a8fa h1,
body.page-id-395 .elementor-element-630a8fa h2,
body.page-id-395 .elementor-element-630a8fa h3,
body.page-id-395 .elementor-element-630a8fa h2 span,
body.page-id-395 .elementor-element-630a8fa .industrium-heading,
body.page-id-395 .elementor-element-630a8fa .industrium-heading-content {
    color: #fff !important;
    font-family: var(--indo-font-display, "Lexend Deca"), sans-serif !important;
    font-weight: 200 !important;
    letter-spacing: -0.01em !important;
    font-size: clamp(22px, 2.6vw, 30px) !important;
    line-height: 1.25 !important;
    margin: 0 0 18px 0 !important;
    background: transparent !important;
}
body.page-id-395 .elementor-element-630a8fa .elementor-widget-text-editor,
body.page-id-395 .elementor-element-630a8fa .elementor-widget-text-editor p,
body.page-id-395 .elementor-element-630a8fa .elementor-widget-text-editor span,
body.page-id-395 .elementor-element-630a8fa .elementor-widget-text-editor div,
body.page-id-395 .elementor-element-630a8fa .gdlr-item,
body.page-id-395 .elementor-element-630a8fa .gdlr-color-wrapper {
    color: #cfd6dc !important;
    font-family: var(--indo-font-body, "Inter"), sans-serif !important;
    font-weight: 400 !important;
    font-size: 15px !important;
    line-height: 1.75 !important;
    background: transparent !important;
    letter-spacing: 0 !important;
}
body.page-id-395 .elementor-element-630a8fa .elementor-widget-text-editor p {
    max-width: 60ch !important;
    margin: 0 0 14px 0 !important;
}
body.page-id-395 .elementor-element-630a8fa .gdlr-color-wrapper,
body.page-id-395 .elementor-element-630a8fa .gdlr-color-wrapper .container,
body.page-id-395 .elementor-element-630a8fa [class*="columns"] {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    float: none !important;
}
/* Image inside navy section — let it fill column with proper aspect */
body.page-id-395 .elementor-element-630a8fa .elementor-widget-image img {
    width: 100% !important;
    height: auto !important;
    max-height: 280px !important;
    object-fit: cover !important;
    border-radius: 4px !important;
    display: block !important;
    margin: 0 0 24px 0 !important;
}

/* --- 5. Values infographic section (38d041d) --- */
/* (2026-05-05) padding + margin migrated into _elementor_data. Background
   + text-align kept here because the section's Elementor settings don't
   carry them. */
body.page-id-395 .elementor-element-38d041d {
    background: #fafbfc !important;
    text-align: center;
}
body.page-id-395 .elementor-element-38d041d .elementor-container {
    max-width: 1100px !important;
    margin: 0 auto !important;
}
body.page-id-395 .elementor-element-38d041d .elementor-widget-image {
    text-align: center !important;
}
body.page-id-395 .elementor-element-38d041d img {
    max-width: 880px !important;
    width: 100% !important;
    height: auto !important;
    margin: 0 auto !important;
    display: block !important;
}

/* --- 6. (REMOVED 2026-04-29) Was hiding "Meet the Team" section
       e0f172e under the false belief that the widget was broken-empty.
       Real cause: missing content-industrium_team.php template in
       indo-2026 + missing layout CSS. Both fixed in
       TEAM-GRID-RESTORE block at end of file. --- */
/* --- 7. (REMOVED 2026-04-29) Same false-empty assumption applied to
       inner section 7b87f0c. Removed. --- */

/* --- 8. Testimonials section (59113ac) — broken owl-carousel; render as grid ---
 *      Real DOM:
 *        section .elementor-element-59113ac
 *          inner-section .elementor-element-7ea7bd6
 *            .elementor-container > .elementor-column (col-50, gets narrowed)
 *              .industrium-testimonial-carousel-widget
 *                .testimonial-carousel-wrapper
 *                  .testimonial-wrapper-inner
 *                    .testimonials-heading
 *                    .testimonials-slider-container
 *                      .testimonials-slider.owl-carousel.owl-theme  ← items here
 *                        .testimonial-item × N                      */
/* (2026-05-05) padding + margin migrated into _elementor_data. */
body.page-id-395 .elementor-element-59113ac {
    background: #f4f6f8 !important;
}
/* (2026-05-05) 7ea7bd6 inner-section padding/margin migrated to _elementor_data;
   min-height + background overrides retained (not editor-controlled). */
body.page-id-395 .elementor-element-59113ac .elementor-element-7ea7bd6 {
    min-height: 0 !important;
    background-image: none !important;
    background-color: transparent !important;
}
/* Kill the .testimonials-heading inner navy background coming from
 * industrium's default skin */
body.page-id-395 .elementor-element-59113ac .testimonials-heading,
body.page-id-395 .elementor-element-59113ac .testimonials-heading > *,
body.page-id-395 .elementor-element-59113ac .testimonials-heading-content {
    background: transparent !important;
    box-shadow: none !important;
    border: 0 !important;
}
body.page-id-395 .elementor-element-59113ac .elementor-element-7ea7bd6 > .elementor-container {
    max-width: 1200px !important;
    margin: 0 auto !important;
    width: 100% !important;
    flex-wrap: wrap !important;
    display: flex !important;
}
/* Hide column 1 (just the broken industrium-decoration) and let column 2 (the
 * carousel widget) span full width. */
body.page-id-395 .elementor-element-59113ac .elementor-element-7ea7bd6 > .elementor-container > .elementor-column:nth-child(1) {
    display: none !important;
}
body.page-id-395 .elementor-element-59113ac .elementor-element-7ea7bd6 > .elementor-container > .elementor-column:nth-child(2),
body.page-id-395 .elementor-element-59113ac .elementor-element-7ea7bd6 > .elementor-container > .elementor-column {
    width: 100% !important;
    max-width: 100% !important;
    flex: 0 0 100% !important;
}
body.page-id-395 .elementor-element-59113ac .industrium-testimonial-carousel-widget,
body.page-id-395 .elementor-element-59113ac .testimonial-carousel-wrapper,
body.page-id-395 .elementor-element-59113ac .testimonial-wrapper-inner,
body.page-id-395 .elementor-element-59113ac .testimonials-slider-container {
    width: 100% !important;
    max-width: 100% !important;
    display: block !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    background-image: none !important;
    background-color: transparent !important;
}
/* Heading block on top, centred */
body.page-id-395 .elementor-element-59113ac .testimonials-heading {
    text-align: center !important;
    margin-bottom: 48px !important;
    display: block !important;
}
body.page-id-395 .elementor-element-59113ac .testimonials-heading .industrium-heading,
body.page-id-395 .elementor-element-59113ac .testimonials-heading .industrium-heading-content,
body.page-id-395 .elementor-element-59113ac .testimonials-heading h2,
body.page-id-395 .elementor-element-59113ac .testimonials-heading h2 span,
body.page-id-395 .elementor-element-59113ac .testimonials-heading h3 {
    font-family: var(--indo-font-display, "Lexend Deca"), sans-serif !important;
    font-weight: 200 !important;
    font-size: clamp(26px, 3.4vw, 38px) !important;
    color: var(--indo-charcoal, #212121) !important;
    margin: 0 !important;
    letter-spacing: -0.01em !important;
    background: transparent !important;
}
body.page-id-395 .elementor-element-59113ac .testimonials-heading .title-icon,
body.page-id-395 .elementor-element-59113ac .testimonials-heading i {
    display: none !important;
}
/* THE actual items container — owl-carousel that never initialised. Force grid. */
body.page-id-395 .elementor-element-59113ac .testimonials-slider,
body.page-id-395 .elementor-element-59113ac .testimonials-slider.owl-carousel {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)) !important;
    gap: 24px !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
    list-style: none !important;
    /* Disable owl's transform/opacity hides */
    opacity: 1 !important;
    transform: none !important;
}
/* Disable owl-carousel's stage transform and clip-out behaviour */
body.page-id-395 .elementor-element-59113ac .owl-stage-outer,
body.page-id-395 .elementor-element-59113ac .owl-stage {
    display: contents !important;
}
body.page-id-395 .elementor-element-59113ac .testimonial-item,
body.page-id-395 .elementor-element-59113ac .slider-item.testimonial-item {
    background: #fff !important;
    border-radius: 6px !important;
    padding: 32px 28px !important;
    box-shadow: 0 1px 3px rgba(18, 28, 34, 0.06), 0 8px 24px rgba(18, 28, 34, 0.04) !important;
    margin: 0 !important;
    display: block !important;
    width: auto !important;
    max-width: 100% !important;
    color: var(--indo-charcoal, #212121) !important;
    font-family: var(--indo-font-body, "Inter"), sans-serif !important;
    font-size: 15px !important;
    line-height: 1.65 !important;
    border-left: 3px solid var(--indo-cyan, #00a6db) !important;
    opacity: 1 !important;
    transform: none !important;
    visibility: visible !important;
}
body.page-id-395 .elementor-element-59113ac .testimonial-item p,
body.page-id-395 .elementor-element-59113ac .testimonial-item .testimonial-text,
body.page-id-395 .elementor-element-59113ac .testimonial-item blockquote {
    margin: 0 0 16px 0 !important;
    font-style: italic !important;
    color: var(--indo-charcoal, #212121) !important;
    font-size: 15px !important;
    line-height: 1.65 !important;
    font-weight: 400 !important;
}
body.page-id-395 .elementor-element-59113ac .testimonial-item .author-name,
body.page-id-395 .elementor-element-59113ac .testimonial-item cite,
body.page-id-395 .elementor-element-59113ac .testimonial-item .testimonial-author,
body.page-id-395 .elementor-element-59113ac .testimonial-item .testimonial-position {
    color: var(--indo-cyan, #00a6db) !important;
    font-style: normal !important;
    font-size: 13px !important;
    text-transform: uppercase !important;
    letter-spacing: .08em !important;
    font-weight: 500 !important;
    display: block !important;
    margin-top: 16px !important;
}
/* Hide owl nav dots/arrows since carousel is dead */
body.page-id-395 .elementor-element-59113ac .owl-nav,
body.page-id-395 .elementor-element-59113ac .owl-dots,
body.page-id-395 .elementor-element-59113ac .testimonials-footer {
    display: none !important;
}

/* --- 9. Partners section (5127dca) — broken owl image-carousel; force grid ---
 *      Real DOM:
 *        section .elementor-element-5127dca
 *          .elementor-widget-industrium_image_carousel
 *            .industrium-image-slider-widget
 *              .slider-wrapper
 *                .slider-container
 *                  .image-carousel.owl-carousel.owl-theme  ← items here
 *                    .slider-item × N
 *                      .slider-item-inner > .slider-item-media > img      */
/* (2026-05-05) padding + margin migrated into _elementor_data. */
body.page-id-395 .elementor-element-5127dca {
    background: #fff !important;
}
/* (2026-05-05) e2f304e inner-section padding/margin migrated to _elementor_data;
   min-height retained. */
body.page-id-395 .elementor-element-5127dca .elementor-element-e2f304e {
    min-height: 0 !important;
}
body.page-id-395 .elementor-element-5127dca .elementor-element-e2f304e > .elementor-container {
    max-width: 1200px !important;
    margin: 0 auto !important;
    text-align: center;
}
body.page-id-395 .elementor-element-5127dca .industrium-heading,
body.page-id-395 .elementor-element-5127dca .industrium-heading-content,
body.page-id-395 .elementor-element-5127dca h1,
body.page-id-395 .elementor-element-5127dca h2,
body.page-id-395 .elementor-element-5127dca h2 span,
body.page-id-395 .elementor-element-5127dca h3 {
    font-family: var(--indo-font-display, "Lexend Deca"), sans-serif !important;
    font-weight: 200 !important;
    font-size: clamp(24px, 3vw, 34px) !important;
    color: var(--indo-charcoal, #212121) !important;
    text-align: center !important;
    margin: 0 0 48px 0 !important;
    letter-spacing: -0.01em !important;
    background: transparent !important;
}
/* The widget's container divs — make them full-width block */
body.page-id-395 .elementor-element-5127dca .industrium-image-slider-widget,
body.page-id-395 .elementor-element-5127dca .industrium-image-slider-widget .slider-wrapper,
body.page-id-395 .elementor-element-5127dca .industrium-image-slider-widget .slider-container {
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
}
/* The actual items list — convert owl-carousel into a logo grid.
 * Locked to 7 columns × 6 rows = 42 items at desktop. The grid uses
 * display:contents on owl-stage / owl-stage-outer to flatten the
 * carousel DOM into the grid; owl-injected .cloned items are hidden
 * with the rule below so only the original 42 entries render. */
body.page-id-395 .elementor-element-5127dca .image-carousel,
body.page-id-395 .elementor-element-5127dca .image-carousel.owl-carousel {
    display: grid !important;
    grid-template-columns: repeat(7, 1fr) !important;
    gap: 32px 24px !important;
    align-items: center !important;
    justify-items: center !important;
    list-style: none !important;
    padding: 0 !important;
    margin: 0 auto !important;
    max-width: 1180px !important;
    width: 100% !important;
    opacity: 1 !important;
    transform: none !important;
}
body.page-id-395 .elementor-element-5127dca .owl-stage-outer,
body.page-id-395 .elementor-element-5127dca .owl-stage {
    display: contents !important;
}
/* Hide owl-carousel's loop clones so only the 42 originals render
 * inside the grid. The clones exist for owl's infinite-scroll loop;
 * since we've replaced the carousel with a static grid they
 * otherwise show up as duplicate logos. */
body.page-id-395 .elementor-element-5127dca .owl-item.cloned,
body.page-id-395 .elementor-element-5127dca .image-carousel .owl-item.cloned {
    display: none !important;
}
/* Owl-carousel JS sets inline width:Npx on each .owl-item — that overrides
 * the grid's `1fr` track sizing and forces the grid wider than its
 * container. Force the entire owl-item → slider-item → slider-item-inner →
 * slider-item-media chain to width:100% so each fills its grid track
 * regardless of image natural-size. Lazy-loaded images report 0×0 until
 * first paint, which would otherwise collapse the chain to zero (any
 * `width: auto` link in the chain causes a collapse). Pin a min-height so
 * empty/lazy cells still occupy a row and the grid stays 7×6. */
body.page-id-395 .elementor-element-5127dca .owl-item,
body.page-id-395 .elementor-element-5127dca .image-carousel .owl-item {
    width: 100% !important;
    min-width: 0 !important;
    min-height: 80px !important;
    max-width: 100% !important;
    margin: 0 !important;
    display: block !important;
}
body.page-id-395 .elementor-element-5127dca .slider-item,
body.page-id-395 .elementor-element-5127dca .image-carousel .slider-item {
    margin: 0 !important;
    padding: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: 100% !important;
    min-height: 80px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    opacity: 1 !important;
    transform: none !important;
}
body.page-id-395 .elementor-element-5127dca .slider-item-inner,
body.page-id-395 .elementor-element-5127dca .slider-item-media {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    margin: 0 !important;
    padding: 0 !important;
    width: 100% !important;
}
body.page-id-395 .elementor-element-5127dca img {
    max-width: 130px !important;
    width: auto !important;
    height: auto !important;
    max-height: 80px !important;
    filter: grayscale(1) !important;
    opacity: .75 !important;
    transition: filter .2s ease, opacity .2s ease !important;
    object-fit: contain !important;
    display: block !important;
    margin: 0 auto !important;
}
body.page-id-395 .elementor-element-5127dca img:hover {
    filter: grayscale(0) !important;
    opacity: 1 !important;
}
/* Hide owl dots/nav since the carousel is broken anyway */
body.page-id-395 .elementor-element-5127dca .owl-nav,
body.page-id-395 .elementor-element-5127dca .owl-dots {
    display: none !important;
}

/* --- 10. Hide empty industrium decoration placeholder divs everywhere on the page --- */
body.page-id-395 .industrium-decoration,
body.page-id-395 .elementor-widget-industrium_decoration {
    display: none !important;
}

/* --- 11. Universal: kill rogue top/bottom margins on ALL top-level sections on /about/ --- */
body.page-id-395 main > .elementor > .elementor-section,
body.page-id-395 .elementor.elementor-395 > .elementor-section {
    margin: 0 !important;
}

/* Tablet (769-991): 5 cols × 9 rows = 45 cells (we have 42, last
 * row partial). Matches the "logos read as a brand-mark grid"
 * intent without becoming too cramped. */
@media (min-width: 769px) and (max-width: 991px) {
    body.page-id-395 .elementor-element-5127dca .image-carousel,
    body.page-id-395 .elementor-element-5127dca .image-carousel.owl-carousel {
        grid-template-columns: repeat(5, 1fr) !important;
        gap: 24px 18px !important;
    }
}

/* --- 12. Mobile tweaks --- */
@media (max-width: 991px) {
    body.page-id-395 .elementor-element-630a8fa .elementor-element-ef1f02f > .elementor-container {
        gap: 24px !important;
    }
    body.page-id-395 .elementor-element-630a8fa .elementor-column {
        width: 100% !important;
        max-width: 100% !important;
        flex: 1 0 100% !important;
    }
}
@media (max-width: 767px) {
    body.page-id-395 .elementor-element-61ddadd .industrium-heading,
    body.page-id-395 .elementor-element-61ddadd h2 {
        font-size: 26px !important;
    }
    body.page-id-395 .elementor-element-630a8fa h2,
    body.page-id-395 .elementor-element-59113ac h2,
    body.page-id-395 .elementor-element-5127dca h2 {
        font-size: 24px !important;
    }
    /* Partners grid (mobile): the previous rule (max-h:60px) was forcing
       square logos to render at 60×60. Also: 4 layers of nested Elementor
       padding (section + widget-wrap + container + widget-wrap) ate ~92px
       at 375px, leaving the grid at only 196px so just 2 cols would fit.
       Fix: strip the inner padding on the partners section's nested wrappers
       on mobile, retarget the real grid selector (.image-carousel — the
       previous rule pointed at .industrium-image-carousel-widget which
       doesn't exist and was a NOOP), reduce gaps, and raise the per-logo
       size cap. Result: 3 cols at 320/375, 4 cols at ~414, logos at 80×80. */
    /* (2026-05-05) mobile section padding migrated into _elementor_data
       (padding_mobile: 60 16 60 16). */
    body.page-id-395 .elementor-element-5127dca .elementor-container,
    body.page-id-395 .elementor-element-5127dca .elementor-widget-wrap.elementor-element-populated {
        padding: 0 !important;
    }
    body.page-id-395 .elementor-element-5127dca .image-carousel,
    body.page-id-395 .elementor-element-5127dca .image-carousel.owl-carousel {
        grid-template-columns: repeat(3, 1fr) !important;
        gap: 20px 16px !important;
    }
    body.page-id-395 .elementor-element-5127dca img {
        max-width: 100px !important;
        max-height: 80px !important;
    }
    body.page-id-395 .elementor-element-59113ac .testimonial-wrapper-inner {
        grid-template-columns: 1fr !important;
    }
}

/* =========================================================================
   ===== HOME RE-FIX (urgent sub-agent) =====
   Date: 2026-04-28. Three user-reported bugs that survived the previous
   home sub-agent's pass.

   1. HERO NOT FULL-BLEED at viewports > ~1424px.
      Root cause: Elementor's stretched-section JS sets inline
      `style="width: <body-width>px; left: Npx;"` on the section. At narrow
      viewports our `width:100vw !important` cancels it; at wider viewports
      the legacy industrium CSS for `.elementor-section.elementor-section-
      full_width` sets a fixed `max-width` (~1424px) inherited from a kit
      var, so the image is capped. Use the bulletproof centered-bleed
      pattern (`position:relative; left:50%; transform:translateX(-50%);
      width:100vw`) which doesn't depend on Elementor JS.

   2. EMPTY "About Us" CTA below "Delivering value since 2007".
      Root cause: industrium's `.elementor-widget-industrium_button
      .button-container { font-size:0; line-height:1 }` zeroes the
      anchor's font. Previous home sub-agent's selector
      `body.home .elementor .industrium-button a` does NOT match because
      `.industrium-button` IS the `<a>`, not its parent. The "What makes
      us unique" CTA only worked because of an additional section-scoped
      rule. Add a rule that targets `a.industrium-button` directly across
      the home + restores font-size on the inner `.industrium-button-text`
      span (industrium also zeroes it).

   3. SAME BUG on "View Case Studies" link inside the navy projects band
      (.pagination_wrapper). Render as a proper underlined arrow link.
   ========================================================================= */

/* --- 1. HERO FULL BLEED — bulletproof, viewport-independent ----------- */
/* Prevent horizontal page scroll caused by 100vw children */
html, body.home { overflow-x: hidden !important; }

/* The first Elementor section under <main> on the home is the hero. */
body.home main .elementor-393 > .elementor-section:first-child,
body.home main > .elementor > .elementor-section:first-child {
    position: relative !important;
    left: 50% !important;
    right: 50% !important;
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: -50vw !important;
    margin-right: -50vw !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    transform: none !important;
    box-sizing: border-box !important;
}
/* Container, column, widget wrapper inside the hero — all 100% of section */
body.home main .elementor-393 > .elementor-section:first-child > .elementor-container,
body.home main .elementor-393 > .elementor-section:first-child .elementor-column,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-wrap,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-image,
body.home main .elementor-393 > .elementor-section:first-child .elementor-widget-container,
body.home main .elementor-393 > .elementor-section:first-child .elementor-image,
body.home main .elementor-393 > .elementor-section:first-child .elementor-image a {
    width: 100% !important;
    max-width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    flex: 1 1 100% !important;
}
/* The image itself — corner-to-corner, height comes from object-fit. */
body.home main .elementor-393 > .elementor-section:first-child img {
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 100% !important;
    height: auto !important;
    min-height: 60vh !important;
    max-height: 100vh !important;
    object-fit: cover !important;
    object-position: center center !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* --- 2. RESTORE TEXT on every .industrium-button on the home ---------- */
/* The legacy industrium widget zeroes font-size on .button-container; we
 * undo it for the anchor itself AND its inner text span. Selector targets
 * `a.industrium-button` directly (the previous CSS used `.industrium-button a`
 * which does NOT match because the anchor IS .industrium-button). */
body.home a.industrium-button,
body.home .industrium-button,
body.home .button-container > a.industrium-button,
body.home .pagination_wrapper > a.industrium-button {
    font-size: 14px !important;
    line-height: 1.4 !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 10px !important;
    padding: 14px 26px !important;
    border: 1px solid var(--indo-cyan, #00a6db) !important;
    color: var(--indo-cyan, #00a6db) !important;
    background: transparent !important;
    font-family: var(--indo-font-body, "Inter"), sans-serif !important;
    font-weight: 500 !important;
    text-transform: uppercase !important;
    letter-spacing: .06em !important;
    border-radius: var(--indo-radius, 4px) !important;
    transition: all .15s ease !important;
    text-decoration: none !important;
    height: auto !important;
    width: auto !important;
    min-height: 46px !important;
}
body.home a.industrium-button .industrium-button-text,
body.home .industrium-button .industrium-button-text {
    font-size: 14px !important;
    line-height: 1.4 !important;
    color: inherit !important;
    display: inline-block !important;
    visibility: visible !important;
    opacity: 1 !important;
    text-indent: 0 !important;
    overflow: visible !important;
    position: static !important;
    clip: auto !important;
    height: auto !important;
    width: auto !important;
}
/* Arrow SVG (used on "View Case Studies") — keep it cyan, sized */
body.home a.industrium-button svg,
body.home .industrium-button svg {
    width: 12px !important;
    height: auto !important;
    fill: none !important;
    stroke: currentColor !important;
    stroke-width: 1.5 !important;
    margin-left: 4px !important;
    flex-shrink: 0 !important;
    display: inline-block !important;
}
body.home a.industrium-button:hover,
body.home .industrium-button:hover,
body.home a.industrium-button:focus,
body.home .industrium-button:focus {
    background: var(--indo-cyan, #00a6db) !important;
    color: #fff !important;
}

/* On the navy "successfully completed projects" band the View Case Studies
 * button needs white border/text (same inversion as the existing rule). */
body.home .elementor-element-9e0df2f a.industrium-button,
body.home .elementor-element-9e0df2f .industrium-button,
body.home .elementor-element-9e0df2f .pagination_wrapper a.industrium-button {
    border-color: #fff !important;
    color: #fff !important;
}
body.home .elementor-element-9e0df2f a.industrium-button:hover,
body.home .elementor-element-9e0df2f .industrium-button:hover {
    background: #fff !important;
    color: var(--indo-navy, #121c22) !important;
}

/* The pagination_wrapper container itself was a tight inline-block —
 * give it room so the button isn't squashed. */
body.home .pagination_wrapper {
    display: inline-block !important;
    width: auto !important;
    margin-top: 32px !important;
}

/* ====================================================================
   ===== PROJECTS + ARTICLES (sub-agent) =====
   Append-only block from the Projects/Articles audit.

   Goals:
   - Tighten the archive design across:
       /projects/, /projects/?category=*, /projects/<slug>/, /blog/,
       /category/news/, /category/events/, single posts.
   - Lock card titles + section titles to Lexend Deca light (200).
   - Trim the archive hero from 80vh to ~52vh (less dead space below the
     supporting subtitle, while still feeling generous).
   - Make the empty meta rail on single project pages collapse instead of
     leaving a 240px void to the left of the body copy.
   - Polish filter chips, pagination, and date pill so they all share the
     same subtle, lowercase, design-led language.
   - Belt-and-braces hide the (now empty) PeRSo project chip.
   ==================================================================== */

/* -------- Archive heroes: shorter, calmer ----------------------------- */
.indo-projects-hero,
body.archive.category .indo-hero,
body.blog .indo-hero,
.indo-section + .indo-hero { /* defensive */
    min-height: 52vh;
}
.indo-projects-hero { min-height: 56vh; } /* projects gets a touch more drama */
@media (max-width: 767px) {
    .indo-projects-hero,
    body.archive.category .indo-hero { min-height: 44vh; }
}
.indo-hero h1.section-title {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(40px, 5vw, 72px);
    letter-spacing: -0.01em;
    line-height: 1.05;
    margin: 0;
    max-width: 14ch;
    margin-left: auto;
    margin-right: auto;
}
/* Filtered project archives have longer titles like "exterior lighting
   projects" — give them a wider clamp so they don't wrap awkwardly. */
.indo-projects-hero h1.section-title {
    max-width: 22ch;
    font-size: clamp(36px, 4.6vw, 64px);
}
.indo-hero p {
    max-width: 560px;
    margin-left: auto;
    margin-right: auto;
}

/* -------- Card grid: lock font + tighten subtitles -------------------- */
.indo-card-grid {
    margin-top: 48px;
}
.indo-card__title {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    text-transform: none; /* keep titles cased as authored */
    letter-spacing: -0.005em;
    margin: 12px 0 6px;
}
.indo-card__sub {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    line-height: 1.55;
    max-width: 56ch;
}
.indo-card__date {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-weight: 500;
}
.indo-card:hover .indo-card__title {
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 1px;
}

/* -------- Filter chips: tighter, more "design-led" ------------------- */
.indo-filter {
    margin: 0 0 32px;
    gap: 10px;
    justify-content: flex-start;
}
.indo-filter a {
    letter-spacing: 0.01em;
    border-color: rgba(33, 33, 33, 0.18);
    padding: 8px 20px;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-weight: 500;
}

/* Belt-and-braces: hide the now-empty PeRSo chip even if WP's
   hide_empty caching falls behind. Targets the chip's anchor by href
   substring so it survives slug renames inside the same term. */
.indo-filter a[href*="category=perso"] { display: none; }
.indo-filter li:has(a[href*="category=perso"]) { display: none; }

/* -------- Pagination: roomier, calmer --------------------------------- */
.indo-pagination {
    margin-top: 64px;
    gap: 6px;
}
.indo-pagination a, .indo-pagination span {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 14px;
    border-radius: 999px;
    transition: background .15s ease, color .15s ease;
}
.indo-pagination .current {
    background: var(--indo-cyan);
    color: #fff;
    border-radius: 999px;
}
.indo-pagination a:hover {
    background: var(--indo-cyan);
    color: #fff;
}

/* -------- Single project: collapse empty meta rail --------------------
   The earlier .indo-single-project__body rule (line ~616) wrongly turned
   the OUTER section into a 2-col grid. Override here so only the INNER
   .indo-single-project__body-grid is the grid; collapse to a single
   centered column when there's no meta sidebar. */
.indo-single-project__body {
    display: block !important;
    grid-template-columns: none !important;
    padding: 0 clamp(16px, 4vw, 40px) var(--indo-section-pad);
}
.indo-single-project__body-grid {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: clamp(24px, 4vw, 80px);
    align-items: start;
}
.indo-single-project__body--no-meta .indo-single-project__body-grid,
.indo-single-project__body-grid:not(:has(.indo-single-project__meta)) {
    grid-template-columns: minmax(0, 760px);
    justify-content: center;
}
@media (max-width: 991px) {
    .indo-single-project__body-grid { grid-template-columns: 1fr; }
}

.indo-single-project__head { padding: 64px 0 24px; text-align: center; }
.indo-single-project__head .entry-title {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(36px, 5vw, 64px);
    line-height: 1.1;
    text-transform: none;
    letter-spacing: -0.01em;
    margin: 8px 0 0;
}
.indo-single-project__head .indo-card__date {
    margin-bottom: 0;
}
.indo-single-project__intro {
    font-size: clamp(18px, 2vw, 22px);
    color: var(--indo-gray);
    margin-top: 20px;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-weight: 300;
    line-height: 1.5;
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

.indo-single-project__content {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 17px;
    line-height: 1.7;
    color: var(--indo-charcoal);
}
.indo-single-project__content p { margin: 0 0 1.2em; }
.indo-single-project__content a { color: var(--indo-cyan); text-decoration: underline; text-underline-offset: 3px; } /* revert 20260501-1500: was var(--indo-cyan-link); brand cyan is authoritative on body links per Tom directive. */

/* Related projects strip on light bg */
.indo-related { background: var(--indo-light, #f5f5f5); }
.indo-related .section-title {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(28px, 3.6vw, 44px);
    letter-spacing: -0.005em;
    margin: 0 0 32px;
}

/* -------- Single post (article) -------------------------------------- */
.indo-single-post__hero {
    width: 100%;
    aspect-ratio: 16/9;
    max-height: 70vh;
    overflow: hidden;
    background: var(--indo-navy);
    position: relative;
}
.indo-single-post__hero img { width: 100%; height: 100%; object-fit: cover; }
/* fix-retrofit-for-purpose-002 (2026-05-04, 2.3.17): hello-elementor parent theme
 * sets `.post .wp-post-image { max-height: 500px }` which capped the hero image
 * height; container was 630px (70vh@1440) leaving a 130px navy band below the
 * photo. Override max-height on the hero <img> so it fills the navy container.
 * Higher specificity needed because .post .wp-post-image (0,2,0) matches the
 * parent <body class="post"> .wp-post-image; we add body.post to win. */
article.post .indo-single-post__hero img.wp-post-image {
    max-height: none !important;
    height: 100% !important;
}
.indo-single-post__head {
    padding: 64px 0 24px;
    text-align: center;
}
.indo-single-post__head .entry-title {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(32px, 4.4vw, 56px);
    line-height: 1.15;
    letter-spacing: -0.005em;
    margin: 12px 0 0;
    max-width: 22ch;
    margin-left: auto;
    margin-right: auto;
}
.indo-single-post .entry-content {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 18px;
    line-height: 1.75;
    color: var(--indo-charcoal);
    max-width: 720px;
    margin: 0 auto;
}
.indo-single-post .entry-content p { margin: 0 0 1.4em; }
.indo-single-post .entry-content a { color: var(--indo-cyan); text-decoration: underline; text-underline-offset: 3px; } /* revert 20260501-1500: was var(--indo-cyan-link); brand cyan is authoritative on body links per Tom directive. */
.indo-single-post .entry-content img { max-width: 100%; height: auto; border-radius: var(--indo-radius, 4px); }

/* -------- /blog/ landing falls through to category-style cards ------- */
body.blog .indo-card-grid { margin-top: 0; padding-top: 48px; }
body.blog .indo-section { padding-top: 48px; }

/* If the page-for-posts route doesn't render a hero (theme template
   priority), keep the cards generously spaced from the header. */
body.blog .site-content > article:first-child,
body.blog .indo-card-grid:first-child {
    margin-top: 32px;
}

/* -------- Mobile defenses -------------------------------------------- */
@media (max-width: 991px) {
    .indo-card__title { font-size: clamp(20px, 3.4vw, 26px); }
    .indo-filter { gap: 8px; }
    .indo-filter a { padding: 6px 14px; font-size: 13px; }
}
@media (max-width: 767px) {
    .indo-hero h1.section-title { font-size: clamp(36px, 9vw, 56px); }
    .indo-card-grid { grid-template-columns: 1fr; gap: 28px; }
    .indo-card__media { margin-bottom: 12px; }
    .indo-single-project__head,
    .indo-single-post__head { padding: 40px 0 16px; }
}

/* =====================================================================
 * WOOCOMMERCE (sub-agent)
 * Shop / product list / category landings / single product / cart / checkout.
 * ===================================================================== */

/* -------- Archive heroes: shorter, calmer (WC variants) --------------
 * 2026-05-03 — added body.page-id-17258 (/geartrays/) to these
 * selectors so the geartrays hero matches the /luminaires/ archive
 * hero height on mobile. Tom flagged the visible inconsistency: at
 * 375vw, /luminaires/ rendered at 390px (48vh effective via this
 * cascade) while /geartrays/ rendered at 487px (60vh from the
 * baseline rule). Adding /geartrays/ to the WC archive-hero treatment
 * brings both to the same height across all mobile/tablet viewports. */
body.post-type-archive-product .indo-hero,
body.tax-product_cat .indo-hero,
body.woocommerce.archive .indo-hero,
body.page-id-17258 .indo-hero {
    min-height: 48vh;
}
/* 2026-05-03 — !important added on these @media-wrapped overrides
 * because the browser cascade was inexplicably preferring the 48vh
 * base rule over the @media-narrowed overrides for /luminaires/
 * (the 36vh rule was at higher source index but didn't win — likely
 * an interaction with browser's CSS specificity calculation across
 * @media boundaries on this build, or a per-post Elementor CSS hook
 * that's invisible to my static walk). !important guarantees the
 * mobile cap takes effect for both /luminaires/ and /geartrays/. */
@media (max-width: 991px) {
    body.post-type-archive-product .indo-hero,
    body.tax-product_cat .indo-hero,
    body.page-id-17258 .indo-hero { min-height: 40vh !important; }
}
@media (max-width: 767px) {
    body.post-type-archive-product .indo-hero,
    body.tax-product_cat .indo-hero,
    body.page-id-17258 .indo-hero { min-height: 36vh !important; }
}
/* On the bare /product-list/ root there's no term, no hero photo, so
 * give the dark navy band a proper feel — not a giant void. */
body.post-type-archive-product .indo-hero:not(:has(.indo-hero__media)) {
    min-height: 40vh;
}

/* -------- Filter chips on category landings -------------------------- */
/* The /projects/ chips already get cyan-on-active; just make sure the
 * WC version is centered and breathes a bit more. */
body.woocommerce .indo-filter {
    justify-content: center;
    margin: 0 0 56px;
}
body.woocommerce .indo-filter li { padding: 0; }

/* -------- Centre product card titles + softer subs ------------------- */
body.woocommerce .indo-card { text-align: center; }
body.woocommerce .indo-card__sub {
    margin-left: auto;
    margin-right: auto;
}
/* Product imagery is mostly tall PNGs of luminaires on white. Use
 * `contain` so we never crop the product, and add a touch of inner
 * padding so the contained image breathes inside the 16:9 frame. */
body.woocommerce .indo-card__media {
    background: var(--indo-light, #f5f5f5);
}
body.woocommerce .indo-card__media img {
    object-fit: contain !important;
    padding: 8px;
}

/* -------- WC's own product loop (defensive, in case the override
 *           template isn't picked up on a particular request) ---------- */
.woocommerce ul.products,
.woocommerce-page ul.products {
    display: grid !important;
    grid-template-columns: repeat(2, 1fr) !important;
    gap: clamp(24px, 3vw, 48px) !important;
    margin: 0 !important;
    padding: 0 !important;
    list-style: none !important;
}
/* WC's woocommerce-layout.css adds ::before/::after with display:table as a
   float-clearfix. Under our grid those pseudos become grid items and steal
   cells, leaving an empty first slot in the related-products row. Suppress. */
.woocommerce ul.products::before,
.woocommerce ul.products::after,
.woocommerce-page ul.products::before,
.woocommerce-page ul.products::after {
    display: none !important;
}
@media (max-width: 767px) {
    .woocommerce ul.products,
    .woocommerce-page ul.products {
        grid-template-columns: 1fr !important;
    }
}
.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    text-align: center;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    font-size: clamp(20px, 2.4vw, 28px) !important;
    color: var(--indo-charcoal) !important;
    line-height: 1.2 !important;
    padding: 14px 0 4px !important;
    text-transform: none !important;
}
.woocommerce ul.products li.product img {
    aspect-ratio: 1/1;
    object-fit: contain;
    width: 100% !important;
    height: auto !important;
    border-radius: var(--indo-radius);
    background: var(--indo-light);
    padding: 16px;
    box-sizing: border-box;
}
.woocommerce ul.products li.product .price {
    color: var(--indo-cyan);
    font-weight: 500;
}

/* -------- Single product page ---------------------------------------- */
/* Wrap WC's default content-single-product layout in our typography
 * + spacing without rewriting the template surface. */
.woocommerce.single-product div.product,
.woocommerce-page.single-product div.product {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(48px, 6vw, 96px) clamp(16px, 4vw, 40px);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(32px, 4vw, 80px);
    align-items: start;
}
@media (max-width: 767px) {
    .woocommerce.single-product div.product,
    .woocommerce-page.single-product div.product {
        grid-template-columns: 1fr;
        gap: 32px;
    }
}

/* Gallery column — give it a clean light background, lock to a 4:3
 * frame so square / tall product PNGs sit nicely in the column. */
.woocommerce.single-product div.product .woocommerce-product-gallery {
    width: 100% !important;
    margin: 0 !important;
    float: none !important;
    background: var(--indo-light, #f5f5f5);
    border-radius: var(--indo-radius);
    padding: 24px;
}
.woocommerce.single-product div.product .woocommerce-product-gallery__image img,
.woocommerce.single-product div.product .woocommerce-product-gallery__image a img {
    width: 100% !important;
    height: auto !important;
    aspect-ratio: 4/3;
    object-fit: contain;
    background: transparent;
}
.woocommerce.single-product div.product .woocommerce-product-gallery__trigger {
    background: rgba(255,255,255,0.85);
    border-radius: 999px;
    padding: 6px 8px;
    top: 16px !important;
    right: 16px !important;
    line-height: 1;
}

/* Summary column — Lexend Deca title, Inter body, cyan accents. */
.woocommerce.single-product div.product .summary,
.woocommerce.single-product div.product .entry-summary {
    width: 100% !important;
    margin: 0 !important;
    float: none !important;
}
.woocommerce.single-product div.product .product_title {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    font-size: clamp(36px, 5vw, 64px) !important;
    line-height: 1.05 !important;
    letter-spacing: -0.01em;
    color: var(--indo-charcoal);
    margin: 0 0 16px !important;
    text-transform: none;
}
.woocommerce.single-product div.product .price,
.woocommerce.single-product div.product p.price,
.woocommerce.single-product div.product span.price {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: clamp(20px, 2.2vw, 26px);
    color: var(--indo-cyan);
    font-weight: 500;
    margin: 0 0 24px;
}
.woocommerce.single-product div.product .woocommerce-product-details__short-description {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 16px;
    line-height: 1.65;
    color: var(--indo-charcoal);
    margin: 0 0 28px;
}
.woocommerce.single-product div.product .woocommerce-product-details__short-description p {
    margin: 0 0 1em;
}
.woocommerce.single-product div.product .product_meta {
    border-top: 1px solid rgba(33,33,33,0.08);
    padding-top: 20px;
    margin-top: 24px;
    font-size: 13px;
    color: var(--indo-gray);
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
}
.woocommerce.single-product div.product .product_meta a {
    color: var(--indo-cyan); /* revert 20260501-1500: was var(--indo-cyan-link); brand cyan is authoritative on body links per Tom directive. */
    text-decoration: none;
}
.woocommerce.single-product div.product .product_meta a:hover { text-decoration: underline; }
.woocommerce.single-product div.product .product_meta .posted_in,
.woocommerce.single-product div.product .product_meta .tagged_as,
.woocommerce.single-product div.product .product_meta .sku_wrapper {
    display: block;
    margin-bottom: 6px;
}

/* Hide list bullet marks on the short-desc spec list */
.woocommerce.single-product .woocommerce-product-details__short-description ul {
    list-style: none;
    padding: 0;
    margin: 0 0 1em;
}
.woocommerce.single-product .woocommerce-product-details__short-description ul li {
    /* Kept as custom properties so the dash offset below stays tied to the
       line-height. Change the line-height here and the marker follows. */
    --indo-bullet-line-height: 1.5;
    --indo-bullet-thickness: 2px;
    position: relative;
    padding-left: 22px;
    margin-bottom: 6px;
    line-height: var(--indo-bullet-line-height);
}
.woocommerce.single-product .woocommerce-product-details__short-description ul li::before {
    content: "";
    /* The legacy industrium theme ships a global `ul > li::before` rule
       carrying `font: 0.6667em/1em fontello` for its menu chevrons. That
       shorthand also lands on THIS pseudo-element, shrinking its font-size to
       0.6667em (10.67px against a 16px item) — so every em length below was
       silently resolving against the wrong size and the dash sat 5.13px above
       the text. Reset the font so 1em here means the list item's own 16px.  */
    font: inherit;
    position: absolute;
    left: 0;
    /* Centre the dash on the FIRST line box: half a line box, less half the
       dash thickness. Anchored to `top` rather than `top:50%` + translate, so
       the dash stays level with line one when an item wraps to two lines. */
    top: calc(var(--indo-bullet-line-height) * 0.5em - var(--indo-bullet-thickness) / 2);
    width: 10px;
    height: var(--indo-bullet-thickness);
    background: var(--indo-cyan);
}

/* -------- Brand button: add-to-cart / add-to-quote / WC button ------ */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce-page a.button,
.woocommerce-page button.button,
.woocommerce-page input.button,
.woocommerce .single_add_to_cart_button {
    background: var(--indo-cyan) !important;
    color: #fff !important;
    border: 1px solid var(--indo-cyan) !important;
    border-radius: 999px !important;
    padding: 12px 28px !important;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif) !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    letter-spacing: 0.02em;
    text-transform: none !important;
    box-shadow: none !important;
    transition: background .15s ease, transform .15s ease;
    line-height: 1.4 !important;
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce-page a.button:hover,
.woocommerce-page button.button:hover,
.woocommerce .single_add_to_cart_button:hover {
    background: var(--indo-charcoal, #212121) !important;
    border-color: var(--indo-charcoal, #212121) !important;
    color: #fff !important;
}
/* Quantity input next to add-to-cart */
.woocommerce .quantity input.qty {
    width: 64px;
    padding: 10px 8px;
    border: 1px solid rgba(33,33,33,0.18);
    border-radius: 999px;
    text-align: center;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
}

/* Legacy .indo-quote-cta block removed 2026-05-01 — the button now uses
 * .indo-btn .indo-btn--primary as primary classes (see single-product.php
 * after the call-back lightbox feature build). The `.indo-quote-cta` class
 * survives only as a hook in case future targeting is needed. */

/* -------- WC tabs (Description / Additional Information) ------------ */
.woocommerce.single-product div.product .woocommerce-tabs {
    grid-column: 1 / -1;
    margin-top: 32px;
    padding-top: 32px;
    border-top: 1px solid rgba(33,33,33,0.08);
}
.woocommerce div.product .woocommerce-tabs ul.tabs {
    border-bottom: 1px solid rgba(33,33,33,0.10) !important;
    padding: 0 !important;
    margin: 0 0 32px !important;
    display: flex;
    gap: 8px;
}
.woocommerce div.product .woocommerce-tabs ul.tabs::before { display: none !important; }
.woocommerce div.product .woocommerce-tabs ul.tabs li {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after {
    display: none !important;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li a {
    display: inline-block;
    padding: 12px 22px !important;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif) !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    color: var(--indo-gray) !important;
    text-decoration: none !important;
    border-bottom: 2px solid transparent !important;
    transition: color .15s ease, border-color .15s ease;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active a,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover {
    color: var(--indo-cyan) !important;
    border-bottom-color: var(--indo-cyan) !important;
}
.woocommerce div.product .woocommerce-tabs .panel {
    padding: 0 !important;
    margin: 0 !important;
}
.woocommerce div.product .woocommerce-tabs .panel h2 {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(22px, 2.4vw, 32px);
    color: var(--indo-charcoal);
    letter-spacing: -0.005em;
    margin: 0 0 16px;
}
.woocommerce div.product .woocommerce-tabs .panel,
.woocommerce div.product .woocommerce-tabs .panel p,
.woocommerce div.product .woocommerce-tabs .panel li {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 16px;
    line-height: 1.7;
    color: var(--indo-charcoal);
}
.woocommerce div.product .woocommerce-tabs .panel img {
    border-radius: var(--indo-radius);
    margin: 16px 0;
}
.woocommerce div.product .woocommerce-tabs .panel table.shop_attributes {
    border: 0;
    margin: 0;
}
.woocommerce div.product .woocommerce-tabs .panel table.shop_attributes th,
.woocommerce div.product .woocommerce-tabs .panel table.shop_attributes td {
    border: 0;
    border-bottom: 1px solid rgba(33,33,33,0.06);
    padding: 12px 16px;
    background: transparent;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 15px;
}
.woocommerce div.product .woocommerce-tabs .panel table.shop_attributes th {
    color: var(--indo-charcoal);
    font-weight: 600;
    width: 32%;
}

/* -------- Related / upsell products under single product ------------ */
.woocommerce.single-product .related,
.woocommerce.single-product .upsells {
    grid-column: 1 / -1;
    margin-top: clamp(48px, 6vw, 96px);
    padding-top: clamp(32px, 4vw, 56px);
    border-top: 1px solid rgba(33,33,33,0.08);
}
/* Related/upsells products — 4-up grid on desktop, scaling down responsively */
.woocommerce.single-product .related ul.products,
.woocommerce.single-product .upsells ul.products {
    grid-template-columns: repeat(4, 1fr) !important;
}
@media (max-width: 1024px) {
    .woocommerce.single-product .related ul.products,
    .woocommerce.single-product .upsells ul.products {
        grid-template-columns: repeat(3, 1fr) !important;
    }
}
@media (max-width: 767px) {
    .woocommerce.single-product .related ul.products,
    .woocommerce.single-product .upsells ul.products {
        grid-template-columns: repeat(2, 1fr) !important;
    }
}
@media (max-width: 480px) {
    .woocommerce.single-product .related ul.products,
    .woocommerce.single-product .upsells ul.products {
        grid-template-columns: 1fr !important;
    }
}
.woocommerce.single-product .related > h2,
.woocommerce.single-product .upsells > h2 {
    font-family: var(--indo-font-display);
    font-weight: 200;
    font-size: clamp(22px, 2.6vw, 32px);
    color: var(--indo-charcoal);
    letter-spacing: -0.005em;
    margin: 0 0 32px;
}

/* -------- WC pagination — unified with .indo-archive .indo-pagination (v2.3.39) ----------
 *
 * FIX (v2.3.39): WooCommerce core CSS sets
 *   .woocommerce nav.woocommerce-pagination ul li a { display: block; }
 * which has specificity 0,0,3,1 and beats our previous
 *   .woocommerce-pagination .page-numbers { display: inline-flex; }   (0,0,2,0)
 * causing arrow links to render as block-level glyphs instead of centred pills.
 * The corrected selectors below match WC core's specificity on display,
 * then our broader class rule still handles the rest (font, size, colour).
 * ----------------------------------------------------------------------- */
.woocommerce nav.woocommerce-pagination ul,
.woocommerce-page nav.woocommerce-pagination ul {
    border: 0 !important;
    display: inline-flex !important;
    gap: 6px;
    padding: 0;
    margin: 48px 0 0;
    justify-content: center;
    flex-wrap: wrap;
}
.woocommerce nav.woocommerce-pagination ul li,
.woocommerce-page nav.woocommerce-pagination ul li {
    border: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    /* Collapse li to button height despite line-height:50px from WC core */
    display: inline-flex !important;
    align-items: center !important;
}
/* High-specificity overrides (v2.3.39):
 * Beats WC core's ul li a { display: block; color: purple; } and
 * Industrium WC CSS overflow: hidden that clips arrow characters.
 * All selectors use the same pattern (.woocommerce nav.woocommerce-pagination ul li a)
 * to match WC core specificity (0,0,3,1) and win the cascade cleanly. */
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span,
.woocommerce-page nav.woocommerce-pagination ul li a,
.woocommerce-page nav.woocommerce-pagination ul li span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    box-sizing: border-box;
    overflow: visible;
    border: 0;
    border-radius: 4px;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    color: var(--indo-charcoal, #212121);
    background: transparent;
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
}
/* Hover — matches WC core specificity on :hover so purple override is beaten */
.woocommerce nav.woocommerce-pagination ul li a:hover,
.woocommerce nav.woocommerce-pagination ul li a:focus,
.woocommerce-page nav.woocommerce-pagination ul li a:hover,
.woocommerce-page nav.woocommerce-pagination ul li a:focus {
    color: var(--indo-cyan, #00a6db);
    background: transparent;
}
/* Current page */
.woocommerce nav.woocommerce-pagination ul li span.current,
.woocommerce-page nav.woocommerce-pagination ul li span.current {
    background: rgba(0,0,0,0.06);
    color: var(--indo-charcoal, #212121);
}
/* Focus ring — accessible cyan outline */
.woocommerce nav.woocommerce-pagination ul li a:focus-visible,
.woocommerce-page nav.woocommerce-pagination ul li a:focus-visible {
    outline: 2px solid #00a6db;
    outline-offset: 2px;
}
/* Lower-specificity class rule kept for any edge cases outside the nav/ul/li chain */
.woocommerce-pagination .page-numbers {
    border: 0;
    border-radius: 4px;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    color: var(--indo-charcoal);
    background: transparent;
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
    overflow: visible;
}
.woocommerce-pagination .page-numbers:hover {
    color: var(--indo-cyan, #00a6db);
    background: transparent;
}
.woocommerce-pagination .page-numbers.current {
    background: rgba(0,0,0,0.06);
    color: inherit;
}
.woocommerce-pagination .page-numbers:focus-visible {
    outline: 2px solid #00a6db;
    outline-offset: 2px;
}

/* -------- Cart / Checkout: light typography pass -------------------- */
.woocommerce-cart .woocommerce,
.woocommerce-checkout .woocommerce {
    max-width: 1200px;
    margin: 0 auto;
    padding: clamp(48px, 6vw, 96px) clamp(16px, 4vw, 40px);
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
}
.woocommerce-cart h1, .woocommerce-cart h2,
.woocommerce-checkout h1, .woocommerce-checkout h2,
.woocommerce-cart .cart_totals h2,
.woocommerce-checkout #order_review_heading {
    font-family: var(--indo-font-display);
    font-weight: 200;
    letter-spacing: -0.005em;
    color: var(--indo-charcoal);
}
.woocommerce table.shop_table {
    border: 1px solid rgba(33,33,33,0.08) !important;
    border-radius: var(--indo-radius);
}
.woocommerce table.shop_table th,
.woocommerce table.shop_table td {
    border-top: 1px solid rgba(33,33,33,0.06) !important;
    padding: 16px !important;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
}
.woocommerce-checkout form .form-row input.input-text,
.woocommerce-checkout form .form-row textarea,
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea {
    border: 1px solid rgba(33,33,33,0.18);
    border-radius: 8px;
    padding: 10px 14px;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 15px;
}

/* -------- Defensive: hide any Industrium decorations on Woo pages --- */
.woocommerce [class*="industrium"]:not(.indo-card):not(.indo-card-grid),
.woocommerce-page [class*="industrium"]:not(.indo-card):not(.indo-card-grid),
.woocommerce .ind-decor,
.woocommerce-page .ind-decor,
.woocommerce-page .indus-vert-text,
.woocommerce .indus-vert-text {
    display: none !important;
}

/* -------- Mobile defenses -------------------------------------------- */
@media (max-width: 991px) {
    .woocommerce.single-product div.product .product_title {
        font-size: clamp(28px, 6vw, 44px) !important;
    }
}
@media (max-width: 767px) {
    body.woocommerce .indo-filter { justify-content: flex-start; margin: 0 0 32px; }
    .woocommerce.single-product div.product .woocommerce-product-gallery { padding: 12px; }
}

/* ===== INNER PAGES + FOOTER (sub-agent) =================================== */

/* --- Reveal hidden Industrium PDF/CTA buttons (font-size:0 leftover) ------ */
a.industrium-button,
a.industrium-button .industrium-button-text {
    font-size: 14px !important;
    line-height: 1.4 !important;
    letter-spacing: 0.04em !important;
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif !important;
    font-weight: 500 !important;
    text-transform: uppercase !important;
}
a.industrium-button {
    display: inline-flex !important;
    align-items: center !important;
    gap: 10px !important;
    padding: 12px 22px !important;
    color: #00a6db !important;
    border: 1px solid #00a6db !important;
    border-radius: 4px !important;
    text-decoration: none !important;
    background: transparent !important;
    transition: background .15s ease, color .15s ease;
}
a.industrium-button:hover {
    background: #00a6db !important;
    color: #fff !important;
}

/* --- Force Lexend Deca on all Elementor / Industrium headings ----------- */
.elementor-element h1,
.elementor-element h2,
.elementor-element h3,
.elementor-element h4,
.elementor-element h5,
.elementor-element h6,
.elementor-widget-heading .elementor-heading-title,
.elementor-image-box-title,
.elementor-icon-box-title,
.industrium-heading,
.industrium-heading > span,
h1.industrium-heading,
h2.industrium-heading,
h3.industrium-heading,
h4.industrium-heading {
    font-family: 'Lexend Deca', 'Inter', system-ui, sans-serif !important;
}

/* Make Elementor h1 / h2 light & lowercase per brand */
.elementor-element h1,
.elementor-element h2,
.elementor-widget-heading h1.elementor-heading-title,
.elementor-widget-heading h2.elementor-heading-title {
    font-weight: 200 !important;
    letter-spacing: -0.01em !important;
    color: #121c22;
}

/* h3 (image-box titles like "Luminaires" / "Top Light") — light + cleaner */
.elementor-element h3,
.elementor-image-box-title {
    font-weight: 300 !important;
    color: #212121;
}

/* --- Heading-like lines that are actually <p><strong>...</strong></p> in
       text-editor widgets (Spectrums, Direct Drive, Horticultural) -------- */
.elementor-widget-text-editor strong:first-child {
    font-weight: 400;
}

/* --- Conditions of Sale: tone the legal-doc headings down ---------------- */
body.page-id-19111 .elementor-widget-text-editor h1,
body.page-id-19111 .elementor-widget-text-editor h2,
body.page-id-19111 h1,
body.page-id-19111 h2 {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    letter-spacing: -0.01em !important;
    color: #121c22 !important;
}
body.page-id-19111 h1 { font-size: clamp(36px, 5vw, 56px) !important; margin-bottom: 48px !important; }
body.page-id-19111 h2 { font-size: clamp(24px, 3vw, 32px) !important; margin-top: 56px !important; margin-bottom: 16px !important; }
body.page-id-19111 .elementor-widget-text-editor { line-height: 1.7; }

/* --- Contacts (page 92): tame "HERE TO HELP" heading -------------------- */
body.page-id-92 h1,
body.page-id-92 h2,
body.page-id-92 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    letter-spacing: -0.01em !important;
    color: #121c22;
}
body.page-id-92 h1 { font-size: clamp(32px, 4vw, 48px) !important; }

/* "Get in Touch" form panel heading should also be light, not bold */
body.page-id-92 .elementor-widget-heading h2.elementor-heading-title {
    font-weight: 200 !important;
}

/* (2026-05-05) Dead rule removed: targeted `.e-con.e-parent` (Elementor v3
   flex container) but the /contacts/ first section is the legacy
   `.elementor-section` wrapper, so this selector never matched. Section
   padding for /contacts/ is now driven from _elementor_data on post 92
   (section 5250112: padding 56/0/0/0). */

/* --- Become A Distributor (16653): visually de-emphasise the
       still-old "INDO Lighting" / indolighting.com lines so they're
       less jarring until the editor fixes them in admin -------------- */
body.page-id-16653 h1,
body.page-id-16653 h2,
body.page-id-16653 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    color: #fff;
}

/* --- Exterior / Horticultural landing pages: tighten white voids --------- */
body.page-id-17285 .elementor-element.e-con.e-parent,
body.page-id-17989 .elementor-element.e-con.e-parent {
    padding-top: 40px !important;
    padding-bottom: 40px !important;
}

/* The image-box rows ("Luminaires / LED Retrofit / Gear Trays" and
   "Top Light / Vertical Farming") often only fill 2 of 3 columns.
   Centre the row so it doesn't look broken with empty space on right */
body.page-id-17989 .elementor-element-7779e98 .e-con-inner {
    justify-content: flex-start !important;
}

/* --- Direct Drive: heading + heading-paragraph hierarchy ---------------- */
body.page-id-16739 h1,
body.page-id-16739 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    color: #121c22 !important;
}
body.page-id-16739 .elementor-widget-text-editor strong {
    font-weight: 500;
    color: #121c22;
}
/* Pull text-editor images to a bit less overwhelming size */
body.page-id-16739 .elementor-widget-image img {
    max-width: 100%;
    height: auto;
    margin: 0 auto;
    display: block;
}

/* Photometry Downloads (17368) and Certificates & Accreditation (17404)
 * page-specific CSS removed 2026-04-30 — both pages were retired (trashed)
 * so the body class never applies. See mu-plugin indo-redirects.php for
 * the 410 handler. */

/* --- Spectrums (17937): tone down inline 'Standard Spectrum' style
       headings & make sub-section paragraphs breathable ------------------- */
body.page-id-17937 .elementor-widget-text-editor p strong {
    font-weight: 500;
    color: #121c22;
}

/* Spectrums hero — uses the same .indo-hero block as the product-category
 * pages, but with `.indo-hero--bare` to suppress the dark scrim overlay
 * and centred text-overlay block. The image alone is the hero. */
.indo-hero.indo-hero--bare .indo-hero__media::after {
    display: none !important;
    background: none !important;
}
.indo-hero.indo-hero--bare .indo-hero__inner {
    display: none !important;
}
/* Spectrums hero: smaller min-height than the 80vh product-category default,
 * since there's no overlay text the photographic image stands on its own
 * and 80vh becomes excessive. 50vh feels right at desktop, 40vh on mobile. */
body.page-id-17937 .indo-hero.indo-hero--bare {
    min-height: 50vh;
}
@media (max-width: 767px) {
    body.page-id-17937 .indo-hero.indo-hero--bare {
        min-height: 40vh;
    }
}
/* Full-bleed breakout: when .indo-hero is rendered inside an Elementor HTML
 * widget on a Hello Elementor "default" template, every ancestor in the
 * Elementor section/column/widget chain is constrained to the theme content
 * column (~980px). Lift the entire chain to 100vw so the hero edges meet
 * the viewport, mirroring the rendering of the product-category hero. */
body.page-id-17937 .elementor-section:has(.indo-hero--bare),
body.page-id-17937 .elementor-section:has(.indo-hero--bare) .elementor-container,
body.page-id-17937 .elementor-section:has(.indo-hero--bare) .elementor-column,
body.page-id-17937 .elementor-section:has(.indo-hero--bare) .elementor-widget-wrap,
body.page-id-17937 .elementor-section:has(.indo-hero--bare) .elementor-widget-html {
    width: 100% !important;
    max-width: 100% !important;
    padding-inline: 0 !important;
}
body.page-id-17937 .elementor-section:has(.indo-hero--bare) {
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: calc(50% - 50vw) !important;
}

/* --- Troubleshooting (16733): h1 + section h2 styling ------------------ */
body.page-id-16733 h1,
body.page-id-16733 h2,
body.page-id-16733 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    color: #121c22 !important;
}

/* --- Customer Feedback (16808): "Your opinion matters" heading --------- */
body.page-id-16808 h1,
body.page-id-16808 h2,
body.page-id-16808 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    color: #121c22 !important;
}

/* --- Installation Manuals (16730): clean table heading style ----------- */
body.page-id-16730 table th {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 300 !important;
    text-transform: uppercase !important;
    letter-spacing: .06em !important;
    background: #f6f7f8 !important;
}

/* --- Geartrays (17258): the "Our range currently includes:" heading --- */
body.page-id-17258 h2,
body.page-id-17258 h3,
body.page-id-17258 .elementor-heading-title {
    font-family: 'Lexend Deca', sans-serif !important;
    font-weight: 200 !important;
    text-transform: none !important;
    color: #121c22 !important;
}

/* --- GET A QUOTE floater: make sure it doesn't overlap form fields ---- */
@media (max-width: 600px) {
    .indo-floater {
        right: 12px !important;
        bottom: 12px !important;
        width: 78px !important;
        height: 78px !important;
        font-size: 11px !important;
    }
}

/* Defensive global: hide any leftover Industrium decorative chevrons / squares
   that might still appear on inner pages */
.industrium-decoration,
.industrium-decoration-square,
.industrium-vert-text,
.indus-vert-text {
    display: none !important;
}

/* ===== MOBILE + FINAL AUDIT (sub-agent) ===== */

/* ---- Defensive: prevent horizontal scroll site-wide ---- */
html, body {
    overflow-x: hidden;
    max-width: 100%;
}

/* ---- Mobile fixes (<= 767px) ---------------------------- */
@media (max-width: 767px) {

    /* Footer link/email tap targets — were 19px tall, now ~44px.
       Inline <style> in footer.php loads later in cascade so we need
       higher specificity than its single-class selectors. */
    footer.site-footer ul li a,
    footer.site-footer address a,
    body footer.site-footer .site-footer__col a {
        display: inline-block;
        padding: 10px 0;
        line-height: 1.4;
        min-height: 44px;
        box-sizing: border-box;
    }

    /* Footer list items: a touch more vertical separation so the larger
       tap targets don't visually crowd each other */
    footer.site-footer li {
        margin: 0 0 4px;
    }

    /* Exterior / Horticultural landing tile cards: at narrow widths the
       3-up grid squeezes "Luminaires" into "Luminaire/s". Force 1-col on
       very narrow screens so titles render on a single line. */
    body.page-id-17285 .elementor-element.e-con > .e-con-inner > .elementor-element.e-con,
    body.page-id-17989 .elementor-element.e-con > .e-con-inner > .elementor-element.e-con {
        flex-basis: 100% !important;
        max-width: 100% !important;
    }

    /* Image-box widget tiles inside those landing pages: ensure single column */
    body.page-id-17285 .elementor-widget-image-box,
    body.page-id-17989 .elementor-widget-image-box {
        width: 100% !important;
        max-width: 100% !important;
    }
    body.page-id-17285 .elementor-image-box-wrapper,
    body.page-id-17989 .elementor-image-box-wrapper {
        max-width: 100%;
    }

    /* Article / single-project main: bottom-pad so the GET A QUOTE
       floater doesn't sit on top of the last paragraph. Pad #site-content
       (not body) so we don't create empty white space below the footer.
       60px is enough to clear the 78px floater without making the page
       feel empty before the footer. */
    body.single #site-content,
    body.single-post #site-content,
    body.single-industrium_project #site-content,
    body.single-product #site-content {
        padding-bottom: 60px;
    }

    /* Make sure cards inside any project/blog grid never cause overflow */
    .indo-card,
    .indo-card__media,
    .indo-projects-grid,
    .indo-blog-grid {
        max-width: 100%;
    }

    /* Compress page hero on mobile so the band stays under 60vh.
     * 2026-05-03 — REMOVED `min-height: 0` from this rule. It was
     * conflicting with the baseline `.indo-hero { min-height: 60vh }`
     * at line 490 (same specificity, this rule defined later → wins
     * cascade), causing pages whose hero content falls below 60vh
     * (like /geartrays/, where the H1+lede compose a shorter inner
     * block than /luminaires/) to collapse to content height while
     * /luminaires/-style pages held at 60vh — Tom flagged the visible
     * inconsistency. Now both branches use the baseline 60vh min;
     * max-height: 60vh keeps content-heavy heroes from overflowing. */
    .indo-hero,
    .archive-hero,
    .single-post__hero,
    .single-project__hero {
        max-height: 60vh;
    }

    /* Footer copy reasonable line-height */
    .site-footer address {
        line-height: 1.7;
    }
}

/* ---- Even narrower viewports (<= 480px) ---------------- */
@media (max-width: 480px) {

    /* Project/article cards — give the title and excerpt more breathing room */
    .indo-card__body {
        padding: 14px 16px 18px;
    }

    /* GET A QUOTE floater: previously shrunk to 78px @ <=600px;
       on very small screens, nudge it further off the right edge so it
       doesn't overlap CTA buttons in the body */
    .indo-floater {
        right: 8px !important;
        bottom: 10px !important;
    }
}

/* ---- Defensive: any image inside the main content area never overflows */
#site-content img,
.entry-content img,
.elementor-widget-text-editor img {
    max-width: 100%;
    height: auto;
}

/* ---- Final audit: empty-anchor visual safeguard --------
   No empty buttons were found in the audit. As a defensive
   measure, any <a> with no text and no children inside main
   content gets visually hidden so it can never look like a
   broken click target. (Skip-link, nav toggle, and intentional
   whole-card cover-links excluded — the .indo-archive-card__link
   is an aria-labelled overlay anchor that MUST stay clickable.) */
#site-content a:empty:not(.skip-link):not([class*=toggle]):not([class*=icon]):not(.indo-archive-card__link):not([aria-label]) {
    display: none;
}

/* ---- "INDO Lighting" body copy is editorial and lives in
   project meta / post content. CSS cannot fix this; flagged
   in the report for the user to update via WP admin.        */


/* ====================================================================
   ===== ARCHIVE REDESIGN (sub-agent) =====

   Captured 2026-04-28 by inspecting reference layouts. Token sheet
   archived locally.

   This block REPLACES the visual treatment of the previous
   "PROJECTS + ARTICLES (sub-agent)" block where they conflict — it
   does not delete those rules, it overrides them with higher
   specificity scoped to the new .indo-archive-* DOM that
   archive-industrium_project.php / home.php / category.php now emit.

   Two themes:
   - .indo-archive--dark  → /projects/, /projects/?category=*
   - .indo-archive--light → /articles/, /category/news/, etc.
   ==================================================================== */

:root {
}

/* ============ INTRO BAND (replaces the big dark hero) ============ */
.indo-archive-intro {
    padding: clamp(48px, 8vw, 112px) 0 clamp(24px, 4vw, 56px);
}
.indo-archive-intro--dark {
    background: var(--indo-navy, #121c22);
    color: #fff;
}
.indo-archive-intro--light {
    background: #fff;
    color: var(--indo-charcoal, #212121);
}
.indo-archive-intro__row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
}
h1.indo-archive-intro__title,
.indo-archive-intro h1.indo-archive-intro__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(36px, 5.5vw, 60px);
    line-height: 1.1;
    letter-spacing: normal;
    color: inherit;
    margin: 0 auto;
    text-align: center;
    max-width: 18ch;
}
.indo-archive-intro--light h1.indo-archive-intro__title,
.indo-archive-intro--light .indo-archive-intro__title {
    text-align: left;
    margin: 0;
    max-width: none;
}
h1.indo-archive-intro__title--small,
.indo-archive-intro__title--small {
    font-weight: 500;
    font-size: clamp(24px, 2.4vw, 30px);
    line-height: 1.2;
}
.indo-archive-intro__lede {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: clamp(15px, 1.2vw, 17px);
    line-height: 1.6;
    color: inherit;
    opacity: 0.85;
    margin: 24px auto 0;
    max-width: 56ch;
    text-align: center;
}

/* ============ FILTER BAR ============ */
.indo-archive {
    padding: 0 0 clamp(80px, 10vw, 120px);
}
.indo-archive--dark {
    background: var(--indo-navy, #121c22);
    color: #fff;
}
.indo-archive--light {
    background: #fff;
    color: var(--indo-charcoal, #212121);
}

/* The filter sits inside the intro band on /projects/ for visual
   right-aligned above the grid. On articles
   it sits inline with the H1 (intro__row). */
.indo-archive .indo-archive-filterbar {
    display: flex;
    justify-content: flex-end;
    margin: 0 0 clamp(24px, 3vw, 40px);
    position: relative;
}
.indo-archive-filterbar--inline {
    margin: 0;
}

.indo-archive-filterbtn {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    background: transparent;
    border: 0;
    cursor: pointer;
    color: inherit;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 18px;
    font-weight: 400;
    padding: 0;
    line-height: 1;
    text-transform: none;
    letter-spacing: normal;
}
.indo-archive-filterbtn:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db);
    outline-offset: 4px;
    border-radius: 2px;
}
/* Override Hello Elementor's reset.css `[type="button"]:hover {
 * background: #cc3366 }` magenta default that bled onto the Projects
 * + Articles Filter toggle. Keep the button looking the same on hover
 * (transparent bg, brand-coloured text for the affordance cue). */
.indo-archive-filterbtn:hover,
.indo-archive-filterbtn:focus {
    background: transparent;
    color: var(--indo-cyan, #00a6db);
}
.indo-archive-filterbtn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 999px;
    background: var(--indo-cyan, #00a6db);
    color: #fff;
    font-size: 16px;
    line-height: 1;
    font-weight: 500;
    transition: transform .25s ease;
}
.indo-archive-filterbtn__icon--dark {
    background: var(--indo-charcoal, #212121);
    color: #fff;
}
.indo-archive-filterbtn[aria-expanded="true"] .indo-archive-filterbtn__icon {
    transform: rotate(45deg);
}

/* The category panel slides into view when the trigger is clicked */
.indo-archive-filterpanel {
    position: absolute;
    right: 0;
    top: calc(100% + 12px);
    background: #fff;
    color: var(--indo-charcoal, #212121);
    padding: 28px 32px;
    border-radius: 9px;
    min-width: 280px;
    max-width: min(560px, 92vw);
    box-shadow: 0 18px 42px rgba(0, 0, 0, 0.18);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 8px 24px;
    z-index: 60;
    max-height: 60vh;
    overflow-y: auto;
}
.indo-archive-filterpanel[hidden] {
    display: none;
}
.indo-archive-filterpanel a {
    display: block;
    color: var(--indo-charcoal, #212121);
    text-decoration: none;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    font-weight: 400;
    padding: 6px 0;
    transition: color .2s ease;
}
.indo-archive-filterpanel a:hover,
.indo-archive-filterpanel a:focus,
.indo-archive-filterpanel a.is-active {
    color: var(--indo-cyan, #00a6db);
}

/* ============ CARD GRID ============ */
.indo-archive-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 16px;
}
/* Projects = dense 6-col grid, hero spans 6, regulars span 3 */
.indo-archive-grid--projects {
    grid-template-columns: repeat(6, 1fr);
}
.indo-archive-grid--projects > .indo-archive-card { grid-column: span 3; }
.indo-archive-grid--projects > .indo-archive-card--hero { grid-column: 1 / -1; }
@media (max-width: 991px) {
    .indo-archive-grid--projects { grid-template-columns: repeat(2, 1fr); }
    .indo-archive-grid--projects > .indo-archive-card { grid-column: span 1; }
    .indo-archive-grid--projects > .indo-archive-card--hero { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
    .indo-archive-grid--projects { grid-template-columns: 1fr; }
    .indo-archive-grid--projects > .indo-archive-card,
    .indo-archive-grid--projects > .indo-archive-card--hero { grid-column: 1 / -1; }
}

/* Articles = 3-col grid, hero spans 3 */
.indo-archive-grid--articles {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
}
.indo-archive-grid--articles > .indo-archive-card--hero { grid-column: 1 / -1; }
@media (max-width: 991px) {
    .indo-archive-grid--articles { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .indo-archive-grid--articles { grid-template-columns: 1fr; }
}

/* ============ CARDS ============ */
.indo-archive-card {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}
.indo-archive-card__inner {
    position: relative;
    display: grid;          /* projects: image + content overlap */
    height: 100%;
    background: var(--indo-navy, #121c22);
    overflow: hidden;
    isolation: isolate;
}
/* PROJECTS variant: image and content share the same grid cell.
   Image-underneath pattern. */
.indo-archive-card--project .indo-archive-card__inner > * {
    grid-area: 1 / 1;
}
.indo-archive-card--project .indo-archive-card__inner {
    aspect-ratio: 1 / 1;
}
.indo-archive-card--project.indo-archive-card--hero .indo-archive-card__inner {
    aspect-ratio: 16 / 7; /* hero is wider, shorter */
}
@media (max-width: 600px) {
    .indo-archive-card--project.indo-archive-card--hero .indo-archive-card__inner { aspect-ratio: 4 / 3; }
}

.indo-archive-card__media {
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 100%;
    z-index: 0;
}
.indo-archive-card--project .indo-archive-card__media {
    background: var(--indo-navy, #121c22);
}
.indo-archive-card--project .indo-archive-card__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.55) 100%);
    z-index: 1;
    pointer-events: none;
    transition: opacity .35s ease;
}
.indo-archive-card__img,
.indo-archive-card__media img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    display: block;
    transition: transform 1.6s ease-in-out;
}

/* PROJECTS variant: content overlays image, anchored bottom-left */
.indo-archive-card--project .indo-archive-card__content {
    position: relative;
    z-index: 2;
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: flex-start;
    padding: 32px;
    height: 100%;
    max-width: 500px;
}

/* ARTICLES variant: stacked image-on-top, content below */
.indo-archive-card--article .indo-archive-card__inner--stacked {
    display: flex;
    flex-direction: column;
    background: transparent;
    aspect-ratio: auto;
    overflow: visible;
}
.indo-archive-card--article .indo-archive-card__media--top {
    aspect-ratio: 16 / 10;
    background: #f1f4f6;
    overflow: hidden;
}
.indo-archive-card--article.indo-archive-card--hero .indo-archive-card__media--top {
    /* Reference hero is 1:1; we use 16:9 to keep the page from feeling
       dominated by a single huge image at 1440px+ widths. */
    aspect-ratio: 16 / 9;
    max-height: 540px;
}
.indo-archive-card--article .indo-archive-card__content--below {
    padding: 18px 0 0;
}

/* Eyebrow / category */
.indo-archive-card__eyebrow {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    margin: 0 0 4px;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.3;
}
.indo-archive-card__eyebrow--dark {
    color: var(--indo-charcoal, #212121);
    font-size: 16px;
}

/* Title — high specificity to win against .elementor-kit-* h3 / theme h1-4 rules */
.indo-archive-grid .indo-archive-card .indo-archive-card__title,
h2.indo-archive-card__title,
h3.indo-archive-card__title,
h4.indo-archive-card__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 500;
    font-size: 22px;
    line-height: 1.2;
    color: #fff;
    margin: 0 0 6px;
    text-transform: none;
    letter-spacing: normal;
    transition: color .2s ease;
    text-wrap: balance;
}
.indo-archive-grid .indo-archive-card--article .indo-archive-card__title--dark,
h2.indo-archive-card__title--dark,
h3.indo-archive-card__title--dark,
h4.indo-archive-card__title--dark {
    color: var(--indo-charcoal, #212121);
    font-weight: 500; /* Lexend Deca only has 200,300,400,500 loaded — clamp to 500 */
    font-size: 22px;
    line-height: 1.2;
    margin: 0 0 12px;
}
.indo-archive-grid .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__title--dark {
    font-size: clamp(24px, 2.6vw, 32px);
}

/* Subheading (project) — cyan accent */
.indo-archive-card__sub {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 16px;
    font-weight: 600;
    color: var(--indo-cyan, #00a6db);
    margin: 0;
    line-height: 1.4;
    /* 2026-05-02: removed `text-transform: lowercase` — Tom-written Opus
       teasers are sentence case with proper-noun capitalisation (RD12,
       Surrey Quays, London Borough of Southwark, INDO etc.). Forcing
       lowercase mangled product names + place names. */
}

/* Date (article) — green accent */
.indo-archive-card__date {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 16px;
    font-weight: 600;
    color: var(--indo-cyan, #00a6db);
    margin: 0;
    letter-spacing: normal;
    text-transform: none;
}

/* Cover-link makes the whole card clickable */
.indo-archive-card__link {
    position: absolute;
    inset: 0;
    z-index: 5;
    text-indent: -9999px;
    overflow: hidden;
    text-decoration: none;
}
.indo-archive-card__link:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db);
    outline-offset: 4px;
    border-radius: 2px;
}

/* Hover: image scales (project + article); article title turns green */
.indo-archive-card:hover .indo-archive-card__img,
.indo-archive-card:focus-within .indo-archive-card__img {
    transform: scale(1.06);
}
.indo-archive-card--article:hover .indo-archive-card__title--dark,
.indo-archive-card--article:focus-within .indo-archive-card__title--dark {
    color: var(--indo-cyan, #00a6db);
}
.indo-archive-card--project:hover .indo-archive-card__media::after {
    opacity: 0.55;
}

/* ============ PAGINATION ============ */
.indo-archive .indo-pagination {
    margin-top: clamp(48px, 6vw, 72px);
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.indo-archive .indo-pagination a,
.indo-archive .indo-pagination span {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    min-width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
    border: 0;
    background: transparent;
    color: inherit;
    text-decoration: none;
    border-radius: 4px;
    transition: background .15s ease, color .15s ease;
}
.indo-archive--dark .indo-pagination a,
.indo-archive--dark .indo-pagination span {
    color: #fff;
}
.indo-archive--light .indo-pagination a,
.indo-archive--light .indo-pagination span {
    color: var(--indo-charcoal, #212121);
}
.indo-archive .indo-pagination .current {
    background: rgba(255,255,255,0.10);
    color: inherit;
}
.indo-archive--light .indo-pagination .current {
    background: rgba(0,0,0,0.06);
}
.indo-archive .indo-pagination a:hover {
    color: var(--indo-cyan, #00a6db);
    background: transparent;
}
.indo-archive .indo-pagination a:focus-visible {
    outline: 2px solid #00a6db;
    outline-offset: 2px;
}

/* ============ Defensive overrides for legacy classes ============
   The previous sub-agent added rules at .indo-card / .indo-card-grid /
   .indo-projects-hero. We're not deleting those, but the new templates
   no longer emit those classes for /projects/ + /articles/, so the old
   rules harmlessly become dead-code for these archives. To be safe
   though, anywhere the legacy hero class might still surface (e.g. a
   filtered URL fallback), we explicitly remove the dark band so we
   don't double-apply both heroes. */
body.post-type-archive-industrium_project .indo-hero,
body.tax-industrium_project_category .indo-hero,
body.blog .indo-hero,
body.archive.category .indo-hero {
    display: none !important;
}

/* ============ Filter behaviour (no-JS fallback)  ============
   The toggle button below uses a tiny inline-JS handler appended via
   a footer hook (registered in indo-cpt.php — see "filter-toggle"
   block). To survive a JS-disabled visit, the panel is also revealed
   by :focus-within on the parent so keyboard tabbing still exposes
   the categories. */
.indo-archive-filterbar:focus-within .indo-archive-filterpanel {
    display: grid;
}

/* ===== END ARCHIVE REDESIGN ===== */


/* ============================================================
   ===== ARCHIVE VISUAL POLISH (sub-agent) =====
   ------------------------------------------------------------
   Added 2026-04-29 after side-by-side comparison of staging
   /projects/ + /articles/ vs the reference layouts at
   /articles/ via Chrome MCP at 1440-1900 viewport width.
   Append-only — does NOT modify earlier rules.

   Mismatches fixed:
   1. /articles/ H1 stuck at 60px / weight 200; reference is
      30px / weight 600. Cause: earlier "--small" rule lost the
      specificity battle with `.indo-archive-intro h1.indo-archive-intro__title`.
      Fix: bump --small selector specificity above the base.
   2. /articles/ hero card overflowed the 1280px container by
      ~640px when the <li> width refused to honour grid-column:
      1 / -1 on a `display: list-item` element. Fix: explicitly
      width:auto + min-width:0 + max-width:100% on the li, plus
      width: 100% on the inner.
   3. /articles/ hero pattern needed the split layout
      (text-left grey panel + image-right) instead of
      image-on-top stacked. Fix: re-flow .indo-archive-card--hero
      .indo-archive-card__inner--stacked into a 2-col grid above
      tablet width.
   4. /projects/ hero overlay & regular-card overlay needed a
      stronger dark gradient — some product/logo images are
      bright white and blow out the eyebrow + title. Fix: bump
      gradient end stop alpha + add a base dark veil.
   5. Article hero date sat above title (article hero sub-agent
      template) — re-order so date sits BELOW title even in
      hero context.
   ============================================================ */

/* (1) /articles/ H1 sizing — high-specificity override.
   Selectors below match BOTH plain h1 + the wrapper to outweigh
   the earlier `.indo-archive-intro h1.indo-archive-intro__title` rule. */
.indo-archive-intro--light h1.indo-archive-intro__title.indo-archive-intro__title--small,
.indo-archive-intro--light .indo-archive-intro__title.indo-archive-intro__title--small,
.indo-archive-intro h1.indo-archive-intro__title.indo-archive-intro__title--small {
    font-weight: 600;
    font-size: clamp(22px, 2.2vw, 30px);
    line-height: 1.2;
    letter-spacing: normal;
    text-transform: none; /* keep "our latest news & insights" sentence-case */
    max-width: none;
    text-align: left;
    margin: 0;
}

/* (2) /articles/ hero card width: stop it from blowing past the
   grid track. The <li> was rendering full container instead of
   honouring `grid-column: 1 / -1` because list-item display
   doesn't always size against grid tracks reliably. Force it. */
.indo-archive-grid--articles > .indo-archive-card,
.indo-archive-grid--articles > .indo-archive-card--hero {
    width: auto;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
}
.indo-archive-grid--articles > .indo-archive-card .indo-archive-card__inner,
.indo-archive-grid--articles > .indo-archive-card--hero .indo-archive-card__inner {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
}

/* (3) /articles/ hero — split layout (text panel
   left, image right) above 768px. Stack at narrower widths. */
@media (min-width: 768px) {
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__inner--stacked {
        display: grid;
        grid-template-columns: 1fr 1fr;
        background: #F2F4F4; /* light grey panel */
        aspect-ratio: auto;
        min-height: 460px;
        overflow: hidden;
        gap: 0;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__media--top {
        order: 2;
        aspect-ratio: auto;
        height: 100%;
        max-height: none;
        background: #f1f4f6;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__media--top img {
        height: 100% !important;
        width: 100% !important;
        object-fit: cover;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__content--below {
        order: 1;
        padding: clamp(32px, 4vw, 64px);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: flex-start;
        background: transparent;
    }
    /* Hero title can be larger in the split layout */
    .indo-archive-grid .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__title--dark {
        font-size: clamp(26px, 3vw, 36px);
        line-height: 1.15;
        margin: 12px 0;
        max-width: 18ch;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__eyebrow--dark {
        margin-bottom: 0;
    }
}

/* (4a) /projects/ hero overlay — strengthen gradient so any
   bright image (e.g. lit-up greenhouse, logo on white) still
   gives the bottom-left text good contrast.
   Revision 2026-05-01: bottom alpha bumped to 0.92/0.88 and the
   ramp pulled higher up the card so the eyebrow (top of the
   overlaid stack) sits in 0.55+ alpha territory rather than
   the 0.15 mid-zone of the previous gradient. WCAG AA Large
   compliant for the 22px white title and 15px white eyebrow.
   The top 35% of the card stays clean so the photograph still
   reads as the dominant element. */
.indo-archive-card--project .indo-archive-card__media::after {
    background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0) 35%,
        rgba(0, 0, 0, 0.55) 60%,
        rgba(0, 0, 0, 0.92) 100%
    );
}
.indo-archive-card--project.indo-archive-card--hero .indo-archive-card__media::after {
    background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0) 35%,
        rgba(0, 0, 0, 0.50) 65%,
        rgba(0, 0, 0, 0.88) 100%
    );
}

/* (4b) /projects/ — text on image-overlay cards. WHY no shadow:
   the .indo-archive-card__media::after gradient already provides
   ample contrast and 14px-blur shadows previously produced a
   fuzzy halo that read as a stroke/glow against solid darker
   images. Leaving text crisp.
   Revision 2026-05-01: eyebrow bumped to 15px / 700 weight so the
   tag reads at AA Large against the gradient's mid-zone (~0.55
   alpha at the eyebrow's vertical position). Title nudged from
   500 → 600 weight for the same reason — at 22px white that's the
   minimum to clear AA Large on busy photographs. */
.indo-archive-card--project .indo-archive-card__eyebrow,
.indo-archive-card--project .indo-archive-card__title,
.indo-archive-card--project .indo-archive-card__sub {
    text-shadow: none;
}
.indo-archive-card--project .indo-archive-card__eyebrow {
    font-size: 15px;
    font-weight: 700;
}
.indo-archive-grid .indo-archive-card--project .indo-archive-card__title,
.indo-archive-card--project h2.indo-archive-card__title,
.indo-archive-card--project h3.indo-archive-card__title,
.indo-archive-card--project h4.indo-archive-card__title {
    font-weight: 600;
}

/* (4c) /projects/ subheading — clamp to one line so cards stay
   visually quiet (reference cards are always short — "transitioning
   to upgrade", "historic wall-mounted lanterns", etc). */
.indo-archive-card--project .indo-archive-card__sub {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    line-clamp: 4;
    overflow: hidden;
    text-overflow: ellipsis;
    /* 2026-05-02: bumped clamp from 1 to 4 lines. The previous 1-line clamp
       was sized for the lowercase auto-truncated 8-word excerpt; with full
       sentence-case Opus teasers (1-2 sentences, ~25-40 words) we need
       room for the whole copy to read. */
}

/* (5) Article card date — sit BELOW the title (already correct
   in DOM order, but defensive: enforce stacking direction so a
   future eyebrow swap doesn't reverse it). */
.indo-archive-card--article .indo-archive-card__content--below {
    display: flex;
    flex-direction: column;
}
.indo-archive-card--article .indo-archive-card__eyebrow--dark { order: 1; margin-bottom: 4px; }
.indo-archive-card--article .indo-archive-card__title--dark   { order: 2; }
.indo-archive-card--article .indo-archive-card__date--green   { order: 3; margin-top: 8px; }

/* (6) Defensive: hide empty `<p>` content placeholders if a post
   has no excerpt / no category, so we don't render bare green
   spaces under article titles. */
.indo-archive-card__sub:empty,
.indo-archive-card__date:empty,
.indo-archive-card__eyebrow:empty {
    display: none !important;
}

/* (7) Articles regular-card image proportion — reference is
   very close to 16:10 / 4:3 family. Our existing rule says
   16/10 but the WP `<img>` ships with intrinsic width/height
   attributes that fight aspect-ratio. Lock the wrap with the
   classic padding-bottom hack so every card image is identical
   size regardless of source ratio. */
.indo-archive-card--article:not(.indo-archive-card--hero) .indo-archive-card__media--top {
    aspect-ratio: auto; /* drop the unreliable property */
    height: 0;
    padding-bottom: 62.5%; /* 16:10 = 10/16 = 62.5% */
    position: relative;
    max-height: none;
}
.indo-archive-card--article:not(.indo-archive-card--hero) .indo-archive-card__media--top img {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
}

/* (8) Pagination already minimal. Just nudge font weight down
   to a lighter feel on the dark theme. */
.indo-archive--dark .indo-pagination a,
.indo-archive--dark .indo-pagination span,
.indo-archive--light .indo-pagination a,
.indo-archive--light .indo-pagination span {
    font-weight: 400;
}

/* (9) Mobile: collapse hero split back to image-on-top,
   text-below. Reference design does the same below 768px. */
@media (max-width: 767px) {
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__inner--stacked {
        display: flex;
        flex-direction: column;
        background: transparent;
        min-height: 0;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__media--top {
        order: 0;
        aspect-ratio: 16 / 10;
        max-height: 360px;
    }
    .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__content--below {
        order: 1;
        padding: 16px 0 0;
        background: transparent;
    }
    .indo-archive-grid .indo-archive-card--article.indo-archive-card--hero .indo-archive-card__title--dark {
        font-size: 22px;
    }
}

/* (10) /projects/ — make sure that the GET A QUOTE floating
   widget doesn't end up overlapping a card title visibly. We
   can't move it (it's a global Elementor widget), so just
   shift the hero content padding-right a touch on desktop. */
@media (min-width: 992px) {
    .indo-archive-card--project.indo-archive-card--hero .indo-archive-card__content {
        padding-right: clamp(32px, 6vw, 96px);
    }
}

/* ===== END ARCHIVE VISUAL POLISH (sub-agent) ===== */

/* ===== TIER1-FIX-DISTRIBUTOR-CONTRAST 2026-04-29 =====
   Issue: Become A Distributor (page-id-16653) form sits on a dark navy
   panel (#121c22). The wpforms placeholder text was rendering at
   rgba(0,0,0,0.7) * opacity 0.5 = effectively black-on-near-black,
   contrast ratio ~1.05:1. Submit button was off-brand #066AAB.
   Fix: light placeholders (#abafb5 INDO gray) with full opacity, ensure
   input text stays white, recolour submit to INDO cyan #00a6db. */
body.page-id-16653 .wpforms-form input::placeholder,
body.page-id-16653 .wpforms-form textarea::placeholder,
body.page-id-16653 .wpforms-form select::placeholder {
    color: #abafb5 !important;
    opacity: 1 !important;
}
body.page-id-16653 .wpforms-form input::-webkit-input-placeholder,
body.page-id-16653 .wpforms-form textarea::-webkit-input-placeholder {
    color: #abafb5 !important;
    opacity: 1 !important;
}
body.page-id-16653 .wpforms-form input::-moz-placeholder,
body.page-id-16653 .wpforms-form textarea::-moz-placeholder {
    color: #abafb5 !important;
    opacity: 1 !important;
}
/* Ensure typed input text is also legible (white on navy) */
body.page-id-16653 .wpforms-form input,
body.page-id-16653 .wpforms-form textarea,
body.page-id-16653 .wpforms-form select {
    color: #fff !important;
}
/* If any visible labels remain (e.g. accessibility-shown), make them light gray */
body.page-id-16653 .wpforms-form .wpforms-field-label,
body.page-id-16653 .wpforms-form .wpforms-field-sublabel {
    color: #f4f4f4 !important;
}
/* Submit button — recolour off-brand #066AAB to INDO cyan */
body.page-id-16653 .wpforms-form button[type="submit"],
body.page-id-16653 .wpforms-form .wpforms-submit {
    background-color: #00a6db !important;
    border-color: #00a6db !important;
    color: #fff !important;
}
body.page-id-16653 .wpforms-form button[type="submit"]:hover,
body.page-id-16653 .wpforms-form .wpforms-submit:hover {
    background-color: #00acea !important;
    border-color: #00acea !important;
}
/* ===== END TIER1-FIX-DISTRIBUTOR-CONTRAST ===== */


/* =====================================================================
 * TIER1-FIX-PRODUCT-HOVER 2026-04-29 17:30
 * ---------------------------------------------------------------------
 * Gordon flagged a glitchy hover state on product cards (/product-list/
 * + /product-category/*). Diagnosis via Chrome MCP:
 *   1. `.indo-card__media` had `transition: all` (cascaded from a
 *      generic earlier rule) — every property on the media frame
 *      animated, including non-animatable ones, causing visible snap.
 *   2. `.indo-card__title` had `transition: all` too — text-decoration-
 *      line is not animatable, so the underline appeared instantly
 *      while the colour faded, producing a two-step glitch.
 *   3. Four simultaneous hover effects (card translate, image scale,
 *      title colour-change, title underline) compounded the busy feel.
 *   4. `object-fit: contain` on product images + transform:scale(1.04)
 *      on a `position: absolute; inset: 0; padding: 8px` image inside
 *      an overflow:hidden parent caused the scaled image to get
 *      clipped at the frame — visible jump on hover-leave.
 *
 * Fix:
 *   - Pin transitions to specific properties on media + title so
 *     `all` cascades from generic rules don't leak in.
 *   - Drop the title underline-on-hover (kept the cyan colour change
 *     — that's enough affordance, and is the homepage-card pattern).
 *   - Add `will-change: transform` to the image for smoother GPU
 *     compositing.
 *   - Scope to body.woocommerce so other archive cards (projects,
 *     articles) keep their existing behaviour; the project/article
 *     hover was not flagged.
 * ===================================================================== */

/* Pin the media frame's transition so an inherited `transition: all`
   can't smuggle in animation on properties that snap (e.g. background,
   aspect-ratio recalculations). The frame itself doesn't need to
   animate anything; the image inside does. */
body.woocommerce .indo-card .indo-card__media {
    transition: none;
}

/* Image: single, smooth scale transition. Override possible `all`
   inheritance with an explicit transform-only declaration. */
body.woocommerce .indo-card .indo-card__media img {
    transition: transform 0.4s cubic-bezier(.4, 0, .2, 1);
    will-change: transform;
}
body.woocommerce .indo-card:hover .indo-card__media img,
body.woocommerce .indo-card:focus-visible .indo-card__media img {
    transform: scale(1.04);
}

/* Title: animate ONLY colour, not `all`. Drop the underline-on-hover
   added by an earlier rule (line 1907) — colour change to cyan is
   enough affordance and matches homepage cards. */
body.woocommerce .indo-card .indo-card__title {
    transition: color 0.25s cubic-bezier(.4, 0, .2, 1);
}
body.woocommerce .indo-card:hover .indo-card__title,
body.woocommerce .indo-card:focus-visible .indo-card__title {
    text-decoration: none;
}

/* Card lift: scope the existing translateY(-4px) explicitly so it
   doesn't fight a parent `transition: all`. */
body.woocommerce .indo-card {
    transition: transform 0.25s cubic-bezier(.4, 0, .2, 1);
}

/* Defensive: WC's own `li.product` markup (template fallback) gets
   the same calm treatment in case archive-product.php delegates to
   the default loop on a particular request. */
body.woocommerce ul.products li.product img {
    transition: transform 0.4s cubic-bezier(.4, 0, .2, 1);
    will-change: transform;
}
body.woocommerce ul.products li.product:hover img {
    transform: scale(1.04);
}
/* ===== END TIER1-FIX-PRODUCT-HOVER ===== */


/* ===== AUDIT / 20260429-1842 ===== */
/* Visually-hidden utility for screen-reader-only headings injected by
   indo-home-audit-fixes.php on the home page hero. Uses the canonical
   sr-only pattern (preserves shape so it remains in the a11y tree). */
.indo-sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Lowercase the "Get in Touch" headline inside the elementor contact-form
   widget to match the rest of the indo-2026 lowercase headline rhythm
   ("delivering value since 2007", "successfully completed projects for
   our clients", etc.). Scoped to the front-page so it cannot affect
   other pages where title-case may be intentional. */
body.home .industrium-wpforms-widget .wpforms-widget-heading,
body.home .industrium-wpforms-widget .industrium-heading,
body.home .industrium-wpforms-widget h2,
body.home .industrium-wpforms-widget h3 {
}
/* ===== END AUDIT / 20260429-1842 ===== */


/* ===== AUDIT /about/ 20260429-1842 ===== */
/* Hide legacy industrium decoration widgets (chevrons, dot grids, vertical
   text) on the About page only — the indo-2026 brief calls for these
   decorations to be removed. They are absolute-positioned and only
   contribute visual noise. Scoped via .page-id pattern with body class. */
body.page .industrium-decoration,
body.page .decoration-widget {
    display: none !important;
}

/* (REVERTED 2026-04-29) These rules were added under the false premise
   that no team CPT entries existed. There ARE 5 published team entries
   (16290, 16292, 16296, 19153, 19155). The widget rendering empty is a
   bug, not a content gap, and must remain visible until fixed. Do NOT
   re-add :empty / :has hide rules here — they would mask the bug. */

/* The hero on /about/ leaves the right column empty on desktop because
   the original layout expected an image we never placed. Centre the left
   column copy so the headline sits in the optical centre rather than
   floating in the left half with a void to its right. Mobile remains
   unchanged (already single-column). */
@media (min-width: 1025px) {
    body.page-id-17 .elementor-section.elementor-top-section:first-of-type
        .elementor-container,
    body.page-template-default.page:not(.home)
        section.elementor-top-section:first-of-type
        > .elementor-container {
        max-width: 980px;
    }
}

/* Force the hero H1 (promoted from H3 by the MU plugin) to inherit the
   indo-2026 lowercase / Lexend Deca treatment. The original H3 styles
   already do this via .industrium-heading, but we re-apply for the new
   H1 selector so the upgrade is invisible visually. */
body.page .industrium-heading-widget h1.industrium-heading {
    font-family: "Lexend Deca", "Inter", sans-serif;
    font-weight: 200;
    letter-spacing: -0.01em;
    color: #212121;
    line-height: 1.15;
}

/* (REMOVED 2026-05-05) The clamp(60px, 8vw, 120px) rule that lived here
   was a 2026-04-29 audit fix that imposed inner-page section padding via
   a high-specificity selector (body.page-template-default.page:not(.home)
   section.elementor-top-section, specificity 0,4,2). It was actively
   blocking Elementor's per-section padding overrides (specificity 0,3,0)
   from taking effect, defeating the new editable-rhythm system. Now that
   the SITE-WIDE SECTION RHYTHM block (lower in this file) provides the
   88/72/56px default at low specificity (0,2,0) without !important,
   Elementor's per-section settings can win as designed. */
/* ===== END AUDIT /about/ 20260429-1842 ===== */

/* ===== TEAM-GRID-RESTORE /about/ 20260429-2105 ===== */
/* WHY: The active theme is `indo-2026` (Hello Elementor child) which never
   shipped the Industrium team-grid CSS. The Industrium plugin's
   `industrium_team_members` widget calls
   `get_template_part('content', 'industrium_team', ...)` and emits markup
   for `.team-listing-wrapper`, `.team-item-wrapper`, `.team-item` etc, but
   without these CSS rules every card collapses to width:0 / height:0 — DOM
   has all 5 team posts but none are visible. This block ports just the
   structural rules from `wp-content/themes/industrium/css/theme.css`
   (lines ~14196–14444) and re-skins them in the indo-2026 idiom: lowercase
   Lexend Deca for names, INDO cyan accent on hover, no greyscale flip. */

.industrium-team-members-widget {
    display: block;
    width: 100%;
}
.industrium-team-members-widget .archive-listing {
    display: block;
    width: 100%;
}

/* Note: the wrapper carries BOTH `archive-listing-wrapper` and
   `team-listing-wrapper` classes. We deliberately use the latter as the
   layout hook so the flex rule wins by specificity inside this widget. */
.industrium-team-members-widget .team-listing-wrapper {
    margin: 0 -20px -50px;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: flex-start;
    width: auto;
}
.team-listing-wrapper .team-item-wrapper {
    padding: 0 20px;
    margin: 0 0 50px;
    box-sizing: border-box;
    width: 100%;
}
@media only screen and (min-width: 576px) {
    .team-listing-wrapper.columns-2 .team-item-wrapper,
    .team-listing-wrapper.columns-3 .team-item-wrapper,
    .team-listing-wrapper.columns-4 .team-item-wrapper,
    .team-listing-wrapper.columns-5 .team-item-wrapper,
    .team-listing-wrapper.columns-6 .team-item-wrapper {
        width: 50%;
    }
}
@media only screen and (min-width: 992px) {
    .team-listing-wrapper.columns-3 .team-item-wrapper { width: 33.3333%; }
    .team-listing-wrapper.columns-4 .team-item-wrapper { width: 25%; }
    .team-listing-wrapper.columns-5 .team-item-wrapper { width: 20%; }
    .team-listing-wrapper.columns-6 .team-item-wrapper { width: 16.6667%; }
}

.team-item {
    overflow: hidden;
    position: relative;
}
.team-item .team-item-link {
    display: block;
    text-decoration: none;
    color: inherit;
}
.team-item .team-item-media {
    display: block;
    position: relative;
    aspect-ratio: 1 / 1; /* WHY: square crop is uniform across the 5 photos
       which have varied native aspects (542x489, etc.) — earlier 4/5 left
       a grey gap below shorter images. Square + object-fit:cover gives a
       consistent grid. */
    /* WHY height:auto !important: legacy industrium theme.css line 14239
       hard-codes height: 381px which combines with our aspect-ratio 1/1 to
       force a 381×381 box that overflows the responsive column (190px at
       columns-5). Forcing height:auto lets aspect-ratio derive height from
       the column width so the photo fits the cell. Reported 2026-05-01:
       Meet the Team images appearing horizontally clipped on /about/. */
    height: auto !important;
    width: 100%;
    background: #f4f4f4;
    overflow: hidden;
}
.team-item .team-item-media img {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    object-position: top center !important;
    transition: transform 0.4s ease !important;
}
.team-item:hover .team-item-media img {
    transform: scale(1.03); /* INDO hover: subtle zoom, no greyscale flip */
}
.team-item .team-item-content {
    display: block;
    padding: 20px 0 0;
}
.team-item .post-title {
    font-family: "Lexend Deca", "Inter", sans-serif;
    font-weight: 300;
    font-size: 20px;
    line-height: 1.4;
    color: #212121;
    display: block;
    transition: color 0.3s;
}
.team-item .team-item-link:hover .post-title {
    color: #00a6db;
}
.team-item .post-title:not(:first-child) {
    margin-top: 4px;
}
.team-item .team-item-position {
    font-family: "Inter", sans-serif;
    font-weight: 400;
    font-size: 13px;
    line-height: 1.5;
    color: #abafb5;
    display: block;
    /* 2026-05-05: removed `text-transform: lowercase` — Tom flagged that
       the legacy lowercase pattern (acrospire-mimicry experiment) doesn't
       match INDO brand voice. Position field stores proper title case in
       the DB ("Materials Manager", "Chairman" etc) — let it render as-is. */
    letter-spacing: 0.02em;
}
/* Suppress the legacy '.' prefix on positions — not on-brief. */
.team-item .team-item-position:before {
    content: none;
}
/* Hide social-button overlay by default — we only show socials if the
   underlying post explicitly defines them, and indo-2026 doesn't use
   them on /about/. */
.team-item .team-item-socials {
    display: none;
}

/* Lowercase the "Meet the Team" heading to match the indo-2026 brief
   (lowercase headlines: "what people say...", "british designed...",
   "component quality"). Scoped to the heading sibling that immediately
   precedes the team widget so we don't lowercase any unrelated H2. */
.elementor-widget-heading + .elementor-widget .industrium-team-members-widget,
.industrium-team-members-widget {
    /* placeholder — actual rule below */
}
.elementor-element:has(> .elementor-widget-container > .industrium-team-members-widget),
.elementor-element:has(+ * .industrium-team-members-widget) {
    /* placeholder */
}
/* Direct route: any H2/H1 inside a heading widget on a page that ALSO
   contains a team widget gets lowercased. Page-id-395 scope keeps it
   surgical. */
body.page-id-395 .industrium-heading-widget h1,
body.page-id-395 .industrium-heading-widget h2,
body.page-id-395 .industrium-heading-widget h3,
body.page-id-395 .industrium-heading h1,
body.page-id-395 .industrium-heading h2 {
    letter-spacing: 0;
}
/* ===== END TEAM-GRID-RESTORE /about/ 20260429-2105 ===== */

/* ===== AUDIT /projects/ 20260430 — switch to white-on-charcoal ===== */
/* WHY: /projects/ was using indo-archive-{intro,archive}--dark which gave it
   a navy bg + white text — visually out of place vs the rest of the site
   (Exterior Lighting, About, Articles all sit on white). Switched both
   sections to --light. The cards themselves stay image-overlay with white
   text — they sit on top of project photos so contrast still works. */

/* Keep the /projects/ hero headline centered on white (the default
   --light rule in the existing block left-aligns the H1, which works for
   /articles/ but reads as off for the projects landing page). */
.indo-archive-intro--light.indo-archive-intro--projects h1.indo-archive-intro__title,
.indo-archive-intro--light.indo-archive-intro--projects .indo-archive-intro__title {
    text-align: center;
    margin: 0 auto;
    max-width: 18ch;
}
.indo-archive-intro--light.indo-archive-intro--projects .indo-archive-intro__lede {
    text-align: center;
    margin: 24px auto 0;
    max-width: 56ch;
    color: var(--indo-charcoal, #212121);
    opacity: 0.7;
}

/* Filter-by trigger on white bg: charcoal label, cyan circle stays as-is.
   Default rules already use color:inherit so this falls out from the
   --light section's color:#212121. The icon needs explicit cyan (already
   set at .indo-archive-filterbtn__icon level, not overridden). */

/* Filter panel was already white-on-light — no change needed there. */

/* Subtle separator under the filter bar so the white intro and white
   archive sections don't visually merge. */
.indo-archive--light {
    border-top: 1px solid #ececec;
    padding-top: clamp(32px, 4vw, 48px);
}
/* ===== END AUDIT /projects/ 20260430 ===== */

/* ===== TIER2-FIX-PRODUCT-TABS 2026-04-29 ===== */
/* Canonical 4-tab product layout: description, additional information,
   data sheet (conditional), photometry (conditional). The base tab list /
   panel typography lives at lines ~2378-2462 ("WC tabs" block); this block
   only adds the conditional-tab content styling (download buttons,
   photometry list). All colours are INDO palette. */

/* WCAG AA contrast bump for inactive tab labels (was --indo-gray #abafb5
   = 2.51:1 vs white, now #7a7d82 = 4.41:1). Active state stays cyan
   (cyan-on-white is a sitewide brand pattern, accepted out-of-scope). */
.woocommerce div.product .woocommerce-tabs ul.tabs li a {
    color: #7a7d82 !important;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active a,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:focus-visible {
    color: var(--indo-cyan, #00a6db) !important;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li a:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Panel intro line (above the download CTA on Data Sheet / Photometry) */
.woocommerce div.product .woocommerce-tabs .panel .indo-product-tab__intro {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 16px;
    line-height: 1.7;
    color: var(--indo-charcoal, #212121);
    max-width: 56ch;
    margin: 0 0 24px;
}

/* Download button used in Data Sheet & Photometry tabs */
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download {
    display: inline-flex;
    align-items: baseline;
    gap: 12px;
    padding: 14px 24px;
    background: #00a6db; /* --indo-cyan */
    color: #fff !important;
    text-decoration: none !important;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-weight: 500;
    font-size: 15px;
    letter-spacing: 0.01em;
    border-radius: 0;
    transition: background .15s ease, transform .15s ease;
}
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download:hover,
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download:focus-visible {
    background: #00acea; /* --indo-cyan-light */
    color: #fff !important;
    transform: translateY(-1px);
}
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download:focus-visible {
    outline: 2px solid #00a6db;
    outline-offset: 3px;
}
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download__label {
    font-weight: 500;
}
.woocommerce div.product .woocommerce-tabs .panel .indo-tab-download__meta {
    font-size: 12px;
    color: rgba(255,255,255,0.85);
    font-weight: 400;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.woocommerce div.product .woocommerce-tabs .panel .indo-product-tab__actions {
    margin: 0;
}

/* Photometry tab list */
.woocommerce div.product .woocommerce-tabs .panel ul.indo-photometry-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.woocommerce div.product .woocommerce-tabs .panel ul.indo-photometry-list .indo-photometry-list__item {
    margin: 0;
    padding: 0;
    list-style: none;
}
.woocommerce div.product .woocommerce-tabs .panel ul.indo-photometry-list .indo-photometry-list__item::marker {
    content: '';
}

/* Mobile: stack tab labels with a tighter gap */
@media (max-width: 640px) {
    .woocommerce div.product .woocommerce-tabs ul.tabs {
        flex-wrap: wrap;
        gap: 4px !important;
    }
    .woocommerce div.product .woocommerce-tabs ul.tabs li a {
        padding: 10px 14px !important;
        font-size: 13px !important;
    }
    .woocommerce div.product .woocommerce-tabs .panel .indo-tab-download {
        width: 100%;
        justify-content: space-between;
    }
}
/* ===== END TIER2-FIX-PRODUCT-TABS 2026-04-29 ===== */

/* ===== TIER3-FIX-SINGLE-PROJECT-HERO 2026-04-29 21:26 =====
   Item 8 — single project pages should match the homepage hero-with-menu-overlay
   pattern, but with INVERTED styling (white text overlaid on full-bleed photo).
   Pre-fix: hero rendered as 16:9 strip ABOVE the title; title sat on white below.
   Post-fix: hero fills viewport, title/eyebrow/intro overlaid as a centred white
   stack at the bottom; transparent header sits over the image; gradient overlay
   keeps menu and overlaid text legible.
   ============================================================ */
body.single-industrium_project .indo-single-project__hero {
    aspect-ratio: auto;
    min-height: 80vh;
    margin-bottom: 0;
}
@media (max-width: 767px) {
    body.single-industrium_project .indo-single-project__hero {
        min-height: 60vh;
    }
}
body.single-industrium_project .indo-single-project__hero::after {
    /* Stronger gradient than the default to keep overlaid head text legible
       even on busy/bright photographs (WCAG 1.4.3 contrast).
       Revision 2026-05-01: bottom alpha 0.70 → 0.90 and 55% stop bumped
       0.40 → 0.55 so the head text (eyebrow date, weight-200 H1, intro)
       sits on a noticeably darker scrim. The 30% dip at 0.20 keeps the
       transparent header / mega menu legibile against bright sky areas
       at the top of hero photos. */
    background: linear-gradient(180deg,
        rgba(0,0,0,0.55) 0%,
        rgba(0,0,0,0.20) 30%,
        rgba(0,0,0,0.55) 55%,
        rgba(0,0,0,0.90) 100%);
}

/* Customer brand logo overlay (e.g. vGreens) — top-right of hero,
   sized responsively to ~14vw at desktop, with a subtle drop shadow
   so it pops against any underlying photograph. The logo asset itself
   needs to read clearly against a dark gradient — most customer logos
   are white-on-transparent SVGs, which work cleanly here. */
body.single-industrium_project .indo-single-project__brand-logo {
    position: absolute;
    top: clamp(80px, 9vh, 120px);
    right: clamp(24px, 3vw, 56px);
    width: clamp(120px, 14vw, 220px);
    height: auto;
    z-index: 3;
    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.45));
    pointer-events: none; /* not interactive — purely decorative attribution */
}
@media (max-width: 767px) {
    body.single-industrium_project .indo-single-project__brand-logo {
        top: 88px;
        right: 16px;
        width: 100px;
    }
}
/* The head is rendered INSIDE the hero (template change in
   single-industrium_project.php), positioned at the bottom. */
body.single-industrium_project .indo-single-project__hero > .indo-single-project__head {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 0 0 clamp(48px, 8vh, 96px);
    text-align: center;
    z-index: 2;
    pointer-events: none;
}
body.single-industrium_project .indo-single-project__hero > .indo-single-project__head .indo-container {
    pointer-events: auto;
}
/* Fallback path: if hero has no image (no_image fallback), the head renders
   as a normal block underneath; revert to default head styling for that case. */
body.single-industrium_project article.indo-single-project > .indo-single-project__head {
    /* default head — no overlay; revert white text */
    text-align: center;
    padding: 64px 0 24px;
}
body.single-industrium_project article.indo-single-project > .indo-single-project__head .entry-title {
    color: var(--indo-charcoal);
    text-shadow: none;
}
body.single-industrium_project article.indo-single-project > .indo-single-project__head .indo-card__date,
body.single-industrium_project article.indo-single-project > .indo-single-project__head .indo-card__date a,
body.single-industrium_project article.indo-single-project > .indo-single-project__head .indo-single-project__intro {
    color: var(--indo-charcoal);
    text-shadow: none;
}
/* INVERTED styling — white text on dark photo background.
   WHY no text-shadow: 2026-04-30 — the 16px / 8px blur shadows were
   producing a fuzzy halo against the dark hero, making the headings
   look smudged rather than clean. Removed across H1, eyebrow date,
   and intro. Legibility on busy hero photos is provided by the
   dark gradient overlay on .indo-single-project__hero::after, NOT
   by per-text shadow. If a future hero photo washes out the text,
   strengthen the overlay alpha rather than re-introducing blur. */
body.single-industrium_project .indo-single-project__head .entry-title,
body.single-industrium_project .indo-single-project__head h1 {
    color: #fff;
    font-weight: 200;
    text-shadow: none;
}
body.single-industrium_project .indo-single-project__head .indo-card__date,
body.single-industrium_project .indo-single-project__head .indo-card__date a {
    color: rgba(255,255,255,0.92);
    text-shadow: none;
}
body.single-industrium_project .indo-single-project__head .indo-card__date a:hover {
    color: var(--indo-cyan);
}
body.single-industrium_project .indo-single-project__intro {
    color: rgba(255,255,255,0.92);
    text-shadow: none;
    max-width: 720px;
    margin: 12px auto 0;
}
/* The body content directly follows the hero — needs top padding now */
body.single-industrium_project .indo-single-project__body {
    padding-top: clamp(48px, 6vw, 96px);
}
/* On the project hero, the head sits ON top of the picture so we need the
   head NOT to consume layout space — the article becomes the positioning
   context and head is absolute, so content (.indo-single-project__body)
   tucks up against the hero. */
body.single-industrium_project .indo-single-project__hero,
body.single-industrium_project .indo-single-project__head {
    /* both pieces share the article's positioning context */
}
/* Ensure header text and toggle stay readable over project hero.
 * WHY scoped to direct child `<a>` only (2026-04-30 fix): the previous
 * selector `.site-header__nav a` was matching submenu (dropdown) links
 * too, which inherited white colour and rendered invisible against the
 * white dropdown panel. Submenu items must keep the charcoal colour
 * defined at line 217. Targeting only the top-level menu link
 * (`> ul > li > a`) leaves the dropdown rule undisturbed. */
body.single-industrium_project.has-fullbleed-hero .site-header,
body.single-industrium_project.has-fullbleed-hero .site-header > .site-header__nav > ul > li > a {
    color: #fff;
}
/* ===== END TIER3-FIX-SINGLE-PROJECT-HERO ===== */

/* ===== TIER3-FIX-ACRONYM-CASING 2026-04-29 21:26 =====
   Item 10 — UK / LED / INDO etc. were rendering lowercase under
   text-transform: lowercase headings. .indo-keep-case opt-out lets
   the runtime shim (functions.php indo_acronym_casing_shim) wrap and
   restore proper casing.
   ============================================================ */
.indo-keep-case { text-transform: none !important; }
/* ===== END TIER3-FIX-ACRONYM-CASING ===== */

/* ===== TIER3-FIX-HEADER-OVER-HERO 2026-04-29 21:26 =====
   (revised 2026-04-30: removed nav text-shadow entirely — was leaking
   onto submenu (dropdown) items which are charcoal-on-white, producing
   a fuzzy halo. The scrim alone provides ample contrast for the
   top-level nav over hero photos. Submenu items now render crisp on
   the white dropdown panel.)
   Item 11 — menu legibility over busy hero photos via a subtle scrim
   (top→transparent gradient on the header strip). Preserves the
   transparent-header-over-hero design.
   ============================================================ */
body.has-fullbleed-hero .site-header:not(.header--on-light) {
    background: linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0) 100%);
}
/* WHY no text-shadow: see comment above. Crisp nav reads better than
   shadowed nav, and removing the shadow is the only way to keep
   submenu (dropdown) items clean without a more selector-fragile
   exclusion rule. */
/* ===== END TIER3-FIX-HEADER-OVER-HERO ===== */

/* ===== TIER3-FIX-DROPDOWN-POLISH 2026-04-29 21:26 =====
   Item 12 — drop-down menus felt clunky. Add gap, soft shadow, and
   a fade+lift reveal animation. Hover/focus-within unlocks pointer
   events.

   2026-04-30 update: the shadow was rgba(0,0,0,0.18) with a 12px
   y-offset, which rendered as a visibly stark "shelf" below the
   white panel — easy to read as a second layer. Switched to a
   softer two-layer stack so the panel reads as floating without
   the distinct band underneath.
   ============================================================ */
.site-header__nav .sub-menu {
    margin-top: 12px;
    box-shadow:
        0 2px 4px rgba(0, 0, 0, 0.04),
        0 12px 32px rgba(0, 0, 0, 0.10);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.18s ease, transform 0.18s ease;
    pointer-events: none;
}
.site-header__nav .menu-item-has-children:hover > .sub-menu,
.site-header__nav .menu-item-has-children:focus-within > .sub-menu {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.site-header__nav .sub-menu li a {
    padding: 14px 20px; /* WCAG 2.5.5 — gets sub-menu items to ~45px touch target */
}
/* ===== END TIER3-FIX-DROPDOWN-POLISH ===== */

/* ===== TIER3-FIX-FOOTER-FULLWIDTH 2026-04-29 21:26 =====
   Item 12b — footer was constrained to ~1140px (Hello Elementor
   parent rule). Force the outer .site-footer to span the viewport
   while keeping content columns capped via .site-footer__inner.
   ============================================================ */
.site-footer {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
}
.site-footer__inner {
    max-width: 1280px;
    margin: 0 auto;
}
/* ===== END TIER3-FIX-FOOTER-FULLWIDTH ===== */

/* ===== TIER3-FIX-HOME-MAP-GAPS 2026-04-29 21:26 =====
   Item 12c — Google Maps embed on home had 10px white padding above
   and below (parent Elementor section #7752216 padding) that broke
   the dark contact band. Strip the padding and inherit the band's
   navy bg so the map sits flush.
   ============================================================ */
body.home .elementor-element-7752216 {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    background-color: var(--indo-navy);
}
body.home .elementor-element-1531b36,
body.home .elementor-element-1531b36 .elementor-widget-container,
body.home .elementor-element-1531b36 .elementor-custom-embed {
    background-color: var(--indo-navy);
}

/* ===== FIX-CONTACTS-FORM 2026-04-30 =====
   /contacts/ "Get in Touch" form (wpforms ID 16168) sits on a navy panel
   but inherits global wpforms styles that:
     - hide the field labels (.wpforms-label-hide → position:absolute clip)
     - render placeholders at rgba(0,0,0,0.7) × 0.5 opacity (effectively
       invisible on navy)
     - use a near-black bottom border that disappears against the panel
   Result: customers see "empty navy boxes" with no clear field labels.

   Fix: scope to body.page-id-92, restore visible labels above inputs,
   set placeholders to readable contrast, give inputs a clear
   bottom border, and add a cyan focus state.
   ============================================================ */
body.page-id-92 .wpforms-form .wpforms-field-label.wpforms-label-hide,
body.page-id-92 .wpforms-form label.wpforms-field-label {
    position: static !important;
    width: auto !important;
    height: auto !important;
    margin: 0 0 8px !important;
    padding: 0 !important;
    overflow: visible !important;
    clip: auto !important;
    clip-path: none !important;
    color: rgba(255,255,255,.92);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.02em;
    display: block !important;
}
body.page-id-92 .wpforms-form .wpforms-field-required-indicator,
body.page-id-92 .wpforms-form .wpforms-required-label {
    color: var(--indo-cyan, #00a6db);
    margin-left: 4px;
}
body.page-id-92 .wpforms-form input[type="text"],
body.page-id-92 .wpforms-form input[type="email"],
body.page-id-92 .wpforms-form input[type="tel"],
body.page-id-92 .wpforms-form input[type="number"],
body.page-id-92 .wpforms-form textarea {
    background: rgba(255,255,255,.04) !important;
    color: #fff !important;
    border: 0 !important;
    border-bottom: 1px solid rgba(255,255,255,.35) !important;
    padding: 10px 12px !important;
    border-radius: 0 !important;
    transition: border-color 0.18s ease, background 0.18s ease;
}
/* Visible labels render above each field, so hide the duplicated
   placeholder text (Full name*, Company*, etc.) which was reading as
   a doubled-up field name when the user clicked into the input. */
body.page-id-92 .wpforms-form input::placeholder,
body.page-id-92 .wpforms-form textarea::placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-92 .wpforms-form input::-webkit-input-placeholder,
body.page-id-92 .wpforms-form textarea::-webkit-input-placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-92 .wpforms-form input::-moz-placeholder,
body.page-id-92 .wpforms-form textarea::-moz-placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-92 .wpforms-form input:focus,
body.page-id-92 .wpforms-form textarea:focus,
body.page-id-92 .wpforms-form select:focus {
    outline: none !important;
    border-bottom-color: var(--indo-cyan, #00a6db) !important;
    background: rgba(0,166,219,.06) !important;
}

/* "What prompted you" Choices.js select — light-on-dark in both states.
   Closed: the .choices__placeholder pseudo-item was rendering at
   rgba(0,0,0,.7) × 0.5 opacity (effectively invisible on navy).
   Open: the dropdown panel was reverting to a white background with
   dark text, breaking the dark-themed form aesthetic. */
body.page-id-92 .wpforms-form .choices__inner,
body.page-id-92 .wpforms-form .choices[data-type*="select-one"] .choices__inner {
    background: rgba(255,255,255,.04);
    border: 0;
    border-bottom: 1px solid rgba(255,255,255,.35);
    border-radius: 0;
    color: #fff;
}
body.page-id-92 .wpforms-form .choices__list--single .choices__item {
    color: rgba(255,255,255,.92);
}
body.page-id-92 .wpforms-form .choices__list--single .choices__placeholder,
body.page-id-92 .wpforms-form .choices__placeholder {
    color: rgba(255,255,255,.55) !important;
    opacity: 1 !important;
}
body.page-id-92 .wpforms-form .choices.is-open .choices__inner {
    border-bottom-color: var(--indo-cyan, #00a6db) !important;
    background: rgba(0,166,219,.06) !important;
}
/* WPForms ships --wpforms-field-menu-color via wpforms-full.min.css with
   higher specificity + !important, so override at the variable level
   (cleanest) AND keep an !important fallback selector at full specificity. */
body.page-id-92 .wpforms-container,
body.page-id-92 .wpforms-container-full {
    --wpforms-field-menu-color: #1a2730;
    --wpforms-field-text-color: rgba(255,255,255,.92);
    --wpforms-field-border-color: rgba(255,255,255,.18);
}
body.page-id-92 div.wpforms-container-full .wpforms-form .wpforms-field.wpforms-field-select-style-modern .choices .choices__list--dropdown,
body.page-id-92 .wpforms-form .choices__list--dropdown {
    background: #1a2730 !important;
    border: 1px solid rgba(255,255,255,.18) !important;
    color: rgba(255,255,255,.92) !important;
}
body.page-id-92 .wpforms-form .choices__list--dropdown .choices__list {
    background: transparent !important;
}
body.page-id-92 .wpforms-form .choices__list--dropdown .choices__item--selectable {
    color: rgba(255,255,255,.92) !important;
    background: transparent !important;
}
body.page-id-92 .wpforms-form .choices__list--dropdown .choices__item--selectable.is-highlighted {
    background: var(--indo-cyan, #00a6db) !important;
    color: #fff !important;
}
body.page-id-92 .wpforms-form .choices__list--dropdown .choices__input {
    background: rgba(255,255,255,.06) !important;
    color: #fff !important;
    border: 1px solid rgba(255,255,255,.25) !important;
}
body.page-id-92 .wpforms-form .choices__list--dropdown .choices__placeholder {
    color: rgba(255,255,255,.45) !important;
}

/* Submit button — INDO cyan, full-width-ish on mobile */
body.page-id-92 .wpforms-form button[type="submit"],
body.page-id-92 .wpforms-form .wpforms-submit {
    background: var(--indo-cyan, #00a6db) !important;
    color: #fff !important;
    border: 1px solid var(--indo-cyan, #00a6db) !important;
    border-radius: 0 !important;
    padding: 12px 28px !important;
    font-weight: 500;
    letter-spacing: 0.02em;
    transition: background 0.18s ease, border-color 0.18s ease;
    min-height: 44px;
}
body.page-id-92 .wpforms-form button[type="submit"]:hover,
body.page-id-92 .wpforms-form button[type="submit"]:focus,
body.page-id-92 .wpforms-form .wpforms-submit:hover,
body.page-id-92 .wpforms-form .wpforms-submit:focus {
    background: #00acea !important;
    border-color: #00acea !important;
    outline: none !important;
}
/* ===== END FIX-CONTACTS-FORM ===== */

/* ===== END TIER3-FIX-HOME-MAP-GAPS ===== */

/* ===== POST-LAUNCH-MEGA-MENU 2026-04-30 =====
   Combined fix for backlog items 1 + 2:
     1. New "Products" parent in primary nav with a wide-panel
        (Concept 2) mega-menu listing the existing
        Exterior + Horticultural categories side-by-side.
     2. Hover-gap bug — sub-menu used to have margin-top:12px which
        created a 12px dead-zone where the cursor would leave the
        parent before entering the dropdown, collapsing it.

   The Products parent's menu db_id is 19646 (added 2026-04-30 via
   wp-cli). All wide-panel rules are scoped to .menu-item-19646 so
   that other parents (e.g. About → Testimonials) keep the existing
   narrow-column dropdown style. If the Products db_id ever changes,
   update the selectors below.

   the reference design is a composition reference only — colours stay on the
   INDO palette: --indo-cyan #00a6db, --indo-charcoal #212121.
   ============================================================ */

/* ----- 3a. Hover-gap fix (applies to ALL sub-menus) -----
   Replace the 12px margin-top dead-zone with padding-top so the
   gap is part of the hoverable area. Add a small close delay via
   visibility transition so brief mouse departures don't collapse
   the menu. */
.site-header__nav .sub-menu {
    margin-top: 0; /* supersede TIER3-FIX-DROPDOWN-POLISH */
    padding-top: 12px; /* visual gap that IS hoverable */
    background-clip: content-box; /* keep the visual gap transparent */
}
.site-header__nav .menu-item-has-children > .sub-menu {
    visibility: hidden;
    transition: opacity 0.18s ease,
                transform 0.18s ease,
                visibility 0s linear 0.18s;
}
.site-header__nav .menu-item-has-children:hover > .sub-menu,
.site-header__nav .menu-item-has-children:focus-within > .sub-menu {
    visibility: visible;
    transition-delay: 0s;
}

/* Belt-and-braces: a transparent ::before bridge so even if the
   cursor leaves the parent's text and skids over the gap, the
   parent's hover state stays alive long enough for :hover on the
   sub-menu to take over. */
.site-header__nav .menu-item-has-children::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 16px;
    pointer-events: none;
}
.site-header__nav .menu-item-has-children:hover::before,
.site-header__nav .menu-item-has-children:focus-within::before {
    pointer-events: auto;
}

/* ----- 3b. Products mega-panel — wide two-column layout ----- */
.site-header__nav .menu-item-19646 {
    /* Static positioning context for the absolutely-positioned panel below.
       We override position:relative here because the panel is centred to
       the viewport, not to the parent <li>. */
    position: static;
}

.site-header__nav .menu-item-19646 > .sub-menu {
    /* Wide centred panel */
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    width: min(960px, calc(100vw - 80px));
    min-width: 0;
    max-width: 960px;
    /* Override the column flex from the narrow dropdown */
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 32px 64px;
    padding: 32px 40px;
    padding-top: calc(32px + 12px); /* room for the hover bridge */
    background: #ffffff;
    /* Same soft two-layer stack as the narrow dropdowns so all popups
     * read the same visually — close-contact + ambient elevation. */
    box-shadow:
        0 2px 4px rgba(0, 0, 0, 0.04),
        0 12px 32px rgba(0, 0, 0, 0.10);
    border-radius: 0; /* sharp corners — INDO house style */
    list-style: none;
}
.site-header__nav .menu-item-19646:hover > .sub-menu,
.site-header__nav .menu-item-19646:focus-within > .sub-menu {
    transform: translateX(-50%) translateY(0);
}

/* Each direct child of the Products panel becomes a column. */
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children {
    position: static; /* kill nested-dropdown absolute positioning */
}

/* Column header (Exterior / Horticultural eyebrow) */
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a {
    display: block;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 12px;
    font-weight: 600;
    color: var(--indo-charcoal, #212121);
    padding: 0 0 12px 0;
    margin: 0 0 12px 0;
    border-bottom: 1px solid #e5e5e5;
    line-height: 1.3;
    min-height: 0; /* override mobile-leaning min-height */
}
/* Column-header hover (Per user 2026-05-01): the EXTERIOR / HORTICULTURAL
 * column titles should read as headings, not as items in the list — so
 * they get a simpler hover treatment than the column items below them.
 * Just a colour change + underline. No left-hand cyan accent bar, and
 * the gray divider underneath stays gray (don't flip it to cyan).
 *
 * The `border-left-color: transparent` and `border-bottom-color: #e5e5e5`
 * lines explicitly cancel the universal `.sub-menu a:hover` rule (which
 * adds the cyan accent bar) and the previous header-specific rule (which
 * flipped the divider to cyan). */
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a:hover,
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a:focus,
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a:focus-visible {
    color: #0086b3; /* darker cyan, WCAG AA on white at this size */
    text-decoration: underline;
    text-underline-offset: 3px;
    border-left-color: transparent;
    border-bottom-color: #e5e5e5;
}

/* Third-level list — render the column body inline (not as another popup).
 *
 * 2026-05-01: visibility + pointer-events are gated on the OUTER Products
 * panel's :hover/:focus-within rather than the column-header's. Two
 * problems we're solving simultaneously:
 *   1. If we set `visibility: visible` unconditionally (the original
 *      approach), the column items become event targets even while the
 *      outer panel is opacity:0/hidden — hovering anywhere in the
 *      960×376 footprint re-triggers the panel.
 *   2. If we drop the override entirely, the items default to the
 *      `.menu-item-has-children > .sub-menu { visibility: hidden }` rule
 *      and only flip to `visible` when the column header itself is
 *      hovered — so the items are invisible until you mouse over each
 *      column, which looks broken on first open.
 * Gating on the Products parent's :hover/:focus-within solves both.
 * The other inline-layout properties (position:static, transform:none,
 * etc.) stay unconditional because they govern layout, not visibility. */
.site-header__nav .menu-item-19646 > .sub-menu .sub-menu {
    position: static;
    display: block;
    /* opacity must be 1 unconditionally — opacity is multiplicative
     * through the ancestor chain. The outer panel's opacity transitions
     * 0 → 1, and a child opacity:1 lets the child fade in WITH the
     * parent rather than staying invisible (the .menu-item-has-children
     * > .sub-menu base rule otherwise sets opacity: 0). */
    opacity: 1;
    transform: none;
    transition: none;
    box-shadow: none;
    background: transparent;
    padding: 0;
    margin: 0;
    width: auto;
    min-width: 0;
    list-style: none;
}
.site-header__nav .menu-item-19646:hover > .sub-menu .sub-menu,
.site-header__nav .menu-item-19646:focus-within > .sub-menu .sub-menu {
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s;
}

.site-header__nav .menu-item-19646 > .sub-menu .sub-menu li {
    margin: 0;
}

.site-header__nav .menu-item-19646 > .sub-menu .sub-menu a {
    display: block;
    padding: 8px 0 8px 0;
    font-size: 15px;
    line-height: 1.4;
    color: var(--indo-charcoal, #212121);
    border-left: 2px solid transparent;
    padding-left: 0;
    transition: color 0.15s ease, padding-left 0.15s ease, border-color 0.15s ease;
    min-height: 36px;
}
.site-header__nav .menu-item-19646 > .sub-menu .sub-menu a:hover,
.site-header__nav .menu-item-19646 > .sub-menu .sub-menu a:focus {
    /* WCAG 1.4.3 — pure cyan on white is 3.04:1 which fails 4.5:1 for
       15px body text. Use darker cyan #0086b3 (~4.55:1) for the text
       colour; the cyan accent is preserved via the 2px left border so
       the brand cue still reads. */
    color: #0086b3;
    border-left-color: var(--indo-cyan, #00a6db);
    padding-left: 8px;
    text-decoration: underline;
    text-underline-offset: 3px;
}
/* Restore a visible focus ring for keyboard users (WCAG 2.4.7) without
   keeping the default orange. Mouse hovers don't fire :focus-visible. */
.site-header__nav .menu-item-19646 > .sub-menu .sub-menu a:focus-visible,
.site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db);
    outline-offset: 2px;
}

/* Hide the bridge ::before for the inner Exterior/Horticultural items
   inside the Products panel — they don't have their own popups in
   this layout, so a hover bridge would just intercept events. */
.site-header__nav .menu-item-19646 .menu-item-has-children::before {
    display: none;
}

/* ----- 3e. Mobile (<768px) — stacked accordion ----- */
@media (max-width: 991px) {
    /* Theme already turns the entire nav into a vertical drawer
       below 991px (line ~240 of this stylesheet). Inside the
       Products panel we just need to disable the two-column grid
       and the wide-panel positioning so the items stack. */
    .site-header__nav .menu-item-19646 > .sub-menu {
        position: static;
        transform: none;
        display: block;
        width: auto;
        max-width: none;
        padding: 0 0 0 16px;
        background: transparent;
        box-shadow: none;
        opacity: 1;
        visibility: visible;
    }
    .site-header__nav .menu-item-19646:hover > .sub-menu,
    .site-header__nav .menu-item-19646:focus-within > .sub-menu {
        transform: none;
    }
    .site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a {
        font-size: 13px;
        padding: 12px 0 8px 0;
        margin: 0;
        border-bottom: none;
    }
    .site-header__nav .menu-item-19646 > .sub-menu .sub-menu {
        padding-left: 12px;
    }
    .site-header__nav .menu-item-19646 > .sub-menu .sub-menu a {
        padding: 12px 0;
        min-height: 44px; /* touch target */
    }
    /* On mobile the bridge isn't needed (the menu is a drawer). */
    .site-header__nav .menu-item-has-children::before {
        display: none;
    }
}

/* ===== END POST-LAUNCH-MEGA-MENU ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V2 2026-04-30 =====
   Two unresolved issues from V1:

   Issue 1 — Products mega-panel still had a 35px hover-gap:
     - Parent <li> bottom = y=52.8, panel top = y=88. Cursor leaving the
       parent text crosses an unhovered band before entering the panel,
       collapsing the dropdown.
     - V1 added a ::before bridge but it was silently neutralised by the
       Industrium reset at line ~334:
         .site-header__nav li::before { content: none !important; }
     - V2 fix: switch to ::after with !important (the reset only nukes
       ::before on this selector). For the Products parent specifically,
       make the bridge tall enough to span from the menu-item text bottom
       (y=53) all the way down to the panel top (y=88) — i.e. across the
       header chrome + 12px panel padding-top.

   Issue 2 — Contact Us → Support 3rd-tier overlapped sibling 2nd-tier
   items. The nested sub-menu was opening at top:49px;left:0 — i.e.
   dropping inside the same column on top of "Become A Distributor",
   "Customer Feedback", "Returns Claim".
     - V2 fix: 3rd-tier flies out horizontally (top:0;left:100%). For the
       rightmost top-level items (Contact Us, About — last 2), flip to
       right:100% so the fly-out doesn't run off the viewport edge.
     - INSIDE the Products mega-panel, 3rd-tier lists are intentionally
       inline (column body) — explicitly preserve that with !important
       overrides scoped to .menu-item-19646.
   ============================================================ */

/* ----- 1. Hover bridge via ::after (the Industrium reset wins on
   ::before, so we use the un-reset pseudo). content + display need
   !important to defeat any other catch-all reset. ----- */
.site-header__nav .menu-item-has-children::after {
    content: "" !important;
    display: block !important;
    position: absolute;
    background: transparent !important;
    pointer-events: none;
    z-index: 99999;
}
.site-header__nav .menu-item-has-children:hover::after,
.site-header__nav .menu-item-has-children:focus-within::after {
    pointer-events: auto;
}

/* Default: top-level parent → vertical bridge below it (covers the
   ~12px gap to the dropdown). */
.site-header__nav > ul > .menu-item-has-children::after {
    top: 100%;
    left: 0;
    right: 0;
    height: 16px;
}

/* PRODUCTS specifically: the parent <li> is position:static (so the
   centred panel can use viewport-relative math). That means ::after's
   `top: 100%` anchors to the next-up positioned ancestor (.site-header,
   80px tall) — NOT to the menu-item bottom. Override: span the full
   header height + 12px so the bridge covers the entire dead zone from
   menu-item bottom to panel top. The bridge sits behind the menu-item
   text (pointer-events:none until parent hover), so visually nothing
   changes. */
.site-header__nav > ul > .menu-item-19646::after {
    top: 0;
    left: 0;
    right: 0;
    height: calc(var(--indo-header-h-sticky, 80px) + 12px);
}

/* ----- 2. Nested 3rd-tier flies out horizontally instead of dropping
   inside the column. Applies to the standard narrow-dropdown pattern
   (Contact Us → Support → Installation Manuals etc.). ----- */
.site-header__nav .sub-menu .sub-menu {
    top: 0 !important;
    left: 100% !important;
    right: auto !important;
    margin: 0 !important;
    padding-top: 0 !important;
    padding-left: 12px !important;  /* horizontal hover-bridge band */
    background-clip: content-box;
}

/* Right-edge flip: when the parent column is one of the last two top-
   level menu items (About, Contact Us), the 3rd-tier flies LEFT to
   stay on-screen. */
.site-header__nav > ul > li:nth-last-child(-n+2) .sub-menu .sub-menu {
    left: auto !important;
    right: 100% !important;
    padding-left: 0 !important;
    padding-right: 12px !important;
}

/* Horizontal hover-bridge for 2nd-tier → 3rd-tier traversal: the bridge
   sits to the right of the 2nd-tier <li> (or left, on edge-flip pages)
   and covers the column-to-column horizontal gap. */
.site-header__nav .sub-menu .menu-item-has-children::after {
    top: 0;
    left: 100%;
    right: auto;
    width: 12px;
    height: 100%;
}
.site-header__nav > ul > li:nth-last-child(-n+2) .sub-menu .menu-item-has-children::after {
    left: auto;
    right: 100%;
}

/* ----- 3. Inside the Products mega-panel, the 3rd-tier lists are
   intentionally rendered INLINE as the column body (not popups). The
   fly-out rules above must NOT apply there — preserve the V1 inline
   layout. ----- */
.site-header__nav .menu-item-19646 > .sub-menu .sub-menu {
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    padding: 0 !important;
    background-clip: border-box !important;
}
/* Suppress the horizontal bridge ::after on the Exterior/Horticultural
   column items — they don't have popups in this layout. */
.site-header__nav .menu-item-19646 .menu-item-has-children::after {
    display: none !important;
}

/* ----- 4. Mobile (<991px): drawer mode — bridges off, fly-outs revert
   to inline accordion so 3rd-tier nests below 2nd-tier. ----- */
@media (max-width: 991px) {
    .site-header__nav .menu-item-has-children::after {
        display: none !important;
    }
    .site-header__nav .sub-menu .sub-menu {
        position: static !important;
        top: auto !important;
        left: auto !important;
        right: auto !important;
        padding-left: 12px !important;
        padding-right: 0 !important;
    }
}
/* ===== END POST-LAUNCH-MEGA-MENU-V2 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V3 2026-04-30 =====
   User feedback: the Products mega-panel's white panel starts at y=80
   (just below the 80px header strip), but the narrow dropdowns
   (About, Contact Us) showed their white panel at y≈65 — visually
   higher than Products. Align all top-level submenus to the same y=80
   "white-panel-top" position as Products.

   Approach: bump `padding-top` on top-level narrow dropdowns from 12px
   (V1) to 19px so the visible white panel (with `background-clip:
   content-box` keeping the padding transparent) starts at y≈80
   matching Products.

   Math: parent <li>.bottom = 52.8, dropdown transform: translateY(8px)
   → dropdown rect.top = 60.8. Want visual_top = 80 (= rect.top + padding-
   top with content-box clipping). 80 - 60.8 = 19.2px ≈ 19px.

   Hover-gap NOT reintroduced: the dropdown rect still anchors at
   parent.bottom + 8px translateY (y=60.8) via `top: 100%`. The padding
   extends the hoverable area down to y=79.8, then the items render
   below. Cursor traversal from parent text → 8px translate gap →
   padding zone → visible items stays inside hovered elements the whole
   way (the V2 ::after bridge spans the 8px translate gap; the dropdown
   rect itself covers the rest).

   Scope: only TOP-LEVEL narrow submenus, explicitly NOT the Products
   mega-panel (its rect already starts at y=80 with border-box bg-clip
   and 44px internal padding — different stack).
   ============================================================ */
.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu {
    /* Math (after V5 unified header at 80px): parent <li>.bottom = 52.8
       (vertically centered menu items in 80px header). Dropdown rect.top
       when hovered = parent.bottom = 52.8 (translateY(0) on hover state).
       Want visual content top = 80 (header bottom). 80 - 52.8 = 27.2px. */
    padding-top: 27px;
}
/* ===== END POST-LAUNCH-MEGA-MENU-V3 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V4 2026-04-30 =====
   User feedback (2026-04-30):
     a) The cyan-accent + indent + underline hover treatment was nice on
        Products' mega-panel but didn't apply to the narrow dropdowns
        (About → Testimonials, Contact Us → *). Apply universally so
        every dropdown item shares the same hover language.
     b) Mobile menu was a plain white drawer with charcoal text — bland,
        not on-brand. Redesign with navy bg, white text, cyan accents,
        larger touch targets and a smoother slide-in.

   Note on V3 alignment + page-template consistency: header height varies
   between pages (home: 80px full-bleed mode; /articles/, /contacts/ etc:
   64px compact mode). V3's padding-top: 19px aligns the visual panel
   top to the header's bottom on EACH page automatically — verified at
   y=80 on home, y=64 on /articles/. So the dropdown always tucks under
   its page's header, which is the desired consistent behaviour.
   ============================================================ */

/* ----- a) Universal hover style — cyan accent bar + indent + underline
   on every dropdown link, not just the mega-panel column items. ----- */
.site-header__nav .sub-menu a {
    border-left: 2px solid transparent;
    transition: color 0.15s ease,
                padding-left 0.15s ease,
                border-color 0.15s ease,
                background 0.15s ease;
}
.site-header__nav .sub-menu a:hover,
.site-header__nav .sub-menu a:focus-visible {
    color: #0086b3 !important;          /* darker cyan, AA on white at 14-15px */
    border-left-color: var(--indo-cyan, #00a6db);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Narrow top-level dropdowns (e.g. About → Testimonials): items have
   ~20px left padding at rest; bump to 28px on hover so the cyan accent
   bar slides in cleanly. */
.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu a {
    padding-left: 20px;
}
.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu a:hover,
.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu a:focus-visible {
    padding-left: 28px;
}

/* 3rd-tier horizontal fly-outs (Contact Us → Support → Installation
   Manuals etc.) use the same indent-on-hover. */
.site-header__nav .sub-menu .sub-menu a {
    padding-left: 20px;
}
.site-header__nav .sub-menu .sub-menu a:hover,
.site-header__nav .sub-menu .sub-menu a:focus-visible {
    padding-left: 28px;
}

/* ----- b) Mobile menu redesign — navy / white / cyan ----- */
@media (max-width: 991px) {
    .site-header__nav {
        background: var(--indo-navy, #121c22) !important;
        color: #fff !important;
        padding: 8px 0 32px !important;
        transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1) !important;
        border-top: 1px solid rgba(255, 255, 255, 0.06);
    }
    .site-header__nav > ul {
        padding: 0 !important;
        margin: 0 !important;
    }
    .site-header__nav a {
        color: rgba(255, 255, 255, 0.92) !important;
        padding: 16px 24px !important;
        min-height: 56px !important;
        font-size: 16px;
        font-weight: 500;
        letter-spacing: 0.005em;
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
        background: transparent !important;
    }
    .site-header__nav > ul > li:last-child > a {
        border-bottom: 0 !important;
    }
    .site-header__nav a:hover,
    .site-header__nav a:focus,
    .site-header__nav .current-menu-item > a,
    .site-header__nav .current_page_item > a {
        color: var(--indo-cyan, #00a6db) !important;
        background: rgba(255, 255, 255, 0.03) !important;
    }

    /* Nested sub-menus: subtle dark band, indented, smaller text */
    .site-header__nav .sub-menu {
        background: rgba(0, 0, 0, 0.22) !important;
        padding: 0 !important;
        margin: 0 !important;
        opacity: 1 !important;
        visibility: visible !important;
        transform: none !important;
    }
    .site-header__nav .sub-menu a {
        padding: 14px 24px 14px 40px !important;
        min-height: 48px !important;
        font-size: 14px;
        font-weight: 400;
        color: rgba(255, 255, 255, 0.78) !important;
        border-bottom: 1px solid rgba(255, 255, 255, 0.04);
        border-left: 0 !important;  /* drop the cyan accent bar on mobile */
    }
    .site-header__nav .sub-menu li:last-child > a {
        border-bottom: 0 !important;
    }
    .site-header__nav .sub-menu a:hover,
    .site-header__nav .sub-menu a:focus,
    .site-header__nav .sub-menu .current-menu-item > a {
        color: var(--indo-cyan, #00a6db) !important;
        background: rgba(0, 166, 219, 0.08) !important;
        text-decoration: none !important;
        padding-left: 40px !important;  /* override desktop indent rule */
    }

    /* 3rd-tier — deeper indent */
    .site-header__nav .sub-menu .sub-menu {
        background: rgba(0, 0, 0, 0.32) !important;
    }
    .site-header__nav .sub-menu .sub-menu a {
        padding-left: 56px !important;
        font-size: 13px;
    }
    .site-header__nav .sub-menu .sub-menu a:hover,
    .site-header__nav .sub-menu .sub-menu a:focus {
        padding-left: 56px !important;
    }

    /* Products mega-panel inside the drawer: column eyebrows become
       small uppercase section headers, items below are indented. */
    .site-header__nav .menu-item-19646 > .sub-menu {
        background: rgba(0, 0, 0, 0.22) !important;
    }
    .site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > a {
        color: rgba(255, 255, 255, 0.75) !important;
        text-transform: uppercase;
        font-size: 12px !important;
        letter-spacing: 0.1em;
        font-weight: 600;
        padding: 20px 24px 10px !important;
        min-height: 0 !important;
        border-bottom: 0 !important;
        border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
        background: transparent !important;
        /* 2026-05-02: pointer-events: none was killing taps on the Exterior
           and Horticultural parent items. Tom flagged that these are real
           destination pages (/exterior-lighting/, /horticultural-lighting/)
           and should navigate when tapped. Removing the rule lets the JS
           inject a sibling chevron — tap the LINK to navigate, tap the
           CHEVRON to expand the sub-menu. */
    }
    .site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children:first-child > a {
        border-top: 0 !important;  /* no double-divider above the first column */
    }

    /* Hamburger: cyan when drawer is open as a small affordance */
    .site-header.is-open .site-header__toggle {
        color: var(--indo-cyan, #00a6db) !important;
    }
}
/* ===== END POST-LAUNCH-MEGA-MENU-V4 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V5 2026-04-30 =====
   User feedback (2026-04-30): About / Contact dropdowns appear "too high"
   on /articles/ vs home — they should match across the site.

   Root cause: the header had two heights —
     --indo-header-h-desktop: 80px  (default, transparent over hero)
     --indo-header-h-sticky:  64px  (compact, used by .header--on-light)

   .header--on-light is applied (a) ALWAYS on inner pages (no fullbleed
   hero), and (b) on the home page once scrolled past the hero. So the
   header was 64px on /articles/, /contacts/ etc, and shrank to 64px on
   home-when-scrolled. Dropdowns anchor to parent <li>.bottom, so they
   tracked the header height — y=80 on home-top, y=64 on inner pages
   and home-scrolled.

   Fix: unified --indo-header-h-sticky to 80px (see line 33). The header
   never shrinks on desktop now; it stays a consistent 80px across all
   pages and all scroll states. Dropdowns auto-align at y≈80 everywhere.
   No within-home scroll jump; no inner-page mismatch. Mobile stays at
   --indo-header-h-mobile (64px) which is independent.
   ============================================================ */
/* (No additional rules needed — the variable change at line 33 handles
   it. Block kept as a documentation marker.) */
/* ===== END POST-LAUNCH-MEGA-MENU-V5 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V6 2026-04-30 =====
   User feedback: About / Contact dropdowns still appear at different
   height to Products. Verified via Chrome MCP — and the cause is the
   `translateY(8px) → translateY(0)` slide-in animation:

   - About / Contact: when hovered, translate animates to 0 →
     rect.top = parent.bottom = 52.8, visible at y=79.8.
   - Products: translate stays at 8 (transition timing race —
     possibly because the hover bridge ::after activation interferes
     with hover-state recalc, or the visibility:0s-delay-180ms is
     blocking the transform transition somewhere) → rect.top = 88,
     visible at y=88.

   Net: 8px misalignment between Products and the narrow dropdowns.

   Fix: drop the translateY slide entirely. The dropdowns just fade in
   via opacity (cleaner anyway — modern menus rarely slide). Without
   the translate variable, both anchor positions are static:
     - About:    rect.top = parent.bottom (52.8) + padding 27 = 79.8
     - Products: rect.top = .site-header.bottom (80) + padding 44 = 124
       BUT bg-clip:border-box → white panel top = rect.top = 80.

   So both panels' WHITE TOPS land at y≈80 — the bottom of the header,
   consistently across all dropdowns and pages.
   ============================================================ */
.site-header__nav .sub-menu {
    transform: none !important;
}
.site-header__nav .menu-item-has-children:hover > .sub-menu,
.site-header__nav .menu-item-has-children:focus-within > .sub-menu {
    transform: none !important;
}
/* Products mega-panel still needs translateX(-50%) for viewport-centred
   horizontal positioning — keep that, but drop the Y component. */
.site-header__nav .menu-item-19646 > .sub-menu {
    transform: translateX(-50%) !important;
}
.site-header__nav .menu-item-19646:hover > .sub-menu,
.site-header__nav .menu-item-19646:focus-within > .sub-menu {
    transform: translateX(-50%) !important;
}

/* Re-tune About/Contact narrow padding now that translate isn't
   adding 8px on top: visible_panel_top should be parent.bottom +
   padding-top = 80. So padding = 80 - 52.8 = 27.2 ≈ 27. (V3 already
   set 27; no change.) */

/* For Products: rect.top is now 80 (was 88 with stuck translate). The
   internal 44px padding pushes content to y=124. The WHITE PANEL top
   sits at y=80 because bg-clip is border-box. Perfectly aligned with
   the narrow dropdowns' content-top at y≈80. */
/* ===== END POST-LAUNCH-MEGA-MENU-V6 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V7 2026-04-30 =====
   User feedback: About / Contact panels' visible white tops are well
   above the y=80 reference line.

   What was happening: `.header--on-light` has `background: #fff` (white
   header on inner pages). About/Contact dropdowns use
   `background-clip: content-box` (padding zone transparent). With the
   dropdown rect.top at parent.bottom (~52.8) and the white header
   behind, the visible white area appears continuous from y=52.8 down
   — making the panel LOOK like it starts at y=53, not y=80, even
   though the dropdown's CONTENT BOX starts at y=79.8.

   Products' parent <li> is position: static so its dropdown anchors
   to .site-header.bottom = 80, AND its bg-clip is border-box (solid
   white from rect.top). So Products visually starts at y=80 distinct
   from the header.

   First V7 attempt tried `align-self: stretch` to make the parent <li>
   80px tall. Didn't work — the parent flex chain (.site-header__nav
   > ul) is only ~34px tall, so the <li> only stretched to 34px.

   Fix (revised): explicitly position the dropdown rect at y=80 via
   `top: calc(100% + 27.2px)`. With parent.bottom=52.8, that puts
   rect.top = 80 directly. Switch bg-clip to border-box so the white
   renders from rect.top (no transparent padding zone to merge with
   the header). Reset padding-top to a small value (12px) for visual
   breath above the first item.

   Hover-gap: 27.2px gap now between parent.bottom (52.8) and
   dropdown.top (80). Existing bridge ::after height was 16px — bump
   to 32px so it spans the full gap with a small overlap for safety.
   ============================================================ */

.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu {
    /* Anchor dropdown rect.top to header.bottom (y=80). Math:
       parent.bottom (52.8) + 27.2 = 80. Tuned for the 80px header
       with vertically-centered ~25px-tall menu items. */
    top: calc(100% + 27.2px);
    padding-top: 12px;
    background-clip: border-box;  /* solid white from rect.top */
    background-color: #fff;
}

/* Bridge ::after height: extend from 16px (V1) to 32px so the bridge
   covers the new 27.2px gap from parent.bottom to dropdown.top, plus
   a small overlap for safety. */
.site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646)::after {
    height: 32px;
}
/* ===== END POST-LAUNCH-MEGA-MENU-V7 ===== */

/* ===== POST-LAUNCH-MEGA-MENU-V8 2026-04-30 =====
   User feedback: when Products dropdown is open, the other primary
   menu links (Home, Projects, Articles, About, Contact Us) cannot be
   clicked.

   Root cause: V2 added a wide hover-bridge ::after on Products
   specifically (`top: 0; left: 0; right: 0; height: 92px`) anchored
   to .site-header (because Products parent <li> was position:static).
   That bridge spanned the FULL HEADER WIDTH. When Products is
   hovered, `pointer-events: auto` activates on the bridge, putting
   it on top of every other top-level menu item — intercepting clicks.

   Fix: switch Products parent <li> from position:static to
   position:relative so the bridge ::after anchors to the parent (and
   left:0;right:0 means parent's width, ~127px, NOT the full header).
   For the mega-panel's viewport-centred horizontal anchor, switch
   from position:absolute to position:fixed with `left: 50vw` so the
   panel doesn't depend on the parent for horizontal positioning.

   Also simplify the Products bridge to the standard pattern (top:100%;
   height:32px) — no need for the 0-to-92 vertical bridge anymore since
   the parent is no longer position:static.
   ============================================================ */

/* Products parent: position:relative so the bridge ::after stays
   inside the parent's bounding box (parent's width, not header's). */
.site-header__nav > ul > .menu-item-19646 {
    position: relative !important;
}

/* Products mega-panel: position:fixed pinned to viewport. This
   decouples the panel's positioning from the parent <li> so we
   don't need the parent to be static for horizontal centring. */
.site-header__nav .menu-item-19646 > .sub-menu {
    position: fixed !important;
    top: var(--indo-header-h-desktop, 80px) !important;
    left: 50vw !important;
    transform: translateX(-50%) !important;
}
.site-header__nav .menu-item-19646:hover > .sub-menu,
.site-header__nav .menu-item-19646:focus-within > .sub-menu {
    transform: translateX(-50%) !important;
}

/* Products bridge ::after: now naturally limited to parent's width
   (because parent is position:relative). Use the standard
   below-parent pattern (top: 100%, height: 32px) — drop V2's
   header-spanning 0-to-92 bridge. */
.site-header__nav > ul > .menu-item-19646::after {
    top: 100% !important;
    left: 0 !important;
    right: 0 !important;
    height: 32px !important;
}
/* ===== END POST-LAUNCH-MEGA-MENU-V8 ===== */

/* ===== AUDIT /contacts/ + /become-a-distributor/ form legibility 20260430 =====
 * WHY: Both pages share the same Elementor template (industrium_wpforms widget
 * on a dark navy column). Labels were rendering at #b7bdc1 (light-gray) on a
 * navy bg — passes WCAG AA for 14px+ but reads as muted. Inputs had a near-
 * transparent background (rgba(255,255,255,0.04)) which made the field box
 * almost invisible at rest. The privacy notice was in a top-level container
 * above the entire layout; moved into the form column (after the form widget)
 * via Elementor postmeta restructure (see contacts/distributor JSON updates).
 * ============================================================================ */

/* Form labels — bump contrast + size for legibility */
.industrium-wpforms-widget label,
.industrium-wpforms-widget .wpforms-field-label,
.industrium-wpforms-widget .wpforms-field > label {
    color: rgba(255, 255, 255, 0.92) !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    letter-spacing: 0.01em !important;
    margin-bottom: 8px !important;
}

/* RECURRING-ISSUE FIX (Tom flagged 2026-05-05, has come back multiple times):
 * WPForms "modern" render (with "hide labels" enabled per-form) adds the
 * .wpforms-label-hide class to every field label and applies a screen-reader-
 * only style (position:absolute; width:1px; height:1px; clip:rect(0,0,0,0)).
 * The label disappears visually and only the input's placeholder text shows
 * inside the box, in a low-opacity colour that vanishes on click.
 *
 * The previous fix was scoped per-page (page-id-92, page-id-16653) which meant
 * any new form page reproduced the issue. Promoting to a sitewide override on
 * any .industrium-wpforms-widget so it sticks across all current AND future
 * pages using the WPForms Elementor widget.
 *
 * Keeps the wpforms-label-hide class intact (so screen readers still get the
 * proper ARIA semantics) but reverses the visual hiding so labels render
 * normally above their inputs. */
.industrium-wpforms-widget .wpforms-form .wpforms-field-label.wpforms-label-hide,
.industrium-wpforms-widget .wpforms-form label.wpforms-field-label.wpforms-label-hide {
    position: static !important;
    width: auto !important;
    height: auto !important;
    clip: auto !important;
    clip-path: none !important;
    overflow: visible !important;
    white-space: normal !important;
    margin: 0 0 8px 0 !important;
    padding: 0 !important;
}
/* Required-asterisk in INDO cyan as a brand accent */
.industrium-wpforms-widget label .wpforms-required-label,
.industrium-wpforms-widget .wpforms-required-label,
.industrium-wpforms-widget label abbr[title="required"] {
    color: var(--indo-cyan, #00a6db) !important;
    text-decoration: none !important;
    margin-left: 4px;
}

/* Inputs — visible at rest with a clear underline; cyan on focus */
.industrium-wpforms-widget input[type="text"],
.industrium-wpforms-widget input[type="email"],
.industrium-wpforms-widget input[type="tel"],
.industrium-wpforms-widget input[type="number"],
.industrium-wpforms-widget input[type="url"],
.industrium-wpforms-widget textarea,
.industrium-wpforms-widget select {
    background: rgba(255, 255, 255, 0.06) !important;
    border: 1px solid rgba(255, 255, 255, 0.18) !important;
    border-bottom: 2px solid rgba(255, 255, 255, 0.55) !important;
    color: #ffffff !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 16px !important;
    line-height: 1.5 !important;
    padding: 12px 14px !important;
    border-radius: 4px 4px 0 0 !important;
    transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.industrium-wpforms-widget input::placeholder,
.industrium-wpforms-widget textarea::placeholder {
    color: rgba(255, 255, 255, 0.55) !important;
    opacity: 1 !important;
}
.industrium-wpforms-widget input:focus,
.industrium-wpforms-widget input:focus-visible,
.industrium-wpforms-widget textarea:focus,
.industrium-wpforms-widget textarea:focus-visible,
.industrium-wpforms-widget select:focus,
.industrium-wpforms-widget select:focus-visible {
    background: rgba(255, 255, 255, 0.10) !important;
    border-color: rgba(0, 166, 219, 0.45) !important;
    border-bottom-color: var(--indo-cyan, #00a6db) !important;
    outline: 0 !important;
    box-shadow: 0 2px 0 0 rgba(0, 166, 219, 0.2) !important;
}
/* Validation error states in red, but keep readable on the dark panel */
.industrium-wpforms-widget input.wpforms-error,
.industrium-wpforms-widget textarea.wpforms-error {
    border-bottom-color: #ff6b6b !important;
}
.industrium-wpforms-widget label.wpforms-error,
.industrium-wpforms-widget .wpforms-error-message {
    color: #ff8a8a !important;
    font-size: 13px !important;
    font-weight: 400 !important;
    margin-top: 4px !important;
}

/* ===== HOMEPAGE form fix 20260430 (page_id 393) ============================
 * WHY: The /contacts/ + /become-a-distributor/ block above globally styles
 * .industrium-wpforms-widget for a DARK surface (white text on translucent
 * white bg, white-translucent placeholders). But the homepage's Get-in-Touch
 * widget (data-id c1896ff) sits on a WHITE card (Elementor widget-container
 * background-color: #FFFFFF). White-on-white = invisible inputs, invisible
 * placeholders. User reported "form is broken" — visually it was, fields
 * showed only an underline with no text or placeholder.
 *
 * FIX: scope an override to body.page-id-393 that re-flips inputs / labels
 * / placeholders / focus to dark-on-white. Matches the existing page-id-92
 * scoping pattern higher up in this file. Does NOT touch the global block
 * (so /contacts/ and /become-a-distributor/ stay correct).
 *
 * NB: if any other page later puts industrium_wpforms on a white card, it
 * needs its own page-id override (or we refactor the global rule to a
 * wrapper-class approach — flagged in audit backlog). */
body.page-id-393 .industrium-wpforms-widget label,
body.page-id-393 .industrium-wpforms-widget .wpforms-field-label,
body.page-id-393 .industrium-wpforms-widget .wpforms-field > label {
    color: #212121 !important;
}
body.page-id-393 .industrium-wpforms-widget input[type="text"],
body.page-id-393 .industrium-wpforms-widget input[type="email"],
body.page-id-393 .industrium-wpforms-widget input[type="tel"],
body.page-id-393 .industrium-wpforms-widget input[type="number"],
body.page-id-393 .industrium-wpforms-widget input[type="url"],
body.page-id-393 .industrium-wpforms-widget textarea,
body.page-id-393 .industrium-wpforms-widget select {
    background: #ffffff !important;
    border: 1px solid rgba(33, 33, 33, 0.18) !important;
    border-bottom: 2px solid rgba(33, 33, 33, 0.45) !important;
    color: #212121 !important;
}
/* Industrium wraps each input with a .floating-placeholder span that supplies
 * the visible label. The parent theme tries to hide the native HTML placeholder
 * via a webkit-only rule, leaving ::placeholder visible in modern browsers.
 * Force the native placeholder transparent here so only the span renders —
 * otherwise both render and you get ghosted/duplicated label text. */
body.page-id-393 .industrium-wpforms-widget input::placeholder,
body.page-id-393 .industrium-wpforms-widget textarea::placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-393 .industrium-wpforms-widget input::-webkit-input-placeholder,
body.page-id-393 .industrium-wpforms-widget textarea::-webkit-input-placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-393 .industrium-wpforms-widget input::-moz-placeholder,
body.page-id-393 .industrium-wpforms-widget textarea::-moz-placeholder {
    color: transparent !important;
    opacity: 1 !important;
}
body.page-id-393 .industrium-wpforms-widget .input-floating-wrap .floating-placeholder {
    color: #abafb5;
}
body.page-id-393 .industrium-wpforms-widget input:focus,
body.page-id-393 .industrium-wpforms-widget input:focus-visible,
body.page-id-393 .industrium-wpforms-widget textarea:focus,
body.page-id-393 .industrium-wpforms-widget textarea:focus-visible,
body.page-id-393 .industrium-wpforms-widget select:focus,
body.page-id-393 .industrium-wpforms-widget select:focus-visible {
    background: #ffffff !important;
    border-color: rgba(0, 166, 219, 0.45) !important;
    border-bottom-color: var(--indo-cyan, #00a6db) !important;
    box-shadow: 0 2px 0 0 rgba(0, 166, 219, 0.2) !important;
}
/* Choices.js select wrapper — match the input styling on white card */
body.page-id-393 .industrium-wpforms-widget .choices__inner,
body.page-id-393 .industrium-wpforms-widget .choices[data-type*="select-one"] .choices__inner {
    background: #ffffff !important;
    border: 1px solid rgba(33, 33, 33, 0.18) !important;
    border-bottom: 2px solid rgba(33, 33, 33, 0.45) !important;
    color: #212121 !important;
}
body.page-id-393 .industrium-wpforms-widget .choices__list--single .choices__item,
body.page-id-393 .industrium-wpforms-widget .choices__placeholder {
    color: #212121 !important;
}
body.page-id-393 .industrium-wpforms-widget .choices__placeholder {
    color: #abafb5 !important;
    opacity: 1 !important;
}
/* Validation errors readable on white */
body.page-id-393 .industrium-wpforms-widget input.wpforms-error,
body.page-id-393 .industrium-wpforms-widget textarea.wpforms-error {
    border-bottom-color: #d63637 !important;
}
body.page-id-393 .industrium-wpforms-widget label.wpforms-error,
body.page-id-393 .industrium-wpforms-widget .wpforms-error-message {
    color: #d63637 !important;
}
/* Industrium's theme.js injects an unsized <svg> chevron into every wpforms
 * submit button on document-ready. With no width/height attr it computes to
 * ~135x208px, and Industrium's overflow:hidden then clips the visible label
 * out of frame — leaving an apparently empty cyan button. The chevron isn't
 * part of the indo-2026 filled-button design, so suppress it here. */
body.page-id-393 .industrium-wpforms-widget .wpforms-submit > svg {
    display: none !important;
}
/* ===== END HOMEPAGE form fix ============================================== */

/* ===== /returns-claim/ (page-id 16797) — Ninja Forms wizard buttons =======
 * The default NF "Next >" / "< Previous" / "Submit" buttons render in a flat
 * dark-charcoal pill with all-lowercase text, which is jarring against the
 * cyan-accented INDO 2026 design language and visually conflicts with the
 * already-cyan step-tab pills above the form. Bring them in line with the
 * homepage / global filled-cyan button style: cyan fill on Next/Submit, ghost
 * outline on Previous (so the back action reads as secondary). */
body.page-id-16797 .nf-form-cont .nf-next,
body.page-id-16797 .nf-form-cont .nf-previous,
body.page-id-16797 .nf-form-cont input[type="button"].ninja-forms-field,
body.page-id-16797 .nf-form-cont input[type="submit"].ninja-forms-field {
    background: var(--indo-cyan, #00a6db) !important;
    color: #ffffff !important;
    border: 0 !important;
    border-radius: var(--indo-radius, 4px) !important;
    padding: 12px 28px !important;
    min-height: 44px !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    text-transform: uppercase !important;
    letter-spacing: 0.06em !important;
    cursor: pointer !important;
    transition: background .15s var(--indo-easing, cubic-bezier(.2,.7,.3,1)) !important;
    box-shadow: none !important;
}
body.page-id-16797 .nf-form-cont .nf-previous {
    background: transparent !important;
    color: var(--indo-cyan, #00a6db) !important;
    border: 1.5px solid var(--indo-cyan, #00a6db) !important;
    padding: 10.5px 26.5px !important; /* compensate for 1.5px border */
}
body.page-id-16797 .nf-form-cont .nf-next:hover,
body.page-id-16797 .nf-form-cont input[type="button"].ninja-forms-field:hover,
body.page-id-16797 .nf-form-cont input[type="submit"].ninja-forms-field:hover {
    background: var(--indo-cyan-light, #00acea) !important;
}
body.page-id-16797 .nf-form-cont .nf-previous:hover {
    background: var(--indo-cyan, #00a6db) !important;
    color: #ffffff !important;
}
body.page-id-16797 .nf-form-cont .nf-next:focus-visible,
body.page-id-16797 .nf-form-cont .nf-previous:focus-visible,
body.page-id-16797 .nf-form-cont input[type="button"].ninja-forms-field:focus-visible,
body.page-id-16797 .nf-form-cont input[type="submit"].ninja-forms-field:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db) !important;
    outline-offset: 2px !important;
}
/* ===== END /returns-claim/ wizard button fix ============================== */

/* /returns-claim/ — hide the redundant top-of-page "Returns Form" Elementor
 * heading widget (db96d16). The page already opens with a clear "Online
 * Customer Return Form" h1 directly below it, so this small h2 only
 * duplicates the page title and, at 80px sticky-header heights, gets clipped
 * behind the header on narrow viewports. Removing it tightens the hierarchy
 * without losing any information. */
body.page-id-16797 .elementor-element-db96d16 {
    display: none !important;
}

/* /returns-claim/ — suppress the global GET A QUOTE floater on this page.
 * The user is already in a customer-service flow (raising a return), so the
 * shopping-intent CTA is contextually irrelevant; on 768/375 it also overlaps
 * the form fields and competes with the form's own Submit. */
body.page-id-16797 .indo-floater {
    display: none !important;
}

/* Privacy notice — sits in the form column, after the form widget.
 *
 * The form widget owns the navy panel bg internally; the column itself is
 * transparent. So the privacy notice ends up rendering on the page's white
 * bg, BELOW the navy form panel. We style it for that light context with
 * charcoal text + cyan inline links + a subtle top border that visually
 * connects it to the form panel above.
 *
 * Specificity is bumped by adding `.elementor-widget` to the selectors so
 * the rules win against Elementor's per-widget generated CSS without us
 * having to chase widget IDs. */
.elementor-widget.indo-form-privacy-notice {
    margin-top: 16px !important;
    padding-top: 16px !important;
    border-top: 1px solid rgba(33, 33, 33, 0.12) !important;
}
.elementor-widget.indo-form-privacy-notice .elementor-widget-container > p,
.elementor-widget.indo-form-privacy-notice p {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 13px !important;
    line-height: 1.6 !important;
    color: rgba(33, 33, 33, 0.72) !important;
    margin: 0 0 10px !important;
    font-style: normal !important;
    text-align: left !important;
    letter-spacing: 0 !important;
}
.elementor-widget.indo-form-privacy-notice p:last-child {
    margin-bottom: 0 !important;
}
.elementor-widget.indo-form-privacy-notice em,
.elementor-widget.indo-form-privacy-notice p em,
.elementor-widget.indo-form-privacy-notice em p {
    /* Source HTML wrapped the privacy notice in <em>; un-italicise for
     * legibility at small size. The notice is informational, not emphatic. */
    font-style: normal !important;
}
.elementor-widget.indo-form-privacy-notice a {
    color: var(--indo-cyan, #00a6db) !important;
    text-decoration: underline !important;
    text-underline-offset: 2px !important;
}
.elementor-widget.indo-form-privacy-notice a:hover,
.elementor-widget.indo-form-privacy-notice a:focus-visible {
    color: var(--indo-cyan-light, #00acea) !important;
}
/* Privacy notice alignment + whitespace trim — addendum 2026-04-30
 * 1. The form widget's inner panel sits ~75px to the right of its widget
 *    outer edge (the form widget has a non-trivial left offset from a
 *    decoration sibling in the same column). The privacy notice — added
 *    later as a sibling widget — extends the full column width and
 *    visually hangs ~75px to the left of the form panel. Adding a left
 *    pad to the privacy notice's inner container brings its left edge
 *    in line with the form panel's left edge. Right edges already match
 *    (same column right).
 *
 * 2. After moving the privacy notice into the form column the form
 *    section (`.elementor-element-5250112`) ends earlier visually, but
 *    the section + the following Google Maps section still carry
 *    bottom/top padding that opens a wide white gap between the privacy
 *    notice and the map. Zero them out so the map butts up against the
 *    bottom of the form section's dotted-world background image.
 */
@media (min-width: 768px) {
    /* Shift the entire privacy widget right by 75px (instead of padding the
     * inner container) so the widget's box — including its top border — is
     * the same width as the text content. With padding-left, the text moved
     * but the border-top still spanned the full column width and read as
     * wider than the copy below. */
    .elementor-widget.indo-form-privacy-notice {
        margin-left: 75px !important;
    }
    .elementor-widget.indo-form-privacy-notice .elementor-widget-container {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
}
/* On mobile the form column stacks full-width and there's no offset to
 * match — keep privacy notice at full container width. */

/* (2026-05-05) Top-level section padding/margin for /contacts/ + /become-a-distributor/
 * (both pages share Elementor section IDs as cloned templates) migrated to
 * _elementor_data on posts 92 and 16653. Values now visible/editable from the
 * Elementor UI per Tom's design-system migration pattern.
 *
 * Migrated values (both pages identical):
 *   Section 5250112 (form/contact-info):
 *     padding: 56 / 0 / 0 / 0  (top/right/bottom/left, px)
 *     margin:  0 / 0 / 0 / 0
 *   Section 3bdf5b6 (Google Map):
 *     padding: 0 / 0 / 0 / 0
 *     margin:  0 / 0 / 0 / 0   (was 135 desktop / 105 tablet-extra / 65 mobile-extra
 *                                in data, but un-prefixed `margin-top: 0 !important`
 *                                CSS forced 0 — data now matches visual reality)
 *
 * The page-id-92-scoped Map full-bleed block (lines ~9395+) and SITE-WIDE
 * SECTION RHYTHM opt-out hook (line ~9663) are kept — they are layout-fix,
 * not simple padding overrides. */
.elementor-widget.indo-form-privacy-notice {
    margin-top: 12px !important;
    margin-bottom: 0 !important;
}
/* Default: 20px shift (matches /contacts/ where "Here to help" big H2 is
 * the first text on the left at y=176 after our padding trim). */
.elementor-element.elementor-element-f036326 {
    margin-top: 20px !important;
}
.elementor-element.elementor-element-f036326 > .elementor-widget-container {
    padding-top: 30px !important;
    padding-bottom: 36px !important;
}
/* /become-a-distributor/ override (post 16653): the left column has no
 * big heading like /contacts/'s "Here to help"; the first visible text
 * on the left is the "INDO Lighting" address heading at y=221. Bump the
 * form widget margin-top so its panel top aligns with "INDO Lighting"
 * rather than sitting 45px above it. */
body.page-id-16653 .elementor-element.elementor-element-f036326 {
    margin-top: 65px !important;
}

/* ===== HEADINGS — restore normal case 20260430 =========================
 * WHY: User rule (re-confirmed 2026-04-30, recorded in indo_brand_voice.md):
 * "every heading and sub-heading on the site MUST start with a capital
 * letter." An earlier (now-reverted) lowercase pass scattered ~20
 * `text-transform: lowercase` declarations across this stylesheet (lines
 * 75, 777, 818, 834, 873, 978, 1216, 1288, 1441, 1554, 1882, 2035, 2444,
 * 2493, 2554, 3010, 3846, 3889, 4002, 4054). Rather than chase each one
 * (with risk of accidentally touching neighbouring properties), this
 * single override flips text-transform back to `none` on heading
 * elements, with !important to beat the !important rules in the
 * source-of-truth lowercase declarations above.
 *
 * SCOPE: applies only to heading elements (h1–h6) and Industrium /
 * Elementor heading wrappers. DOES NOT touch decorative non-heading
 * lowercase styling (filter chips, tab labels, eyebrow micro-labels,
 * CTA buttons) — those are intentional layout choices per the
 * indo_brand_voice.md "lowercase visual style on certain elements" note.
 * ====================================================================== */
/* Specificity boost via body[class][class]: the existing lowercase-pass
 * rules above use selectors like body.page-id-XXX .elementor-element-YYY
 * .industrium-heading (0,0,3,1) with !important. body[class][class]
 * descendant .industrium-heading totals (0,0,3,1) — equal specificity, but
 * source order favours us (we come last). For element-level selectors,
 * body[class][class] :is(h1...) totals (0,0,2,2), beating the lowercase-pass
 * page-scoped element rules. Brittle-looking syntax, but it's the lowest-
 * risk way to win without rewriting 20 individual rules. */
body[class][class][class][class] :is(h1, h2, h3, h4, h5, h6),
body[class][class][class][class] .section-title,
body[class][class][class][class] .indo-hero h1,
body[class][class][class][class] .indo-hero h2,
body[class][class][class][class] .indo-related .section-title,
body[class][class][class][class] .industrium-heading,
body[class][class][class][class] .industrium-heading .industrium-heading-content,
body[class][class][class][class] .industrium-heading-content,
body[class][class][class][class] .industrium-heading-widget :is(h1, h2, h3),
body[class][class][class][class] .testimonials-heading :is(h1, h2, h3),
body[class][class][class][class] .elementor-heading-title,
body[class][class][class][class] .wpforms-widget-heading,
body[class][class][class][class] .indo-archive-intro__title,
body[class][class][class][class] .team-item .post-title {
    text-transform: none !important;
}
/* ===== END AUDIT form legibility 20260430 ===== */

/* ============================================================================
 * INDO PILLAR PAGES (2026-04-30)
 *
 * Shared styling for /exterior-lighting/ and /horticultural-lighting/.
 * Both use custom PHP page templates (page-exterior-lighting.php /
 * page-horticultural-lighting.php) that bypass Elementor and render the
 * same 6-section structure: hero, stats strip, range cards, projects
 * rotator, why-INDO band, CTA band.
 * ============================================================================ */

/* ---------------- HERO ----------------------------------------------------- */
.indo-pillar-hero {
    position: relative;
    min-height: clamp(420px, 60vh, 640px);
    display: flex;
    align-items: flex-end;
    padding: clamp(48px, 8vw, 96px) 0;
    color: #ffffff;
    overflow: hidden;
    background: var(--indo-navy, #121c22);
}
.indo-pillar-hero__media {
    position: absolute;
    inset: 0;
    z-index: 0;
}
.indo-pillar-hero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 40%;
    display: block;
}
.indo-pillar-hero__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(18, 28, 34, 0.55) 0%,
        rgba(18, 28, 34, 0.35) 35%,
        rgba(18, 28, 34, 0.85) 100%
    );
}
.indo-pillar-hero__inner {
    position: relative;
    z-index: 1;
    padding: 0 clamp(20px, 4vw, 40px);
    max-width: 760px;
}
.indo-pillar-hero__eyebrow {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
    margin: 0 0 16px;
}
.indo-pillar-hero__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(40px, 6vw, 72px);
    line-height: 1.05;
    letter-spacing: -0.01em;
    color: #ffffff;
    margin: 0 0 20px;
}
.indo-pillar-hero__lede {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: clamp(17px, 1.6vw, 20px);
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.92);
    max-width: 640px;
    margin: 0 0 32px;
}
.indo-pillar-hero__cta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
}

/* ---------------- BUTTONS (shared with CTA band) -------------------------- */
.indo-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 14px 28px;
    border-radius: 999px;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-decoration: none;
    border: 1px solid transparent;
    transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
    cursor: pointer;
    white-space: nowrap;
}
.indo-btn--primary {
    background: var(--indo-cyan, #00a6db);
    color: #ffffff;
    border-color: var(--indo-cyan, #00a6db);
}
/* Mouse-only focus (no :focus-visible) = idle look. Defends against
 * reset.css's `button:focus { background: #cc3366 }` which would otherwise
 * paint the button red after our modal restores focus to the trigger. */
.indo-btn--primary:focus {
    background: var(--indo-cyan, #00a6db);
    border-color: var(--indo-cyan, #00a6db);
    color: #ffffff;
    outline: none;
    transform: none;
}
.indo-btn--primary:hover,
.indo-btn--primary:focus-visible {
    background: var(--indo-cyan-light, #00acea);
    border-color: var(--indo-cyan-light, #00acea);
    color: #ffffff;
    transform: translateY(-1px);
}
/* revert 20260501-1430: brand cyan #00a6db is authoritative on the in-content "Request a quote" pill — Tom directive. AA contrast for white-on-cyan must be remediated by label-size/weight or navy-text-on-cyan, NEVER by darkening brand cyan. */
.indo-btn--ghost {
    background: transparent;
    color: var(--indo-charcoal, #212121);
    border-color: rgba(33, 33, 33, 0.4);
}
.indo-btn--ghost:hover,
.indo-btn--ghost:focus-visible {
    border-color: var(--indo-cyan, #00a6db);
    color: var(--indo-cyan, #00a6db);
}
.indo-btn--ghost.indo-btn--light,
.indo-pillar-hero .indo-btn--ghost {
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.55);
}
.indo-btn--ghost.indo-btn--light:hover,
.indo-pillar-hero .indo-btn--ghost:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: #ffffff;
    color: #ffffff;
}
.indo-btn--large {
    padding: 18px 36px;
    font-size: 16px;
}

/* ---------------- STATS STRIP --------------------------------------------- */
.indo-stats-strip {
    background: var(--indo-light, #f4f4f4);
    padding: clamp(40px, 6vw, 72px) clamp(16px, 4vw, 40px);
    border-bottom: 1px solid rgba(33, 33, 33, 0.06);
}
.indo-stats-strip__row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(24px, 4vw, 48px);
    align-items: start;
}
.indo-stat {
    text-align: left;
}
.indo-stat__num {
    display: block;
    font-family: "Manrope", "Lexend Deca", sans-serif;
    font-weight: 700;
    font-size: clamp(56px, 7vw, 88px);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--indo-cyan, #00a6db);
}
.indo-stat__num-unit {
    display: inline-block;
    margin-left: 8px;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 400;
    font-size: clamp(28px, 3vw, 40px);
    letter-spacing: 0;
    color: var(--indo-charcoal, #212121);
    vertical-align: baseline;
}
.indo-stat__label {
    display: block;
    margin-top: 12px;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    line-height: 1.5;
    color: var(--indo-charcoal, #212121);
    max-width: 28ch;
}

/* ---------------- SECTION (light/dark variants) --------------------------- */
.indo-pillar-section {
    padding: clamp(64px, 8vw, 112px) clamp(16px, 4vw, 40px);
}
.indo-pillar-section--light {
    background: #ffffff;
    color: var(--indo-charcoal, #212121);
}
.indo-pillar-section--dark {
    background: var(--indo-navy, #121c22);
    color: #ffffff;
}
.indo-pillar-section__head {
    max-width: 760px;
    margin: 0 0 clamp(40px, 5vw, 64px);
}
.indo-pillar-section__head--row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    max-width: none;
}
.indo-pillar-section__eyebrow {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--indo-gray, #abafb5);
    margin: 0 0 14px;
}
.indo-pillar-section__eyebrow--light {
    color: rgba(255, 255, 255, 0.7);
}
.indo-pillar-section__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(30px, 4vw, 48px);
    line-height: 1.1;
    letter-spacing: -0.005em;
    color: var(--indo-charcoal, #212121);
    margin: 0 0 16px;
}
.indo-pillar-section__title--light {
    color: #ffffff;
}
.indo-pillar-section__lede {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: clamp(16px, 1.4vw, 18px);
    line-height: 1.6;
    color: rgba(33, 33, 33, 0.78);
    max-width: 680px;
    margin: 0;
}

/* ---------------- RANGE GRID ---------------------------------------------- */
.indo-range-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(20px, 2.5vw, 32px);
}
.indo-range-card {
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border: 1px solid rgba(33, 33, 33, 0.08);
    border-radius: 4px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}
.indo-range-card:hover,
.indo-range-card:focus-visible {
    transform: translateY(-4px);
    box-shadow: 0 16px 48px rgba(33, 33, 33, 0.1);
    border-color: rgba(0, 166, 219, 0.4);
}
.indo-range-card__media {
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: #f0f1f3;
}
.indo-range-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.4s ease;
}
.indo-range-card:hover .indo-range-card__media img {
    transform: scale(1.04);
}
.indo-range-card__body {
    padding: clamp(20px, 2vw, 28px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1;
}
.indo-range-card__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 300;
    font-size: clamp(22px, 2vw, 28px);
    line-height: 1.2;
    color: var(--indo-charcoal, #212121);
    margin: 0;
}
.indo-range-card__copy {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 15px;
    line-height: 1.55;
    color: rgba(33, 33, 33, 0.72);
    margin: 0;
}
.indo-range-card__cta {
    margin-top: auto;
    padding-top: 8px;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--indo-cyan, #00a6db);
}
.indo-range-card:hover .indo-range-card__cta {
    color: var(--indo-cyan-light, #00acea);
}

/* ---------------- PROJECTS STRIP ------------------------------------------ */
.indo-pillar-projects {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(20px, 2.5vw, 32px);
}
.indo-pillar-project {
    margin: 0;
}
.indo-pillar-project__link {
    display: block;
    text-decoration: none;
    color: #ffffff;
}
.indo-pillar-project__media {
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 4px;
    margin: 0 0 16px;
}
.indo-pillar-project__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.4s ease, opacity 0.2s ease;
    opacity: 0.92;
}
.indo-pillar-project__link:hover .indo-pillar-project__media img,
.indo-pillar-project__link:focus-visible .indo-pillar-project__media img {
    transform: scale(1.04);
    opacity: 1;
}
.indo-pillar-project__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 300;
    font-size: clamp(18px, 1.6vw, 22px);
    line-height: 1.3;
    color: #ffffff;
    margin: 0;
}

/* ---------------- WHY INDO GRID ------------------------------------------- */
.indo-pillar-section--why {
    background: #f8f9fa;
}
.indo-why-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(28px, 3vw, 48px);
}
.indo-why-cell {
    padding: 0;
}
.indo-why-cell__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 400;
    font-size: clamp(18px, 1.6vw, 22px);
    line-height: 1.3;
    color: var(--indo-charcoal, #212121);
    margin: 0 0 14px;
    padding-top: 24px;
    border-top: 2px solid var(--indo-cyan, #00a6db);
}
.indo-why-cell__copy {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 15px;
    line-height: 1.65;
    color: rgba(33, 33, 33, 0.78);
    margin: 0;
}

/* ---------------- CTA BAND ------------------------------------------------ */
.indo-cta-band {
    background: var(--indo-navy, #121c22);
    color: #ffffff;
    padding: clamp(72px, 9vw, 120px) clamp(16px, 4vw, 40px);
    text-align: center;
}
.indo-cta-band__inner {
    max-width: 760px;
}
.indo-cta-band__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(28px, 3.5vw, 44px);
    line-height: 1.15;
    color: #ffffff;
    margin: 0 0 18px;
}
.indo-cta-band__lede {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: clamp(16px, 1.4vw, 18px);
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.85);
    margin: 0 0 32px;
}

/* ---------------- RESPONSIVE ---------------------------------------------- */
@media (max-width: 900px) {
    .indo-stats-strip__row,
    .indo-range-grid,
    .indo-pillar-projects,
    .indo-why-grid {
        grid-template-columns: 1fr;
    }
    .indo-pillar-section__head--row {
        align-items: flex-start;
    }
    .indo-pillar-hero {
        min-height: clamp(380px, 70vh, 540px);
    }
}
@media (max-width: 600px) {
    .indo-pillar-hero__cta {
        flex-direction: column;
        align-items: stretch;
    }
    .indo-btn {
        justify-content: center;
    }
}
/* ===== END INDO PILLAR PAGES ============================================== */

/* ============================================================================
 * INDO PILLAR PAGES — ELEMENTOR WRAPPER RESET (Phase E, 2026-05-05)
 *
 * The pillar pages now render through the bespoke INDO pillar widgets
 * (Indo_Pillar_Hero_Widget etc) inside Elementor sections. Each widget
 * outputs a full-bleed <section class="indo-pillar-*">, but Elementor's
 * default .elementor-section-boxed + column padding constrains the
 * widget container to ~1324px on a 1440 viewport, breaking the edge-bleed.
 *
 * Rule: when a body has elementor-page-17989 OR elementor-page-17285,
 * zero out the Elementor section/column/widget paddings + max-widths so
 * the bespoke <section> tags fill the viewport, exactly matching the
 * pre-Phase-E layout. Internal width is owned by .indo-container as
 * before.
 * ============================================================================ */
body.elementor-page-17989 .elementor-section.elementor-top-section,
body.elementor-page-17285 .elementor-section.elementor-top-section,
body.elementor-page-17989 main .elementor-section.elementor-top-section,
body.elementor-page-17285 main .elementor-section.elementor-top-section {
    padding: 0 !important;
    margin: 0 !important;
}
body.elementor-page-17989 .elementor-section.elementor-top-section > .elementor-container,
body.elementor-page-17285 .elementor-section.elementor-top-section > .elementor-container {
    max-width: none !important;
    width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
}
body.elementor-page-17989 .elementor-section.elementor-top-section .elementor-column,
body.elementor-page-17285 .elementor-section.elementor-top-section .elementor-column {
    padding: 0 !important;
}
body.elementor-page-17989 .elementor-section.elementor-top-section .elementor-widget,
body.elementor-page-17285 .elementor-section.elementor-top-section .elementor-widget {
    margin-bottom: 0 !important;
}
body.elementor-page-17989 .elementor-section.elementor-top-section .elementor-widget > .elementor-widget-container,
body.elementor-page-17285 .elementor-section.elementor-top-section .elementor-widget > .elementor-widget-container {
    padding: 0 !important;
}
/* Project rotator: force images to fill the aspect-ratio'd media box.
 * Inside Elementor wrappers some upstream rule was collapsing img height
 * to 0 (height: auto on a max-width:100% img inside a flex/aspect box). */
body.elementor-page-17989 .indo-pillar-project__media img,
body.elementor-page-17285 .indo-pillar-project__media img,
body.elementor-page-17989 .indo-range-card__media img,
body.elementor-page-17285 .indo-range-card__media img,
body.elementor-page-17989 .indo-pillar-hero__media img,
body.elementor-page-17285 .indo-pillar-hero__media img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    display: block !important;
}

/* Industrium child theme has a "fontHelp" CSS rule:
 *   .elementor-element h3, .elementor-image-box-title { color: rgb(33,33,33); font-weight:300 !important; }
 * It wins over the pillar's white-on-dark .indo-pillar-project__title rule
 * because .elementor-element h3 has the same specificity (0,1,1) and
 * appears later in the cascade. Force pillar headings on dark backgrounds
 * back to white for these two pages.
 */
body.elementor-page-17989 .indo-pillar-section--dark .indo-pillar-project__title,
body.elementor-page-17285 .indo-pillar-section--dark .indo-pillar-project__title,
body.elementor-page-17989 .indo-pillar-section--dark .indo-pillar-section__title--light,
body.elementor-page-17285 .indo-pillar-section--dark .indo-pillar-section__title--light,
body.elementor-page-17989 .indo-pillar-hero__title,
body.elementor-page-17285 .indo-pillar-hero__title,
body.elementor-page-17989 .indo-cta-band__title,
body.elementor-page-17285 .indo-cta-band__title {
    color: #ffffff !important;
}

/* ============================================================================
 * HOMEPAGE PROJECTS-LISTING SLIDER (2026-05-01)
 *
 * Root-cause history: the homepage projects slider (Elementor widget
 * 3e20dcf in section 9e0df2f) was previously saved with `view_type: type-2`
 * — Industrium's "luxury showroom" mode. That single setting pulls in:
 *   - <img class="owl-stage-bg"> (a stage-wide backdrop of the active
 *     slide's image at natural ~1280×960 size that overflows any compact
 *     container)
 *   - <span class="slide-counter-big">, <span class="content-alt">,
 *     <span class="button-container"> with "More about project"
 *   - clip-path: inset(100% 0 0 0) entrance animation on
 *     .project-item-content (which is what was hiding the title)
 *   - oversized vertical layout (~817px per tile)
 * We were fighting all of those with !important overrides. Switching the
 * widget's `view_type` to `type-1` removes the source of every one of
 * those symptoms (the template at content-industrium_project.php is
 * gated on $view_type), so this stylesheet doesn't have to.
 *
 * What's left below is genuine polish that applies regardless of view_type:
 *   - dot styling (industrium-plugin's default dots have a pink border)
 *   - heading word-spacing on the section's H2
 *   - "View all projects" SVG arrow positioning
 * ============================================================================ */

/* DISABLE industrium's view-type-1 hover-reveal pattern.
 *
 * industrium/css/theme.css line 13086 puts .project-item-media into a
 * default-hidden state — opacity:0, clip-path:inset(0 100% 0 0),
 * position:absolute, top:-35px, height:113% — and only reveals it on
 * link hover (lines 13076-13080). That's industrium's intentional
 * "showroom" UX for project galleries: the thumbnail wipes in from
 * the left when you hover the card.
 *
 * On our homepage 3-up project strip we want thumbnails visible
 * always, with a normal hover-zoom effect. So:
 *   1. Reset the default-hidden state (opacity, clip-path, positioning)
 *   2. Pin media to position: relative with a fixed image-strip height
 *      so the layout doesn't depend on the natural image aspect ratio
 *   3. Make the IMG fill the constrained media box via object-fit cover
 *
 * That single block replaces ~10 separate symptom-overrides and is the
 * actual root-cause fix for the hidden-images / runaway-tile-height
 * problems. */
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item .project-item-media {
    position: relative;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: clamp(200px, 16vw, 260px);
    min-width: 0;
    overflow: hidden;
    opacity: 1;
    clip-path: none;
    -webkit-clip-path: none;
    pointer-events: auto;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 4px;
    margin: 0 0 16px 0;
}
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item .project-item-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
    opacity: 1;
}
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item:hover .project-item-media img {
    transform: scale(1.04);
}

/* Title under the image — industrium defaults it to 30px cyan with a
 * hover colour-flip to white. Pull back to a sensible card-title size
 * in Lexend Deca, always white. */
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item .post-title,
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item .post-title span,
body.home .elementor-element-9e0df2f .project-slider-listing .slider-item .post-title a {
    color: #ffffff;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 300;
    font-size: clamp(15px, 1.3vw, 18px);
    line-height: 1.3;
    letter-spacing: 0;
    margin: 0;
}

/* Pagination dots — industrium-plugin ships them with a 10px-padded box +
 * pink (rgb(204, 51, 102)) 1px border. Replace with simple INDO cyan
 * circles. */
/* Stack the "View all projects" button above the dots (industrium-plugin
 * lays them out side-by-side via inline-block on .pagination_wrapper,
 * which puts the dot row to the right of the button and tight against
 * its bottom border). Convert pagination_wrapper to a vertical flex
 * stack so the button sits on its own line, dots below with a real gap. */
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .pagination_wrapper {
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 24px !important;
}

/* Top-align the headline cluster with the big counter on the right.
 * The counter sits in an inner section that gets pulled up via
 * Elementor inline margin (~150px); the heading wrapper inside the
 * projects-listing widget lands ~64px lower than the counter top.
 * Lift the heading visually with position:relative + matching
 * margin-bottom so the slider doesn't shift up too. */
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-heading {
    position: relative;
    top: -64px;
    margin-bottom: 0 !important;
}
/* Reduce heading max-width so it stops crashing into the counter
 * column on the right. Was 60% (768px at 1280 container) — heading
 * literally overlapped the counter's left edge.
 *
 * Use calc(50% - 90px) instead of a flat % so the clearance from the
 * counter is constant regardless of viewport width. Flat 48% worked
 * at ≥1300px but at ~1160px the gap collapsed to ~30px and the
 * heading visually crashed into the "4,700+". */
body.home .elementor-element-9e0df2f .industrium-heading {
    max-width: calc(50% - 90px) !important;
}

/* Counter alignment fix: the counter widget afa2bdd sits flush-LEFT
 * inside its inner column. As the counter animates from 0 → 4,700 the
 * widget grows wider; the column is only 50% of the section so even
 * right-aligned the widget's left edge crashes into the heading column
 * at narrower viewports.
 *
 * Two-tier strategy:
 *   - DESKTOP (≥1280px): right-align the widget within its column +
 *     reduce font-size so the widget fits comfortably to the right of
 *     the heading.
 *   - SUB-DESKTOP (<1280px): give up on side-by-side and stack the
 *     counter ABOVE the heading via order: -1 on the heading section,
 *     restoring full-width to the heading and centring the counter.
 *
 * This is cleaner than chasing column widths at every breakpoint. */

/* Desktop right-align (always applied; the inner column's
 * justify-content:flex-end takes effect when there's enough room). */
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd {
    margin-left: auto !important;
    margin-right: 0 !important;
    width: -moz-fit-content;
    width: fit-content;
    max-width: 100% !important;
}
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-number-wrapper,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-title {
    text-align: right !important;
}
body.home .elementor-element-9e0df2f .elementor-element-30ed23b > .elementor-widget-wrap,
body.home .elementor-element-9e0df2f .elementor-element-30ed23b > .elementor-element-populated > .elementor-widget-wrap {
    justify-content: flex-end !important;
    align-items: flex-end !important;
}

/* STACK at all widths (per user 2026-05-01 — the side-by-side
 * heading+counter layout was clashing at every breakpoint between
 * ~1100px and ~1400px because the counter's own inner column starts
 * at ~50% of the section and the heading column extends past 50%
 * regardless of font-size tricks). Switch to the tablet-style stacked
 * layout universally:
 *   1. Counter renders ABOVE heading (natural document order — the
 *      Elementor inner section containing the counter sits above the
 *      projects-listing widget; we just remove the -150px lift that
 *      was pulling them into visual side-by-side).
 *   2. Heading + button + dots all left-aligned, full container width.
 *   3. Counter left-aligned (same column rhythm as the heading below). */

/* Remove the -150px margin Elementor injects on the projects-listing
 * widget. Without it, the heading naturally sits below the counter
 * inner section instead of overlapping it. */
body.home .elementor-element-9e0df2f .elementor-element-3e20dcf > .elementor-widget-container {
    margin-top: 0 !important;
}
/* Reset heading max-width — full container width. */
body.home .elementor-element-9e0df2f .industrium-heading {
    max-width: 100% !important;
}
/* Reset the heading lift — no more counter to top-align with. */
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-heading {
    top: 0 !important;
}
/* Counter widget back to default left alignment in its column. */
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd {
    margin-left: 0 !important;
    margin-right: 0 !important;
}
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-number-wrapper,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-title {
    text-align: left !important;
}
body.home .elementor-element-9e0df2f .elementor-element-30ed23b > .elementor-widget-wrap,
body.home .elementor-element-9e0df2f .elementor-element-30ed23b > .elementor-element-populated > .elementor-widget-wrap {
    justify-content: flex-start !important;
    align-items: flex-start !important;
}
/* Counter inner column was sized 50% (col-50) to host the side-by-
 * side layout; with stacking, expand to full width so the counter
 * left-edge lines up with the heading left-edge. */
body.home .elementor-element-9e0df2f .elementor-element-30ed23b {
    width: 100% !important;
    max-width: 100% !important;
    flex: 1 1 100% !important;
}
/* The original side-by-side layout had a SIBLING empty column (d438bd1)
 * to the LEFT of the counter column, acting as a 50%-wide spacer that
 * left room for the heading visually. With the counter now stacked,
 * that empty spacer just shoves the counter right by its own width
 * (~340px) which breaks left-alignment with the heading. Collapse it
 * to zero so the counter column starts at the section's left edge. */
body.home .elementor-element-9e0df2f .elementor-element-d438bd1 {
    display: none !important;
}
/* Inner section that holds the counter has a 40px horizontal container
 * padding which leaves the counter ~50px right of where the heading
 * starts. Strip that padding + any column padding so both share the
 * same left edge. */
body.home .elementor-element-9e0df2f .elementor-element-cc1ee49 > .elementor-container {
    padding-left: 0 !important;
    padding-right: 0 !important;
}
body.home .elementor-element-9e0df2f .elementor-element-30ed23b > .elementor-element-populated {
    padding-left: 0 !important;
    margin-left: 0 !important;
}

/* === SIDE-BY-SIDE FINAL (per user 2026-05-01) ============================
 * Heading on LEFT, counter on RIGHT, tops aligned, no overlap at any
 * viewport. Counter is absolute-positioned relative to the SECTION,
 * pinned to its top-right padding-box corner.
 *
 * Gotcha caught the first iteration: every Elementor ancestor between
 * the counter widget and the section has `position: relative`, which
 * makes the CLOSEST one the offsetParent (so top:135 was landing at
 * widget-wrap.top + 135, not at section-top + 135). To put the counter
 * at the section's top-right corner, neutralise position on every
 * intermediate ancestor of the counter widget so the section becomes
 * the offsetParent. */

/* Section is the positioning context. */
body.home .elementor-element-9e0df2f {
    position: relative !important;
}
/* Make the OUTER .elementor-container the counter widget's offsetParent
 * so `right: 0` lands exactly on the container's right edge at every
 * viewport (no formula needed; the container itself already handles
 * the max-width:1280 cap + auto-centring). The structure is:
 *   section .9e0df2f
 *     > container .elementor-container          ← counter's offsetParent
 *       > column .f4fdaa8 > widget-wrap
 *         > inner section .cc1ee49 > container > column .30ed23b
 *           > widget-wrap > counter widget .afa2bdd
 * Outer container = position:relative; every wrapper between it and
 * the counter = position:static so the container stays the closest
 * positioned ancestor. */
body.home .elementor-element-9e0df2f > .elementor-container {
    position: relative !important;
}
body.home .elementor-element-9e0df2f > .elementor-container > .elementor-column,
body.home .elementor-element-9e0df2f > .elementor-container > .elementor-column > .elementor-widget-wrap,
body.home .elementor-element-9e0df2f .elementor-element-cc1ee49,
body.home .elementor-element-9e0df2f .elementor-element-cc1ee49 > .elementor-container,
body.home .elementor-element-9e0df2f .elementor-element-cc1ee49 .elementor-column,
body.home .elementor-element-9e0df2f .elementor-element-cc1ee49 .elementor-widget-wrap {
    position: static !important;
}
/* Counter widget: anchored to the OUTER container's top-right corner.
 * `right: 0` aligns with container right edge automatically. `top` is
 * the offset from container top to where the counter's number-baseline
 * should sit; ~30px accounts for Manrope's taller x-height vs Lexend
 * Deca so the rendered "6" tops the rendered "S" of "Successfully". */
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd {
    position: absolute !important;
    top: clamp(28px, 2.5vw, 38px) !important;
    right: 0 !important;
    width: -moz-fit-content !important;
    width: fit-content !important;
    max-width: 50% !important;
    margin: 0 !important;
    z-index: 5;
}
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-number-wrapper,
body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-title {
    text-align: right !important;
}
/* Heading: cap at 50% so it stays clear of the absolute counter, AND
 * push to the container's LEFT edge (the H2 had auto horizontal
 * margins from industrium-plugin which centred it inside the widget
 * container — that put the heading 335px right of the container's
 * left edge). margin-left: 0 + margin-right: auto pins it left. */
body.home .elementor-element-9e0df2f .industrium-heading {
    max-width: calc(50% - 30px) !important;
    margin-left: 0 !important;
    margin-right: auto !important;
}
/* === END SIDE-BY-SIDE FINAL ========================================== */

body.home .elementor-element-9e0df2f .owl-dots {
    display: flex !important;
    gap: 8px !important;
    align-items: center;
    justify-content: flex-start;
    /* Margin reset to 0 since the pagination_wrapper now provides the
     * spacing via gap. */
    margin: 0 !important;
}
body.home .elementor-element-9e0df2f .owl-dots .owl-dot {
    border: 0 !important;
    background: transparent !important;
    padding: 6px !important;
    width: auto !important;
    height: auto !important;
}
body.home .elementor-element-9e0df2f .owl-dots .owl-dot span {
    display: block !important;
    width: 8px !important;
    height: 8px !important;
    border-radius: 50% !important;
    background: rgba(255, 255, 255, 0.3) !important;
    border: 0 !important;
    margin: 0 !important;
    transition: background 0.18s ease, transform 0.18s ease;
}
body.home .elementor-element-9e0df2f .owl-dots .owl-dot.active span {
    background: var(--indo-cyan, #00a6db) !important;
    transform: scale(1.4);
}
body.home .elementor-element-9e0df2f .owl-dots .owl-dot:hover span,
body.home .elementor-element-9e0df2f .owl-dots .owl-dot:focus-visible span {
    background: rgba(255, 255, 255, 0.6) !important;
}

/* "Successfully completed projects for our clients" — Lexend Deca thin
 * 200 carries a -0.01em letter-spacing default that reads packed on
 * normal-case copy. Relax letter-spacing and add a small word-spacing. */
body.home .elementor-element-9e0df2f .industrium-heading,
body.home .elementor-element-9e0df2f .industrium-heading .industrium-heading-content {
    letter-spacing: 0 !important;
    word-spacing: 0.06em !important;
    line-height: 1.18 !important;
}

/* "View all projects" CTA — industrium-plugin pins the SVG arrow with
 * position: absolute against the button's right border. Pull it into
 * flex flow so the button's gap + padding actually apply. */
/* "View all projects" CTA — match the ABOUT US button style from the
 * About INDO segment above (2px outline, 4px corner radius, generous
 * padding, uppercase text, centred text + diagonal arrow on the right)
 * but keep the white-on-dark colour scheme this navy section needs.
 *
 * Current button is industrium-projects-listing's pagination button: an
 * <a class="industrium-button"> with an inline SVG chevron-right child.
 * We hide the SVG and render a Unicode diagonal-arrow (↗) via ::after,
 * sized + spaced to match the icon-font glyph the ABOUT US button uses. */
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 24px !important;
    min-width: 240px !important;
    padding: 16px 28px !important;
    border: 2px solid #ffffff !important;
    border-radius: 4px !important;
    background: transparent !important;
    color: #ffffff !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    letter-spacing: 0.06em !important;
    text-transform: uppercase !important;
    text-decoration: none !important;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button:hover,
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button:focus-visible {
    background: rgba(255, 255, 255, 0.08) !important;
    border-color: #ffffff !important;
    color: #ffffff !important;
}
/* Hide the inline SVG chevron — replaced by a diagonal-arrow ::after
 * that matches the ABOUT US button's icon-font glyph. */
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button svg {
    display: none !important;
}
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button::after {
    content: "\2197"; /* ↗ NORTH EAST ARROW */
    /* Reset the upstream industrium-legacy positioning (theme.css line
     * 9514 sets .industrium-button:after to position:absolute; right:0;
     * which pins the arrow to the button's right border, ignoring our
     * padding). Force the arrow back into normal flex flow so the
     * button's `padding-right` and `gap` actually create breathing room
     * between the arrow and the right edge. */
    position: static !important;
    top: auto !important;
    right: auto !important;
    transform: none !important;
    margin: 0 !important;
    display: inline-block !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 18px !important;
    line-height: 1 !important;
    font-weight: 400 !important;
    color: inherit !important;
    transition: transform 0.2s ease !important;
}
body.home .elementor-element-9e0df2f .industrium-projects-listing-widget .industrium-button:hover::after {
    transform: translate(2px, -2px) !important;
}

/* ===== END HOMEPAGE PROJECTS-LISTING SLIDER ============================== */

/* ===== CALL-BACK MODAL ====================================================
 * Lightbox triggered by [data-indo-callback-open]. Replaces the legacy
 * single-product "Request a quote" link that pointed at /contact-us/ (404).
 * Pattern mirrors .indo-search-overlay (header.php) — backdrop + centered
 * white panel with cyan submit. Markup in inc/callback-modal.php.
 * ======================================================================== */
.indo-callback-modal[hidden] { display: none !important; }
body.indo-callback-open { overflow: hidden; }

.indo-callback-modal {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.indo-callback-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(18, 28, 34, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.indo-callback-modal__panel {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 480px;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    background: #ffffff;
    border-radius: 18px;
    box-shadow: 0 24px 56px rgba(18, 28, 34, 0.32);
    padding: 36px 32px 28px;
    color: var(--indo-charcoal, #212121);
}
.indo-callback-modal__close {
    position: absolute;
    top: 12px;
    right: 14px;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--indo-charcoal, #212121);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    border-radius: 50%;
    transition: background 0.15s ease;
    /* Flex centering — defeats reset.css's 0.5rem 1rem padding inheritance
     * which otherwise pushes the × off the centre of the hover circle. */
    display: flex;
    align-items: center;
    justify-content: center;
}
.indo-callback-modal__close:hover,
.indo-callback-modal__close:focus-visible {
    background: rgba(0, 0, 0, 0.06);
    outline: none;
}
.indo-callback-modal__title {
    font-family: var(--indo-font-display, "Lexend Deca", system-ui, sans-serif);
    font-weight: 200;
    font-size: 28px;
    line-height: 1.2;
    margin: 0 0 8px;
    color: var(--indo-charcoal, #212121);
}
.indo-callback-modal__lede {
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif);
    font-size: 14px;
    line-height: 1.5;
    color: #4a4a4a;
    margin: 0 0 20px;
}

.indo-callback-form__field {
    margin: 0 0 14px;
}
.indo-callback-form__field label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--indo-charcoal, #212121);
    margin-bottom: 6px;
    letter-spacing: 0.01em;
}
.indo-callback-form__field input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 11px 14px;
    font: inherit;
    font-size: 15px;
    color: var(--indo-charcoal, #212121);
    background: #fafafa;
    border: 1px solid #d8dadd;
    border-radius: 10px;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.indo-callback-form__field input:focus-visible {
    outline: none;
    border-color: var(--indo-cyan, #00a6db);
    background: #ffffff;
}
.indo-callback-form__field.has-error input {
    border-color: #c0392b;
    background: #fff5f4;
}

.indo-callback-form__hp {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.indo-callback-form__actions {
    margin: 18px 0 0;
}
.indo-callback-form__submit {
    width: 100%;
    justify-content: center;
}
.indo-callback-form__submit:disabled {
    opacity: 0.65;
    cursor: progress;
}

.indo-callback-form__status {
    margin: 12px 0 0;
    font-size: 13px;
    line-height: 1.4;
    min-height: 1.4em;
    color: #4a4a4a;
}
.indo-callback-form__status.is-success { color: #1f7a3a; }
.indo-callback-form__status.is-error   { color: #c0392b; }
.indo-callback-form__status.is-pending { color: #4a4a4a; }

@media (max-width: 480px) {
    .indo-callback-modal { padding: 12px; }
    .indo-callback-modal__panel { padding: 30px 22px 22px; border-radius: 14px; }
    .indo-callback-modal__title { font-size: 24px; }
}

/* ===== END CALL-BACK MODAL ============================================== */

/* fix-cluster-blog-exterior-lighting-005 20260501-1110: shrink .indo-floater to 64x64 + tighten inset + add 96px bottom-padding to main content at <=480px so it stops overlapping cards/bullets/copy [closes 20 entries: blog-exterior-lighting-005, category-blog-007, category-clippings-007, customer-feedback-007, direct-drive-006, product-blade-core-005, product-blade-max-005, product-category-led-retrofit-lamps-005, product-category-lighting-for-rail-004, product-category-luminaires-004, product-category-major-minor-road-lighting-006, product-category-top-light-005, product-chancery-005, product-hortilink-004, product-lpsx-002, product-lpsx-004, product-plue-002, product-vertilink-005, projects-autopot-005, projects-cardiff-university-004] */
@media (max-width: 480px) {
    body .indo-floater {
        width: 64px !important;
        height: 64px !important;
        right: 12px !important;
        bottom: 12px !important;
        font-size: 10px !important;
        line-height: 1.15 !important;
    }
    body main,
    body .site-main,
    body .content-area,
    body .entry-content {
        padding-bottom: 96px;
    }
}

/* ============================================================================
 * cluster-5-lowercase-headings REVERSED 20260501
 *
 * Tom directive: "We want to use proper capitalisation" on all headings.
 * The cluster-5-lowercase-headings block from earlier 2026-05-01 has been
 * reversed: text-transform: lowercase removed from headings, captions, and
 * specific page H1s. Font/weight/size/color rules retained.
 * Per indo_brand_voice.md: every heading must start with a capital letter.
 * ====================================================================== */

/* Retained: WC tabs panel H2 font treatment (font/weight/size only). */
body[class][class][class][class] .woocommerce-Tabs-panel h2,
body[class][class][class][class] .woocommerce-Tabs-panel--description h2,
body[class][class][class][class] .woocommerce-Tabs-panel--additional_information h2 {
    font-family: var(--indo-font-display) !important;
    font-weight: 200 !important;
    font-size: clamp(28px, 3.5vw, 40px) !important;
    margin-bottom: 16px !important;
}

/* Retained: /request-quote/ Lexend Deca treatment (font/weight only). */
body.page-id-16554 h1,
body.page-id-16554 .entry-title,
body[class][class][class][class].page-id-16554 h1,
body[class][class][class][class].page-id-16554 .entry-title {
    font-family: 'Lexend Deca', system-ui, sans-serif !important;
    font-weight: 200 !important;
}

/* Retained: /catalogues/ caption Lexend Deca styling (font/weight/size/color only). */
body.page-id-17374 .widget-image-caption,
body[class][class][class][class].page-id-17374 .widget-image-caption {
    font-style: normal !important;
    font-family: 'Lexend Deca', system-ui, sans-serif !important;
    font-weight: 200 !important;
    font-size: clamp(20px, 2vw, 28px) !important;
    color: #212121 !important;
    margin-top: 16px !important;
    text-align: left !important;
}
/* ===== END cluster-5-lowercase-headings REVERSED ============================ */

/* ===== indo-project-video (self-hosted MP4 in single project content) ===== */
/* Embedded customer-interview videos on /projects/<slug>/ pages.
   Replaces legacy YouTube `project_button` postmeta links with HTML5 <video>. */
.indo-project-video {
    margin: clamp(24px, 4vw, 48px) 0;
    max-width: 100%;
}
.indo-project-video video {
    width: 100%;
    height: auto;
    display: block;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: 4px;
}
.indo-project-video figcaption {
    margin-top: 8px;
    font-size: 14px;
    color: #595959;
    line-height: 1.4;
}

/* ===== HOMEPAGE HERO VIDEO 2026-05-01 =====
   The .indo-hp-hero block is injected by mu-plugin
   indo-homepage-hero-video.php at body-open. It flows normally as the
   first visible block on the homepage and replaces the Elementor first
   section (whose only content was a static M2-Logo image with the INDO
   wordmark baked in — both now redundant, so the section is hidden).
   The INDO wordmark is composited back in as a white-outline PNG
   centred over the roundabout in the drone footage.
   ============================================================ */
.indo-hp-hero {
    position: relative;
    width: 100%;
    /* True cinema letterbox 2.40:1 (12:5). Source videos are encoded at
     * 1920×800 to match — no cover-crop, full intended composition shows
     * through. max-height caps it on tall narrow viewports so the hero
     * doesn't become a sliver on very portrait-aspect screens. */
    aspect-ratio: 12 / 5;
    max-height: 90vh;
    overflow: hidden;
    background: var(--indo-navy, #121c22);
    margin: 0;
}
@media (max-width: 767px) {
    /* Mobile keeps a vh-based height — at 2.40:1 a 375px-wide phone
     * would give a 156px-tall hero which is too pancake. Use a fixed
     * vh and let object-fit: cover crop the sides on portrait screens. */
    .indo-hp-hero {
        aspect-ratio: auto;
        height: 50vh;
    }
}
.indo-hp-hero__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    z-index: 0;
}
/* Per-hero darkening overlay + brightness control, both modulated over
 * the clip's playback time via JS reading dim_schedule keyframes.
 *
 * Default opacity is 0 — heroes that don't explicitly schedule the
 * overlay (i.e. all-night footage like Bournemouth) get no overlay.
 * Daytime/transition heroes (e.g. M2 Medway) ramp the opacity up
 * during their bright sections + back down through the day-to-night
 * transition. Brightness defaults to 1.0; nighttime sections that look
 * a bit too dark can be lifted slightly via the same schedule.
 *
 * Schedule format: [[time_s, overlay_opacity, brightness], …] linear
 * interpolation between keyframes. Set per-hero in the mu-plugin
 * registry (indo_get_homepage_heroes()). */
.indo-hp-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0.20) 0%, rgba(0,0,0,0.45) 100%);
    pointer-events: none;
    z-index: 1;
    opacity: var(--indo-hp-dim-opacity, 0);
    transition: opacity 0.4s linear;
}
.indo-hp-hero__video {
    filter: brightness(var(--indo-hp-video-brightness, 1));
    transition: filter 0.4s linear;
}
/* INDO wordmark — position is per-hero, set inline via CSS custom
 * properties on .indo-hp-hero so each clip can put the wordmark over
 * its own focal point (the roundabout, the bridge midspan, etc).
 * Defaults to dead-centre if the hero doesn't override. */
.indo-hp-hero__wordmark {
    position: absolute;
    left: var(--indo-hp-wordmark-left, 50%);
    top: var(--indo-hp-wordmark-top, 50%);
    transform: translate(-50%, -50%);
    width: clamp(180px, 22vw, 360px);
    height: auto;
    z-index: 2;
    pointer-events: none;
    filter: drop-shadow(0 2px 12px rgba(0,0,0,0.4));
}

/* Hide the original Elementor first section — its M2-Logo image
 * (with wordmark baked in) is now replaced by .indo-hp-hero. Using
 * display:none so the section collapses fully and there's no
 * dead whitespace below the video before the next section. */
body.home .elementor-element-0dacabb {
    display: none !important;
}

/* Hero CTA — "Request a call back" (INDO Marketing plan item 24,
 * 2026-07-26). Rendered by mu-plugin indo-homepage-hero-video.php as the
 * hero's only interactive element; bottom-centred so it sits clear of the
 * wordmark (dead-centre) and the video's focal point. z-index above the
 * darkening ::after overlay (z1); the wordmark (z2) is pointer-events
 * none so the button stays clickable even if they ever overlap on very
 * short viewports. */
.indo-hp-hero__cta {
    position: absolute;
    left: 50%;
    bottom: clamp(24px, 6vh, 56px);
    transform: translateX(-50%);
    z-index: 3;
}
@media (max-width: 767px) {
    .indo-hp-hero__cta {
        bottom: 20px;
        width: max-content;
        max-width: calc(100vw - 32px);
    }
}

/* If a user prefers reduced motion the browser will already skip
 * autoplay; still, fall back the visible state to the poster image so
 * we don't show a navy void. */
@media (prefers-reduced-motion: reduce) {
    .indo-hp-hero__video { display: none; }
    .indo-hp-hero {
        background-image: url('/wp-content/uploads/hero-video/bournemouth-ion-hero-poster.jpg');
        background-size: cover;
        background-position: center;
    }
}
/* ===== END HOMEPAGE HERO VIDEO ===== */

/* fix-articles-001 20260501-1511: raise archive H1 size from 22px to 36-44px [closes 1]
 *
 * /articles/ template renders the archive H1 with the .indo-archive-intro__title--small
 * modifier, capping it at clamp(24px, 2.4vw, 30px) — smaller than the article card
 * titles (29.6px), inverting hierarchy. Override the --small rule on the blog
 * archive only so the H1 returns to the standard archive scale (36-44px at 988px).
 * Container padding-inline is already 32px from cluster-6 (articles-002).
 * Targets body.blog scope to avoid leaking into other archives that legitimately
 * use the small modifier. */
body.blog h1.indo-archive-intro__title.indo-archive-intro__title--small,
body.blog .indo-archive-intro h1.indo-archive-intro__title.indo-archive-intro__title--small,
body.blog .indo-archive-intro__title.indo-archive-intro__title--small {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 600;
    font-size: clamp(2rem, 4vw, 2.75rem); /* 32-44px */
    line-height: 1.15;
}
/* ===== END fix-articles-001 ===== */

/* ===== fix-category-news-003 20260501-1536 =====
 * Re-applied per user re-direction (overrides 15:10Z rev2 marker for this entry).
 * Card dates from cyan-on-white #00a6db (~3.0:1, fails WCAG 1.4.3 4.5:1) to
 * charcoal at opacity 0.7 (~5.96:1 effective on white — passes AA). Cyan reserved
 * for interactive accents only on this surface. Closes 1 entry. */
.indo-archive-grid .indo-archive-card .indo-archive-card__date,
.indo-archive-card .indo-archive-card__date,
p.indo-archive-card__date,
.indo-archive-card__date {
    color: var(--indo-charcoal, #212121);
    opacity: 0.7;
}
/* ===== END fix-category-news-003 ===== */

/* ===== fix-projects-no-overlay-001 20260501-2002 =====
 * Override TIER3-FIX-SINGLE-PROJECT-HERO 2026-04-29 21:26 (single hero) and
 * (4a) /projects/ archive overlay 2026-05-01 (archive cards).
 *
 * WHY: project hero photos and videos are deliberately dark night-time
 * scenes that show INDO luminaires doing their job. A dark overlay on top
 * of those shots makes the products look dimmer than they actually are,
 * which is the opposite of what the imagery is supposed to communicate.
 *
 * Strategy: drop the heavy full-area gradients on both surfaces. Keep
 * a SMALL bottom scrim (~bottom 25-30%, low alpha) for head/title text
 * legibility on the rare shot that does have a brighter lower band.
 * Add a modest text-shadow on the overlaid head text as belt-and-braces
 * legibility insurance. Top of hero stays clean (the night photo is
 * already dark enough for the white menu links).
 *
 * Scope: ONLY the project surfaces. Article hero, homepage hero, and
 * any other surface using the same overlay pattern are unaffected.
 *
 * If a future project hero image turns out to need more contrast (e.g.
 * a daytime install shot), the right fix is to swap that single image
 * for a darker frame, NOT to re-globalise the overlay.
 * ============================================================ */

/* Single project hero — drop the dark gradient entirely. The bottom
 * scrim from the previous revision was producing a visible dark band
 * across night-time shots (the 50% alpha black at 100% combined with
 * already-dark grass/sky content read as a thin black line above the
 * body). Hairline top fade only, for menu legibility safety on the
 * occasional lighter-skies frame. Head text gets text-shadow below. */
body.single-industrium_project .indo-single-project__hero::after {
    background: linear-gradient(180deg,
        rgba(0,0,0,0.18) 0%,
        rgba(0,0,0,0)    8%,
        rgba(0,0,0,0)    100%);
}
/* Belt-and-braces text-shadow on the overlaid head text so the hero
 * stays legible even with the lighter scrim. Subtle blur only — no
 * fuzzy halo. */
body.single-industrium_project .indo-single-project__head .entry-title,
body.single-industrium_project .indo-single-project__head h1,
body.single-industrium_project .indo-single-project__head .indo-card__date,
body.single-industrium_project .indo-single-project__head .indo-card__date a,
body.single-industrium_project .indo-single-project__intro {
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.50);
}

/* Archive card project overlay — drop the bottom scrim too. Same root
 * cause as the single hero: a soft 0 → 0.4-0.45 alpha gradient on the
 * bottom 38% of a dark-content card looks like a hard black band. The
 * card title + eyebrow stay legible via text-shadow alone. */
.indo-archive-card--project .indo-archive-card__media::after,
.indo-archive-card--project.indo-archive-card--hero .indo-archive-card__media::after {
    background: none;
}
/* Belt-and-braces shadow on the card text overlay. */
.indo-archive-card--project .indo-archive-card__eyebrow,
.indo-archive-card--project .indo-archive-card__title,
.indo-archive-card--project .indo-archive-card__sub {
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.50);
}
/* ===== END fix-projects-no-overlay-001 ===== */

/* ===== fix-projects-horticulture-overlay-001 2026-05-03 =====
 * Tom-flagged on /projects/?category=horticultural: the daytime greenhouse
 * shots (NIAB, Rothamsted, Cardiff, Fairweathers, AutoPot, Seedleaves, etc)
 * are too bright for the text-shadow-only treatment to carry the white
 * card title at WCAG-AA. Restoring a darker bottom-anchored gradient
 * scrim ONLY for cards in the horticultural category — exterior cards
 * (nighttime shots) keep the bare/text-shadow treatment because their
 * inherent darkness gives the white text adequate contrast.
 *
 * The category-slug class (.indo-archive-card--cat-horticultural) is
 * emitted by archive-industrium_project.php from the post's
 * industrium_project_category terms.
 *
 * Gradient mirrors the previous fix-projects-no-overlay-001 era's
 * darker treatment but scoped per category. The 30% clear top zone
 * preserves the photograph's dominant role; bottom 70% ramps to 0.92
 * alpha at the bottom edge for AA-large white text legibility.
 * ============================================================ */
.indo-archive-card--project.indo-archive-card--cat-horticultural .indo-archive-card__media::after {
    background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0.00) 0%,
        rgba(0, 0, 0, 0.00) 30%,
        rgba(0, 0, 0, 0.55) 60%,
        rgba(0, 0, 0, 0.92) 100%
    );
}
/* Hero card horticulture variant — slightly lighter top of gradient
 * because the hero card is much taller and the dark zone shouldn't
 * dominate the photo. */
.indo-archive-card--project.indo-archive-card--cat-horticultural.indo-archive-card--hero .indo-archive-card__media::after {
    background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0.00) 0%,
        rgba(0, 0, 0, 0.00) 35%,
        rgba(0, 0, 0, 0.50) 65%,
        rgba(0, 0, 0, 0.88) 100%
    );
}
/* ===== END fix-projects-horticulture-overlay-001 ===== */

/* ===== fix-geartrays-hero-001 — SUPERSEDED 2026-05-03 =====
 * The original /geartrays/ hero treatment was a fullbleed-hero pattern
 * with the image widget sitting under a transparent header (page-id-17258
 * was added to indo_page_has_fullbleed_hero(), main padding-top was
 * zeroed, the Elementor hero widgets were targeted directly).
 *
 * Tom-driven structural conversion (2026-05-03): /geartrays/ now uses
 * page-geartrays.php with the .indo-hero pillar pattern (matching
 * /luminaires/), which sits BELOW the standard on-light header. The
 * Elementor sections [0] (indo-hero-geartrays) and [1]
 * (indo-hero-geartrays-text) have been stripped from the post's
 * _elementor_data; the H1 + lede are now emitted by page-geartrays.php
 * inside .indo-hero__inner overlaying the york-bridge image.
 *
 * Consequently:
 *   - The main padding-top zero (line 7251) was BREAKING the new layout
 *     by removing header clearance — H1 collided with the fixed header
 *     on mobile. Removed.
 *   - Targeted rules for indo-hero-geartrays / -img / -h1 / -lede
 *     widget data-IDs no longer match anything (those widgets are gone).
 *   - The page is no longer in indo_page_has_fullbleed_hero() —
 *     functions.php updated 2026-05-03.
 *
 * Original block kept here as a TRACE in case rollback is needed:
 *
 *   body.page-id-17258 main { padding-top: 0; }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays"] {
 *       padding-top: 0 !important; margin-top: 0 !important;
 *   }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-img"] {
 *       margin: 0 !important;
 *   }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-img"] img {
 *       display: block; width: 100%; height: auto; max-height: 80vh; object-fit: cover;
 *   }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-h1"],
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-lede"] {
 *       padding-left: 10px; padding-right: 10px;
 *   }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-h1"] h1 {
 *       margin: 32px 0 8px;
 *   }
 *   body.page-id-17258 .elementor-element[data-id="indo-hero-geartrays-lede"] p {
 *       max-width: 62ch; margin: 0 0 32px;
 *   }
 * ===== END SUPERSEDED ===== */

/* ============================================================================
 * Homepage best-in-class layout pass — 2026-05-01 (replaces compaction pass)
 *
 * Goal: a deliberate, even, professional layout at 375 / 480 / 768 / 1024 / 1440.
 *
 * Rhythm scale (use these throughout, no random clamps):
 *   --indo-rhythm-tight:   clamp(48px, 6vw,  64px)     mobile-first
 *   --indo-rhythm-default: clamp(64px, 7vw,  88px)     most sections
 *   --indo-rhythm-roomy:   clamp(80px, 9vw, 120px)     feature bands
 *
 * Bottom padding on the page-final section needs >= 96px to clear the
 * fixed "GET A QUOTE" floater (64px tall + 24px margin = 88px occupancy).
 *
 * Section-by-section:
 *   89ad7fd / 679fe30  UK manufacturer band — heading left, CTA right at >=768,
 *                       CTA full-width below at <768. Un-hides the
 *                       elementor-hidden-mobile widget so mobile users see
 *                       the CTA (the previous "stacks below" layout was a
 *                       no-op because of that hidden flag).
 *   9e24185            Delivering value — Made-in-Britain capped, body
 *                       left-aligned on mobile, single CTA style.
 *   9e0df2f            Successfully completed navy — counter stacks ABOVE
 *                       heading at <1280 (kills the side-by-side collision
 *                       at 800/1024/1180), project tile height auto + content
 *                       flowed below image (replaces 645px fixed + abs-pinned
 *                       content), saves ~300px per tile.
 *   bc68b9f / 4e3d2f3  Trusted By + Find out more — padding aligned to scale.
 *
 * A11y:
 *   - All CTAs: 15px / 600 weight (qualifies brand cyan #00a6db for AA Large
 *     contrast on white without darkening the brand colour).
 *   - 48px min tap height.
 *   - :focus-visible outline.
 *   - Floater label 13px / 600 (same a11y remediation).
 * ============================================================================ */

/* --- 0. Section padding rhythm ---------------------------------------- */
/* Per-section padding for 89ad7fd, 9e24185, bc68b9f, 9e0df2f, 4e3d2f3
   migrated to _elementor_data on 2026-05-05 so values are visible in
   Elementor's UI. Final rendered values at desktop 1440 / mobile 375 are
   preserved exactly:
       89ad7fd  110/60/110/60   60/20/60/20
       9e24185   88/60/88/60    64/20/64/20
       bc68b9f   80/60/80/60    40/20/40/20
       9e0df2f  104/60/112/60   72/20/80/20
       4e3d2f3  100/60/120/60   60/20/96/20
   The earlier intro-band rule at line ~832 was also removed in the same pass. */

/* --- 1. UK manufacturer band (89ad7fd / 679fe30) ---------------------- */

/* Inner row: heading on left, CTA on right at >=768. The button-widget
 * (5fd486b) at the FAR right is a leftover and stays hidden. */
/* (2026-05-05) 679fe30 section padding/margin migrated to _elementor_data;
   11c1177 column padding migrated to _elementor_data. Grid layout
   override for the column populated wrapper retained below. */
body.home .elementor-element-679fe30 .elementor-element-11c1177 > .elementor-element-populated {
    display: grid !important;
    grid-template-columns: 1fr auto !important;
    gap: 24px 48px !important;
    align-items: center !important;
}
body.home .elementor-element-679fe30 .elementor-element-1f8a60d {
    grid-column: 1;
    grid-row: 1;
    width: auto !important;
}
body.home .elementor-element-679fe30 .elementor-element-221e087 {
    grid-column: 2;
    grid-row: 1;
    justify-self: end !important;
    width: auto !important;
}
body.home .elementor-element-679fe30 .elementor-element-5fd486b {
    display: none !important;
}

/* Override Elementor's `elementor-hidden-mobile` on widget 221e087: it was
 * hiding the WHAT MAKES US UNIQUE CTA on mobile, leaving the heading sitting
 * in dead space. Force it visible at <768 and stack below the heading
 * full-width with a clean 32px gap. */
@media (max-width: 767px) {
    body.home .elementor-element-679fe30 .elementor-element-11c1177 > .elementor-element-populated {
        grid-template-columns: 1fr !important;
        gap: 32px !important;
    }
    body.home .elementor-element-679fe30 .elementor-element-221e087 {
        display: block !important;       /* override .elementor-hidden-mobile */
        grid-column: 1;
        grid-row: 2;
        justify-self: stretch !important;
        width: 100% !important;
    }
    body.home .elementor-element-679fe30 .elementor-element-221e087 .button-widget,
    body.home .elementor-element-679fe30 .elementor-element-221e087 .button-container {
        width: 100% !important;
    }
    body.home .elementor-element-679fe30 .elementor-element-221e087 .industrium-button {
        width: 100% !important;
        justify-content: center !important;
    }
}

/* --- 2. Delivering value (9e24185) ------------------------------------ */

/* Cap Made-in-Britain logo so it doesn't dominate the column on mobile */
body.home .elementor-element-9e24185 img[src*="Made-in-Britain"] {
    max-width: 200px !important;
    height: auto !important;
}
@media (min-width: 768px) {
    body.home .elementor-element-9e24185 img[src*="Made-in-Britain"] {
        max-width: 280px !important;
    }
}

/* Body copy reads better left-aligned on mobile (centred long paragraphs
 * are ragged-both-edges and tiring). Keep centred on >=768 if Elementor
 * authored it that way. */
@media (max-width: 767px) {
    body.home .elementor-element-9e24185 .elementor-text-editor,
    body.home .elementor-element-9e24185 .elementor-text-editor p,
    body.home .elementor-element-9e24185 .elementor-widget-text-editor {
        text-align: left !important;
    }
    body.home .elementor-element-9e24185 h2 {
        text-align: left !important;
    }
}

/* Standardise the "ABOUT US" CTA to match the WHAT MAKES US UNIQUE button
 * style (outline cyan with diagonal arrow). Inherits the .industrium-button
 * base style at line 794-812; add full-width on mobile for consistent
 * tap-target rhythm. */
@media (max-width: 767px) {
    body.home .elementor-element-9e24185 .industrium-button {
        width: 100% !important;
        justify-content: center !important;
    }
}

/* --- 3. Successfully completed projects navy band (9e0df2f) ----------- */

/* Counter widget stacks ABOVE the heading at <1280px (the side-by-side
 * absolute-position layout collides with the heading at intermediate
 * widths). At >=1280 it pins to the section's top-right per the earlier
 * SIDE-BY-SIDE FINAL block. */
@media (max-width: 1279px) {
    body.home .elementor-element-9e0df2f .elementor-element-afa2bdd {
        position: static !important;
        top: auto !important;
        right: auto !important;
        margin: 0 0 32px 0 !important;
        width: auto !important;
        max-width: none !important;
    }
    body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter,
    body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-number-wrapper,
    body.home .elementor-element-9e0df2f .elementor-element-afa2bdd .elementor-counter-title {
        text-align: left !important;
    }
    body.home .elementor-element-9e0df2f .industrium-heading {
        max-width: 36ch !important;
    }
}

/* Re-pin the absolute counter top offset for desktop (>=1280) — slightly
 * higher than the previous clamp(28,2.5vw,38) so it lines up cleanly with
 * the heading baseline given the new section padding. */
@media (min-width: 1280px) {
    body.home .elementor-element-9e0df2f .elementor-element-afa2bdd {
        top: clamp(72px, 7.5vw, 104px) !important;
    }
}

/* PROJECT TILE: kill the 645px fixed height (industrium theme.css line 13066)
 * and the absolute-bottom positioning of .project-item-content (theme.css
 * line 13124), so the card flows: image → title → excerpt → button with
 * normal block flow and a content-fit height. Saves ~300px of empty navy
 * space per tile. */
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-link {
    height: auto !important;
    min-height: 0 !important;
    display: block !important;
}
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-content,
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-content:not(:first-child) {
    position: static !important;
    padding: 16px 4px 0 4px !important;   /* tight inner gutter, not 0 48 65 70 */
    margin: 0 !important;
    bottom: auto !important;
    left: auto !important;
    right: auto !important;
    transform: none !important;            /* kill the hover translateY(15%) */
    transition: none !important;
}
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-link:hover .project-item-content {
    transform: none !important;
}
body.home .elementor-element-9e0df2f .project-slider-listing .post-title {
    margin: 0 !important;
}
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-excerpt {
    margin: 8px 0 0 !important;
    font-size: 13px !important;
    line-height: 1.5 !important;
    color: rgba(255, 255, 255, 0.72) !important;
    /* Cap excerpt at 2 lines so tile heights stay even across the row */
    display: -webkit-box !important;
    -webkit-line-clamp: 2 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
}
body.home .elementor-element-9e0df2f .project-slider-listing .project-item-button {
    margin: 14px 0 0 !important;
}

/* --- 4. CTA buttons — a11y remediation -------------------------------- */

/* Bump cyan-on-white CTAs to 15px / 600 so brand cyan #00a6db qualifies for
 * AA Large contrast (3.4:1 ratio is fine at >=18.66px effective OR >=14px
 * bold). The previous 14px / 500 failed both AA Normal and AA Large.
 *
 * Brand cyan is immutable per project rules — this is the correct
 * remediation: bump size/weight, never darken the colour. */
body.home .elementor-element-89ad7fd .industrium-button,
body.home .elementor-element-89ad7fd .industrium-button a,
body.home .elementor-element-9e24185 .industrium-button,
body.home .elementor-element-9e24185 .industrium-button a {
    font-size: 15px !important;
    font-weight: 600 !important;
    min-height: 48px !important;
    padding: 14px 28px !important;
}

/* Visible focus state on every CTA on the homepage */
body.home .industrium-button:focus-visible,
body.home .industrium-button a:focus-visible,
body.home .indo-floater:focus-visible {
    outline: 3px solid var(--indo-cyan) !important;
    outline-offset: 3px !important;
}
body.home .elementor-element-9e0df2f .industrium-button:focus-visible {
    outline-color: #ffffff !important;
}

/* Floating GET A QUOTE: bump label to 13px / 600 so white-on-cyan qualifies
 * for AA Large. Width/height untouched — circle is brand-defining. */
.indo-floater {
    font-size: 13px !important;
    font-weight: 600 !important;
}
/* ===== END homepage best-in-class pass 2026-05-01 ===== */

/* ===== MOBILE MENU BEST-IN-CLASS REDESIGN 2026-04-27 =====
   Goals:
   - Fix overlap of Products mega-menu fixed-positioned panel on mobile.
   - Accordion sub-menus (collapsed by default, expand on tap with chevron).
   - Hamburger morphs to X when open.
   - Body scroll-lock while drawer is open.
   - Hide GET A QUOTE floater while drawer open (it overlapped the menu).
   - Tighter spacing at <=360px.
   ============================================================ */
@media (max-width: 991px) {
    /* --- Reset desktop mega-menu positioning rules that bled into mobile ---
       Keep Products parent <li> as position:relative so the accordion chevron
       (which is position:absolute) anchors to its own row. On desktop V8 sets
       this to position:relative !important too — no override needed here. */
    .site-header__nav > ul > .menu-item-19646 {
        position: relative !important;
    }
    /* Products mega-panel: cancel desktop position:fixed/translateX overlay */
    .site-header__nav .menu-item-19646 > .sub-menu,
    .site-header__nav .menu-item-19646:hover > .sub-menu,
    .site-header__nav .menu-item-19646:focus-within > .sub-menu {
        position: static !important;
        top: auto !important;
        left: auto !important;
        transform: none !important;
        background: rgba(0, 0, 0, 0.22) !important;
    }
    /* Reset V7 narrow-dropdown top offset */
    .site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646) > .sub-menu {
        top: auto !important;
        padding-top: 0 !important;
        background-clip: padding-box !important;
    }
    /* Kill desktop hover-bridge / chevron pseudo elements on mobile */
    .site-header__nav .menu-item-has-children::after,
    .site-header__nav .menu-item-has-children::before,
    .site-header__nav > ul > .menu-item-has-children:not(.menu-item-19646)::after,
    .site-header__nav > ul > .menu-item-19646::after {
        content: none !important;
        display: none !important;
        background: none !important;
    }

    /* --- Body scroll lock while drawer is open --- */
    body.indo-menu-open {
        overflow: hidden !important;
        touch-action: none;
    }
    /* Hide the GET A QUOTE floater while the drawer is open — it overlaps */
    body.indo-menu-open .indo-floater {
        display: none !important;
    }

    /* --- Sub-menus collapsed by default; .is-expanded reveals them --- */
    .site-header__nav .menu-item-has-children > .sub-menu {
        max-height: 0 !important;
        overflow: hidden !important;
        opacity: 0 !important;
        visibility: hidden !important;
        transition: max-height 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 0.18s ease-out !important;
    }
    .site-header__nav .menu-item-has-children.is-expanded > .sub-menu {
        max-height: 1500px !important;
        opacity: 1 !important;
        visibility: visible !important;
        /* 2026-05-02: restore pointer-events on the expanded sub-menu.
           The base .site-header__nav .sub-menu rule sets pointer-events:none
           (used together with opacity:0 for the desktop fade-in/out). When
           the mobile drawer expands a sub-menu, that none was inherited by
           descendants, killing taps on Exterior + Horticultural even with
           full opacity/visibility. Restore auto so child links navigate. */
        pointer-events: auto !important;
    }

    /* --- Accordion chevron: sibling button alongside the <a> on every
       parent with children. Lives on the <li> (position:relative) so it
       can be absolutely positioned to the right of the row. --- */
    .site-header__nav .menu-item-has-children {
        position: relative;
    }
    .site-header__nav .menu-item-has-children > a {
        padding-right: 64px !important;
    }
    .site-header__nav .indo-acc-chev {
        /* Anchor to the TOP of the LI, NOT 50% — the LI grows when its
           sub-menu expands inside it, and a 50% anchor would sink the
           chevron down with the growing height. The top:4px offset
           vertically centres the 48px chevron on the 56px-tall <a> row
           (4 + 48 = 52, leaving 4px below — visually centred enough,
           and stable when the sub-menu accordion opens below). */
        position: absolute;
        right: 12px;
        top: 4px;
        width: 48px;
        height: 48px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        background: transparent !important;
        border: 0 !important;
        padding: 0 !important;
        color: rgba(255, 255, 255, 0.85) !important;
        opacity: 0.85;
        transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
        z-index: 2;
    }
    .site-header__nav .indo-acc-chev:hover,
    .site-header__nav .indo-acc-chev:focus,
    .site-header__nav .indo-acc-chev:active {
        background: rgba(255, 255, 255, 0.04) !important;
        color: var(--indo-cyan, #00a6db) !important;
        opacity: 1;
    }
    .site-header__nav .indo-acc-chev:focus-visible {
        outline: 2px solid var(--indo-cyan, #00a6db) !important;
        outline-offset: -2px !important;
    }
    .site-header__nav .indo-acc-chev > span {
        display: block;
        width: 10px;
        height: 10px;
        border-right: 2px solid currentColor;
        border-bottom: 2px solid currentColor;
        transform: rotate(45deg);
        transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
        margin-top: -3px;
    }
    .site-header__nav .menu-item-has-children.is-expanded > .indo-acc-chev {
        color: var(--indo-cyan, #00a6db) !important;
        opacity: 1;
    }
    .site-header__nav .menu-item-has-children.is-expanded > .indo-acc-chev > span {
        transform: rotate(-135deg);
        margin-top: 3px;
    }
    /* Sub-menu rows: chevron sits a bit smaller and aligned with the row */
    .site-header__nav .sub-menu .menu-item-has-children > .indo-acc-chev {
        top: 2px;
        right: 8px;
        width: 44px;
        height: 44px;
    }
    /* Eyebrow rows in Products mega-menu act as labels (pointer-events:none in CSS),
       so suppress their chevrons. */
    .site-header__nav .menu-item-19646 > .sub-menu > .menu-item-has-children > .indo-acc-chev {
        display: none !important;
    }

    /* --- Hamburger → X morph --- */
    .site-header__toggle .indo-menu-icon {
        position: relative;
        display: inline-block;
        width: 24px;
        height: 18px;
        vertical-align: middle;
    }
    .site-header__toggle .indo-menu-icon span {
        position: absolute;
        left: 0;
        right: 0;
        height: 2px;
        background: currentColor;
        border-radius: 2px;
        transform-origin: center;
        transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 0.18s ease-out,
                    top 0.24s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .site-header__toggle .indo-menu-icon span:nth-child(1) { top: 2px; }
    .site-header__toggle .indo-menu-icon span:nth-child(2) { top: 8px; }
    .site-header__toggle .indo-menu-icon span:nth-child(3) { top: 14px; }
    .site-header.is-open .site-header__toggle .indo-menu-icon span:nth-child(1) {
        top: 8px;
        transform: rotate(45deg);
    }
    .site-header.is-open .site-header__toggle .indo-menu-icon span:nth-child(2) {
        opacity: 0;
        transform: scaleX(0);
    }
    .site-header.is-open .site-header__toggle .indo-menu-icon span:nth-child(3) {
        top: 8px;
        transform: rotate(-45deg);
    }
    /* Hide the legacy SVG once JS has swapped in the morphing icon */
    .site-header__toggle.has-morph-icon > svg {
        display: none !important;
    }

    /* --- Tap targets >= 44x44 for header buttons --- */
    .site-header__toggle,
    .site-header__search {
        min-width: 44px;
        min-height: 44px;
        padding: 10px;
    }

    /* --- Restore sub-menus inside the Products mega-menu (3rd tier) ---
       The EXTERIOR / HORTICULTURAL eyebrows are rendered as labels with
       `pointer-events: none` and no chevron, so users cannot toggle them.
       The product list under each eyebrow MUST therefore stay visible
       whenever Products itself is expanded. Override the universal collapse
       rule above for these specific sub-menus. */
    .site-header__nav .menu-item-19646.is-expanded > .sub-menu .sub-menu,
    .site-header__nav .menu-item-19646.is-expanded > .sub-menu > .menu-item-has-children > .sub-menu {
        max-height: none !important;
        opacity: 1 !important;
        visibility: visible !important;
        overflow: visible !important;
        /* Same pointer-events restore as the outer rule above — the inner
           always-visible product lists need to be tappable too. */
        pointer-events: auto !important;
    }
    /* Belt & braces: also force their containing eyebrow LIs into a visible
       "expanded" computed state for any descendant CSS that reads it. */
    .site-header__nav .menu-item-19646.is-expanded > .sub-menu > .menu-item-has-children {
        /* purely a hook in case future rules want to differentiate */
    }

    /* --- Header stays solid white while drawer open (independent of scroll) --- */
    .site-header.is-open,
    body .site-header.is-open,
    body.home .site-header.is-open {
        background: #ffffff !important;
        box-shadow: 0 1px 0 rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.04) !important;
    }

    /* --- Smoother drawer slide --- */
    .site-header__nav {
        transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1) !important;
        will-change: transform;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
        scrollbar-color: rgba(255,255,255,0.2) transparent;
    }
    .site-header__nav::-webkit-scrollbar { width: 4px; }
    .site-header__nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 2px; }

    /* --- Visible focus state inside drawer for keyboard users --- */
    .site-header__nav a:focus-visible {
        outline: 2px solid var(--indo-cyan, #00a6db) !important;
        outline-offset: -2px !important;
        background: rgba(0, 166, 219, 0.10) !important;
    }
    .site-header__toggle:focus-visible,
    .site-header__search:focus-visible {
        outline: 2px solid var(--indo-cyan, #00a6db) !important;
        outline-offset: 2px !important;
    }
}

/* --- Edge case: 360px and narrower (smallest common Android, iPhone SE 1st gen) --- */
@media (max-width: 360px) {
    .site-header { padding: 0 12px !important; }
    .site-header__inner { gap: 4px !important; }
    /* The ≤991px rule pulls the toggle 8px toward the search button to
       absorb the 16px flex gap; at this narrower breakpoint the gap is
       already 4px so the same -8 would create overlap. Reset to 0 so
       only the 4px container gap applies. */
    .site-header__search + .site-header__toggle { margin-left: 0 !important; }
    .site-header__nav a {
        padding-left: 20px !important;
        padding-right: 48px !important;
        font-size: 15px;
    }
    .site-header__nav .sub-menu a { padding-left: 36px !important; }
    .site-header__nav .sub-menu .sub-menu a { padding-left: 52px !important; }
    .site-header__nav .menu-item-has-children > a .indo-acc-chev { right: 12px; }
}
/* --- Brand-colour overrides for the header buttons across every state.
   Industrium's reset.css paints `button:focus { background: #cc3366 }`
   (an off-brand magenta/red). It applies at every viewport. Keep the
   trigger and search buttons backgroundless and on-brand cyan in every
   visual state — pulled from the brand token --indo-cyan / #00a6db. */
.site-header__toggle,
.site-header__toggle:hover,
.site-header__toggle:focus,
.site-header__toggle:focus-visible,
.site-header__toggle:focus-within,
.site-header__toggle:active,
.site-header__search,
.site-header__search:hover,
.site-header__search:focus,
.site-header__search:focus-visible,
.site-header__search:focus-within,
.site-header__search:active {
    background: transparent !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
}
.site-header__toggle:hover,
.site-header__toggle:focus,
.site-header__toggle:active,
.site-header__search:hover,
.site-header__search:focus,
.site-header__search:active {
    color: var(--indo-cyan, #00a6db) !important;
}
.site-header__toggle:focus-visible,
.site-header__search:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db) !important;
    outline-offset: 2px !important;
}
/* Active/pressed state on the morphing X spans: brand cyan, never red */
.site-header.is-open .site-header__toggle:active .indo-menu-icon span,
.site-header.is-open .site-header__toggle .indo-menu-icon span {
    background: currentColor !important;
}

/* Brand-colour overrides for the accordion chevron buttons. Same Industrium
   reset.css `button:focus { background: #cc3366 }` paint hits these — defend
   at every viewport so a tap-down never flashes magenta. The mobile drawer
   block above sets the visible look; these defend the active/focus states. */
.site-header__nav .indo-acc-chev,
.site-header__nav .indo-acc-chev:hover,
.site-header__nav .indo-acc-chev:focus,
.site-header__nav .indo-acc-chev:focus-visible,
.site-header__nav .indo-acc-chev:focus-within,
.site-header__nav .indo-acc-chev:active {
    background: transparent !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
}
.site-header__nav .indo-acc-chev:hover,
.site-header__nav .indo-acc-chev:focus,
.site-header__nav .indo-acc-chev:active {
    background-color: rgba(255, 255, 255, 0.06) !important;
    color: var(--indo-cyan, #00a6db) !important;
}
.site-header__nav .indo-acc-chev:focus-visible {
    outline: 2px solid var(--indo-cyan, #00a6db) !important;
    outline-offset: -2px !important;
}
/* ===== END MOBILE MENU BEST-IN-CLASS REDESIGN ===== */

/* ===== HERO + DARK-SECTION MOBILE TIGHTEN 2026-05-02 =====
 *
 * Root cause:
 *   - Category pillar hero: min-height clamp floor (380px) + heavy bottom
 *     scrim (rgba 0.85) + generous padding = hero consumes >55% of mobile
 *     viewport. The dark scrim at the hero bottom creates a hard navy edge
 *     abutting the next section with no breathing room.
 *   - Single project hero: head (eyebrow + H1 + intro) is absolutely
 *     positioned at the hero bottom with padding clamp(48px, 8vh, 96px).
 *     The hero background is --indo-navy and the scrim at line 4318 ramps
 *     to rgba(0,0,0,0.90) at 100%, creating a near-solid black bottom band
 *     that bleeds 60vh+ before the body section starts. Intro lede is also
 *     too large (clamp 18-22px) for mobile.
 *
 * Fix strategy (CSS-only, appended block, no existing rules touched):
 *   A) Pillar hero — reduce min-height at ≤991px, lighten bottom scrim stop,
 *      reduce vertical padding, change scrim gradient to fade to transparent
 *      (not navy), add a short "bridge" gradient on the section that follows.
 *   B) Single project hero — reduce min-height at ≤767px, reduce bottom
 *      head padding, tighten H1 clamp lower bound, reduce intro font size,
 *      lighten bottom scrim, shorten eyebrow-to-H1 gap.
 *   C) Both — ensure CTA buttons meet 48px tap height via min-height.
 * ============================================================ */

/* ── A. CATEGORY PILLAR HERO (mobile ≤ 991px) ───────────────────────────── */
@media (max-width: 991px) {

    /* Reduce hero height: was clamp(380px,70vh,540px).
       New: 50vh minimum, sensible max for short mobile screens. */
    .indo-pillar-hero {
        min-height: clamp(320px, 52vh, 480px);
        /* Reduce internal top+bottom padding so text block isn't padded so heavily */
        padding: clamp(32px, 5vw, 64px) 0;
    }

    /* Scrim: was 0→0.35→0.85. New: softer bottom (0.60) so image remains
       visible and the bottom edge doesn't read as a solid navy block.
       Fade fully to transparent so there's no hard navy-to-light boundary. */
    .indo-pillar-hero__scrim {
        background: linear-gradient(
            to bottom,
            rgba(18, 28, 34, 0.50) 0%,
            rgba(18, 28, 34, 0.20) 35%,
            rgba(18, 28, 34, 0.72) 100%
        );
    }

    /* Title: tighten lower-bound of clamp so it doesn't overflow at 320px.
       Was clamp(40px,6vw,72px). New: clamp(28px,7vw,48px). */
    .indo-pillar-hero__title {
        font-size: clamp(28px, 7vw, 48px);
        margin: 0 0 14px;
    }

    /* Eyebrow: keep small — reduce gap below */
    .indo-pillar-hero__eyebrow {
        margin: 0 0 10px;
        font-size: 12px;
        letter-spacing: 0.15em;
    }

    /* Lede: cap at 15px on mobile; was clamp(17px,1.6vw,20px) */
    .indo-pillar-hero__lede {
        font-size: 14px;
        line-height: 1.5;
        margin: 0 0 24px;
    }

    /* CTAs: stack vertically on ≤991, each full-width, 48px min tap height */
    .indo-pillar-hero .indo-pillar-hero__cta {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    .indo-pillar-hero .indo-btn {
        justify-content: center;
        min-height: 48px;
        padding: 12px 24px;
    }
}

/* Tighter inner padding at narrowest (≤414px).
   This breakpoint also overrides the ≤991px rule above, so it sets
   the final min-height for 320–414px viewports.
   Target: hero height ≤ 45% of viewport (≤365px at 812px device). */
@media (max-width: 414px) {
    .indo-pillar-hero {
        /* 44vh at 812 = 357px = 44% of viewport. Content (265px) + 60px
           padding = 325px, so content fits comfortably within min-height. */
        min-height: clamp(280px, 44vh, 380px);
        padding: clamp(24px, 4vw, 40px) 0;
    }
    .indo-pillar-hero__inner {
        padding: 0 clamp(16px, 4vw, 24px);
    }
    .indo-pillar-hero__title {
        font-size: clamp(26px, 7.5vw, 38px);
    }
    .indo-pillar-hero__lede {
        font-size: 14px;
        margin: 0 0 20px;
    }
}


/* ── B. SINGLE PROJECT HERO (mobile ≤ 767px) ─────────────────────────────── */
@media (max-width: 767px) {

    /* Hero height: was min-height 60vh (~487px at 812px device).
       Reduce to 45vh so the hero takes less absolute space.
       aspect-ratio: auto (from line 4301) still applies via the
       body.single-industrium_project rule — this overrides the min-height. */
    body.single-industrium_project .indo-single-project__hero {
        min-height: clamp(260px, 45vh, 400px);
    }

    /* Scrim: was ramping to rgba(0,0,0,0.90) at 100% — almost solid black.
       Replace with the hairline-top-only approach from line 7127, but with
       a slightly stronger bottom fade so text at the hero bottom stays
       legible without creating a solid-black band.
       Override the earlier heavy-scrim rule at line 4318 and the
       later light-scrim at line 7127 — this sits after both. */
    body.single-industrium_project .indo-single-project__hero::after {
        background: linear-gradient(180deg,
            rgba(0, 0, 0, 0.40) 0%,
            rgba(0, 0, 0, 0.08) 18%,
            rgba(0, 0, 0, 0.35) 55%,
            rgba(0, 0, 0, 0.68) 100%);
    }

    /* Head (overlaid on hero): reduce bottom padding so it doesn't
       push the hero bottom edge so far down.
       Was clamp(48px,8vh,96px). New: clamp(20px,4vh,40px). */
    body.single-industrium_project .indo-single-project__hero > .indo-single-project__head {
        padding: 0 0 clamp(20px, 4vh, 40px);
    }

    /* H1: was clamp(36px,5vw,64px) — on mobile 5vw at 375 = 19px, so
       clamp floor 36px kicks in. That's fine but ensure it wraps at 320.
       Tighten to clamp(26px,6.5vw,40px) so it fits 2 lines at 320. */
    body.single-industrium_project .indo-single-project__head .entry-title,
    body.single-industrium_project .indo-single-project__head h1 {
        font-size: clamp(26px, 6.5vw, 40px);
        line-height: 1.15;
        margin: 6px 0 0;
    }

    /* Eyebrow / breadcrumb: keep at 12-13px, tighten gap.
       Rubric: 8-12px gap between eyebrow and H1. margin-bottom sets this. */
    body.single-industrium_project .indo-single-project__head .indo-card__date {
        font-size: 12px;
        margin-bottom: 8px;
        letter-spacing: 0.12em;
    }

    /* Intro / lede: was clamp(18px,2vw,22px). Too large on mobile.
       Cap at 14-15px with generous line-height for readability. */
    body.single-industrium_project .indo-single-project__intro {
        font-size: 14px;
        line-height: 1.55;
        margin: 10px auto 0;
        max-width: 100%;
    }

    /* Body section (white area after hero): reduce top padding so next
       content appears sooner above the fold.
       Was clamp(48px,6vw,96px). New: clamp(28px,4vw,48px). */
    body.single-industrium_project .indo-single-project__body {
        padding-top: clamp(28px, 4vw, 48px);
    }
}

/* Extra-narrow: 320px */
@media (max-width: 360px) {
    body.single-industrium_project .indo-single-project__head .entry-title,
    body.single-industrium_project .indo-single-project__head h1 {
        font-size: clamp(22px, 6.5vw, 32px);
    }
    body.single-industrium_project .indo-single-project__intro {
        font-size: 13px;
    }
}

/* ── B2. PILLAR → STATS TRANSITION BRIDGE ────────────────────────────────── */
/* At mobile, the dark hero ends with a hard horizontal edge above the light
   stats strip. We add a narrow gradient bridge on the stats strip's top edge
   (navy → transparent) so the colour change looks intentional rather than
   abrupt. Uses a box-shadow on the ::before pseudo since the stats strip has
   overflow:hidden, which would clip a negative-margin gradient. */
@media (max-width: 991px) {
    .indo-stats-strip {
        position: relative;
    }
    .indo-stats-strip::before {
        content: "";
        position: absolute;
        top: 0; left: 0; right: 0;
        height: 12px;
        background: linear-gradient(
            to bottom,
            rgba(18, 28, 34, 0.22) 0%,
            transparent 100%
        );
        pointer-events: none;
        z-index: 1;
    }
}

/* ── C. MAGENTA GUARD — Industrium reset.css `button:focus { background: #cc3366 }` ── */
/* Belt-and-braces: reinforce for all CTA buttons in hero and pillar sections
   in case any aren't caught by the earlier per-component rules. */
.indo-pillar-hero .indo-btn:focus,
.indo-pillar-hero .indo-btn:focus-visible,
.indo-pillar-hero .indo-btn:active,
body.single-industrium_project .indo-btn:focus,
body.single-industrium_project .indo-btn:focus-visible,
body.single-industrium_project .indo-btn:active {
    background: var(--indo-cyan, #00a6db) !important;
    border-color: var(--indo-cyan, #00a6db) !important;
    color: #ffffff !important;
    outline: none;
}
.indo-pillar-hero .indo-btn--ghost:focus,
.indo-pillar-hero .indo-btn--ghost:focus-visible,
.indo-pillar-hero .indo-btn--ghost:active {
    background: rgba(255, 255, 255, 0.08) !important;
    border-color: rgba(255, 255, 255, 0.55) !important;
    color: #ffffff !important;
}

/* ===== END HERO + DARK-SECTION MOBILE TIGHTEN 2026-05-02 ===== */

/* ===== ABOUT VALUES SECTION REDESIGN 2026-04-27 =====
 * Replaces the static Values_3.webp circular image. Renders as semantic HTML
 * (eyebrow + h2 + dynamic years badge + 7 value cards in a responsive grid).
 * Mobile-first; 1 column at 320-767, 2 cols at 768+, 3 cols at 1100+.
 * ============================================================ */

.indo-values {
    padding: clamp(48px, 10vw, 120px) 0;
    background: #ffffff;
}
.indo-values__head {
    text-align: center;
    margin-bottom: clamp(32px, 5vw, 64px);
}
.indo-values__eyebrow {
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--indo-cyan, #00a6db);
    margin: 0 0 12px;
}
.indo-values__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(28px, 4.5vw, 48px);
    line-height: 1.15;
    color: var(--indo-charcoal, #212121);
    margin: 0 0 24px;
}
/* Years badge — segmented-ring SVG, big display number, anniversary feel.
   Cycle 2 (2026-05-02): upgraded from a thin solid ring to a richer
   composition with a 7-segment outer ring (echoes the 7 values), a soft
   inner ring for depth, two minimal cyan laurel sprigs flanking the year,
   and a "Since November 2007" sub-label that mirrors the "2007 - 2017"
   stamp in the source diagram. */
.indo-values__badge {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: clamp(180px, 22vw, 220px);
    height: clamp(180px, 22vw, 220px);
    margin: 0 auto 8px;
    background: transparent;
    color: var(--indo-cyan, #00a6db);
    isolation: isolate;
}
.indo-values__badge-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    /* Subtle entrance: ease the ring in with a slight rotate-and-fade.
       Respects reduced-motion via the @media query below. */
    animation: indoValuesBadgeIn 0.7s cubic-bezier(.22,1,.36,1) both;
}
@keyframes indoValuesBadgeIn {
    from { opacity: 0; transform: rotate(-12deg); }
    to   { opacity: 1; transform: rotate(0); }
}
@media (prefers-reduced-motion: reduce) {
    .indo-values__badge-ring { animation: none; }
}
.indo-values__badge-num {
    position: relative;
    z-index: 1;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(56px, 7.5vw, 84px);
    line-height: 0.95;
    color: var(--indo-cyan, #00a6db);
    margin-top: 4px;
    /* Tabular figures so the number swap from "10" to "11" doesn't shift width. */
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}
.indo-values__badge-unit {
    position: relative;
    z-index: 1;
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    /* Cycle 2.1: charcoal not cyan. Reasons:
       1) Hierarchy — the year number is the focal cyan element inside the ring;
          the unit caps shouldn't compete for that role.
       2) Accessibility — cyan #00a6db on white is 2.81:1, failing WCAG AA at
          12px normal weight. Charcoal at 0.85 opacity gives ~7:1. */
    color: rgba(33, 33, 33, 0.85);
    margin-top: 6px;
    line-height: 1;
}
/* DORMANT 2026-05-02: .indo-values__badge-since span removed from values-shortcode.php
   (Tweak 2 — badge shows only number + YEARS unit). Keep for reference. */
/* .indo-values__badge-since {
    position: relative;
    z-index: 1;
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(33, 33, 33, 0.50);
    margin-top: 10px;
    line-height: 1.2;
} */
/* DORMANT 2026-05-02: .indo-values__lede was never in shortcode markup — dead rule. */
/* .indo-values__lede {
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 15px;
    color: var(--indo-charcoal, #212121);
    opacity: 0.72;
    margin: 24px auto 0;
    max-width: 520px;
} */
/* Suppress industrium-legacy theme's `ul > li::before` fontello arrow icon.
 * The legacy css/theme.css adds a decorative arrow to every ul > li via
 * fontello pseudo-content. Our value cards are <li> elements and inherit it.
 * Override to restore clean card appearance. */
.indo-values__grid > li::before {
    display: none !important;
    content: none !important;
    font-family: inherit !important;
}

/* Cards grid */
.indo-values__grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(16px, 2.5vw, 24px);
}
@media (min-width: 768px) {
    .indo-values__grid { grid-template-columns: repeat(2, 1fr); }
    /* 7 cards in a 2-col grid = 2+2+2+1 → final card alone in row 4.
       Centre it horizontally so it doesn't read as an abandoned item. */
    .indo-values__grid > .indo-values__card:last-child:nth-child(2n - 1) {
        grid-column: 1 / -1;
        justify-self: center;
        max-width: calc(50% - clamp(8px, 1.25vw, 12px));
        width: 100%;
    }
}
@media (min-width: 1100px) {
    .indo-values__grid { grid-template-columns: repeat(3, 1fr); }
    /* 7 cards in a 3-col grid = 3+3+1 → final card alone in row 3.
       Pull it into the centre column to centre the row visually.
       :nth-child(3n - 2) = position 1 of a row (i.e. first column).
       The :last-child match means it's also the lone card in that row. */
    .indo-values__grid > .indo-values__card:last-child:nth-child(3n - 2) {
        grid-column: 2 / 3;
    }
    /* Reset the 2-col-orphan rule's max-width when we're in 3-col territory. */
    .indo-values__grid > .indo-values__card:last-child:nth-child(2n - 1) {
        max-width: none;
        width: auto;
        justify-self: stretch;
    }
}
.indo-values__card {
    padding: clamp(20px, 3vw, 28px);
    background: var(--indo-light, #f4f4f4);
    border-radius: var(--indo-radius, 4px);
    border-top: 3px solid var(--indo-cyan, #00a6db);
    transition: transform 0.2s var(--indo-easing, cubic-bezier(.4,0,.2,1)),
                box-shadow 0.2s var(--indo-easing, cubic-bezier(.4,0,.2,1));
}
.indo-values__card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
}
/* Magenta guard — Industrium reset.css `button:focus { background: #cc3366 }` */
.indo-values__card:focus,
.indo-values__card:focus-visible,
.indo-values__card:active {
    background: var(--indo-light, #f4f4f4) !important;
    outline: 2px solid var(--indo-cyan, #00a6db);
    outline-offset: 2px;
}
.indo-values__card-title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 400;
    font-size: clamp(18px, 1.6vw, 22px);
    color: var(--indo-charcoal, #212121);
    margin: 0 0 10px;
    line-height: 1.25;
}
.indo-values__card-body {
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 15px;
    line-height: 1.55;
    color: var(--indo-charcoal, #212121);
    opacity: 0.85;
    margin: 0;
}
/* Mobile tighten: stack closer, slightly smaller card padding */
@media (max-width: 767px) {
    .indo-values { padding: clamp(40px, 8vw, 60px) 0; }
    .indo-values__head { margin-bottom: 32px; }
    .indo-values__card { padding: 20px; }
    .indo-values__card-title { font-size: 17px; }
    .indo-values__card-body { font-size: 14px; }
}
@media (max-width: 767px) {
    .indo-values__badge {
        width: clamp(150px, 44vw, 180px);
        height: clamp(150px, 44vw, 180px);
    }
    .indo-values__badge-num { font-size: clamp(48px, 14vw, 60px); }
    .indo-values__badge-unit { font-size: 11px; letter-spacing: 0.20em; margin-top: 4px; }
    /* DORMANT 2026-05-02: badge-since removed from markup */
    /* .indo-values__badge-since { font-size: 9px; margin-top: 6px; } */
}
@media (max-width: 360px) {
    .indo-values__badge { width: 140px; height: 140px; }
    .indo-values__badge-num { font-size: 44px; }
    /* DORMANT 2026-05-02: badge-since removed from markup */
    /* .indo-values__badge-since { display: none; } */
}
/* ===== END ABOUT VALUES SECTION REDESIGN ===== */

/* ===== /direct-drive/ pillar hero: H1 + scrim fix 2026-04-27 =====
 * The legacy `body.page-id-16739 h1 { color: #121c22 !important }` rule
 * (line ~2792) was added to dark-tone the Elementor body H2/H3s on the page.
 * It also paints the new pillar-hero H1 navy, which on the dark PCB photo
 * reads invisible. Override scoped to the hero only — leaves the body H2/H3
 * dark navy (correct for white-card sections below). Also strengthen the
 * scrim because the PCB photo has bright green/gold mid-tones at the
 * top where the H1 sits, and white text needs a darker overlay there.
 * ============================================================ */
body.page-id-16739 .indo-pillar-hero__title,
body.page-id-16739 .indo-pillar-hero h1 {
    color: #ffffff !important;
}
body.page-id-16739 .indo-pillar-hero__scrim {
    background: linear-gradient(
        to bottom,
        rgba(18, 28, 34, 0.72) 0%,
        rgba(18, 28, 34, 0.55) 35%,
        rgba(18, 28, 34, 0.88) 100%
    );
}
/* ===== END /direct-drive/ pillar hero fix ===== */

/* ===== /about/ testimonial section P0 sizing pass 2026-05-02 =====
 * Tom flagged: logos still too small at 375 (80px), card width too narrow
 * at 320 (185px on a 320 viewport), GET A QUOTE floater overlapping cards.
 *
 * Fixes (per Tom's spec):
 *   - Logos: 120 desktop / 110 tablet / 100 @ 375 / 88 @ 320
 *   - Card width: full carousel-container width on mobile (was rendering
 *     ~58% of viewport at 320 due to OWL type-2 layout default)
 *   - Card padding: more generous internal spacing on mobile so bigger
 *     logos don't crowd the quote text
 *   - Bottom padding on the testimonials section at mobile so the
 *     fixed-position GET A QUOTE floater (z:90, bottom:12, right:27)
 *     doesn't sit on top of the last visible card
 * ============================================================ */
.elementor-widget-industrium_testimonial_carousel .testimonial-photo img {
    width: 120px !important;
    height: 120px !important;
    object-fit: contain;
    border-radius: 50%;
    display: block;
}
.elementor-widget-industrium_testimonial_carousel .testimonial-photo {
    width: 120px !important;
    height: 120px !important;
    flex-shrink: 0;
}

/* Tablet 768–1099 */
@media (min-width: 768px) and (max-width: 1099px) {
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo img,
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo {
        width: 110px !important;
        height: 110px !important;
    }
}

/* Mobile (≤767, includes 375 + 414) */
@media (max-width: 767px) {
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo img,
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo {
        width: 100px !important;
        height: 100px !important;
    }

    /* Card layout: force each carousel item to fill the available width.
       OWL/type-2 leaves cards at ~185px on 320 — too narrow. Override.
       OWL keeps managing translateX for the cycle; we just stop its
       per-item width shrinkage so each visible card uses the full row. */
    .elementor-element-55ae6e7 .owl-item,
    .elementor-element-55ae6e7 .testimonial-item.slider-item-type-2 {
        max-width: 100% !important;
    }
    .elementor-element-55ae6e7 .testimonial-item.slider-item-type-2 .testimonial-content {
        padding: 28px 24px !important; /* more generous than the default 65px/70px tight grid */
    }

    /* (2026-05-05) Removed dead `padding-bottom: 100px` rule for
       .elementor-element-59113ac on mobile. It was previously masked by
       the !important section-padding rule (now migrated). The section's
       padding_mobile is set to 70px to match the prior rendered value;
       Tom can lift it via the editor if GET A QUOTE clearance returns
       as an issue. */
}

/* Narrow 320 — Tom's floor */
@media (max-width: 360px) {
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo img,
    .elementor-widget-industrium_testimonial_carousel .testimonial-photo {
        width: 88px !important;
        height: 88px !important;
    }
    .elementor-element-55ae6e7 .testimonial-item.slider-item-type-2 .testimonial-content {
        padding: 24px 18px !important;
    }
}
/* ===== END /about/ testimonial section P0 sizing pass ===== */

/* ===== /about/ Change B: Made-in-Britain badge on dark navy section =====
 * The Made-in-Britain logo (id 19324) was designed for light backgrounds —
 * its "MADE IN BRITAIN" text is dark gray, which reads as muted/illegible
 * on the navy section it now sits in. Wrap with a white pad + subtle radius
 * so the badge has its native light context. The Union Jack inside still
 * carries its own colours; the white pad just lifts the wordmark to legibility.
 * ============================================================ */
body.page-id-395 .elementor-element-e7b0670 img {
    background: #ffffff;
    padding: clamp(16px, 2.5vw, 28px) clamp(24px, 4vw, 40px);
    border-radius: 4px;
    max-width: 100%;
    height: auto;
    display: inline-block;
}
body.page-id-395 .elementor-element-e7b0670 .elementor-widget-container {
    text-align: left;
}
@media (max-width: 767px) {
    body.page-id-395 .elementor-element-e7b0670 img {
        max-width: 280px;
    }
}
/* ===== END /about/ Change B Made-in-Britain pad ===== */

/* ===== Pillar hero — clear mobile header overlap 2026-05-02 (revised) =====
 * On mobile (≤991), the indo-pillar-hero block has only ~24-32px top
 * padding, but the fixed header overlays the top of the viewport at
 * ~80px tall. The eyebrow + first line of the H1 end up clipped behind
 * the header bar. Bump the top padding so the eyebrow always sits below
 * the header.
 *
 * 2026-05-02 v2: originally scoped to body.page-id-395 only. Tom flagged
 * /direct-drive/ as also affected (page-id-16739). Generalising to ALL
 * .indo-pillar-hero blocks is the right move — every pillar page lives
 * under the same fixed-header overlay, so the overlap is universal. The
 * fallback bumped from 64px → 80px to match the actually-rendered
 * header height observed in Playwright (was clipping by 25px even with
 * the previous fix-me-not value).
 * ============================================================ */
@media (max-width: 991px) {
    .indo-pillar-hero {
        padding-top: calc(var(--indo-header-h-mobile, 80px) + clamp(20px, 4vw, 36px)) !important;
    }
}
/* ===== END pillar hero mobile padding ===== */

/* ===== /about/ testimonials block 2026-05-02 — dynamic 5-rolling shortcode =====
 * Rendered by [indo_about_testimonials] (inc/about-testimonials.php).
 * Pulls 5 random testimonials from the canonical /testimonials/ post each
 * page-load. New testimonials added to /testimonials/ flow through here
 * automatically.
 *
 * Layout per Tom (Issue 2):
 *   - Mobile (≤768): logo is FULL-WIDTH of the card. Quote on top, then
 *     logo full-width as a centred block, then name + role below.
 *   - Desktop (≥1024): logo lives in an attribution row at the bottom
 *     of the card alongside name + role. Logo capped at 140px square so
 *     it reads as a brand mark, not a banner.
 *   - Tablet (769-1023): hybrid — logo right-aligned with name + role on
 *     left, both fitting one row.
 * ============================================================ */

.indo-about-testimonials {
    padding: clamp(48px, 8vw, 96px) 0;
    background: var(--indo-light, #f4f4f4);
}
.indo-about-testimonials__head {
    text-align: center;
    margin: 0 0 clamp(28px, 4vw, 48px);
}
.indo-about-testimonials__title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(28px, 4vw, 44px);
    line-height: 1.15;
    color: var(--indo-charcoal, #212121);
    margin: 0;
}

/* Cards grid — 1 col mobile, 2 col tablet, 3 col + orphan-centre at desktop.
 * 5 cards in a 3-col grid produces 3+2; the orphan-card rule centres the
 * lone last card in row 2's middle column for visual balance. */
.indo-about-testimonials__grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(16px, 2.5vw, 24px);
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: clamp(16px, 4vw, 24px);
}
@media (min-width: 769px) and (max-width: 1099px) {
    .indo-about-testimonials__grid { grid-template-columns: repeat(2, 1fr); }
    /* 5 in 2-col = 2+2+1: lone last card spans full width centred-narrow */
    .indo-about-testimonials__grid > .indo-about-testimonials__card:last-child:nth-child(odd) {
        grid-column: 1 / -1;
        justify-self: center;
        max-width: calc(50% - clamp(8px, 1.25vw, 12px));
        width: 100%;
    }
}
@media (min-width: 1100px) {
    /* 6-col grid; each card spans 2. Row 1 fills 6 cols (3 cards × 2). Row 2
     * has 2 cards × 2 = 4 cols → shift first card of row 2 to col 2 so
     * cards span cols 2-3 + 4-5, leaving cols 1 and 6 empty (visually centred). */
    .indo-about-testimonials__grid {
        grid-template-columns: repeat(6, 1fr);
    }
    .indo-about-testimonials__card {
        grid-column: span 2;
    }
    /* Match: 4th-of-5 (penultimate of 5-card list) → start at col 2 with full
     * 2-col span so cols 2-3 contain card 4, cols 4-5 contain card 5 (centred). */
    .indo-about-testimonials__card:nth-last-child(2):nth-child(4) {
        grid-column: 2 / span 2;
    }
}

/* Suppress industrium-legacy fontello arrows on cards (`ul > li::before`).
 * The .indo-about-testimonials__grid uses <li> for cards which inherits the
 * legacy decorative arrow icon. Override to keep cards clean. */
.indo-about-testimonials__grid > li::before,
.indo-about-testimonials__grid > li::after {
    display: none !important;
    content: none !important;
    background: none !important;
}

.indo-about-testimonials__card {
    background: #ffffff;
    border-top: 3px solid var(--indo-cyan, #00a6db);
    padding: clamp(24px, 3vw, 32px);
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 2.5vw, 28px);
    transition: box-shadow 0.2s var(--indo-easing, cubic-bezier(.4,0,.2,1)),
                transform 0.2s var(--indo-easing, cubic-bezier(.4,0,.2,1));
}
.indo-about-testimonials__card:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
    transform: translateY(-2px);
}
.indo-about-testimonials__quote {
    margin: 0;
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: clamp(15px, 1.6vw, 17px);
    line-height: 1.6;
    color: var(--indo-charcoal, #212121);
    font-style: italic;
    flex: 1;
}
.indo-about-testimonials__quote p {
    margin: 0 0 0.8em;
}
.indo-about-testimonials__quote p:last-child { margin-bottom: 0; }

/* Belt-and-braces typography unification (Issue B):
 * The Birmingham testimonial source HTML had `<span style="font-size: 20.8px;">`
 * wrapping the whole quote. The shortcode now strips inline `style="..."` server-
 * side, but in case a future testimonial slips through with inline typography
 * we also unify any descendant element to the parent's font-size + line-height.
 * Every testimonial renders identically regardless of source HTML quirks. */
.indo-about-testimonials__quote,
.indo-about-testimonials__quote * {
    font-size: inherit !important;
    line-height: inherit !important;
    font-family: inherit !important;
    font-weight: inherit !important;
}
.indo-about-testimonials__quote * {
    color: inherit !important;
}

/* Attribution row — flex layout that swaps to column on mobile so logo
 * goes full-width per Tom's spec. */
.indo-about-testimonials__attrib {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: auto; /* pin to card bottom even when quote is short */
}
.indo-about-testimonials__logo {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
    max-height: 80px;
    object-fit: contain;
    object-position: left center;
}
.indo-about-testimonials__meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.indo-about-testimonials__name {
    margin: 0;
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--indo-cyan, #00a6db);
    line-height: 1.2;
}
.indo-about-testimonials__role {
    margin: 0;
    font-family: var(--indo-font-body, "Inter", sans-serif);
    font-size: 13px;
    color: var(--indo-charcoal, #212121);
    opacity: 0.7;
    line-height: 1.3;
}

/* Mobile (≤768): logo is FULL-WIDTH of the card's text column.
 * Tom's directive: "logo is full-width of the testimonial card". The
 * text column is the inner area inside the card padding. We drop the
 * max-height cap (it was capping at 96px and stopping logos from
 * filling the width) and let logos render at their natural aspect at
 * the full text-column width. object-fit:contain preserves aspect
 * without distortion. */
@media (max-width: 768px) {
    .indo-about-testimonials__attrib {
        align-items: stretch;
    }
    .indo-about-testimonials__logo {
        display: block;
        width: 100%;
        max-width: 100%;
        height: auto;
        max-height: none;
        object-fit: contain;
        object-position: center center;
        margin-bottom: 8px;
    }
    .indo-about-testimonials__meta {
        text-align: center;
        align-items: center;
    }

    /* Issue D: widen the mobile testimonial container by breaking out of
     * the Elementor section/column padding chain. Without this, ancestor
     * padding leaves the card at ~55% viewport width.
     * Pattern: span 100vw and offset back to align with viewport edges. */
    .indo-about-testimonials {
        width: 100vw;
        margin-left: calc(50% - 50vw);
        max-width: 100vw;
        padding-inline: 0;
    }
    .indo-about-testimonials .indo-container {
        max-width: none;
        padding-inline: 0;
        width: 100%;
    }
    .indo-about-testimonials__grid {
        padding-inline: 16px;
        max-width: none;
    }
}

/* Tighter at 320 — keep gutter slightly smaller to maximise card width. */
@media (max-width: 360px) {
    .indo-about-testimonials__grid {
        padding-inline: 12px;
    }
}

/* Tablet (769-1023): logo right-aligned, meta on left, single row. */
@media (min-width: 769px) and (max-width: 1023px) {
    .indo-about-testimonials__attrib {
        flex-direction: row;
        align-items: center;
        gap: 14px;
    }
    .indo-about-testimonials__card .indo-about-testimonials__meta {
        order: 1;
        flex: 1 1 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .indo-about-testimonials .indo-about-testimonials__logo,
    .indo-about-testimonials__card .indo-about-testimonials__logo {
        order: 2;
        width: auto !important;
        max-width: 110px !important;
        max-height: 60px !important;
        flex-shrink: 0;
    }
}

/* Desktop (≥1024): logo on the left of attribution row, meta on the right.
 * Logo capped at 110×60 so it reads as a brand mark inside the card while
 * leaving room for the meta text column. Wide-aspect logos like Westminster
 * (rendered 237×60 at medium_large) used to render at the base 100% and
 * squeeze the meta text off the card — tightening to 110px keeps every logo
 * visually consistent.
 *
 * Selector specificity note: chained the parent class to push specificity
 * to (0,2,0), which beats Elementor's ".elementor img" rule (0,1,1) that
 * was setting max-width:100% from custom-frontend.min.css. */
@media (min-width: 1024px) {
    .indo-about-testimonials__attrib {
        flex-direction: row;
        align-items: center;
        gap: 16px;
    }
    .indo-about-testimonials .indo-about-testimonials__logo,
    .indo-about-testimonials__card .indo-about-testimonials__logo {
        width: auto !important;
        max-width: 110px !important;
        max-height: 60px !important;
        flex-shrink: 0;
    }
    .indo-about-testimonials__card .indo-about-testimonials__meta {
        flex: 1 1 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .indo-about-testimonials__name,
    .indo-about-testimonials__role {
        overflow-wrap: anywhere;
        word-break: normal;
    }
}

/* Small touch-up: when there's no name AND no job, hide the meta block
 * gracefully (the logo alone carries the attribution). The 4 anonymous
 * testimonials with blank name+job render cleanly this way. */
.indo-about-testimonials__card:has(.indo-about-testimonials__attrib > :only-child) .indo-about-testimonials__attrib {
    align-items: center;
}

/* ===== END /about/ testimonials block ===== */

/* ===== /testimonials/ page redesign 2026-05-02 v2 — best-in-class showcase =====
 * Page id 16753. Per Tom: dedicated customer-trust showcase, logos
 * substantial, type hierarchy clear across quote / company / role.
 *
 * Card structure (re-ordered via CSS, DOM unchanged):
 *   1. Logo (centered, large)
 *   2. Cyan accent quote glyph
 *   3. Quote text (Lexend Deca, breathing room)
 *   4. Company name (Inter 14, semibold)
 *   5. Job title  (Inter 12, muted)
 *
 * Re-ordering uses `display: contents` on the testimonial-meta wrapper
 * so its grandchildren (image, name, job) become flex siblings of the
 * content paragraph at the wrapper level. Browser support for
 * display:contents is universal in 2024+; accessibility caveats
 * (Chrome <89 stripping roles) are no longer a concern.
 *
 * All rules scoped to body.page-id-16753 so the same Elementor
 * testimonial widget renders normally elsewhere on the site.
 * ==================================================================== */

/* Section heading ("Find out what other customers have said...") */
body.page-id-16753 .elementor-widget-heading h1.elementor-heading-title,
body.page-id-16753 .elementor-widget-heading h2.elementor-heading-title {
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-weight: 200;
    font-size: clamp(28px, 4vw, 44px);
    line-height: 1.15;
    text-align: center;
    color: var(--indo-charcoal, #212121);
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

/* Card shell */
body.page-id-16753 .elementor-widget-testimonial {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 8px;
    height: 100%;
    transition: box-shadow .25s ease, transform .25s ease;
}
body.page-id-16753 .elementor-widget-testimonial:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
    transform: translateY(-2px);
}
body.page-id-16753 .elementor-widget-testimonial > .elementor-widget-container {
    height: 100%;
    padding: clamp(28px, 3vw, 48px) clamp(24px, 2.4vw, 36px);
}

/* Wrapper becomes flex column; meta wrappers go contents */
body.page-id-16753 .elementor-testimonial-wrapper {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: clamp(20px, 2vw, 28px) !important;
    text-align: center !important;
    height: 100%;
}
body.page-id-16753 .elementor-testimonial-meta,
body.page-id-16753 .elementor-testimonial-meta-inner {
    display: contents !important;
}

/* 1. Logo at top — substantial, centered, in colour */
body.page-id-16753 .elementor-testimonial-image {
    order: 1 !important;
    width: clamp(140px, 16vw, 200px) !important;
    height: clamp(140px, 16vw, 200px) !important;
    min-width: 0 !important;
    max-width: 200px;
    flex: 0 0 auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    border-radius: 0 !important;
    margin: 0 auto !important;
}
body.page-id-16753 .elementor-testimonial-image img {
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    max-height: 100% !important;
    object-fit: contain !important;
    border-radius: 0 !important;
    /* Logos remain in colour on this page (vs grayscale on /about/'s
     * partner strip). Trust signal is stronger when they read as
     * branded marks, not muted thumbnails. */
}

/* 2 + 3. Quote text with cyan accent glyph */
body.page-id-16753 .elementor-testimonial-content {
    order: 2 !important;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif) !important;
    font-size: clamp(16px, 1.2vw, 18px) !important;
    line-height: 1.6 !important;
    color: var(--indo-charcoal, #212121) !important;
    font-style: normal !important;
    font-weight: 300 !important;
    position: relative;
    padding: 28px 0 0 !important;
    margin: 0 !important;
    flex: 1 1 auto;
}
body.page-id-16753 .elementor-testimonial-content::before {
    content: "\201C"; /* left double quotation mark U+201C */
    position: absolute;
    top: -10px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-size: 64px;
    line-height: 0.6;
    color: var(--indo-cyan, #00a6db);
    font-weight: 300;
}

/* 4. Company name */
body.page-id-16753 .elementor-testimonial-name {
    order: 3 !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    color: var(--indo-charcoal, #212121) !important;
    line-height: 1.3 !important;
    letter-spacing: 0.01em !important;
    margin: 8px 0 0 !important;
    padding: 0 !important;
}

/* 5. Job title */
body.page-id-16753 .elementor-testimonial-job {
    order: 4 !important;
    font-family: var(--indo-font-body, "Inter", system-ui, sans-serif) !important;
    font-size: 12px !important;
    font-weight: 400 !important;
    color: rgba(33, 33, 33, 0.6) !important;
    line-height: 1.3 !important;
    margin: 2px 0 0 !important;
    padding: 0 !important;
    letter-spacing: 0.02em !important;
}

/* Tighter mobile sizing — Tom: "quote could be smaller on mobile" */
@media (max-width: 767px) {
    body.page-id-16753 .elementor-testimonial-content {
        font-size: 16px !important;
        padding-top: 24px !important;
    }
    body.page-id-16753 .elementor-testimonial-content::before {
        font-size: 52px;
    }
    body.page-id-16753 .elementor-testimonial-image {
        width: 140px !important;
        height: 140px !important;
    }
    body.page-id-16753 .elementor-widget-testimonial > .elementor-widget-container {
        padding: 32px 24px;
    }
}

@media (max-width: 360px) {
    body.page-id-16753 .elementor-testimonial-image {
        width: 120px !important;
        height: 120px !important;
    }
    body.page-id-16753 .elementor-testimonial-content {
        font-size: 15px !important;
    }
}

/* Generous vertical spacing between cards. */
@media (max-width: 767px) {
    body.page-id-16753 .e-flex > .e-con-full {
        margin-bottom: 16px;
    }
}

/* Tablet (768-1023): force 2-col grid. Default Elementor flex shows 1-col
 * here. Flatten the nested row containers so all 28 cells become direct
 * grid items of b48467f. */
@media (min-width: 768px) and (max-width: 1023px) {
    body.page-id-16753 .elementor-element-b48467f {
        display: grid !important;
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 24px !important;
        flex-direction: initial !important;
    }
    body.page-id-16753 .elementor-element-c12597b,
    body.page-id-16753 .elementor-element-8cffc11,
    body.page-id-16753 .elementor-element-faf0e76 {
        display: contents !important;
    }
}
/* ===== END /testimonials/ page redesign ===== */

/* ===== /contacts/ form fixes 2026-05-02 =====
 * Two issues Tom flagged on the WPForms contact form (form 16168, page 92):
 *
 *  (a) GHOST LABEL DUPLICATION. WPForms is configured with label_hide=1 on
 *      Full Name / Company / Email / Phone, expecting placeholders to carry
 *      the label text. The /contacts/ design re-shows those labels above
 *      each input via the existing `body.page-id-92 ... position: static
 *      !important` rule. The placeholders ALSO render — creating a
 *      duplicate "Email* / Email*" effect (label above, placeholder
 *      inside). Tom wants visible labels, no ghost placeholders. Hide
 *      placeholders site-locally on /contacts/.
 *
 *  (b) BLANK SUBMIT BUTTON. The WPForms submit ships with an inline
 *      <svg viewBox="0 0 13 20"> chevron after the text node. The SVG has
 *      no width/height attributes, and the wpforms-full reset sets
 *      `* { height: auto }`, so the SVG resolved to ~132×204px — fully
 *      overflowing the 190×44 button and pushing the "Send a message"
 *      text out of the visible bounds. Constrain it to 13×20 (its
 *      intrinsic viewBox) so the label renders alongside.
 * ============================================================ */
body.page-id-92 .wpforms-form input::placeholder,
body.page-id-92 .wpforms-form input::-webkit-input-placeholder,
body.page-id-92 .wpforms-form textarea::placeholder {
    color: transparent !important;
    opacity: 0 !important;
}
body.page-id-92 .wpforms-form button[type="submit"] svg,
body.page-id-92 .wpforms-form .wpforms-submit svg {
    width: 13px !important;
    height: 20px !important;
    flex: 0 0 auto;
    margin-left: 8px;
    vertical-align: middle;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
}
/* ===== END /contacts/ form fixes ===== */

/* ===== /returns-claim/ Ninja Forms next/prev buttons 2026-05-02 =====
 * Page id 16797. Ninja Forms ships an inline `<style>` rule in the form
 * markup that hard-codes `.nf-next-item .nf-next { width: 75px }` (and
 * the same for .nf-previous-item .nf-previous). That collides with our
 * theme's `body.page-id-16797 .nf-form-cont .nf-next { padding: 12px 28px }`
 * — 75px button - 56px horizontal padding leaves ~19px for the label
 * "Next >" which is ~50px wide → text clips to "NEX" / "NEXT" at every
 * viewport. (Initially scoped to ≤768; promoted to all viewports once
 * desktop verification showed the same clipping there.)
 *
 * Fix: override the inline width to auto on both the <li> wrapper AND
 * the <input> button so they grow to fit content + padding.
 * ============================================================ */
body.page-id-16797 .nf-next-item,
body.page-id-16797 .nf-previous-item {
    width: auto !important;
    min-width: 0 !important;
}
body.page-id-16797 .nf-next-item .nf-next,
body.page-id-16797 .nf-previous-item .nf-previous {
    width: auto !important;
    min-width: 0 !important;
}
/* ===== END /returns-claim/ button fix ===== */

/* ===== Mobile menu chevrons: hide at desktop 2026-05-02 =====
 * The setupAccordion() JS in header.js injects an .indo-acc-chev <button>
 * next to every .menu-item-has-children's <a>. The chevron's positioning
 * styles are scoped to @media (max-width: 991px) — at desktop the buttons
 * have no CSS, default to inline-block 32×16, and leak as empty 32px
 * spaces between top-level nav items.
 *
 * Suppress them on desktop. Mobile rules at line ~7567 onward continue to
 * style + position them as the accordion toggles.
 * ============================================================ */
@media (min-width: 992px) {
    .site-header__nav .indo-acc-chev {
        display: none !important;
    }
}
/* ===== END mobile menu chevrons desktop hide ===== */

/* ===== /horticultural-lighting/ hero scrim deepen 2026-05-02 =====
 * The /horticultural-lighting/ pillar hero was swapped to the top-light-hero-v2
 * glasshouse-corridor image (post 17989, body class page-id-17989). The base
 * .indo-pillar-hero__scrim gradient (charcoal 0.55 → 0.35 → 0.85) reads fine
 * over the previously-used Borrmann installation but isn't strong enough over
 * this brighter image — the white H1 + white lede ride into a high-key sky
 * area at the top of the frame. Override with a uniform black overlay on
 * this page only so text contrast lands cleanly without darkening every
 * other pillar page.
 *
 * Tom asked for a "black overlay across the front" — keeping the gradient
 * shape but pulling the values toward black + bumping minimum opacity.
 * ============================================================ */
body.page-id-17989 .indo-pillar-hero__scrim {
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.62) 0%,
        rgba(0, 0, 0, 0.50) 35%,
        rgba(0, 0, 0, 0.78) 100%
    );
}
/* ===== END /horticultural-lighting/ hero scrim ===== */

/* ===== Site-wide customer-quote treatment 2026-05-02 =====
 * Tom: customer quotes across the site previously rendered in plain
 * paragraph font — no italic, no border, no glyph — visually
 * indistinguishable from body copy. Unify under a single `.indo-quote`
 * class with a deliberate brand-on treatment: 4px cyan left border, large
 * cyan opening-quote glyph hanging top-left, italic Lexend Deca display
 * font, generous breathing room.
 *
 * Scope: applied to <blockquote class="indo-quote"> wrappers only — does
 * NOT catch generic <blockquote>s used for non-customer purposes (regulatory
 * citations, INDO pull-quotes, etc) which were classified per-post and left
 * un-retagged. The /testimonials/ + /about/ Elementor testimonial widget
 * styling stays as the showcase reference (cyan glyph centred, Lexend Deca
 * larger). This rule is the inline-body-of-a-page treatment, scaled down.
 *
 * .indo-quote--center is for centred quotes (the legacy gdlr-align-center
 * pattern + my retrofit-for-purpose conversion). Drops the left border,
 * centres glyph + text.
 * ============================================================ */
.indo-quote {
    position: relative;
    margin: clamp(28px, 4vw, 48px) 0;
    padding: clamp(20px, 3vw, 32px) clamp(20px, 3vw, 32px) clamp(20px, 3vw, 32px) clamp(28px, 4vw, 48px);
    border-left: 4px solid var(--indo-cyan, #00a6db);
    background: transparent;
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-style: italic;
    font-weight: 300;
    font-size: clamp(17px, 1.4vw, 20px);
    line-height: 1.55;
    color: var(--indo-charcoal, #212121);
}

.indo-quote::before {
    content: "\201C"; /* left double quotation mark U+201C */
    position: absolute;
    top: -4px;
    left: clamp(16px, 2.4vw, 28px);
    font-family: var(--indo-font-display, "Lexend Deca", sans-serif);
    font-size: clamp(36px, 4vw, 56px);
    line-height: 1;
    color: var(--indo-cyan, #00a6db);
    font-weight: 200;
}

/* Centred variant: legacy gdlr-align-center pattern + my retrofit-for-purpose
 * conversion. Drops the border and centres the glyph + text. */
.indo-quote.indo-quote--center,
.indo-quote.gdlr-align-center {
    border-left: 0;
    padding-left: clamp(20px, 3vw, 32px);
    text-align: center;
}
.indo-quote.indo-quote--center::before,
.indo-quote.gdlr-align-center::before {
    left: 50%;
    transform: translateX(-50%);
}

@media (max-width: 767px) {
    .indo-quote {
        font-size: 16px;
        margin: clamp(20px, 4vw, 32px) 0;
    }
    .indo-quote::before {
        font-size: 36px;
    }
}
/* ===== END site-wide customer-quote treatment ===== */

/* ===== /contacts/ Google Map full-bleed 2026-05-02 =====
 * The map iframe (Google Maps embed inside Elementor's google_maps widget,
 * section .elementor-element-3bdf5b6 on page-id-92) was constrained to
 * the boxed 1425px container with ~125px of bottom padding before the
 * footer. Tom: full-width with the white space below removed.
 *
 * Approach: 100vw break-out on the section (mirrors the standard
 * indo-2026 stretched-section pattern), zero horizontal padding through
 * the container/column/widget chain, zero bottom padding on the section,
 * and force the iframe to fill 100% width.
 * ============================================================ */
body.page-id-92 .elementor-element-3bdf5b6 {
    /* Break out of any boxed parent into full viewport width */
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-bottom: 0 !important;
    /* Also collapse top padding so the map butts up cleanly against the
     * section above it. If Tom wants a small visual gap above, dial this
     * back to e.g. clamp(8px, 1vw, 16px). */
    padding-top: 0 !important;
    margin-bottom: 0 !important;
}
body.page-id-92 .elementor-element-3bdf5b6 > .elementor-container {
    max-width: 100% !important;
    width: 100% !important;
    padding: 0 !important;
}
/* (2026-05-05) column 3a0f495 padding migrated to _elementor_data; google_maps widget
   24baf63 _padding/_margin migrated to _elementor_data. The legacy
   margin-bottom + widget-container reset rules are no longer needed. */
body.page-id-92 .elementor-element-3bdf5b6 .elementor-custom-embed {
    padding: 0 !important;
    margin: 0 !important;
    width: 100%;
}
body.page-id-92 .elementor-element-3bdf5b6 iframe {
    display: block; /* removes the inline-baseline gap under iframes */
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    border: 0 !important;
}
/* ===== END /contacts/ map full-bleed ===== */

/* ===== Homepage Google Map full-bleed 2026-05-02 =====
 * Same treatment as /contacts/ but scoped to body.home and the homepage's
 * Elementor v3 flex-container parent (.elementor-element-7752216) +
 * map widget (.elementor-element-1531b36). Tom: full-width with the
 * mobile white space below removed.
 * ============================================================ */
body.home .elementor-element-7752216 {
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-bottom: 0 !important;
    /* The Elementor flex container had a 424px min-height with
       `justify-content: center`, which left ~29px of empty space above
       AND below the 366px-tall map iframe — visible as a stripe of
       white between the map and the footer (and a matching stripe
       above). Collapse to fit-content so the container hugs the map. */
    min-height: 0 !important;
    height: auto !important;
}
/* (2026-05-05) 1531b36 widget _padding/_margin migrated to _elementor_data;
   the redundant margin-bottom:0 + widget-container reset rules removed. */
body.home .elementor-element-1531b36 .elementor-custom-embed {
    padding: 0 !important;
    margin: 0 !important;
    width: 100%;
}
body.home .elementor-element-1531b36 iframe {
    display: block;          /* removes the inline-baseline gap that creates the visible mobile white-space below */
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    border: 0 !important;
    vertical-align: bottom;  /* belt-and-braces against any inherited inline-block alignment */
}
/* ===== END homepage map full-bleed ===== */

/* The mobile-floater-clearance rule at line ~6920 adds 96px padding-bottom
 * to <main> at ≤480px so the Get-a-Quote / cookie floaters don't overlap
 * footer copy. On pages where the LAST element is a full-bleed map (home
 * + /contacts/), that 96px padding leaves an awkward white stripe between
 * the map and the dark footer. Zero it out on those two pages. The
 * floaters still clear the dark footer naturally because there's no copy
 * to overlap once the map is the final body element. */
@media (max-width: 480px) {
    body.home main,
    body.page-id-92 main {
        padding-bottom: 0 !important;
    }
}

/* ===== Homepage section vertical padding tighten 2026-05-02 =====
 * Tom: every top-level section on /home has its own ad-hoc vertical
 * padding (110/110, 88/88, 80/80, 104/112, 100/120) — inconsistent,
 * adds up to ~300px of dead air between "Successfully completed
 * projects" and "Find out more" alone. Tighten to a unified scale.
 *
 * Scale chosen:
 *   Default sections     → clamp(48px, 5vw, 72px) top + bottom
 *   "Trusted by" section → clamp(40px, 4vw, 56px) top + bottom (lighter
 *                           trim per Tom — keep some breathing room
 *                           because the logos already feel sparse)
 *
 * Section IDs (locked to the current build):
 *   89ad7fd — UK manufacturer / "WHAT MAKES US UNIQUE" CTA   (was 110/110)
 *   9e24185 — Delivering value since 2007 / Made in Britain  (was 88/88)
 *   bc68b9f — Trusted By                                     (was 80/80)
 *   9e0df2f — Successfully completed projects                (was 104/112)
 *   4e3d2f3 — Find out more / contact form                   (was 100/120)
 *
 * If section IDs change in a future Elementor edit, these rules need
 * re-targeting. Comment markers in style.css per Tom's audit convention.
 * ============================================================ */
/* High-specificity selectors needed to beat:
 *   - `body.home .elementor-section:has(.elementor-widget-image-carousel)` ((0, 3, 1), legacy line ~869)
 *   - `body.home .elementor.elementor-393 > .elementor-section:nth-last-child(2)` ((0, 4, 1), legacy)
 *   - per-section padding rules at lines ~1177, ~7312
 *
 * SUPERSEDED 2026-05-03 by the site-wide design-system rule below
 * (search "SITE-WIDE SECTION RHYTHM"). The homepage-specific overrides
 * here are kept as a TRACE for reference but commented out. They were
 * cycle 2.2.x band-aids before Tom's site-wide design-system brief.
 *
 * body.home main .elementor.elementor-393 .elementor-section.elementor-element-89ad7fd,
 * body.home main .elementor.elementor-393 .elementor-section.elementor-element-9e24185,
 * body.home main .elementor.elementor-393 .elementor-section.elementor-element-9e0df2f,
 * body.home main .elementor.elementor-393 .elementor-section.elementor-element-4e3d2f3 {
 *     padding-top: clamp(48px, 5vw, 72px) !important;
 *     padding-bottom: clamp(48px, 5vw, 72px) !important;
 * }
 * body.home main .elementor.elementor-393 .elementor-section.elementor-element-bc68b9f {
 *     padding-top: clamp(40px, 4vw, 56px) !important;
 *     padding-bottom: clamp(40px, 4vw, 56px) !important;
 * }
 */
/* ===== END homepage section padding tighten (now superseded) ===== */


/* ============================================================
 * SITE-WIDE SECTION RHYTHM (2.3.3, 2026-05-03 — supersedes 2.3.0)
 *
 * Tom brief: every primary page should use the same inter-section
 * vertical gap, sourced from --indo-section-pad-y-* tokens.
 *
 * 2.3.3 changes vs 2.3.0:
 *  A) SPECIFICITY BUMP — selectors now lead with `body .elementor`
 *     and `body .indo-...` to defeat per-post cached Elementor CSS
 *     (post-XXX.css selectors like `body.elementor-page-393
 *     .elementor-393 .elementor-element-XXX` are (0,3,0) — adding
 *     `body` + a chained class lifts ours to (0,3,0) too, and
 *     cascade order then wins because we define after the per-post
 *     CSS loads).
 *
 *  B) EXTENDED SELECTOR — covers custom theme classes that the v2.3.0
 *     selector missed:
 *       .indo-pillar-section  (pillar pages: /exterior-lighting/,
 *                              /horticultural-lighting/, /direct-drive/,
 *                              /about/'s body sections, /retrofit-for-purpose/)
 *       .indo-cta-band        (CTA bands at the foot of pillar pages)
 *       .indo-stats-strip     (stat counters near pillar-page heroes)
 *       .indo-section         (product-category archive body sections,
 *                              /retrofit-for-purpose/ body sections)
 *       .indo-archive         (project + post archive grids — /projects/)
 *       .indo-archive-intro   (intro band above archive grids)
 *
 *  C) OPT-OUT HOOKS — sections that intentionally render flush:
 *       .indo-hero, .indo-pillar-hero — full-bleed photographic heroes
 *         with their own internal header-clearance padding (101/32 etc).
 *         Token padding would break that, so excluded entirely.
 *       .indo-section--flush, .indo-archive--flush — modifier hooks for
 *         per-instance opt-outs.
 *       Per-page Google Map sections (homepage, /contacts/) — already
 *         opt-out from 2.3.0, retained.
 *
 * !important needed to defeat per-post Elementor CSS (loaded after
 * theme CSS but lower-or-equal specificity — !important wins).
 *
 * Tokens (defined in :root):
 *   mobile  --indo-section-pad-y-mobile  56px → gap 112
 *   tablet  --indo-section-pad-y-tablet  72px → gap 144
 *   desktop --indo-section-pad-y-desktop 88px → gap 176
 * ============================================================ */

/* Mobile-first base: applies at all viewports unless a per-section
 * Elementor padding override (specificity 0,3,0) takes precedence.
 *
 * 2026-05-05: removed `!important` and dropped the `body` ancestor /
 * doubled-class specificity bumps so the rule sits at (0,2,0). This
 * gives Tom per-section editability via Elementor's UI: when no
 * override is set, the rhythm tokens cascade through; when Tom
 * adjusts a section's padding in Elementor, his per-section rule
 * (0,3,0, loaded later) wins by both specificity AND source order.
 * The OPT-OUT HOOKS block below KEEPS its !important so named
 * flush classes (.indo-section--flush etc) and the targeted
 * page-id rules still always win, regardless of Elementor settings. */
/* Path A: Elementor 4 containers (.e-con.e-parent) consume --padding-top
 * and --padding-bottom via their framework CSS. Set those custom props
 * here so Elementor's per-element CSS (which also sets the same custom
 * props at higher specificity 0,3,0) cleanly wins when an editor sets
 * a value, while empty/unset elements inherit our rhythm defaults. */
.e-con.e-parent {
    --padding-top:    var(--indo-section-pad-y-mobile);
    --padding-bottom: var(--indo-section-pad-y-mobile);
}
/* Path B: legacy Elementor 3.x sections + bespoke INDO classes set
 * padding directly. */
.elementor-section.elementor-top-section,
.indo-pillar-section,
.indo-cta-band,
.indo-stats-strip,
.indo-section,
.indo-archive,
.indo-archive-intro {
    padding-block-start: var(--indo-section-pad-y-mobile);
    padding-block-end:   var(--indo-section-pad-y-mobile);
}

/* Tablet — 768px to 1023px */
@media (min-width: 768px) and (max-width: 1023px) {
    .e-con.e-parent {
        --padding-top:    var(--indo-section-pad-y-tablet);
        --padding-bottom: var(--indo-section-pad-y-tablet);
    }
    .elementor-section.elementor-top-section,
    .indo-pillar-section,
    .indo-cta-band,
    .indo-stats-strip,
    .indo-section,
    .indo-archive,
    .indo-archive-intro {
        padding-block-start: var(--indo-section-pad-y-tablet);
        padding-block-end:   var(--indo-section-pad-y-tablet);
    }
}

/* Desktop — 1024px+ */
@media (min-width: 1024px) {
    .e-con.e-parent {
        --padding-top:    var(--indo-section-pad-y-desktop);
        --padding-bottom: var(--indo-section-pad-y-desktop);
    }
    .elementor-section.elementor-top-section,
    .indo-pillar-section,
    .indo-cta-band,
    .indo-stats-strip,
    .indo-section,
    .indo-archive,
    .indo-archive-intro {
        padding-block-start: var(--indo-section-pad-y-desktop);
        padding-block-end:   var(--indo-section-pad-y-desktop);
    }
}

/* OPT-OUT HOOKS — sections that intentionally render flush.
 * Defined AFTER the in-scope rules so cascade-order wins (matched
 * specificity, last wins). */
body .indo-hero.indo-hero,
body .indo-pillar-hero.indo-pillar-hero,
body .indo-section--flush.indo-section--flush,
body .indo-archive--flush.indo-archive--flush,
body.home .elementor-element.elementor-element-7752216,         /* homepage Google Map (full-bleed) */
body.page-id-92 .elementor-element.elementor-element-3bdf5b6 {  /* /contacts/ Google Map (full-bleed) */
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}
/* /about/ Meet the Team is now controlled via Elementor's per-section
   padding setting (stored in _elementor_data). Removed the targeted CSS
   rule 2026-05-05 so Tom sees and edits the value from the Elementor UI. */
/* ===== END SITE-WIDE SECTION RHYTHM ===== */


/* ============================================================
 * fix-pillar-hero-cta-mobile-edge-001  (2026-05-03, 2.3.6)
 *
 * Tom-flagged: cyan filled-rectangle CTA buttons in .indo-pillar-hero
 * blocks stretch to the full inner content width on mobile, leaving
 * only the parent's 16px inner padding from the dark hero edge. Buttons
 * read visually cramped against the hero block edge.
 *
 * Affects: /exterior-lighting/, /horticultural-lighting/, /direct-drive/,
 * /about/, /product/skysync/ (every page using the .indo-pillar-hero
 * pattern). Single CSS rule covers all 5.
 *
 * At desktop (≥768px) the CTA is flex-direction: row and buttons are
 * auto-width — issue is mobile-only.
 *
 * Fix (Flavour A, agent's pick): add horizontal padding to the CTA
 * container on mobile. Buttons still fill the row width but with
 * additional 16-32px breathing room (clamps with viewport).
 * ============================================================ */
@media (max-width: 767px) {
    .indo-pillar-hero__cta {
        padding-left:  clamp(16px, 4vw, 32px);
        padding-right: clamp(16px, 4vw, 32px);
    }
}
/* ===== END fix-pillar-hero-cta-mobile-edge-001 ===== */


/* ============================================================
 * fix-contacts-001  (2026-05-04, 2.3.7)
 *
 * Issue: Get-in-Touch form on /contacts/ (page-id-92, wpforms-form-16168)
 * had only a 1px bottom border at rgba(255,255,255,0.35) — visually
 * indistinct against the dark navy form panel and barely showed where
 * fields begin/end. Select widget rendered with no border at all.
 * Affects every form submission. WCAG 2.1 1.4.11 (non-text contrast).
 *
 * Specificity note: industrium theme.css ships
 *   `div.wpforms-container.wpforms-container-full .wpforms-form input[type="text"]`
 *   (specificity 0,4,2). To win, prefix `body.page-id-92` and mirror the
 *   div + container chain exactly, then attribute selectors per type.
 *
 * Fix: full 1px box border at rgba(255,255,255,0.45) on every input,
 * textarea, select, and the choices.js wrapper. On focus, border
 * becomes solid INDO cyan #00a6db with a 1px outer ring shadow.
 * ============================================================ */
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="text"],
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="email"],
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="tel"],
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="url"],
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="number"],
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form textarea,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form select,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form .choices__inner {
    border: 1px solid rgba(255, 255, 255, 0.45) !important;
    background-color: rgba(255, 255, 255, 0.06) !important;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="text"]:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="email"]:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="tel"]:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="url"]:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form input[type="number"]:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form textarea:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form select:focus,
body.page-id-92 div.wpforms-container.wpforms-container-full .wpforms-form .choices.is-focused .choices__inner {
    border-color: #00a6db !important;
    box-shadow: 0 0 0 1px #00a6db !important;
    outline: none !important;
}
/* ===== END fix-contacts-001 ===== */


/* ============================================================
 * fix-product-category-top-light-008  (2026-05-04, 2.3.8)
 *
 * Issue: /product-category/top-light/ archive hero (term-108) uses
 * BioGartenbau_Hero.webp — a high-key bright greenhouse photo.
 * The base .indo-hero__media::after scrim is weak (0.20 → 0.45 black)
 * so the white H1 + lede ride into a bright sky area with poor
 * contrast (a11y / WCAG 1.4.3).
 *
 * Fix: term-scoped multi-stop scrim mirroring /direct-drive/'s
 * pattern (0.72 / 0.55 / 0.88) but slightly darkened toward black
 * for the brighter image, matching the /horticultural-lighting/
 * treatment that was already proven on a similar bright greenhouse.
 * ============================================================ */
body.term-108 .indo-hero__media::after {
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.62) 0%,
        rgba(0, 0, 0, 0.50) 35%,
        rgba(0, 0, 0, 0.78) 100%
    ) !important;
}
/* ===== END fix-product-category-top-light-008 ===== */


/* ============================================================
 * fix-product-category-led-retrofit-lamps-006  (2026-05-04, 2.3.9)
 *
 * Issue: /product-category/exterior-lighting/led-retrofit-lamps/
 * archive (term-105) hero uses indo-retrofit-sign-light-hero-v2 — a
 * road shot with a "One way" road sign as the focal point. The base
 * .indo-hero__media::after scrim (0.20 → 0.45 black) leaves the white
 * H1 colliding visually with the sign.
 *
 * Tom directive: CSS-only, NO image swap. Darken the scrim heavier
 * at the TOP where the sign + H1 sit (not bottom-heavy like the
 * default).
 *
 * Fix: term-scoped multi-stop scrim with strong top weighting:
 * 0.78 top → 0.55 mid → 0.55 bottom (inverted vs default so the
 * upper half where the sign + H1 live gets the heaviest darken).
 * ============================================================ */
body.term-105 .indo-hero__media::after {
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.82) 0%,
        rgba(0, 0, 0, 0.65) 50%,
        rgba(0, 0, 0, 0.55) 100%
    ) !important;
}
/* ===== END fix-product-category-led-retrofit-lamps-006 ===== */


/* ============================================================
 * fix-retrofit-for-purpose-001  (2026-05-04, 2.3.11)
 *
 * Issue: /retrofit-for-purpose/ (post 1368) had its opening lede
 * paragraph wrapped in <h5><span style="color: #00a5db;">...</span></h5>
 * — semantically wrong (h5 used for body copy), and inline span set
 * the lede in cyan (clashed with the dark body text below).
 *
 * Fix: post_content edit (wp eval-file) swapped the <h5> for
 * <p class="indo-lede">. This rule supplies the typographic intent
 * the original cyan h5 was reaching for: slightly larger body size,
 * comfortable line-height, charcoal text. Class is generic enough
 * to be reused on future posts.
 * ============================================================ */
.indo-lede {
    font-size: 1.125rem;
    line-height: 1.6;
    color: #213240;
    margin: 0 0 1.5em;
    font-weight: 400;
}
@media (min-width: 768px) {
    .indo-lede {
        font-size: 1.25rem;
    }
}
/* ===== END fix-retrofit-for-purpose-001 ===== */


/* ============================================================
 * fix-returns-claim-001  (2026-05-04, 2.3.12)
 *
 * Issue: /returns-claim/ step buttons (Ninja Forms multi-part
 * breadcrumb pattern .nf-breadcrumbs li) showed a small ↘ arrow icon
 * truncated at the top-left corner of every step. Diagnosis: the
 * inherited industrium theme.css rule
 *     ul > li::before {
 *       content: ""; font: 0.6667em / 1em fontello;
 *       position: absolute; top: 0.7em; left: 0;
 *     }
 * adds a fontello icon to EVERY ul > li globally as a custom bullet.
 * Ninja Forms multi-part sets `list-style-type: none !important` but
 * doesn't reset the ::before, so the bullet renders on the breadcrumb
 * <li>s and lands at the rounded-corner of the button — half visible,
 * looks truncated.
 *
 * Fix: suppress the inherited bullet pseudo on the breadcrumb list.
 * The active step is already indicated by the cyan background; no
 * additional indicator is needed.
 * ============================================================ */
.nf-breadcrumbs li::before,
.nf-next-previous li::before {
    content: none !important;
    display: none !important;
}
/* ===== END fix-returns-claim-001 ===== */


/* ============================================================
 * fix-product-category-vertical-farming-004  (2026-05-04, 2.3.13)
 *
 * Issue: /product-category/vertical-farming/ shows a single VertiLink
 * card in the .indo-card-grid (a 2-col grid at desktop). The card sits
 * stranded in column 1, leaving the second column empty — looks like
 * a layout error / missing product.
 *
 * Generic fix: when an .indo-card-grid contains only a single child,
 * span that child across all grid columns and centre it. Capped at
 * 600px max-width so it doesn't stretch ungainly. Applies anywhere a
 * sparse archive surfaces a single product card.
 * ============================================================ */
.indo-card-grid > li:only-child {
    grid-column: 1 / -1;
    max-width: 600px;
    width: 100%;
    justify-self: center;
}
/* ===== END fix-product-category-vertical-farming-004 ===== */


/* (REMOVED 2026-05-05) fix-testimonials-001 was a page-scoped padding
   override on /testimonials/ (post 16753). The padding values are now
   stored in _elementor_data (containers 8549890 and b48467f) and the
   global rhythm rule has been migrated to logical properties
   (padding-block-start/end) so Elementor's per-element rules win
   cleanly by selector specificity. Tom now edits via the Elementor UI. */


/* ============================================================
 * fix-returns-claim-002  (2026-05-04, 2.3.20)
 *
 * Issue: /returns-claim/ Ninja Forms title "Online Customer Return
 * Form" wrapped awkwardly at 375 with the trailing word ("Form") on
 * its own line as an orphan.
 *
 * Fix: text-wrap: balance on the form title so the browser shares
 * width across both lines evenly. Generic — applies to any Ninja
 * Forms title across the site.
 * ============================================================ */
.nf-form-title h3 {
    text-wrap: balance;
    text-align: left;
}
/* ===== END fix-returns-claim-002 ===== */


/* ============================================================
 * fix-contacts-003 + fix-contacts-004  (2026-05-04, 2.3.20)
 *
 * #003: WPForms label "What prompted you to contact us today?"
 * followed by required-asterisk <span> wrapped at 1024 with the
 * asterisk landing alone on the second line. Use white-space:nowrap
 * on the trailing required-label span so it stays attached to the
 * preceding word ("today?*" stays together).
 *
 * #004: industrium-heading h5 "INDO Technologies" wrapped to two
 * lines at 1024 in the contact-info column. Use white-space:nowrap
 * on the span so the heading stays on a single line. (Generic to
 * all industrium_heading widgets containing single-phrase headings;
 * if it bites a future longer heading we'll scope it tighter.)
 * ============================================================ */
body.page-id-92 .wpforms-form .wpforms-field-label .wpforms-required-label {
    white-space: nowrap;
    margin-left: 0.15em;
}
body.page-id-92 .elementor-element-aacff6d h5.industrium-heading .industrium-heading-content {
    white-space: nowrap;
}
/* ===== END fix-contacts-003 + fix-contacts-004 ===== */

/* ===== FIX-PRODUCT-GALLERY-HOVER 2026-05-05 =====
   Hovering a single-product image revealed a "duplicated" fragment
   below the lamp (the bottom of the source asset showing twice).
   Cause: WooCommerce JS sets an inline padding-top in pixels on
   .woocommerce-product-gallery__image > a (locking the wrapper to a
   near-square aspect derived from the largest image), but the IMG
   inside is rebased to 4:3 by the rule at line ~2368. The 60-90px
   gap between the 4:3 image and the squarer wrapper is filled by
   the hover-zoom layer (img.zoomImg, position:absolute, opacity 1
   on hover), which renders the bottom edge of the source asset and
   reads as a "ghost" copy of the foot of the lamp.

   Fix: lock the wrapper, the inner <a>, and the zoom layer to the
   same 4:3 aspect as the visible image, so there is no gap for the
   zoom to spill into.
   ============================================================ */
.woocommerce.single-product div.product .woocommerce-product-gallery__image {
    aspect-ratio: 4 / 3 !important;
    height: auto !important;
    overflow: hidden;
}
.woocommerce.single-product div.product .woocommerce-product-gallery__image a {
    position: relative;     /* positioning context for the abs-pos img child */
    padding-top: 75% !important;
    height: 0 !important;
}
/* fix-product-image-clip (v2.3.44): the padding-ratio <a> (height:0, padding-top:75%)
 * had no `position:relative`, so block-flow placed the <img> BELOW the 75% padding
 * region — outside the overflow:hidden clip area — clipping the top of the product
 * image. Absolute-position the img inside the padding box instead. */
.woocommerce.single-product div.product .woocommerce-product-gallery__image a img:not(.zoomImg) {
    position: absolute;
    inset: 0;
    height: 100% !important;
    object-fit: contain !important;
}
.woocommerce.single-product div.product .woocommerce-product-gallery__image img.zoomImg {
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    max-height: 100% !important;
    object-fit: contain !important;
    object-position: center !important;
}
/* ===== END FIX-PRODUCT-GALLERY-HOVER ===== */

/* ============================================================
 * fix-pillar-hero-cta-bottom-room  (2026-05-05, Phase C)
 *
 * Tom-flagged: cyan "Browse the range" + ghost "See projects" CTAs in
 * .indo-pillar-hero sit too close to the bottom edge of the hero photo.
 * The pillar-hero uses `align-items: flex-end` and the SITE-WIDE
 * SECTION RHYTHM block above explicitly opts .indo-pillar-hero OUT of
 * padding with `padding-top: 0 !important; padding-bottom: 0 !important`.
 * That zero-bottom-padding parks the CTA block hard against the bottom
 * edge of the hero photo. Result: cyan button rim almost touches the
 * stats-strip seam below.
 *
 * Fix:
 *   1. Re-introduce a bottom padding on .indo-pillar-hero that beats
 *      the opt-out rule (matched body .indo-pillar-hero.indo-pillar-hero
 *      specificity (0,3,0) so the !important values land).
 *   2. Lift the hero image's focal point (object-position: 50% 30%) so
 *      the most interesting part of the photo isn't covered by the
 *      title/lede/CTA stack and so foreground content drifts below the
 *      button row.
 *
 * Defined AFTER the SITE-WIDE SECTION RHYTHM block (line 9531) and AFTER
 * the existing 991px header-gap rule, so cascade order + matched
 * specificity wins.
 *
 * Scope: site-wide on .indo-pillar-hero (single rule covers
 * /horticultural-lighting/, /exterior-lighting/, /direct-drive/,
 * /about/, /skysync/ — every pillar page).
 * ============================================================ */
body .indo-pillar-hero.indo-pillar-hero {
    /* +48-56px breathing room below the CTA at desktop (clamp scales to
       viewport). Beats the `padding-bottom: 0 !important` opt-out
       declared above. */
    padding-bottom: clamp(48px, 6vw, 88px) !important;
}
.indo-pillar-hero__media img {
    /* Was `center 40%`; lift to 30% so the photo's vertical interest
       sits in the upper part of the visible frame, with foreground
       drift naturally tucked below the CTA. */
    object-position: 50% 30%;
}
@media (max-width: 991px) {
    body .indo-pillar-hero.indo-pillar-hero {
        /* +24-40px breathing room on mobile. The header-gap top-padding
           rule at line 8616 (`padding-top: calc(...)`) is preserved
           because we only override padding-bottom here. */
        padding-bottom: clamp(28px, 7vw, 48px) !important;
    }
}
/* ===== END fix-pillar-hero-cta-bottom-room ===== */

/* ===== indo-team-single (single-industrium_team.php) ===== */
.indo-team-single__back { margin: 0 0 24px; font-size: 14px; }
.indo-team-single__back a { color: #00a6db; text-decoration: none; }
.indo-team-single__back a:hover { text-decoration: underline; }
.indo-team-single__intro {
    display: flex;
    gap: clamp(24px, 4vw, 48px);
    align-items: flex-start;
    flex-wrap: wrap;
}
.indo-team-single__photo { flex: 0 0 240px; max-width: 240px; }
.indo-team-single__photo img { width: 100%; height: auto; display: block; border-radius: 4px; }
.indo-team-single__heading { flex: 1 1 320px; min-width: 0; }
.indo-team-single__heading .entry-title { margin: 0 0 8px; }
.indo-team-single__position {
    margin: 0 0 16px;
    font-size: 14px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #00a6db;
    font-weight: 600;
}
.indo-team-single__lede { margin: 0 0 20px; font-size: 18px; line-height: 1.55; color: #444; }
.indo-team-single__socials { list-style: none; padding: 0; margin: 0 0 16px; display: flex; gap: 16px; }
.indo-team-single__socials a { color: #00a6db; text-decoration: none; font-size: 14px; }
.indo-team-single__socials a:hover { text-decoration: underline; }
.indo-team-single__joined { margin: 0; color: #777; font-size: 14px; }
.indo-team-single__body .entry-content h4 { margin-top: 32px; color: #00a6db; }
.indo-team-single__quote {
    border-left: 3px solid #00a6db;
    padding: 8px 0 8px 24px;
    margin: 0;
    font-size: 20px;
    line-height: 1.5;
    color: #222;
    font-style: italic;
}
.indo-team-single__quote p { margin: 0 0 8px; }
.indo-team-single__quote cite { font-size: 14px; color: #777; font-style: normal; }
@media (max-width: 640px) {
    .indo-team-single__photo { flex: 0 0 160px; max-width: 160px; }
}
/* ===== END indo-team-single ===== */

/* ===== indo-lang-dropdown (header flag dropdown) ========================= */
/* Stretch the lang container + dropdown to fill header height so the panel's
 * `top: 100%` anchor lands at the header bottom — same vertical position as the
 * primary-nav sub-menus, regardless of whether the header is in its tall hero
 * variant or the shorter sticky/scrolled variant. */
.site-header__lang { display: flex; align-items: center; align-self: stretch; margin-right: 8px; position: relative; }
.indo-lang-dropdown { position: relative; display: inline-flex; align-items: center; align-self: stretch; }

/* Trigger pill — shows current language flag + code + caret. */
.indo-lang-dropdown__trigger {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 10px;
    border: 0; border-radius: 999px;
    background: transparent;
    font-family: var(--indo-font-body, Inter, sans-serif);
    font-size: 12px; line-height: 1; font-weight: 600; letter-spacing: .04em;
    color: var(--indo-charcoal, #212121);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.indo-lang-dropdown__trigger:hover,
.indo-lang-dropdown__trigger:focus-visible {
    background: rgba(0,0,0,.06);
    outline: none;
}
.indo-lang-dropdown__caret {
    transition: transform .2s ease;
    margin-left: 2px;
    flex: 0 0 auto;
}
.indo-lang-dropdown:hover .indo-lang-dropdown__caret,
.indo-lang-dropdown:focus-within .indo-lang-dropdown__caret,
.indo-lang-dropdown[data-open="true"] .indo-lang-dropdown__caret {
    transform: rotate(180deg);
}

/* Panel — drops down from the trigger with white surface + soft shadow,
 * matching the primary nav dropdowns (POST-LAUNCH-MEGA-MENU pattern). */
.indo-lang-dropdown__panel {
    position: absolute;
    top: 100%; right: 0;
    margin: 0; padding: 6px;
    list-style: none;
    min-width: 220px;
    background: #fff;
    border-radius: 0;
    box-shadow: 0 12px 32px rgba(0,0,0,0.08);
    opacity: 0; visibility: hidden;
    transform: translateY(4px);
    transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
    z-index: 200;
}
/* Hover bridge — a transparent strip between trigger and panel so the
 * cursor doesn't leave the parent box mid-traversal (same pattern as the
 * primary mega-menu in POST-LAUNCH-MEGA-MENU-V8). */
.indo-lang-dropdown::after {
    content: "";
    position: absolute;
    top: 100%; right: 0; left: 0;
    height: 12px;
    pointer-events: none;
}
.indo-lang-dropdown:hover::after,
.indo-lang-dropdown:focus-within::after,
.indo-lang-dropdown[data-open="true"]::after { pointer-events: auto; }

.indo-lang-dropdown:hover .indo-lang-dropdown__panel,
.indo-lang-dropdown:focus-within .indo-lang-dropdown__panel,
.indo-lang-dropdown[data-open="true"] .indo-lang-dropdown__panel {
    opacity: 1; visibility: visible; transform: translateY(0);
    transition-delay: 0s;
}

.indo-lang-dropdown__item { margin: 0; padding: 0; list-style: none; }
.indo-lang-dropdown__item a {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 16px;
    border-radius: 0;
    font-family: var(--indo-font-body, Inter, sans-serif);
    font-size: 13px; line-height: 1.2;
    color: var(--indo-charcoal, #212121);
    text-decoration: none;
    transition: background-color .12s ease, color .12s ease;
}
.indo-lang-dropdown__item a:hover,
.indo-lang-dropdown__item a:focus-visible {
    background: rgba(0,166,219,.08);
    color: var(--indo-cyan, #00a6db);
    outline: none;
}
.indo-lang-dropdown__item.is-active a {
    background: rgba(0,166,219,.12);
    color: var(--indo-cyan, #00a6db);
    font-weight: 600;
}
.indo-lang-dropdown__item .indo-lang-dropdown__code {
    color: var(--indo-gray, #abafb5);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .04em;
    flex: 0 0 26px;
}
.indo-lang-dropdown__item.is-active .indo-lang-dropdown__code,
.indo-lang-dropdown__item a:hover .indo-lang-dropdown__code,
.indo-lang-dropdown__item a:focus-visible .indo-lang-dropdown__code {
    color: var(--indo-cyan, #00a6db);
}

.indo-lang-dropdown__name { flex: 1 1 auto; font-feature-settings: "tnum"; white-space: nowrap; }

/* Flag emoji rendering — WP rewrites unicode flag pairs to img.emoji.
 * Force a stable display size inside the flex layout. */
.indo-lang-dropdown__flag {
    display: inline-flex; align-items: center; flex: 0 0 auto;
    font-size: 14px; line-height: 1;
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
}
.indo-lang-dropdown__flag img.emoji {
    width: 20px !important; height: 14px !important;
    margin: 0 !important; padding: 0 !important;
    flex: 0 0 20px;
    object-fit: contain;
    vertical-align: middle;
    border: 0; background: none;
}

/* Header-on-light variant: when the header is over a transparent hero, give
 * the trigger a light tint so it stays legible on dark backgrounds. */
.site-header:not(.header--on-light) .indo-lang-dropdown__trigger {
    color: rgba(255,255,255,.92);
}
.site-header:not(.header--on-light) .indo-lang-dropdown__trigger:hover,
.site-header:not(.header--on-light) .indo-lang-dropdown__trigger:focus-visible {
    background: rgba(255,255,255,.16);
}

/* Mobile: trigger only shows the flag (drop the code), panel still works.
 * Keep the panel right-anchored so it doesn't overflow the viewport. */
@media (max-width: 767px) {
    .site-header__lang { margin-right: 4px; }
    .indo-lang-dropdown__trigger { padding: 6px 8px; gap: 4px; }
    .indo-lang-dropdown__trigger .indo-lang-dropdown__code { display: none; }
    .indo-lang-dropdown__flag { font-size: 16px; }
    .indo-lang-dropdown__panel { min-width: 240px; right: 0; left: auto; }
}

/* Backwards-compat: keep the old `.indo-lang-switcher` styles for any
 * place that uses the inline shortcode (sidebars, footers). */
.indo-lang-switcher { display: flex; gap: 6px; list-style: none; margin: 0; padding: 0; align-items: center; }
.indo-lang-switcher__item { margin: 0; padding: 0; }
.indo-lang-switcher__item a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 10px; border-radius: 999px;
    font-family: var(--indo-font-body, Inter, sans-serif);
    font-size: 12px; line-height: 1; font-weight: 600;
    color: var(--indo-charcoal, #212121); text-decoration: none;
    transition: background-color .15s ease;
}
.indo-lang-switcher__item a:hover,
.indo-lang-switcher__item a:focus { background: rgba(0,0,0,.06); }
.indo-lang-switcher__item.is-active a { background: var(--indo-cyan, #00a6db); color: #fff; }
.indo-lang-switcher__flag img.emoji {
    width: 18px !important; height: 14px !important;
    margin: 0 !important; flex: 0 0 18px; object-fit: contain; vertical-align: middle;
    border: 0; background: none;
}
/* ===== END indo-lang-dropdown ============================================ */


/* ============================================================
 * fix-article-body-rhythm-001  (2026-07-06, 2.3.45)
 *
 * Tom-flagged: huge vertical gaps between paragraphs on
 * /direct-drive-proven-since-2010-and-warrantied-for-15-years/
 * and /indo-expands-horti-range/.
 *
 * Root cause: the SITE-WIDE SECTION RHYTHM block (2.3.3) sets
 * --padding-top/--padding-bottom on every .e-con.e-parent
 * (56/72/88px by breakpoint). Four blog posts (18353 VertiFarm,
 * 18619 SkySync, 18806 Horti Range, 19497 Direct Drive — plus
 * their six translation siblings each) were authored in Elementor
 * with EVERY paragraph and heading in its own top-level container,
 * so each text block inherits full section padding: ~176px of dead
 * space between paragraphs on desktop.
 *
 * Fix: inside the single-post narrow article column, containers
 * are paragraphs, not page sections. Zero the rhythm tokens there
 * and restore text-scale spacing for heading widgets (the theme's
 * .entry-content p margin 0 0 1.4em already spaces paragraphs).
 *
 * Specificity: (0,3,0) beats the rhythm defaults (0,2,0) at every
 * breakpoint; Elementor per-element padding set via the editor UI
 * ((0,3,0), loaded after theme CSS) still wins, preserving
 * per-section editability established 2026-05-05.
 * ============================================================ */
.indo-single-post .entry-content .e-con.e-parent {
    --padding-top: 0px;
    --padding-bottom: 0px;
}
/* Heading widgets are separate containers, so paragraph margins never
 * collapse into them. Give article-body headings editorial rhythm:
 * clear air above (adds to the preceding paragraph's 1.4em), a tight
 * seat below. */
.indo-single-post .entry-content .elementor-widget-heading .elementor-heading-title {
    margin-top: 28px;
    margin-bottom: 12px;
}
/* ===== END fix-article-body-rhythm-001 ===== */


/* ============================================================
 * fix-article-body-rhythm-002  (2026-07-06, 2.3.45)
 *
 * Companion to fix-article-body-rhythm-001. The six colour-coded
 * wattage-band containers on /indo-expands-horti-range/ (post
 * 18806 + siblings) carry per-element background colours; zeroing
 * the rhythm tokens left their text hugging the panel edges.
 * Restore a compact symmetric interior close to the article's
 * original pre-rhythm look (Elementor default was 10px).
 * data-id attributes are stable across translation siblings
 * (siblings render the EN _elementor_data), so target those
 * rather than .elementor-18806 post classes.
 * ============================================================ */
.indo-single-post .entry-content .e-con[data-id="4b90a40"],
.indo-single-post .entry-content .e-con[data-id="396d6ec"],
.indo-single-post .entry-content .e-con[data-id="5c8401a"],
.indo-single-post .entry-content .e-con[data-id="31a621f"],
.indo-single-post .entry-content .e-con[data-id="062456b"],
.indo-single-post .entry-content .e-con[data-id="8aaac2f"] {
    --padding-top: 14px;
    --padding-bottom: 14px;
}
/* The trailing paragraph's 1.4em margin paints outside the white
 * text-editor box, making the colour frame bottom-heavy (14px top vs
 * ~39px bottom). Zero it inside the bands only — article paragraph
 * flow elsewhere still relies on that margin for inter-block gaps. */
.indo-single-post .entry-content .e-con[data-id="4b90a40"] p:last-child,
.indo-single-post .entry-content .e-con[data-id="396d6ec"] p:last-child,
.indo-single-post .entry-content .e-con[data-id="5c8401a"] p:last-child,
.indo-single-post .entry-content .e-con[data-id="31a621f"] p:last-child,
.indo-single-post .entry-content .e-con[data-id="062456b"] p:last-child,
.indo-single-post .entry-content .e-con[data-id="8aaac2f"] p:last-child {
    margin-bottom: 0;
}
/* ===== END fix-article-body-rhythm-002 ===== */

/* ============================================================
 * PRODUCT-PAGE-TIDY 2026-08-05  (TopLink launch)
 *
 * Tom, 2026-08-05: "ensure the page is tidied up as currently it's
 * below acceptable quality design standard" (TopLink product page,
 * ahead of the 06 Aug launch emails).
 *
 * Three scoped fixes on single-product pages. All three are additive:
 * nothing above this block is edited, so reverting is a clean delete
 * of this block.
 *
 * 1. .indo-spec-table — the "Additional information" panel rendered as
 *    a flat <ul> of "Label: value" lines with no table markup at all.
 *    That content does NOT come from WooCommerce product attributes
 *    (TopLink has no `_product_attributes` meta); it comes from the
 *    legacy yikes plugin's `yikes_woo_products_tabs` postmeta, echoed
 *    through wp_kses_post() by indo_render_additional_information_tab().
 *    The meta now holds a grouped two-column table instead. This styles
 *    it: uppercase group headers on a cyan rule, zebra data rows, and a
 *    stacked label-over-value layout below 600px. Products still using
 *    the old <ul> or the WooCommerce shop_attributes table are
 *    unaffected — this only matches `table.indo-spec-table`.
 *
 * 2. Description panel rhythm — h3 section headings, paragraph measure
 *    and spacing, and a lede paragraph, so a multi-section description
 *    reads as sections instead of a wall of text. The in-content
 *    product render (300px "medium") floats right from 900px up. It is
 *    keyed on `.size-medium` inside the panel rather than on an
 *    alignment class because this site ships no .alignright/.alignnone
 *    rules at all, in any active stylesheet.
 *
 * 3. Related / upsells top gap — WooCommerce core's woocommerce.css
 *    ships
 *      .single-product.woocommerce div.product .related { margin-top:150px }
 *    at >=992px, specificity (0,4,1). The theme's intended
 *      .woocommerce.single-product .related { margin-top: clamp(48px,6vw,96px) }
 *    (line ~2652) is only (0,3,0), so core silently won and desktop
 *    rendered a dead white band before "Related products". Measured on
 *    live at 1440px: 208px from the bottom of the tab panel to the top
 *    of the section, 265px to its H2. The doubled class below lifts us
 *    to (0,5,1) so this holds through future WooCommerce updates. The
 *    product grid's own 57.6px row-gap already provides the separation;
 *    measured after: 58px / 102px.
 * ============================================================ */

/* -- 1. Additional information: grouped two-column spec table -------- */
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table {
    width: 100%;
    margin: 0;
    border: 0;
    border-collapse: collapse;
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table th,
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table td {
    border: 0;
    border-bottom: 1px solid rgba(33,33,33,0.08);
    padding: 13px 16px;
    background: transparent;
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-size: 15px;
    line-height: 1.6;
    vertical-align: top;
    text-align: left;
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-group th {
    padding: 30px 16px 8px;
    border-bottom: 2px solid var(--indo-cyan, #00a5db);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--indo-gray, #6b6b6b);
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-group:first-child th {
    padding-top: 0;
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row th {
    width: 34%;
    font-weight: 600;
    color: var(--indo-charcoal, #212121);
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row td {
    color: var(--indo-charcoal, #212121);
}
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row--alt th,
.woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row--alt td {
    background: rgba(33,33,33,0.025);
}
/* Stack to label-over-value on phones: a 34/66 split at 375px leaves the
   value column ~200px wide, which breaks "10kV differential mode, 6kV
   common mode" onto four lines. */
@media (max-width: 599px) {
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table,
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tbody,
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr,
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table th,
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table td {
        display: block;
        width: auto;
    }
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row th {
        width: auto;
        border-bottom: 0;
        padding: 12px 14px 0;
        font-size: 13px;
        color: var(--indo-gray, #6b6b6b);
    }
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-row td {
        padding: 2px 14px 12px;
    }
    .woocommerce div.product .woocommerce-tabs .panel table.indo-spec-table tr.indo-spec-group th {
        padding: 26px 14px 8px;
    }
}

/* -- 2. Description panel rhythm ------------------------------------ */
.woocommerce div.product .woocommerce-tabs .panel h3 {
    font-family: var(--indo-font-body, 'Inter', system-ui, sans-serif);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--indo-gray, #6b6b6b);
    margin: 34px 0 10px;
}
.woocommerce div.product .woocommerce-tabs .panel p {
    margin: 0 0 16px;
    max-width: 72ch;
}
.woocommerce div.product .woocommerce-tabs .panel p.indo-product-lede {
    font-size: 19px;
    line-height: 1.55;
    color: var(--indo-charcoal, #212121);
    max-width: 64ch;
}
@media (min-width: 900px) {
    .woocommerce div.product .woocommerce-tabs .panel p > a > img.size-medium,
    .woocommerce div.product .woocommerce-tabs .panel p > img.size-medium {
        float: right;
        margin: 4px 0 20px 32px;
    }
}

/* -- 3. Related / upsells top gap ----------------------------------- */
.woocommerce.single-product div.product .related.related,
.woocommerce.single-product div.product .upsells.upsells {
    margin-top: 0;
    padding-top: clamp(28px, 3vw, 44px);
}
/* ===== END PRODUCT-PAGE-TIDY 2026-08-05 ===== */
