/* ==========================================================================
   BRANDS SUB-PROJECT — component styles
   ------------------------------------------------------------------------
   Everything in this file is SPECIFIC to the /brands sub-project (the
   brand install & service landing pages). It loads AFTER the shared
   variables.css / base.css / header-footer.css / layout.css / responsive.css
   bundle, so it can reuse every existing token (--primary, --accent-blue,
   .glass-panel, .btn, .badge, .max-content, etc.) and only adds the NEW
   pieces that main-site pages don't have:

     1. Breadcrumb trail
     2. "At a glance" AEO/GEO quick-answer box
     3. Brand hero banner variant
     4. Brand process steps
     5. Related-brands chip list
     6. The reusable FOOTER BLOCK: scrolling reviews / logos / recent
        projects on mobile, static full-grid on desktop+ (this is the
        block referenced in partials/footer-block.html — edit markup
        there, edit visual rules here, and every brand page picks up
        the change after the next build-brands.php run)
     7. Brands hub (index.html) directory grid
     8. Mobile sticky CTA bar (shared component, defined in the main
        layout.css but not wired into any page yet — used here)
   ========================================================================== */

/* --- 1. Breadcrumb ------------------------------------------------------- */
.breadcrumb-bar {
    padding: 18px var(--container-padding) 0;
    max-width: var(--container-max);
    margin: 0 auto;
}

.breadcrumb-bar ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 0.9rem;
    color: var(--text-muted);
}

.breadcrumb-bar a { color: var(--text-muted); font-weight: 600; }
.breadcrumb-bar a:hover { color: var(--primary-hover); }
.breadcrumb-bar li[aria-current] { color: var(--text-main); font-weight: 700; }
.breadcrumb-bar li:not(:last-child)::after {
    content: '/';
    margin-left: 8px;
    color: var(--border);
}

/* --- 2. AEO / GEO "at a glance" quick-answer box -------------------------
   Purpose-built for answer-engine and LLM extraction: short, factual,
   labelled data points an AI assistant (or a Google featured snippet) can
   lift verbatim. Keep every brand page's version of this box in the
   same label/value shape so it's trivial to diff across suburbs. */
/* 5 items don't divide evenly into a 2-column mobile grid — the trailing
   odd item left one grid cell empty (showing the gap-background as a
   blank tinted box). Below desktop this now runs as a continuous,
   always-on scroll loop instead (same duplicated-content marquee
   technique as .reviews-marquee/.reviews-track), rather than a
   manually-swiped strip — never a dangling empty cell, and nothing for
   a phone user to have to drag. At ≥1025px it switches back to the
   original fixed 5-column grid, and the aria-hidden duplicate set is
   hidden entirely. */
.at-a-glance-marquee {
    overflow: hidden;
    position: relative;
    margin: clamp(28px, 4vw, 44px) 0;
}

.at-a-glance {
    display: flex;
    align-items: stretch;
    gap: 10px;
    width: max-content;
    padding: 4px 2px 14px;
    animation: reviews-scroll 26s linear infinite;
}

.at-a-glance-marquee:hover .at-a-glance,
.at-a-glance-marquee:focus-within .at-a-glance { animation-play-state: paused; }

/* Same navy-gradient "block" treatment as the rest of the site's brand
   cards (.feature-card / .testimonial-card / .service-card-content on
   the main homepage) instead of a plain white cell. Narrower and taller
   than the first pass (was 230px wide, 3 lines of value text) — slim,
   elongated cards with short, quick-glance copy. Width (176px) is sized
   so every value line fits on ONE line (measured against the longest
   value, "3 SA trade licences", at the dd font-size below) rather than
   wrapping to 2 lines. */
.at-a-glance-item {
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-blue-dark));
    padding: 18px 14px 22px;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    flex: 0 0 auto;
    width: min(176px, 46vw);
}

@media (prefers-reduced-motion: reduce) {
    .at-a-glance { animation: none; }
    .at-a-glance-marquee { overflow-x: auto; }
}

@media (min-width: 1025px) {
    .at-a-glance-marquee {
        overflow: visible;
    }

    .at-a-glance {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 1px;
        background: rgba(var(--primary-rgb), 0.18);
        border-radius: var(--radius-md);
        overflow: hidden;
        box-shadow: var(--shadow-md);
        padding: 0;
        width: auto;
        animation: none;
    }

    /* Desktop shows the fixed grid, not the loop — the duplicated set
       exists purely to make the mobile/tablet marquee seamless. */
    .at-a-glance-item[aria-hidden="true"] { display: none; }

    .at-a-glance-item {
        padding: 20px 22px;
        border-radius: 0;
        box-shadow: none;
        width: auto;
        flex: initial;
    }
}

.at-a-glance-item dt {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: rgba(255, 255, 255, 0.65);
    font-weight: 700;
    margin-bottom: 6px;
    white-space: nowrap;
}

.at-a-glance-item dd {
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1.3;
    color: #fff;
    white-space: nowrap;
}

@media (min-width: 1025px) {
    .at-a-glance-item dt { font-size: 0.78rem; letter-spacing: 0.6px; }
    .at-a-glance-item dd { font-size: 1.05rem; }
}

/* Icon inline, before the text, on every screen size — was display:block
   (icon on its own row above the value) on mobile only, which read as an
   odd extra row instead of one glanceable line. */
.at-a-glance-item dd i { display: inline; color: var(--primary); margin-right: 5px; font-size: 0.95rem; }

@media (min-width: 1025px) {
    .at-a-glance-item dd i { margin-right: 6px; font-size: 1.1rem; }
}

/* --- 3. Brand hero banner ---------------------------------------------
   The "common banner image" the whole brands sub-project shares.
   Visually the same .hero component as the main site, with a brand
   badge and a compact brand-facts strip under the CTA row. */
.brand-hero .badge.badge-brand {
    background: rgba(255, 255, 255, 0.1);
    color: var(--primary);
    border: 1px solid rgba(255, 255, 255, 0.18);
}

.brand-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 22px;
    margin-top: 18px;
}

.brand-facts span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-muted);
}

.brand-facts i { color: var(--primary); }

/* --- 4. Process steps ----------------------------------------------------- */
.process-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(20px, 3vw, 32px);
    counter-reset: process-step;
}

.process-card {
    padding: clamp(26px, 3vw, 34px) clamp(22px, 3vw, 28px);
    position: relative;
    border-radius: var(--radius-lg);
}

.process-card::before {
    counter-increment: process-step;
    content: counter(process-step);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: linear-gradient(135deg, hsl(35, 95%, 56%), var(--primary-hover));
    color: #1a1200;
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 1.1rem;
    margin-bottom: 16px;
    box-shadow: 0 8px 20px rgba(var(--primary-rgb), 0.35);
}

.process-card h3 { font-size: 1.2rem; margin-bottom: 10px; }
.process-card p { color: var(--text-muted); font-size: 0.98rem; }

/* --- 5. "Explore Other Brands We Install & Service" logo grid (Pass 4,
   Aug 2026) --------------------------------------------------------------
   Was a two-row always-scrolling logo wall (Pass 3); feedback asked for
   this per-page section specifically to become a static, smaller-logo
   grid on desktop/larger screens (5-per-row) with a single continuously-
   scrolling row on mobile only — the OPPOSITE interaction from the
   shared footer-block "Brands We Install & Service" strip, which moved
   the other way (see section 6 below: .brand-wall is now the always-on
   two-row scroller). Still shows every brand we have a real logo image
   for (ALL_LOGO_BRANDS in generate_brands.py), just in this reversed
   layout and at a smaller size than Pass 3's chips. Mobile/tablet
   (<1025px): overflow-hidden marquee, content doubled with aria-hidden on
   the clone half for a seamless loop (same technique as .reviews-track).
   Desktop (>=1025px): switches to a plain 5-column wrapping grid showing
   every real logo at once, no scrolling, duplicates hidden. */
.related-brands-band { padding: clamp(50px, 7vw, 90px) 0; }

.brand-explore-marquee {
    overflow: hidden;
    position: relative;
    margin-top: clamp(20px, 3vw, 32px);
    scrollbar-width: none;
}

.brand-explore-marquee::-webkit-scrollbar { display: none; }

.brand-explore-track {
    display: flex;
    align-items: center;
    gap: clamp(10px, 1.4vw, 16px);
    width: max-content;
    animation: logo-wall-scroll 34s linear infinite;
}

.brand-explore-marquee:hover .brand-explore-track,
.brand-explore-marquee:focus-within .brand-explore-track { animation-play-state: paused; }

@keyframes logo-wall-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

@keyframes logo-wall-scroll-reverse {
    from { transform: translateX(-50%); }
    to { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
    .brand-explore-track { animation: none; }
    .brand-explore-marquee { overflow-x: auto; }
}

@media (min-width: 1025px) {
    .brand-explore-marquee { overflow: visible; margin-top: clamp(24px, 3vw, 36px); }

    .brand-explore-track {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: clamp(12px, 1.4vw, 18px);
        width: auto;
        animation: none;
    }

    .brand-explore-chip[aria-hidden="true"] { display: none; }
}

@media (min-width: 1025px) and (max-width: 1300px) {
    .brand-explore-track { grid-template-columns: repeat(3, 1fr); }
}

/* Pass 5 (Aug 2026): sized up again per feedback that the logos
   themselves should read slightly bigger while still fitting 5-per-row
   on desktop — grew the box height/width and pulled back the padding
   (rather than growing the padding too) so more of the box is actual
   visible logo, not surrounding whitespace. */
.brand-explore-chip {
    flex: 0 0 auto;
    width: clamp(100px, 11vw, 132px);
    height: clamp(72px, 7.6vw, 92px);
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: clamp(6px, 0.7vw, 9px);
    box-shadow: var(--shadow-sm);
    transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

@media (min-width: 1025px) { .brand-explore-chip { width: auto; } }

.brand-explore-chip:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: var(--primary);
}

.brand-explore-chip img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* --- 6. FOOTER BLOCK: proof strip (reviews / logos / projects) ----------- */
.proof-block { padding: clamp(50px, 7vw, 90px) 0; }

.proof-section + .proof-section { margin-top: clamp(40px, 6vw, 64px); }

.proof-section .section-header { margin-bottom: clamp(24px, 4vw, 36px); }

/* layout.css's shared .section-header p caps at max-width:800px. Rule of
   thumb requested for every subtitle on this page: keep it on a single
   line whenever the text can actually fit one at the current font-size —
   only wrap when it genuinely doesn't fit. 800/900px was too narrow for
   the longest subtitle here ("Fully trained and licensed to work on
   every major air conditioning brand sold in Australia.", which needs
   ~1090px at the largest fluid font-size the clamp() reaches on very
   wide monitors) — it wrapped with a single dangling word on its own
   second line. Measured the real text width at every common breakpoint
   (1024–3440px) and widened just enough to comfortably fit it as one
   line everywhere the section itself has room (--container-max is
   1400px, so 1150px still leaves healthy side margins); on narrow
   mobile/tablet viewports where 1150px doesn't fit, it naturally wraps
   to 2 lines as expected — that's the "unless it doesn't fit" case. */
.section-header p { max-width: 1150px; }

/* Shared "continuous auto-scroll on mobile, static grid on desktop"
   behaviour — same duplicated-content @keyframes marquee technique as
   .reviews-marquee/.reviews-track (no more manual swipe-to-scroll or
   JS-driven scrollBy timer; brand-blocks.js no longer touches these).
   Mobile/tablet (<1025px): .scroll-strip-marquee clips overflow, the
   inner .scroll-strip track is doubled-content and animates continuously.
   Desktop (>=1025px, matching the site's existing header nav breakpoint):
   switches to a plain wrapping grid showing every real item at once, no
   scrolling, no animation — the aria-hidden duplicates are hidden. */
.scroll-strip-marquee {
    overflow: hidden;
    position: relative;
    margin: 6px 0 18px;
    scrollbar-width: none;
}

.scroll-strip-marquee::-webkit-scrollbar { display: none; }

.scroll-strip {
    display: flex;
    align-items: stretch;
    gap: clamp(16px, 2.5vw, 24px);
    width: max-content;
    animation: reviews-scroll 34s linear infinite;
}

.scroll-strip-marquee:hover .scroll-strip,
.scroll-strip-marquee:focus-within .scroll-strip { animation-play-state: paused; }

.scroll-strip > * { flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
    .scroll-strip { animation: none; }
    .scroll-strip-marquee { overflow-x: auto; }
}

@media (min-width: 1025px) {
    .scroll-strip-marquee { overflow: visible; margin: 0; }

    .scroll-strip {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
        width: auto;
        animation: none;
    }

    /* Desktop shows the fixed grid, not the loop — the duplicated set
       exists purely to make the mobile/tablet marquee seamless. */
    .scroll-strip > *[aria-hidden="true"] { display: none; }
    .scroll-strip > * { flex: initial; }
}

/* Reviews strip — reuses .testimonial-card visuals from layout.css so
   the proof block matches the rest of the site exactly, just at a more
   compact width suited to a strip instead of a full section. */
.review-strip-card {
    width: min(320px, 82vw);
}

@media (min-width: 1025px) { .review-strip-card { width: auto; } }

/* Logo strip — brand/partner cards. Originally text-only wordmark chips
   with a fixed height tuned for two lines of text; once real <img> logos
   were added inside (Pass 2) the actual content (image + name + tag)
   no longer fit inside that fixed height, so it silently overflowed the
   card's own bounds and visually bled into/over the row underneath on
   the desktop grid (Aug 2026 Pass 3 bug report). Pass 4: this whole strip
   moved from a static desktop-grid/mobile-marquee layout to a
   two-row always-on scroller (see .brand-wall below) and the card itself
   was made noticeably smaller — feedback was that it read too large,
   especially once the strip is continuously scrolling on desktop too.
   Pass 5: reversed course on "smaller" — feedback was now that the logo
   should be bigger, and since every chip loops back into view repeatedly
   in this continuous scroller, a WIDER card with the logo and its
   name/tag sitting side by side (image left, text right, via the new
   .logo-chip-text column) reads better than the old narrow stacked
   layout, where a long name like "Mitsubishi Heavy Industries" ate up
   most of the card's height on its own. */
.logo-chip {
    width: clamp(220px, 22vw, 280px);
    min-height: 92px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    gap: 16px;
    padding: 14px 20px;
    border-radius: var(--radius-md);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.logo-chip:hover { transform: translateY(-4px); }

.logo-chip-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.logo-chip span {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 0.95rem;
    /* Brand name in gold, tag/system label in white below — set with
       higher specificity further down (near .card-navy) since this strip
       is always a .card-navy chip and would otherwise inherit the
       generic white .card-navy span color. */
    letter-spacing: 0.2px;
    line-height: 1.25;
}

.logo-chip small {
    display: block;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-top: 4px;
}

/* --- Brand logo wall (Pass 4, Aug 2026) — the shared footer-block
   "Brands We Install & Service" strip. Two independently-scrolling rows,
   looping continuously in opposite directions, on EVERY screen size
   including desktop/larger screens (feedback was explicit: this
   shared/"global" strip should always be a continuous scroll, unlike the
   per-page "Explore Other Brands" section above, which now does the
   opposite — static desktop grid + mobile-only scroll). Reuses the
   logo-wall-scroll/-reverse keyframes defined in section 5 above; content
   in each row is doubled with aria-hidden on the clone half so the loop
   is seamless (same technique as .reviews-track). */
.brand-wall {
    display: flex;
    flex-direction: column;
    gap: clamp(12px, 1.6vw, 18px);
    margin: 6px 0 4px;
}

.brand-wall-row {
    overflow: hidden;
    position: relative;
}

.brand-wall-track {
    display: flex;
    align-items: stretch;
    gap: clamp(12px, 1.6vw, 18px);
    width: max-content;
    animation: logo-wall-scroll 30s linear infinite;
}

.brand-wall-row--b .brand-wall-track {
    animation-name: logo-wall-scroll-reverse;
    animation-duration: 34s;
}

.brand-wall-row:hover .brand-wall-track,
.brand-wall-row:focus-within .brand-wall-track { animation-play-state: paused; }

.brand-wall-track > * { flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
    .brand-wall-track { animation: none; }
    .brand-wall-row { overflow-x: auto; }
}

/* Recent projects strip — reuses the existing service photography as
   illustrative "recent job" thumbnails. Swap the images/captions for
   real completed-job photos per suburb whenever you have them; until
   then this keeps every brand page visually full and consistent. */
.project-card {
    width: min(280px, 78vw);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--bg-card);
}

@media (min-width: 1025px) { .project-card { width: auto; } }

/* Aug 2026: the shared .scroll-strip grid (repeat(auto-fit, minmax(220px,
   1fr)) from layout.css) only fits 5 of this strip's 6 real photo cards
   per row within the ~1400px container cap, wrapping the 6th card onto
   an orphaned second row on every one of /brands, /blogs, /locations —
   confirmed via screenshot, not just this project. Reviews cards
   (.review-strip-card) share the same .scroll-strip grid and read fine
   at the wider 220px minimum, so narrowing that shared value directly
   would needlessly shrink the reviews strip too. Scoping a narrower
   minimum to just the grid that actually contains .project-card
   (via :has(), supported in all evergreen desktop browsers this site
   targets) fits all 6 photo cards on one row at realistic desktop
   widths without touching the reviews strip. */
@media (min-width: 1025px) {
    .scroll-strip:has(.project-card) {
        grid-template-columns: repeat(auto-fit, minmax(175px, 1fr));
    }
}

.project-card img { width: 100%; height: 180px; object-fit: cover; display: block; }

.project-card-body { padding: 18px 20px; }
.project-card-body h4 { font-size: 1.02rem; margin-bottom: 4px; }
.project-card-body span { font-size: 0.85rem; color: var(--text-muted); font-weight: 600; }

/* Fixed guarantee/trust content shared across every brand page */
.trust-fixed-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: clamp(18px, 2.5vw, 28px);
}

.trust-fixed-item {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: clamp(20px, 2.5vw, 26px);
    border-radius: var(--radius-md);
}

.trust-fixed-item i { color: var(--primary); font-size: 1.5rem; margin-top: 2px; flex-shrink: 0; }
.trust-fixed-item h4 { font-size: 1.05rem; margin-bottom: 4px; }
.trust-fixed-item p { font-size: 0.92rem; color: var(--text-muted); margin: 0; }

/* --- 7. Brands hub (index.html) directory grid ------------------------
   Redesigned (Pass 2, Aug 2026) to match /locations' richer .hub-card
   treatment (real .glass-panel card + hover lift) instead of the flat,
   unstyled text-only cards from Pass 1 — Pass 1's markup carried
   .hub-card with no .glass-panel class and no image/logo area at all,
   so cards rendered with no visible background, border, or shadow. Every
   card now gets a real logo showcase area at the top (an actual brand
   logo image where we have one in assets/images/brand-logos/, or a
   plain typographic fallback tile when we don't — see hub_card_logo()
   in build-brands.php) so the grid reads as a proper brand directory,
   not a list of headings. -------------------------------------------- */
.hub-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(20px, 3vw, 30px);
}

.hub-card {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.hub-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

/* Logo showcase strip — light, near-white backdrop so every brand logo
   (all currently sourced as white-background JPGs) sits on a clean,
   consistent card regardless of the logo image's own aspect ratio.
   object-fit:contain (not cover) so logos are never cropped or
   stretched — unlike a photo, a squashed or clipped logo reads as
   broken/wrong immediately.
   Pass 5 (Aug 2026): feedback was that this showcase area read as a
   small logo floating in a lot of empty space. Two changes together fix
   this — (a) the source JPGs in assets/images/brand-logos/ themselves
   were auto-cropped to their real logo content + a small margin (they
   previously carried 55-85% internal white padding baked into a fixed
   420x240 canvas, so no amount of CSS sizing here could make the logo
   itself look bigger), and (b) this showcase area was made taller with
   tighter padding so the now-larger logo has more room to fill. */
.hub-card-logo {
    height: 170px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px 20px;
    background: linear-gradient(180deg, #ffffff, #f4f6fb);
    border-bottom: 1px solid var(--border);
}
.hub-card-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.hub-card-logo-fallback {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 1.4rem;
    color: var(--text-main);
    letter-spacing: 0.2px;
    text-align: center;
}

.hub-card-body { padding: clamp(20px, 3vw, 26px); }
.hub-card-body h3 { font-size: 1.2rem; margin-bottom: 8px; }
.hub-card-body p { color: var(--text-muted); font-size: 0.92rem; margin-bottom: 18px; }

.hub-card-tag {
    display: inline-block;
    background: rgba(255, 176, 32, 0.12);
    color: var(--primary-hover, var(--primary));
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 4px 10px;
    border-radius: 999px;
    margin-bottom: 10px;
}

.hub-card-coming {
    border: 2px dashed var(--border);
    background: var(--bg-alt);
}
.hub-card-coming .hub-card-logo {
    background: linear-gradient(180deg, #f4f6fb, #ececf3);
    /* Real logos on "coming soon" cards are shown at reduced opacity and
       desaturated — enough to preview which brand is next without the
       card looking indistinguishable from a live, linked brand guide. */
    filter: grayscale(60%);
    opacity: 0.7;
}
.hub-card-coming .hub-card-logo-fallback { color: var(--text-muted); }
.hub-card-coming-ribbon {
    position: absolute;
    top: 14px;
    right: -34px;
    transform: rotate(40deg);
    background: var(--text-muted);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 4px 40px;
    z-index: 1;
}
.hub-card-coming .hub-card-body p { font-size: 0.88rem; }

/* --- 7b. (removed, Aug 2026) -----------------------------------------------
   The hero used to also show a small logo tile above the "Brand Guide ·
   <category>" badge. Feedback was that it rendered far too large/heavy at
   the top of the hero and wasn't needed there — the brand name is already
   carried by the H1 and the badge text, and the logo gets a proper
   showcase lower down in the About-brand bio card instead. Removed the
   markup entirely in generate_brands.py rather than just hiding it here. */

/* --- 7c. About-brand bio card (Pass 2, Aug 2026) --------------------------
   A short, scannable "About <Brand>" snapshot placed right after the
   at-a-glance box and before the long-form overview — genuine brand
   history condensed to 2 short paragraphs (same sourced facts as the
   overview section below it, just tightened for SEO/AEO snippet value
   and to give the real logo image a proper showcase on the page). */
.brand-bio-card {
    display: flex;
    align-items: center;
    gap: clamp(20px, 3vw, 36px);
    padding: clamp(24px, 3vw, 36px);
    border-radius: var(--radius-lg);
}
.brand-bio-logo {
    flex: 0 0 auto;
    width: clamp(120px, 16vw, 160px);
    height: clamp(90px, 12vw, 120px);
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px;
    /* Feedback (Aug 2026): sitting flush against the bio card's own
       near-white glass-panel background, the logo read as flat/undefined
       — no visible edge to it. A real shadow + a subtle lift-on-hover
       gives it its own "framed" presence instead of blending into the
       card behind it. */
    box-shadow: 0 6px 18px rgba(15, 30, 60, 0.10), 0 1px 3px rgba(15, 30, 60, 0.06);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.brand-bio-logo:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 26px rgba(15, 30, 60, 0.14), 0 2px 6px rgba(15, 30, 60, 0.08);
}
.brand-bio-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.brand-bio-logo-fallback {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 1.1rem;
    text-align: center;
    color: var(--text-main);
}
.brand-bio-text h2 { margin-bottom: 10px; }
.brand-bio-text p { color: var(--text-muted); font-size: 0.98rem; margin-bottom: 10px; }
.brand-bio-text p:last-child { margin-bottom: 0; }
@media (max-width: 700px) {
    .brand-bio-card { flex-direction: column; text-align: center; }
    .brand-bio-logo { width: min(200px, 60vw); height: 110px; }
}

/* --- 7d. Disclaimer — own dedicated card (Pass 2, Aug 2026) ---------------
   Originally nested silently inside the FAQ accordion box with ZERO CSS
   of its own (brands.css never carried a .disclaimer-box rule at all,
   unlike /blogs' copy this was meant to mirror) — it rendered as
   unstyled plain text bleeding into the accordion's own padding, with no
   visual separation from the FAQ content above it. Fixed by (a) moving
   the DISCLAIMER markers to their own <section> in generate_brands.py's
   PAGE_TEMPLATE, entirely outside .faq-accordion-box, and (b) giving it
   real, deliberately quiet card styling here — distinct from the FAQ
   accordion and from the bold .card-navy CTA bands, but still a clearly
   bounded, separate design element rather than invisible text. */
.disclaimer-box {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: clamp(20px, 2.5vw, 26px);
    border-radius: var(--radius-lg);
    background: rgba(255, 176, 32, 0.06);
    border: 1px solid rgba(255, 176, 32, 0.28);
    border-left: 4px solid var(--primary);
    box-shadow: var(--shadow-sm);
}
.disclaimer-box .disclaimer-icon {
    flex: 0 0 auto;
    font-size: 1.3rem;
    color: var(--primary-hover, var(--primary));
    line-height: 1.5;
}
.disclaimer-box p {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.7;
    color: var(--text-muted);
}
.disclaimer-box strong { color: var(--text-main); }
.disclaimer-box a { color: var(--accent-blue); text-decoration: underline; }
@media (max-width: 600px) { .disclaimer-box .disclaimer-icon { display: none; } }

/* --- 7e. Logo thumbnail on the footer-block "Brands We Install &
   Service" strip (Pass 2/3/4/5, Aug 2026). (The related-brand chip
   version of this comment no longer applies — that section is now the
   .brand-explore-chip grid in section 5 above, which has its own logo
   box.) Pass 5: sized back up and switched from a stacked (logo above
   text, margin-bottom pushing the text down) to a side-by-side layout —
   .logo-chip is now flex-direction:row, so this box just needs its own
   fixed size and no bottom margin; flex:0 0 auto keeps it from being
   squashed by the text column next to it. */
.logo-chip-img {
    flex: 0 0 auto;
    width: 108px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border-radius: var(--radius-sm);
    padding: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14);
}
.logo-chip-img img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* --- 7f. Feature-card text clamp + "Read more" modal (Aug 2026) -----------
   .feature-card is reused for several different grids on a brand page —
   the Warranty/Refrigerant/Australian-Standards row, the brand-vs-brand
   comparison cards, and the "Why Choose Voltas" row — and paragraph
   length varies a lot between them per brand (e.g. a detailed sourced
   warranty quote vs. a one-line refrigerant note). Left unclamped, the
   shared flex row stretches every card in it to match the longest, so
   short cards end up mostly empty space next to one long card. Clamped
   to a fixed line count (matching the normal/shorter cards) with a
   "Read more" button — added by brand-blocks.js only when a card's text
   actually overflows the clamp — opening the full text in a small
   modal. Reuses the exact .review-modal-overlay/.review-modal/
   .review-modal-close/.read-more-btn CSS already defined in layout.css
   for the reviews strip, so the popup matches that pattern exactly. */
.feature-card p {
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.feature-card .read-more-btn {
    align-self: center;
    margin-top: 10px;
}

/* --- 8. Mobile sticky CTA is defined in layout.css/responsive.css already;
   nothing to add here — just documenting that /brands pages reuse it
   verbatim via the same .mobile-sticky-cta markup. */

/* --- Misc long-form article helpers -------------------------------------- */
.article-copy h2 { margin-top: clamp(40px, 5vw, 56px); margin-bottom: 16px; }
.article-copy h3 { margin-top: clamp(26px, 3vw, 34px); margin-bottom: 12px; }
.article-copy p { color: var(--text-muted); font-size: 1.05rem; margin-bottom: 16px; }
.article-copy ul, .article-copy ol { color: var(--text-muted); font-size: 1.02rem; margin: 0 0 20px 22px; }
.article-copy li { margin-bottom: 8px; }
.article-copy strong { color: var(--text-main); }

/* Centered as one group (text + button together, in the middle of the
   band) rather than the old space-between layout, which pinned the text
   hard-left and the button hard-right — the two ends read as
   disconnected on a wide screen instead of as a single call-to-action.
   Now uses .card-navy (in the HTML) instead of .section-tinted/
   .glass-panel, so every "inline CTA" reads as the same branded blue
   block as the rest of the page instead of a plain light strip. */
.inline-cta-band {
    margin: clamp(36px, 5vw, 56px) 0;
    padding: clamp(26px, 3vw, 36px);
    border-radius: var(--radius-lg);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: clamp(16px, 3vw, 28px);
    /* This element also carries .max-content, whose own width:100% only
       insets its INNER content via padding — the box's own background/
       border-radius still spans the full viewport width, so on mobile the
       rounded navy card was touching both screen edges with zero outside
       gutter (unlike the body copy around it, which sits inside the same
       container-padding inset). Shrinking the box itself and centering it
       gives this "card" a real gutter that lines up with the rest of the
       page's text margins. */
    width: calc(100% - 2 * var(--container-padding));
    margin-left: auto;
    margin-right: auto;
}

/* Text color comes from .card-navy p (white) automatically now that the
   band is a navy card — this just sets size/weight. Bumped up on phones
   (see the max-width:720px block near the bottom of this file) since
   1.1rem read small as the ONLY line of copy in an otherwise big, bold
   navy block. */
.inline-cta-band p { margin: 0; font-weight: 700; font-size: 1.15rem; }
.inline-cta-band .btn { flex-shrink: 0; }

/* ==========================================================================
   LOCALEXPERTS RE-SKIN (Aug 2026)
   ------------------------------------------------------------------------
   Brings the brands sub-project visually in line with the
   LocalExperts/AirconExperts/ElectricalExperts landing pages: a solid navy
   header (not the light glass header the main-site copy of
   header-footer.css assumes), navy-gradient cards for reviews/logos/
   projects/trust items, and an always-scrolling reviews marquee that runs
   on every screen size, not just mobile. See variables.css for the actual
   navy/gold/coral token values — this section is markup-specific overrides
   that couldn't just fall out of swapping variables.
   ========================================================================== */

/* --- Header: kept as the standard light glass header (header-footer.css
   default), NOT solid navy. A first pass made the header solid navy to
   match LocalExperts' dark topbar, but on THIS site the header sits
   directly on top of the also-navy `.brand-hero` with nothing but a
   faint 14% border between them — the two blocks visually merged into
   one another with no readable seam. Leaving the header as its normal
   light/glass self (same as every other page) gives the hero a clear,
   contrasting edge to start from instead. No overrides needed here —
   header-footer.css's defaults already apply. ------------------------- */

/* --- Eyebrow / badge on dark hero, matching LocalExperts' .eyebrow ------- */
.badge-brand {
    background: rgba(255, 255, 255, 0.1);
    color: var(--primary);
}

/* --- Stats strip (24/7, 20+ years, 100%, licensed) ----------------------- */
.stats-strip { background: var(--accent-blue-dark); }
.stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    background: rgba(255, 255, 255, 0.12);
}
.stat { background: var(--accent-blue-dark); padding: clamp(24px, 2.6vw, 40px) 20px; text-align: center; }
.stat strong { display: block; font-family: var(--font-heading); font-size: clamp(1.8rem, 1.4vw + 1.5rem, 2.7rem); color: var(--primary); font-weight: 800; line-height: 1; }
.stat span { display: block; margin-top: 8px; font-size: clamp(0.9rem, 0.3vw + 0.82rem, 1.05rem); font-weight: 500; color: rgba(255, 255, 255, 0.85); }

@media (max-width: 720px) { .stats { grid-template-columns: repeat(2, 1fr); } }

/* --- Navy card skin — applied to reviews/logos/projects/trust items so
   every "card" reads as one consistent, branded surface instead of the
   plain white .glass-panel used elsewhere on light sections. ------------- */
.card-navy {
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-blue-dark));
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: var(--shadow-strong);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.card-navy .review-text,
.card-navy p { color: rgba(255, 255, 255, 0.92); }
.card-navy .reviewer h4 { color: var(--primary); }
.card-navy .reviewer span { color: rgba(255, 255, 255, 0.65); }
.card-navy .logo-chip-inner span,
.card-navy span { color: #fff; }
.card-navy small { color: rgba(255, 255, 255, 0.65); }
.card-navy h4,
.card-navy h3 { color: #fff; }
.card-navy .project-card-body span { color: rgba(255, 255, 255, 0.65); }
.card-navy .trust-fixed-item-icon,
.card-navy i { color: var(--primary); }

/* .card-navy i above (gold icons, meant for icons sitting directly on a
   navy card) incorrectly also wins inside any BUTTON nested in a navy
   card — e.g. the gold .btn-primary "Call ..." button inside an
   .inline-cta-band.card-navy — painting its phone icon the exact same
   gold as the button's own background, so the icon nearly disappears
   even though the button's own text stays dark and readable (flagged by
   the user: "yellow icon color on yellow background hard to see").
   A button's icon should always match that button's own text color, not
   whatever ambient icon-color rule its container happens to set — higher
   specificity (.card-navy .btn i) than the plain .card-navy i rule above
   so this wins regardless of source order. */
.card-navy .btn i { color: inherit; }

/* Logo-chip brand name (span) in gold, tag/system label (small) in solid
   white — overrides the generic .card-navy span (white) / .card-navy
   small (muted 65% white) rules above with a more specific selector. */
.logo-chip.card-navy span { color: var(--primary); }
.logo-chip.card-navy small { color: #fff; }

/* Voltas Service Promise cards: heading stays white (from the generic
   .card-navy h4 rule above) and the description line underneath is gold
   instead of the generic near-white .card-navy p — gives the bold
   heading and its supporting copy real visual separation instead of two
   very-similar-looking white lines stacked on the navy card. */
.trust-fixed-item.card-navy p { color: var(--primary); }
/* .process-card's numbered circle (::before) already carries its own gold
   background/dark text regardless of card background — no override
   needed there when process-card also gets .card-navy. */

/* --- Reviews marquee — CSS-animation auto-scroll on EVERY screen size,
   not gated to mobile like the logos/projects .scroll-strip above. The
   HTML duplicates the review card list once (aria-hidden on the clones)
   so the loop is seamless; this just needs the animation (no edge mask —
   the fade-to-transparent mask revealed the light section background
   through the navy cards at both ends, reading as a washed-out/translucent
   strip rather than a clean scroll). */
.reviews-marquee {
    overflow: hidden;
    position: relative;
}
.reviews-track {
    display: flex;
    align-items: stretch;
    gap: clamp(16px, 2.5vw, 24px);
    width: max-content;
    animation: reviews-scroll 70s linear infinite;
    padding: 4px 0;
}
.reviews-marquee:hover .reviews-track,
.reviews-marquee:focus-within .reviews-track { animation-play-state: paused; }
@keyframes reviews-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.reviews-track .review-strip-card { width: clamp(280px, 26vw, 360px); flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
    .reviews-track { animation: none; }
    .reviews-marquee { overflow-x: auto; }
}

@media (max-width: 720px) {
    .reviews-track { gap: 14px; }
    .reviews-track .review-strip-card { width: min(80vw, 300px); }
}

/* --- Brand hero — full dark-navy treatment, matching the LocalExperts
   reference hero (dark navy background, gold accent text, light eyebrow
   badge, hero image with a floating "5.0 rated" pill, stats-strip below).
   Scoped to .brand-hero only so the rest of the site's (still light)
   .hero sections are untouched. ------------------------------------------ */
/* .hero (shared with the rest of the site) is capped at
   var(--container-max) and centered — invisible when the hero
   background matches the page background, but on this DARK hero it left
   visible pale gutters down both sides on any screen wider than ~1400px
   (the light page background showing through around the boxed navy
   panel). A full-bleed ::before, sized to the viewport and centered
   behind the real (still width-capped) content, gives an edge-to-edge
   navy band like the LocalExperts reference instead. */
.brand-hero {
    background: transparent;
    overflow: visible;
    /* Base .hero (layout.css) is min-height:100vh with align-items:center —
       right for the site's true homepage hero (dense two-column content
       that actually fills a full viewport) but every /brands page is an
       interior landing page, not the homepage: the badge/H1/short
       paragraph/single CTA column here is noticeably shorter, so centering
       it inside a forced full-viewport-tall box left a large empty gap
       above the badge and an equally large one below the CTA row/hero
       image — visible on any normal desktop window height (confirmed via
       screenshot on a ~1900px-wide, ~1000px-tall window). Overridden here
       (same numbers as the site's existing .hero--compact modifier) so it
       sizes to its own content instead — applies automatically to every
       current AND future brand page since they all share this one
       class, no need to remember to add a modifier class per page. */
    min-height: 0;
    padding-top: clamp(140px, 16vw, 170px);
    padding-bottom: clamp(50px, 6vw, 80px);
}
.brand-hero::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 100vw;
    height: 100%;
    transform: translateX(-50%);
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-blue-dark));
    z-index: -1;
}
.brand-hero h1 { color: #fff; }
/* .text-gradient fades from gold to navy — perfect on a light/white
   section, but on any DARK navy section (this hero, and the existing
   .section-on-brand "Why locals choose Voltas" block) the navy end of
   the gradient blends straight into the background and disappears.
   Solid gold (matching LocalExperts' .hero h1 .accent treatment) reads
   correctly on dark sections instead. */
.brand-hero .text-gradient,
.section-on-brand .text-gradient {
    background: none;
    -webkit-text-fill-color: initial;
    color: var(--primary);
}
.brand-hero p { color: var(--text-on-dark-muted); }
.brand-hero .brand-facts span { color: rgba(255, 255, 255, 0.82); }
.brand-hero .brand-facts i { color: var(--primary); }
.brand-hero .reviews span { color: rgba(255, 255, 255, 0.75); }
.brand-hero .hero-background {
    background: radial-gradient(circle, rgba(var(--primary-rgb), 0.22) 0%, rgba(0, 0, 0, 0) 60%);
}
.brand-hero .image-wrapper.glass-panel {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.14);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.brand-hero .floating-card { background: #fff; }

/* .hero-mobile-call (layout.css) gives every "Call ..." button a solid
   navy-gradient fill — right for the root site's light hero (navy pops
   against white) but wrong here: .brand-hero's OWN background is that
   exact same navy gradient (see .brand-hero::before above), so the
   button all but disappeared into the hero behind it (flagged directly
   by the user from a screenshot — "both cta and hero section has similar
   blue background colour"). Reuse the site's existing
   .btn-outline-on-dark treatment (transparent fill, semi-transparent
   white border — already used successfully elsewhere on this exact dark
   hero, e.g. the mid-page CTA bands) instead, scoped to .brand-hero
   only so the root site's light-hero button (which still wants the solid
   navy fill) is untouched. Higher specificity than the base
   .hero-mobile-call rule (two classes vs one) so it wins regardless of
   source order. */
.brand-hero .hero-mobile-call {
    background: transparent;
    color: var(--text-on-dark);
    border: 2px solid rgba(255, 255, 255, 0.4);
}
.brand-hero .hero-mobile-call:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.7);
    color: var(--text-on-dark);
}

/* Trust-chip pills under the hero CTA row (Licensed & insured / 24-7 /
   satisfaction guarantee) — same pill treatment as LocalExperts. */
.trust-chips { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.trust-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    background: rgba(255, 255, 255, 0.09);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    padding: 10px 16px;
    font-size: clamp(0.85rem, 0.25vw + 0.8rem, 0.98rem);
    font-weight: 600;
    color: #fff;
}
.trust-chip svg { color: var(--primary); flex: 0 0 auto; width: 16px; height: 16px; }

/* Floating "5.0 rated" badge on the hero image itself (separate from the
   existing bottom-left .floating-card so the two don't collide — this
   one sits inside the top-right corner of the photo). */
.hero-media-badge {
    position: absolute;
    top: 16px;
    right: 16px;
    z-index: 3;
    background: #fff;
    color: var(--accent-blue);
    border-radius: var(--radius-sm);
    padding: 12px 16px;
    box-shadow: var(--shadow-md);
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: clamp(0.8rem, 0.25vw + 0.75rem, 0.92rem);
    line-height: 1.25;
}
.hero-media-badge .stars-inline { color: var(--gold-deep, var(--primary-hover)); letter-spacing: 1px; }

@media (max-width: 720px) {
    .hero-media-badge { top: 10px; right: 10px; padding: 10px 12px; gap: 8px; }
    /* Trust chips duplicate the stats-strip immediately below on phones —
       hide here (same call LocalExperts' mobile.css makes) so the two
       don't repeat the same "24/7 / licensed / guarantee" claims twice
       in a row on a narrow screen. */
    .trust-chips { display: none; }
}

/* ==========================================================================
   MOBILE TYPE & CTA POLISH
   ------------------------------------------------------------------------
   A full-width, big-type pass for phones (≤600px): the inline CTA bands
   read too small/cramped against their new solid-navy .card-navy
   background, and several titles/subtitles/labels elsewhere on the page
   used their clamp() *minimum* size at this width, which is comfortable
   on desktop but reads small as the main, only thing on a phone screen.
   Everything here only changes size/layout at this breakpoint — colors
   and structure are untouched.
   ========================================================================== */
@media (max-width: 600px) {
    /* Inline CTA band: full-width button (was an inline pill sitting in
       a lot of empty navy space) and a noticeably bigger line of copy
       above it, since on a phone that's the whole "headline" of the
       block. */
    .inline-cta-band { flex-direction: column; align-items: stretch; text-align: center; }
    .inline-cta-band p { font-size: 1.25rem; line-height: 1.35; }
    .inline-cta-band .btn { width: 100%; }

    /* Section titles/intros — was clamp(1.9rem,...) / clamp(1rem,...),
       both of which sit at their floor on a phone. */
    .section-header h2 { font-size: 2.05rem; }
    .section-header p { font-size: 1.08rem; }

    /* FAQ accordion questions/answers */
    .faq-question { font-size: 1.15rem; }
    .faq-answer { font-size: 1.02rem; }

    /* Process steps, trust/guarantee items — body copy inside these
       cards was noticeably smaller than the section copy around them.
       (at-a-glance is deliberately NOT bumped here — see its own
       slimmer-card rules above; bigger text there is what caused the
       3-line wrapping this block was meant to fix.) */
    .process-card h3 { font-size: 1.28rem; }
    .process-card p { font-size: 1.04rem; }
    .trust-fixed-item h4 { font-size: 1.12rem; }
    .trust-fixed-item p { font-size: 1rem; }

    /* Article copy (the long-form local intro/FAQ text) */
    .article-copy p,
    .article-copy ul,
    .article-copy ol { font-size: 1.08rem; }
    /* .badge-brand's own fluid sizing is defined below (bumping it to
       a fixed 0.92rem here — bigger than the base 0.85rem — is exactly
       what pushed "Modbury · SA 5092 · City of Tea Tree Gully" onto 2-3
       lines on phones; see the dedicated rule after this block). */
}

/* Suburb-pin hero badge ("Modbury · SA 5092 · City of Tea Tree Gully") —
   the full text at the base 0.85rem badge size doesn't fit on one line
   on any phone width once the hero's own side padding is accounted for,
   and the old mobile override above made it WORSE by bumping the size
   up rather than down. Real text width was measured with a canvas
   context at 320-1024px (the same breakpoint the site's nav/hamburger
   switches at) and the clamp below was chosen so the text always fits
   on a single line in that whole range, with the badge growing back to
   its normal 0.85rem/fixed padding on desktop (>1024px, the existing
   `.brand-hero .badge.badge-brand` / `.badge-brand` rules
   elsewhere still apply there, untouched). */
@media (max-width: 1024px) {
    .brand-hero .badge-brand {
        font-size: clamp(0.58rem, 2.3vw, 0.92rem);
        letter-spacing: 0.25px;
        padding: 6px 10px;
        gap: 5px;
        white-space: nowrap;
    }
    .brand-hero .badge-brand i { font-size: 0.9em; }
}
